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
David Baker 2017-05-25 16:45:32 +01:00
parent db45e99536
commit 39dbc4c6e1
1 changed files with 80 additions and 96 deletions

View File

@ -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;
}