mirror of https://github.com/vector-im/riot-web
Lots of changes to languageHandler
* Replace callbacks with promises * Move plain functions to top level * De-duplicate bits that fetched languages.json * Take full language preference list from the browser if we can get it, rather than just the first.pull/21833/head
parent
db45e99536
commit
39dbc4c6e1
|
@ -37,117 +37,63 @@ export function _t(...args) {
|
||||||
return counterpart.translate(...args);
|
return counterpart.translate(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setLanguage(languages) {
|
export function setLanguage(preferredLangs) {
|
||||||
request(i18nFolder + 'languages.json', function(err, response, body) {
|
if (!Array.isArray(preferredLangs)) {
|
||||||
function getLanguage(langPath, langCode, callback) {
|
preferredLangs = [preferredLangs];
|
||||||
let response_return = {};
|
|
||||||
let resp_raw = {};
|
|
||||||
request(
|
|
||||||
{ method: "GET", url: langPath },
|
|
||||||
(err, response, body) => {
|
|
||||||
if (err || response.status < 200 || response.status >= 300) {
|
|
||||||
if (response) {
|
|
||||||
if (response.status == 404 || (response.status == 0 && body == '')) {
|
|
||||||
resp_raw = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const resp = {err: err, response: resp_raw};
|
|
||||||
err = resp['err'];
|
|
||||||
const response_cb = resp['response'];
|
|
||||||
callback(err, response_cb, langCode);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response_return = JSON.parse(body);
|
let langToUse;
|
||||||
callback(null, response_return, langCode);
|
let availLangs;
|
||||||
return;
|
return getLangsJson().then((result) => {
|
||||||
|
availLangs = result;
|
||||||
|
|
||||||
|
for (let i = 0; i < preferredLangs.length; ++i) {
|
||||||
|
if (availLangs.hasOwnProperty(preferredLangs[i])) {
|
||||||
|
langToUse = preferredLangs[i];
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
return;
|
if (!langToUse) {
|
||||||
|
throw new Error("Unable to find an appropriate language");
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerTranslations(err, langJson, langCode){
|
return getLanguage(i18nFolder + availLangs[langToUse]);
|
||||||
if (err !== null) {
|
}).then((langData) => {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
counterpart.registerTranslations(langToUse, langData);
|
||||||
Modal.createDialog(ErrorDialog, {
|
counterpart.setLocale(langToUse);
|
||||||
title: counterpart.translate('Error changing language'),
|
UserSettingsStore.setLocalSetting('language', langToUse);
|
||||||
description: counterpart.translate('Riot was unable to find the correct Data for the selected Language.'),
|
console.log("set language to " + langToUse);
|
||||||
button: counterpart.translate("OK"),
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
counterpart.registerTranslations(langCode, langJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let languageFiles = {};
|
|
||||||
if(err){
|
|
||||||
console.error(err);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (body) {
|
|
||||||
languageFiles = JSON.parse(body);
|
|
||||||
} else {
|
|
||||||
languageFiles = JSON.parse('{"en": "en_EN.json"}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const isValidFirstLanguage = (languageFiles.hasOwnProperty(languages[0]));
|
|
||||||
var validLanguageKey = "";
|
|
||||||
if ((isValidFirstLanguage) || (languages.length==2 && languageFiles.hasOwnProperty(languages[1]))) {
|
|
||||||
validLanguageKey = (isValidFirstLanguage) ? languages[0] : languages[1];
|
|
||||||
getLanguage(i18nFolder + languageFiles[validLanguageKey], validLanguageKey, registerTranslations);
|
|
||||||
counterpart.setLocale(validLanguageKey);
|
|
||||||
UserSettingsStore.setLocalSetting('language', validLanguageKey);
|
|
||||||
console.log("set language to "+validLanguageKey);
|
|
||||||
} else {
|
|
||||||
console.log("didnt find any language file");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 'en' as fallback language:
|
// Set 'en' as fallback language:
|
||||||
if (validLanguageKey!="en") {
|
if (langToUse != "en") {
|
||||||
getLanguage(i18nFolder + languageFiles['en'], 'en', registerTranslations);
|
return getLanguage(i18nFolder + availLangs['en']);
|
||||||
}
|
}
|
||||||
counterpart.setFallbackLocale('en');
|
}).then((langData) => {
|
||||||
|
if (langData) counterpart.registerTranslations('en', langData);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getAllLanguageKeysFromJson() {
|
export function getAllLanguageKeysFromJson() {
|
||||||
let deferred = q.defer();
|
return getLangsJson().then((langs) => {
|
||||||
|
return Object.keys(langs);
|
||||||
request(
|
});
|
||||||
{ method: "GET", url: i18nFolder + 'languages.json' },
|
|
||||||
(err, response, body) => {
|
|
||||||
if (err || response.status < 200 || response.status >= 300) {
|
|
||||||
if (response) {
|
|
||||||
if (response.status == 404 || (response.status == 0 && body == '')) {
|
|
||||||
deferred.resolve({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deferred.reject({err: err, response: response});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var languages = JSON.parse(body);
|
|
||||||
// If no language is found, fallback to 'en':
|
|
||||||
if (!languages) {
|
|
||||||
languages = [{"en": "en_EN.json"}];
|
|
||||||
}
|
|
||||||
const languageKeys = Object.keys(languages);
|
|
||||||
deferred.resolve(languageKeys);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLanguageFromBrowser() {
|
export function getLanguagesFromBrowser() {
|
||||||
return navigator.languages[0] || navigator.language || navigator.userLanguage;
|
if (navigator.languages) return navigator.languages;
|
||||||
|
if (navigator.language) return [navigator.language]
|
||||||
|
return [navigator.userLanguage];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a language string, normalises it,
|
||||||
|
* (see normalizeLanguageKey) into an array of language strings
|
||||||
|
* with fallback to generic languages
|
||||||
|
* (eg. 'pt-BR' => ['pt-br', 'pt'])
|
||||||
|
*
|
||||||
|
* @param {string} language The input language string
|
||||||
|
* @return {string[]} List of normalised languages
|
||||||
|
*/
|
||||||
export function getNormalizedLanguageKeys(language) {
|
export function getNormalizedLanguageKeys(language) {
|
||||||
if (!language) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const languageKeys = [];
|
const languageKeys = [];
|
||||||
const normalizedLanguage = this.normalizeLanguageKey(language);
|
const normalizedLanguage = this.normalizeLanguageKey(language);
|
||||||
const languageParts = normalizedLanguage.split('-');
|
const languageParts = normalizedLanguage.split('-');
|
||||||
|
@ -162,6 +108,44 @@ export function getNormalizedLanguageKeys(language) {
|
||||||
return languageKeys;
|
return languageKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a language string with underscores replaced with
|
||||||
|
* hyphens, and lowercased.
|
||||||
|
*/
|
||||||
export function normalizeLanguageKey(language) {
|
export function normalizeLanguageKey(language) {
|
||||||
return language.toLowerCase().replace("_","-");
|
return language.toLowerCase().replace("_","-");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getLangsJson() {
|
||||||
|
const deferred = q.defer();
|
||||||
|
|
||||||
|
request(
|
||||||
|
{ method: "GET", url: i18nFolder + 'languages.json' },
|
||||||
|
(err, response, body) => {
|
||||||
|
if (err || response.status < 200 || response.status >= 300) {
|
||||||
|
deferred.reject({err: err, response: response});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deferred.resolve(JSON.parse(body));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguage(langPath) {
|
||||||
|
const deferred = q.defer();
|
||||||
|
|
||||||
|
let response_return = {};
|
||||||
|
request(
|
||||||
|
{ method: "GET", url: langPath },
|
||||||
|
(err, response, body) => {
|
||||||
|
if (err || response.status < 200 || response.status >= 300) {
|
||||||
|
deferred.reject({err: err, response: response});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.resolve(JSON.parse(body));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue