Skip to content
Snippets Groups Projects
Unverified Commit 62e95410 authored by Marcelo Schmidt's avatar Marcelo Schmidt
Browse files

Automatically display translated texts

parent dfb100eb
No related branches found
No related tags found
No related merge requests found
Meteor.startup(function() {
Tracker.autorun(function() {
if (RocketChat.settings.get('AutoTranslate_Enabled')) {
RocketChat.callbacks.add('renderMessage', (message) => {
if (message.u._id !== Meteor.userId()) {
const subscription = RocketChat.models.Subscriptions.findOne({ rid: message.rid }, { fields: { autoTranslate: 1, autoTranslateLanguage: 1, autoTranslateDisplay: 1 } });
if (subscription && subscription.autoTranslate === true && subscription.autoTranslateDisplay === true && subscription.autoTranslateLanguage) {
const autoTranslateLanguage = subscription.autoTranslateLanguage;
if (!message.translations) {
message.translations = {};
}
message.translations['original'] = message.html;
if (message.translations[autoTranslateLanguage]) {
message.html = message.translations[autoTranslateLanguage];
}
return message;
}
}
}, RocketChat.callbacks.priority.HIGH - 3, 'autotranslate');
} else {
RocketChat.callbacks.remove('renderMessage', 'autotranslate');
}
});
});
......@@ -9,18 +9,10 @@
<li>
<label>{{_ "Enabled"}}</label>
<div>
{{#if editing 'autoTranslate'}}
<label>
<select name="autoTranslate">
<option value="" selected="{{$eq autoTranslate false}}">{{_ "False"}}</option>
<option value="1" selected="{{$eq autoTranslate true}}">{{_ "True"}}</option>
</select>
</label>
<button type="button" class="button cancel">{{_ "Cancel"}}</button>
<button type="button" class="button primary save">{{_ "Save"}}</button>
{{else}}
<span class="current-setting">{{autoTranslateValue}} <i class="icon-pencil" data-edit="autoTranslate"></i></span>
{{/if}}
<div class="input checkbox toggle">
<input type="checkbox" id="autoTranslate" name="autoTranslate" value="1" checked="{{$eq autoTranslate true}}" />
<label for="autoTranslate"></label>
</div>
</div>
</li>
{{#if $eq autoTranslate true}}
......@@ -38,10 +30,19 @@
<button type="button" class="button cancel">{{_ "Cancel"}}</button>
<button type="button" class="button primary save">{{_ "Save"}}</button>
{{else}}
<span class="current-setting">{{autoTranslateLanguage}} <i class="icon-pencil" data-edit="autoTranslateLanguage"></i></span>
<span class="current-setting">{{languageName autoTranslateLanguage}} <i class="icon-pencil" data-edit="autoTranslateLanguage"></i></span>
{{/if}}
</div>
</li>
<li>
<label>{{_ "Display_translated_text"}}</label>
<div>
<div class="input checkbox toggle">
<input type="checkbox" id="autoTranslateDisplay" name="autoTranslateDisplay" value="1" checked="{{$eq autoTranslateDisplay true}}"/>
<label for="autoTranslateDisplay"></label>
</div>
</div>
</li>
{{/if}}
</ul>
</form>
......
......@@ -13,6 +13,17 @@ Template.autoTranslateFlexTab.helpers({
return sub && sub.autoTranslate ? true : false;
},
autoTranslateDisplay() {
const sub = ChatSubscription.findOne({
rid: Session.get('openedRoom')
}, {
fields: {
autoTranslateDisplay: 1
}
});
return sub && sub.autoTranslateDisplay ? true : false;
},
autoTranslateValue() {
const sub = ChatSubscription.findOne({
rid: Session.get('openedRoom')
......@@ -35,7 +46,7 @@ Template.autoTranslateFlexTab.helpers({
const autoTranslateLanguage = sub && sub.autoTranslateLanguage;
const supportedLanguages = Template.instance().supportedLanguages.get();
const language = _.findWhere(supportedLanguages, { language: autoTranslateLanguage });
return language && (language.name || language.language) || autoTranslateLanguage;
return language && language.language || autoTranslateLanguage || (Meteor.user() && Meteor.user().language);
},
editing(field) {
......@@ -44,6 +55,12 @@ Template.autoTranslateFlexTab.helpers({
supportedLanguages() {
return Template.instance().supportedLanguages.get();
},
languageName(language) {
const supportedLanguages = Template.instance().supportedLanguages.get();
language = _.findWhere(supportedLanguages, { language: language });
return language && language.name;
}
});
......@@ -56,15 +73,13 @@ Template.autoTranslateFlexTab.onCreated(function() {
});
this.validateSetting = (field) => {
const value = this.$('select[name='+ field +']').val();
let value;
switch (field) {
case 'autoTranslate':
if (['', '1'].indexOf(value) === -1) {
toastr.error(t('Invalid_setting_s'), value || '');
return false;
}
case 'autoTranslateDisplay':
return true;
case 'autoTranslateLanguage':
value = this.$('select[name='+ field +']').val();
if (!_.findWhere(this.supportedLanguages.get(), { language: value })) {
toastr.error(t('Invalid_setting_s', value || ''));
return false;
......@@ -75,7 +90,17 @@ Template.autoTranslateFlexTab.onCreated(function() {
this.saveSetting = () => {
const field = this.editing.get();
const value = this.$('select[name='+field+']').val();
let value;
switch (field) {
case 'autoTranslate':
case 'autoTranslateDisplay':
value = this.$('input[name='+field+']').prop('checked') ? '1' : '0';
break;
case 'autoTranslateLanguage':
value = this.$('select[name='+ field +']').val();
break;
}
if (this.validateSetting(field)) {
Meteor.call('autoTranslate.saveSettings', Session.get('openedRoom'), field, value, (err/*, result*/) => {
if (err) {
......@@ -101,6 +126,11 @@ Template.autoTranslateFlexTab.events({
setTimeout(function() { instance.$('input.editing').focus().select(); }, 100);
},
'change [type=checkbox]'(e, instance) {
instance.editing.set($(e.currentTarget).attr('name'));
instance.saveSetting();
},
'click .cancel'(e, instance) {
e.preventDefault();
instance.editing.set();
......
......@@ -17,6 +17,7 @@ Package.onUse(function(api) {
api.addFiles([
'client/stylesheets/autotranslate.less',
'client/lib/autotranslate.js',
'client/lib/tabBar.js',
'client/views/autoTranslateFlexTab.html',
'client/views/autoTranslateFlexTab.js'
......
......@@ -3,6 +3,7 @@ class AutoTranslate {
this.languages = [];
this.enabled = RocketChat.settings.get('AutoTranslate_Enabled');
this.apiKey = RocketChat.settings.get('AutoTranslate_GoogleAPIKey');
this.supportedLanguages = {};
RocketChat.callbacks.add('afterSaveMessage', this.translateMessage.bind(this), RocketChat.callbacks.priority.MEDIUM, 'AutoTranslate');
}
......@@ -66,10 +67,8 @@ class AutoTranslate {
translateMessage(message, room) {
if (this.enabled && this.apiKey && message.msg) {
Meteor.defer(() => {
// console.log(RocketChat.models.Subscriptions.getAutoTranslateLanguages());
const translations = {};
const targetLanguages = ['pt', 'es'];
const targetLanguages = RocketChat.models.Subscriptions.getAutoTranslateLanguagesByRoom(room._id);
message.html = s.escapeHTML(String(message.msg));
message = this.tokenize(message);
......@@ -94,20 +93,33 @@ class AutoTranslate {
getSupportedLanguages(target) {
if (this.enabled && this.apiKey) {
if (this.supportedLanguages[target]) {
return this.supportedLanguages[target];
}
let result;
const params = { key: this.apiKey };
if (target) {
params.target = target;
}
try {
result = HTTP.get('https://translation.googleapis.com/language/translate/v2/languages', { params: params });
} catch (e) {
if (e.response && e.response.statusCode === 400 && e.response.data && e.response.data.error && e.response.data.error.status === 'INVALID_ARGUMENT') {
delete params.target;
result = HTTP.get('https://translation.googleapis.com/language/translate/v2/languages', { params: params });
target = 'en';
if (!this.supportedLanguages[target]) {
result = HTTP.get('https://translation.googleapis.com/language/translate/v2/languages', { params: params });
}
}
} finally {
return result && result.data && result.data.data && result.data.data.languages;
if (this.supportedLanguages[target]) {
return this.supportedLanguages[target];
} else {
this.supportedLanguages[target || 'en'] = result && result.data && result.data.data && result.data.data.languages;
return this.supportedLanguages[target || 'en'];
}
}
}
}
......
......@@ -8,7 +8,7 @@ Meteor.methods({
check(field, String);
check(value, String);
if (['autoTranslate', 'autoTranslateLanguage'].indexOf(field) === -1) {
if (['autoTranslate', 'autoTranslateLanguage', 'autoTranslateDisplay'].indexOf(field) === -1) {
throw new Meteor.Error('error-invalid-settings', 'Invalid settings field', { method: 'saveAutoTranslateSettings' });
}
......@@ -21,6 +21,9 @@ Meteor.methods({
case 'autoTranslate':
RocketChat.models.Subscriptions.updateAutoTranslateById(subscription._id, value === '1' ? true : false);
break;
case 'autoTranslateDisplay':
RocketChat.models.Subscriptions.updateAutoTranslateDisplayById(subscription._id, value === '1' ? true : false);
break;
case 'autoTranslateLanguage':
RocketChat.models.Subscriptions.updateAutoTranslateLanguageById(subscription._id, value);
break;
......
......@@ -35,3 +35,34 @@ RocketChat.models.Subscriptions.updateAutoTranslateLanguageById = function(_id,
return this.update(query, update);
};
RocketChat.models.Subscriptions.updateAutoTranslateDisplayById = function(_id, autoTranslateDisplay) {
const query = {
_id: _id
};
let update;
if (autoTranslateDisplay) {
update = {
$set: {
autoTranslateDisplay: autoTranslateDisplay
}
};
} else {
update = {
$unset: {
autoTranslateDisplay: 1
}
};
}
return this.update(query, update);
};
RocketChat.models.Subscriptions.getAutoTranslateLanguagesByRoom = function(rid) {
const subscriptionsRaw = RocketChat.models.Subscriptions.model.rawCollection();
const distinct = Meteor.wrapAsync(subscriptionsRaw.distinct, subscriptionsRaw);
const query = {
rid: rid,
autoTranslate: true
};
return distinct('autoTranslateLanguage', query);
};
......@@ -398,6 +398,7 @@
"Direct_message_someone": "Direct message someone",
"Direct_Messages": "Direct Messages",
"Display_offline_form": "Display offline form",
"Display_translated_text": "Display translated text",
"Displays_action_text": "Displays action text",
"Do_you_want_to_change_to_s_question": "Do you want to change to <strong>%s</strong>?",
"Domain": "Domain",
......
......@@ -22,7 +22,8 @@ const fields = {
blocked: 1,
blocker: 1,
autoTranslate: 1,
autoTranslateLanguage: 1
autoTranslateLanguage: 1,
autoTranslateDisplay: 1
};
Meteor.methods({
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment