diff --git a/app.js b/app.js
index 2b6e21982..570c48706 100644
--- a/app.js
+++ b/app.js
@@ -29,6 +29,7 @@ import API from './modules/API/API';
import UIEvents from './service/UI/UIEvents';
import getTokenData from "./modules/TokenData/TokenData";
+import translation from "./modules/translation/translation";
/**
* Tries to push history state with the following parameters:
@@ -95,6 +96,7 @@ const APP = {
UI,
settings,
conference,
+ translation,
/**
* After the APP has been initialized provides utility methods for dealing
* with the conference room URL(address).
@@ -106,7 +108,6 @@ const APP = {
init () {
this.keyboardshortcut =
require("./modules/keyboardshortcut/keyboardshortcut");
- this.translation = require("./modules/translation/translation");
this.configFetch = require("./modules/config/HttpConfigFetch");
this.tokenData = getTokenData();
}
diff --git a/lang/languages.json b/lang/languages.json
index b0a73eada..235c7b75b 100644
--- a/lang/languages.json
+++ b/lang/languages.json
@@ -1,6 +1,5 @@
{
"en": "English",
-
"bg": "Bulgarian",
"de": "German",
"es": "Spanish",
diff --git a/modules/UI/side_pannels/settings/SettingsMenu.js b/modules/UI/side_pannels/settings/SettingsMenu.js
index f6a3d263c..3f8bc8451 100644
--- a/modules/UI/side_pannels/settings/SettingsMenu.js
+++ b/modules/UI/side_pannels/settings/SettingsMenu.js
@@ -105,6 +105,9 @@ export default {
APP.translation.translateElement(selectEl);
+ APP.translation.addLanguageChangedListener(
+ lng => selectInput[0].dataset.i18n = `languages:${lng}`);
+
UIUtil.showElement(wrapperId);
}
// DEVICES LIST
diff --git a/modules/translation/translation.js b/modules/translation/translation.js
index 42afc7045..6597db936 100644
--- a/modules/translation/translation.js
+++ b/modules/translation/translation.js
@@ -1,15 +1,16 @@
/* global $, require, config, interfaceConfig */
-var i18n = require("i18next-client");
-var languages = require("../../service/translation/languages");
-var DEFAULT_LANG = languages.EN;
+import i18n from 'i18next';
+import XHR from 'i18next-xhr-backend';
+import jqueryI18next from 'jquery-i18next';
+import languagesR from "../../lang/languages.json";
+import mainR from "../../lang/main.json";
+import languages from "../../service/translation/languages";
-i18n.addPostProcessor(
- "resolveAppName",
- value => value.replace("__app__", interfaceConfig.APP_NAME));
+const DEFAULT_LANG = languages.EN;
-var defaultOptions = {
- detectLngQS: "lang",
- useCookie: false,
+const defaultOptions = {
+ compatibilityAPI: 'v1',
+ compatibilityJSON: 'v1',
fallbackLng: DEFAULT_LANG,
load: "unspecific",
resGetPath: 'lang/__ns__-__lng__.json',
@@ -21,48 +22,11 @@ var defaultOptions = {
fallbackOnNull: true,
fallbackOnEmpty: true,
useDataAttrOptions: true,
- app: interfaceConfig.APP_NAME,
- getAsync: true,
- defaultValueFromContent: false,
- customLoad: function(lng, ns, options, done) {
- var resPath = "lang/__ns__-__lng__.json";
- if(lng === languages.EN)
- resPath = "lang/__ns__.json";
- var url = i18n.functions.applyReplacement(resPath,
- { lng: lng, ns: ns });
- i18n.functions.ajax({
- url: url,
- success: function(data) {
- i18n.functions.log('loaded: ' + url);
- done(null, data);
- },
- error : function(xhr, status, error) {
- if ((status && status == 200) ||
- (xhr && xhr.status && xhr.status == 200)) {
- // file loaded but invalid json, stop waste time !
- i18n.functions.error('There is a typo in: ' + url);
- } else if ((status && status == 404) ||
- (xhr && xhr.status && xhr.status == 404)) {
- i18n.functions.log('Does not exist: ' + url);
- } else {
- var theStatus = status ? status :
- ((xhr && xhr.status) ? xhr.status : null);
- i18n.functions.log(theStatus + ' when loading ' + url);
- }
-
- done(error, {});
- },
- dataType: "json",
- async : options.getAsync
- });
- }
- // options for caching
-// useLocalStorage: true,
-// localStorageExpirationTime: 86400000 // in ms, default 1 week
+ app: interfaceConfig.APP_NAME
};
function initCompleted() {
- $("[data-i18n]").i18n();
+ $("[data-i18n]").localize();
}
function getLangFromQuery() {
@@ -78,8 +42,8 @@ function getLangFromQuery() {
return null;
}
-module.exports = {
- init: function (settingsLang) {
+class Translation {
+ init (settingsLang) {
let options = defaultOptions;
let lang = getLangFromQuery() || settingsLang || config.defaultLanguage;
@@ -98,31 +62,48 @@ module.exports = {
options.lng = lang;
}
- i18n.init(options, initCompleted);
- },
- setLanguage: function (lang) {
+ i18n.use(XHR)
+ .use({
+ type: 'postProcessor',
+ name: "resolveAppName",
+ process: (res, key) => {
+ return i18n.t(key, {app: options.app});
+ }
+ })
+ .init(options, initCompleted);
+ // adds default language which is preloaded from code
+ i18n.addResourceBundle(DEFAULT_LANG, 'main', mainR, true, true);
+ i18n.addResourceBundle(
+ DEFAULT_LANG, 'languages', languagesR, true, true);
+ jqueryI18next.init(i18n, $, {useOptionsAttr: true});
+ }
+
+ setLanguage (lang) {
if(!lang)
lang = DEFAULT_LANG;
i18n.setLng(lang, defaultOptions, initCompleted);
- },
- getCurrentLanguage: function () {
- return i18n.lng();
- },
- translateElement: function (selector, options) {
- // i18next expects undefined if options are missing, check if its null
- selector.i18n(
- options === null ? undefined : options);
- },
- generateTranslationHTML: function (key, options) {
- var str = "";
- // i18next expects undefined if options ARE missing, check if its null
- str += i18n.t(key, options === null ? undefined : options);
- str += "";
- return str;
-
}
-};
+
+ getCurrentLanguage () {
+ return i18n.lng();
+ }
+
+ translateElement (selector, options) {
+ // i18next expects undefined if options are missing, check if its null
+ selector.localize(
+ options === null ? undefined : options);
+ }
+
+ generateTranslationHTML (key, options) {
+ let optAttr = options
+ ? ` data-i18n-options='${JSON.stringify(options)}'` : "";
+ let text = i18n.t(key, options === null ? undefined : options);
+ return `${text}`;
+ }
+
+ addLanguageChangedListener(listener) {
+ i18n.on('languageChanged', listener);
+ }
+}
+
+export default new Translation();
diff --git a/package.json b/package.json
index 58bf98625..64958eaa2 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,10 @@
"autosize": "^1.18.13",
"bootstrap": "3.1.1",
"events": "*",
- "i18next-client": "1.7.7",
+ "i18next": "3.4.4",
+ "i18next-xhr-backend": "1.1.0",
+ "jquery-i18next": "1.1.0",
+ "json-loader": "0.5.4",
"jQuery-Impromptu": "trentrichardson/jQuery-Impromptu#v6.0.0",
"jquery": "~2.1.1",
"jquery-contextmenu": "*",
diff --git a/service/translation/languages.js b/service/translation/languages.js
index 8a714377d..20c2f134c 100644
--- a/service/translation/languages.js
+++ b/service/translation/languages.js
@@ -1,4 +1,4 @@
-module.exports = {
+export default {
getLanguages : function () {
var languages = [];
for (var lang in this)
diff --git a/webpack.config.js b/webpack.config.js
index d3362a785..977f9aa57 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -58,6 +58,11 @@ var config = {
name: '[path][name].[ext]'
},
test: /\.(gif|png|svg)$/
+ },{
+ //Adds the ability to import json files.
+ loader: 'json',
+ exclude: __dirname + '/node_modules/',
+ test: /\.json$/
}],
noParse: [
// Do not parse the files of the Strophe.js library or at least