From e1f967869a2b58e26257ce62d16ca0c94995fdd2 Mon Sep 17 00:00:00 2001 From: Lyubo Marinov Date: Fri, 26 Jan 2018 12:18:43 -0600 Subject: [PATCH] [RN] Add builtin translations --- .../base/i18n/BuiltinLanguages.native.js | 147 ++++++++---------- react/features/base/i18n/i18next.js | 20 +-- react/features/base/react/functions.js | 33 ---- react/features/base/react/functions.web.js | 0 react/features/recent-list/functions.js | 61 ++++---- 5 files changed, 107 insertions(+), 154 deletions(-) delete mode 100644 react/features/base/react/functions.js create mode 100644 react/features/base/react/functions.web.js diff --git a/react/features/base/i18n/BuiltinLanguages.native.js b/react/features/base/i18n/BuiltinLanguages.native.js index aedba94a8..4558e009a 100644 --- a/react/features/base/i18n/BuiltinLanguages.native.js +++ b/react/features/base/i18n/BuiltinLanguages.native.js @@ -1,144 +1,129 @@ +// @flow + import i18next from 'i18next'; /** - * Collection of builtin languages. + * The builtin languages. */ -const languages = [ +const _LANGUAGES = { // Bulgarian - { - name: 'bg', - mainResource: require('../../../../lang/main-bg'), - langResource: require('../../../../lang/languages-bg') + 'bg': { + languages: require('../../../../lang/languages-bg'), + main: require('../../../../lang/main-bg') }, // German - { - name: 'de', - mainResource: require('../../../../lang/main-de'), - langResource: require('../../../../lang/languages-de') + 'de': { + languages: require('../../../../lang/languages-de'), + main: require('../../../../lang/main-de') }, // Esperanto - { - name: 'eo', - mainResource: require('../../../../lang/main-eo'), - langResource: require('../../../../lang/languages-eo') + 'eo': { + languages: require('../../../../lang/languages-eo'), + main: require('../../../../lang/main-eo') }, // Spanish - { - name: 'es', - mainResource: require('../../../../lang/main-es'), - langResource: require('../../../../lang/languages-es') + 'es': { + languages: require('../../../../lang/languages-es'), + main: require('../../../../lang/main-es') }, // French - { - name: 'fr', - mainResource: require('../../../../lang/main-fr'), - langResource: require('../../../../lang/languages-fr') + 'fr': { + languages: require('../../../../lang/languages-fr'), + main: require('../../../../lang/main-fr') }, // Armenian - { - name: 'hy', - mainResource: require('../../../../lang/main-hy'), - langResource: require('../../../../lang/languages-hy') + 'hy': { + languages: require('../../../../lang/languages-hy'), + main: require('../../../../lang/main-hy') }, // Italian - { - name: 'it', - mainResource: require('../../../../lang/main-it'), - langResource: require('../../../../lang/languages-it') + 'it': { + languages: require('../../../../lang/languages-it'), + main: require('../../../../lang/main-it') }, // Norwegian Bokmal - { - name: 'nb', - mainResource: require('../../../../lang/main-nb'), - langResource: require('../../../../lang/languages-nb') + 'nb': { + languages: require('../../../../lang/languages-nb'), + main: require('../../../../lang/main-nb') }, // Occitan - { - name: 'oc', - mainResource: require('../../../../lang/main-oc'), - langResource: require('../../../../lang/languages-oc') + 'oc': { + languages: require('../../../../lang/languages-oc'), + main: require('../../../../lang/main-oc') }, // Polish - { - name: 'pl', - mainResource: require('../../../../lang/main-pl'), - langResource: require('../../../../lang/languages-pl') + 'pl': { + languages: require('../../../../lang/languages-pl'), + main: require('../../../../lang/main-pl') }, // Portuguese (Brazil) - { - name: 'ptBR', - mainResource: require('../../../../lang/main-ptBR'), - langResource: require('../../../../lang/languages-ptBR') + 'ptBR': { + languages: require('../../../../lang/languages-ptBR'), + main: require('../../../../lang/main-ptBR') }, // Russian - { - name: 'ru', - mainResource: require('../../../../lang/main-ru'), - langResource: require('../../../../lang/languages-ru') + 'ru': { + languages: require('../../../../lang/languages-ru'), + main: require('../../../../lang/main-ru') }, // Slovak - { - name: 'sk', - mainResource: require('../../../../lang/main-sk'), - langResource: require('../../../../lang/languages-sk') + 'sk': { + languages: require('../../../../lang/languages-sk'), + main: require('../../../../lang/main-sk') }, // Slovenian - { - name: 'sl', - mainResource: require('../../../../lang/main-sl'), - langResource: require('../../../../lang/languages-sl') + 'sl': { + languages: require('../../../../lang/languages-sl'), + main: require('../../../../lang/main-sl') }, // Swedish - { - name: 'sv', - mainResource: require('../../../../lang/main-sv'), - langResource: require('../../../../lang/languages-sv') + 'sv': { + languages: require('../../../../lang/languages-sv'), + main: require('../../../../lang/main-sv') }, // Turkish - { - name: 'tr', - mainResource: require('../../../../lang/main-tr'), - langResource: require('../../../../lang/languages-tr') + 'tr': { + languages: require('../../../../lang/languages-tr'), + main: require('../../../../lang/main-tr') }, // Chinese (China) - { - name: 'zhCN', - mainResource: require('../../../../lang/main-zhCN'), - langResource: require('../../../../lang/languages-zhCN') + 'zhCN': { + languages: require('../../../../lang/languages-zhCN'), + main: require('../../../../lang/main-zhCN') } -]; +}; + +// Register all builtin languages with the i18n library. +for (const name in _LANGUAGES) { // eslint-disable-line guard-for-in + const { languages, main } = _LANGUAGES[name]; -/** - * Registers all builtin languages with the i18n library. - */ -for (const language of languages) { i18next.addResourceBundle( - language.name, - 'main', - language.mainResource, + name, + 'languages', + languages, /* deep */ true, /* overwrite */ true); i18next.addResourceBundle( - language.name, - 'languages', - language.langResource, + name, + 'main', + main, /* deep */ true, /* overwrite */ true); } diff --git a/react/features/base/i18n/i18next.js b/react/features/base/i18n/i18next.js index 20001a6f9..6e9d9b6bd 100644 --- a/react/features/base/i18n/i18next.js +++ b/react/features/base/i18n/i18next.js @@ -1,4 +1,4 @@ -/* @flow */ +// @flow import i18next from 'i18next'; import I18nextXHRBackend from 'i18next-xhr-backend'; @@ -68,23 +68,23 @@ i18next .init(options); // Add default language which is preloaded from the source code. -i18next.addResourceBundle( - DEFAULT_LANGUAGE, - 'main', - MAIN_RESOURCES, - /* deep */ true, - /* overwrite */ true); i18next.addResourceBundle( DEFAULT_LANGUAGE, 'languages', LANGUAGES_RESOURCES, /* deep */ true, /* overwrite */ true); +i18next.addResourceBundle( + DEFAULT_LANGUAGE, + 'main', + MAIN_RESOURCES, + /* deep */ true, + /* overwrite */ true); // Add builtin languages. -// XXX: Note we are using require here, because we want the side-effects of -// the import, but imports can only be placed at the top, and it would be -// too early, since i18next is not yet initialized at that point. +// XXX: Note we are using require here, because we want the side-effects of the +// import, but imports can only be placed at the top, and it would be too early, +// since i18next is not yet initialized at that point. require('./BuiltinLanguages'); export default i18next; diff --git a/react/features/base/react/functions.js b/react/features/base/react/functions.js deleted file mode 100644 index 9b0f163e7..000000000 --- a/react/features/base/react/functions.js +++ /dev/null @@ -1,33 +0,0 @@ -/* @flow */ - -/* eslint-disable flowtype/space-before-type-colon */ - -/** - * Prevents further propagation of the events to be handler by a specific event - * handler/listener in the capturing and bubbling phases. - * - * @param {Function} eventHandler - The event handler/listener which handles - * events that need to be stopped from propagating. - * @returns {Function} An event handler/listener to be used in place of the - * specified eventHandler in order to stop the events from propagating. - */ -export function stopEventPropagation(eventHandler: (ev: Event) => T) - : (ev: Event) => T { - -/* eslint-enable flowtype/space-before-type-colon */ - - return (ev: Event): T => { - const r = eventHandler(ev); - - // React Native does not propagate the press event so, for the sake of - // cross-platform compatibility, stop the propagation on Web as well. - // Additionally, use feature checking in order to deal with browser - // differences. - if (ev && ev.stopPropagation) { - ev.stopPropagation(); - ev.preventDefault && ev.preventDefault(); - } - - return r; - }; -} diff --git a/react/features/base/react/functions.web.js b/react/features/base/react/functions.web.js new file mode 100644 index 000000000..e69de29bb diff --git a/react/features/recent-list/functions.js b/react/features/recent-list/functions.js index d78774bcd..eb4447b64 100644 --- a/react/features/recent-list/functions.js +++ b/react/features/recent-list/functions.js @@ -2,17 +2,17 @@ import moment from 'moment'; -import { RECENT_URL_STORAGE } from './constants'; - import { i18next } from '../base/i18n'; import { parseURIString } from '../base/util'; +import { RECENT_URL_STORAGE } from './constants'; + /** - * MomentJS uses static language bundle loading, so in order to support - * dynamic language selection in the app we need to load all bundles that we - * support in the app. - * FIXME: If we decide to support MomentJS in other features as well - * we may need to move this import and the lenient matcher to the i18n feature. + * MomentJS uses static language bundle loading, so in order to support dynamic + * language selection in the app we need to load all bundles that we support in + * the app. + * FIXME: If we decide to support MomentJS in other features as well we may need + * to move this import and the lenient matcher to the i18n feature. */ require('moment/locale/bg'); require('moment/locale/de'); @@ -23,8 +23,7 @@ require('moment/locale/hy-am'); require('moment/locale/it'); require('moment/locale/nb'); -// OC is not available. Please submit OC translation -// to the MomentJS project. +// OC is not available. Please submit OC translation to the MomentJS project. require('moment/locale/pl'); require('moment/locale/pt'); @@ -50,9 +49,9 @@ export function getRecentRooms(): Promise> { const recentRoomDS = []; if (recentURLs) { - // we init the locale on every list render, so then it - // changes immediately if a language change happens - // in the app. + // We init the locale on every list render, so then it + // changes immediately if a language change happens in the + // app. const locale = _getSupportedLocale(); for (const e of JSON.parse(recentURLs)) { @@ -114,8 +113,8 @@ export function updateRecentURLs(recentURLs: Array) { * * @param {number} dateTimeStamp - The UTC timestamp to be converted to String. * @param {string} locale - The locale to init the formatter with. Note: This - * locale must be supported by the formatter so ensure this prerequisite - * before invoking the function. + * locale must be supported by the formatter so ensure this prerequisite before + * invoking the function. * @private * @returns {string} */ @@ -137,8 +136,8 @@ function _getDateString(dateTimeStamp: number, locale: string) { * * @param {number} duration - The duration in MS. * @param {string} locale - The locale to init the formatter with. Note: This - * locale must be supported by the formatter so ensure this prerequisite - * before invoking the function. + * locale must be supported by the formatter so ensure this prerequisite before + * invoking the function. * @private * @returns {string} */ @@ -165,8 +164,8 @@ function _getInitials(room: string) { * @private * @param {Date | number} dateToFormat - The date or duration to format. * @param {string} locale - The locale to init the formatter with. Note: This - * locale must be supported by the formatter so ensure this prerequisite - * before invoking the function. + * locale must be supported by the formatter so ensure this prerequisite before + * invoking the function. * @returns {Object} */ function _getLocalizedFormatter(dateToFormat: Date | number, locale: string) { @@ -184,20 +183,22 @@ function _getLocalizedFormatter(dateToFormat: Date | number, locale: string) { * @returns {string} */ function _getSupportedLocale() { - const i18nLocale = i18next.language.toLowerCase(); - const localeRegexp = new RegExp('^([a-z]{2,2})(-)*([a-z]{2,2})*$'); - const localeResult = localeRegexp.exec(i18nLocale); + const i18nLocale = i18next.language; + let supportedLocale; - if (localeResult) { - const currentLocaleRegexp = new RegExp( - `^${localeResult[1]}(-)*${`(${localeResult[3]})*` || ''}` - ); + if (i18nLocale) { + const localeRegexp = new RegExp('^([a-z]{2,2})(-)*([a-z]{2,2})*$'); + const localeResult = localeRegexp.exec(i18nLocale.toLowerCase()); - return moment.locales().find( - lang => currentLocaleRegexp.exec(lang) - ) || 'en'; + if (localeResult) { + const currentLocaleRegexp + = new RegExp( + `^${localeResult[1]}(-)*${`(${localeResult[3]})*` || ''}`); + + supportedLocale + = moment.locales().find(lang => currentLocaleRegexp.exec(lang)); + } } - // default fallback - return 'en'; + return supportedLocale || 'en'; }