-
Notifications
You must be signed in to change notification settings - Fork 3k
/
index.js
107 lines (97 loc) · 3.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Str from 'expensify-common/lib/str';
import * as RNLocalize from 'react-native-localize';
import Log from '../Log';
import Config from '../../CONFIG';
import translations from '../../languages/translations';
import CONST from '../../CONST';
import LocaleListener from './LocaleListener';
import BaseLocaleListener from './LocaleListener/BaseLocaleListener';
// Listener when an update in Onyx happens so we use the updated locale when translating/localizing items.
LocaleListener.connect();
/**
* Return translated string for given locale and phrase
*
* @param {String} [desiredLanguage] eg 'en', 'es-ES'
* @param {String|Array} phraseKey
* @param {Object} [phraseParameters] Parameters to supply if the phrase is a template literal.
* @returns {String}
*/
function translate(desiredLanguage = CONST.LOCALES.DEFAULT, phraseKey, phraseParameters = {}) {
const languageAbbreviation = desiredLanguage.substring(0, 2);
let translatedPhrase;
// Search phrase in full locale e.g. es-ES
const desiredLanguageDictionary = lodashGet(translations, desiredLanguage);
translatedPhrase = lodashGet(desiredLanguageDictionary, phraseKey);
if (translatedPhrase) {
return Str.result(translatedPhrase, phraseParameters);
}
// Phrase is not found in full locale, search it in fallback language e.g. es
const fallbackLanguageDictionary = lodashGet(translations, languageAbbreviation);
translatedPhrase = lodashGet(fallbackLanguageDictionary, phraseKey);
if (translatedPhrase) {
return Str.result(translatedPhrase, phraseParameters);
}
if (languageAbbreviation !== CONST.LOCALES.DEFAULT) {
Log.alert(`${phraseKey} was not found in the ${languageAbbreviation} locale`);
}
// Phrase is not translated, search it in default language (en)
const defaultLanguageDictionary = lodashGet(translations, CONST.LOCALES.DEFAULT, {});
translatedPhrase = lodashGet(defaultLanguageDictionary, phraseKey);
if (translatedPhrase) {
return Str.result(translatedPhrase, phraseParameters);
}
// Phrase is not found in default language, on production log an alert to server
// on development throw an error
if (Config.IS_IN_PRODUCTION) {
const phraseString = _.isArray(phraseKey) ? phraseKey.join('.') : phraseKey;
Log.alert(`${phraseString} was not found in the en locale`);
return phraseString;
}
throw new Error(`${phraseKey} was not found in the default language`);
}
/**
* Uses the locale in this file updated by the Onyx subscriber.
*
* @param {String|Array} phrase
* @param {Object} [variables]
* @returns {String}
*/
function translateLocal(phrase, variables) {
return translate(BaseLocaleListener.getPreferredLocale(), phrase, variables);
}
/**
* Format an array into a string with comma and "and" ("a dog, a cat and a chicken")
*
* @param {Array} anArray
* @return {String}
*/
function arrayToString(anArray) {
const and = this.translateLocal('common.and');
let aString = '';
if (_.size(anArray) === 1) {
aString = anArray[0];
} else if (_.size(anArray) === 2) {
aString = anArray.join(` ${and} `);
} else if (_.size(anArray) > 2) {
aString = `${anArray.slice(0, -1).join(', ')} ${and} ${anArray.slice(-1)}`;
}
return aString;
}
/**
* Returns the user device's preferred language.
*
* @return {String}
*/
function getDevicePreferredLocale() {
return lodashGet(
RNLocalize.findBestAvailableLanguage([CONST.LOCALES.EN, CONST.LOCALES.ES]), 'languageTag', CONST.LOCALES.DEFAULT,
);
}
export {
translate,
translateLocal,
arrayToString,
getDevicePreferredLocale,
};