mirror of https://github.com/jitsi/jitsi-meet
parent
c361e1e31a
commit
18368fefaa
@ -0,0 +1,36 @@ |
||||
/** |
||||
* The available/supported languages. |
||||
* |
||||
* XXX The element at index zero is the default language. |
||||
* |
||||
* @public |
||||
* @type {Array<string>} |
||||
*/ |
||||
export const LANGUAGES = [ |
||||
'en', // XXX The default language.
|
||||
|
||||
'bg', |
||||
'de', |
||||
'es', |
||||
'fr', |
||||
'hy', |
||||
'it', |
||||
'oc', |
||||
'pl', |
||||
'ptBR', |
||||
'ru', |
||||
'sk', |
||||
'sl', |
||||
'sv', |
||||
'tr' |
||||
]; |
||||
|
||||
/** |
||||
* The default language. |
||||
* |
||||
* XXX The element at index zero of {@link LANGUAGES} is the default language. |
||||
* |
||||
* @public |
||||
* @type {string} The default language. |
||||
*/ |
||||
export const DEFAULT_LANGUAGE = LANGUAGES[0]; |
@ -0,0 +1,31 @@ |
||||
import React from 'react'; |
||||
import { translate as reactI18nextTranslate } from 'react-i18next'; |
||||
|
||||
/** |
||||
* Wraps a specific React Component in order to enable translations in it. |
||||
* |
||||
* @param {Component} component - The React Component to wrap. |
||||
* @returns {Component} The React Component which wraps {@link component} and |
||||
* enables translations in it. |
||||
*/ |
||||
export function translate(component) { |
||||
// Use the default list of namespaces.
|
||||
return ( |
||||
reactI18nextTranslate([ 'main', 'languages' ], { wait: true })( |
||||
component)); |
||||
} |
||||
|
||||
/** |
||||
* Translates a specific key to text containing HTML via a specific translate |
||||
* function. |
||||
* |
||||
* @param {Function} t - The translate function. |
||||
* @param {string} key - The key to translate. |
||||
* @param {Array<*>} options - The options, if any, to pass to {@link t}. |
||||
* @returns {ReactElement} A ReactElement which depicts the translated HTML |
||||
* text. |
||||
*/ |
||||
export function translateToHTML(t, key, options = {}) { |
||||
// eslint-disable-next-line react/no-danger
|
||||
return <span dangerouslySetInnerHTML = {{ __html: t(key, options) }} />; |
||||
} |
@ -0,0 +1,63 @@ |
||||
import i18next from 'i18next'; |
||||
import I18nextXHRBackend from 'i18next-xhr-backend'; |
||||
|
||||
import LANGUAGES_RESOURCES from '../../../../lang/languages.json'; |
||||
import MAIN_RESOURCES from '../../../../lang/main.json'; |
||||
|
||||
import { DEFAULT_LANGUAGE, LANGUAGES } from './constants'; |
||||
import languageDetector from './languageDetector'; |
||||
|
||||
declare var interfaceConfig: Object; |
||||
|
||||
/** |
||||
* The options to initialize i18next with. |
||||
* |
||||
* @type {Object} |
||||
*/ |
||||
const options = { |
||||
app: |
||||
(typeof interfaceConfig !== 'undefined' && interfaceConfig.APP_NAME) |
||||
|| 'Jitsi Meet', |
||||
compatibilityAPI: 'v1', |
||||
compatibilityJSON: 'v1', |
||||
fallbackLng: DEFAULT_LANGUAGE, |
||||
fallbackOnEmpty: true, |
||||
fallbackOnNull: true, |
||||
|
||||
// XXX i18next modifies the array lngWhitelist so make sure to clone
|
||||
// LANGUAGES.
|
||||
lngWhitelist: LANGUAGES.slice(), |
||||
load: 'unspecific', |
||||
ns: { |
||||
defaultNs: 'main', |
||||
namespaces: [ 'main', 'languages' ] |
||||
}, |
||||
resGetPath: 'lang/__ns__-__lng__.json', |
||||
useDataAttrOptions: true |
||||
}; |
||||
|
||||
i18next |
||||
.use(I18nextXHRBackend) |
||||
.use(languageDetector) |
||||
.use({ |
||||
name: 'resolveAppName', |
||||
process: (res, key) => i18next.t(key, { app: options.app }), |
||||
type: 'postProcessor' |
||||
}) |
||||
.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); |
||||
|
||||
export default i18next; |
@ -0,0 +1,6 @@ |
||||
export * from './constants'; |
||||
export * from './functions'; |
||||
|
||||
// TODO Eventually (e.g. when the non-React Web app is rewritten into React), it
|
||||
// should not be necessary to export i18next.
|
||||
export { default as i18next } from './i18next'; |
@ -0,0 +1,24 @@ |
||||
/* @flow */ |
||||
|
||||
import locale from 'react-native-locale-detector'; |
||||
|
||||
/** |
||||
* The singleton language detector for React Native which uses the system-wide |
||||
* locale. |
||||
*/ |
||||
export default { |
||||
/** |
||||
* Does not support caching. |
||||
* |
||||
* @returns {void} |
||||
*/ |
||||
cacheUserLanguage: Function.prototype, |
||||
|
||||
detect() { |
||||
return locale; |
||||
}, |
||||
|
||||
init: Function.prototype, |
||||
|
||||
type: 'languageDetector' |
||||
}; |
@ -0,0 +1,42 @@ |
||||
/* @flow */ |
||||
|
||||
import BrowserLanguageDetector from 'i18next-browser-languagedetector'; |
||||
|
||||
import configLanguageDetector from './configLanguageDetector'; |
||||
|
||||
declare var interfaceConfig: Object; |
||||
|
||||
/** |
||||
* The ordered list (by name) of language detectors to be utilized as backends |
||||
* by the singleton language detector for Web. |
||||
* |
||||
* @type {Array<string>} |
||||
*/ |
||||
const order = [ |
||||
'querystring', |
||||
'localStorage', |
||||
configLanguageDetector.name |
||||
]; |
||||
|
||||
// Allow i18next to detect the system language reported by the Web browser
|
||||
// itself.
|
||||
interfaceConfig.LANG_DETECTION && order.push('navigator'); |
||||
|
||||
/** |
||||
* The singleton language detector for Web. |
||||
*/ |
||||
const languageDetector |
||||
= new BrowserLanguageDetector( |
||||
/* services */ null, |
||||
/* options */ { |
||||
caches: [ 'localStorage' ], |
||||
lookupLocalStorage: 'language', |
||||
lookupQuerystring: 'lang', |
||||
order |
||||
}); |
||||
|
||||
// Add the language detector which looks the language up in the config. Its
|
||||
// order has already been established above.
|
||||
languageDetector.addDetector(configLanguageDetector); |
||||
|
||||
export default languageDetector; |
@ -1,3 +1,3 @@ |
||||
export * from './Container'; |
||||
export * from './Link'; |
||||
export * from './Watermarks'; |
||||
export { default as Watermarks } from './Watermarks'; |
||||
|
@ -1,11 +0,0 @@ |
||||
import locale from 'react-native-locale-detector'; |
||||
|
||||
/** |
||||
* A language detector that uses native locale. |
||||
*/ |
||||
export default { |
||||
init: Function.prototype, |
||||
type: 'languageDetector', |
||||
detect: () => locale, |
||||
cacheUserLanguage: Function.prototype |
||||
}; |
@ -1,34 +0,0 @@ |
||||
/* global interfaceConfig */ |
||||
import Browser from 'i18next-browser-languagedetector'; |
||||
import ConfigLanguageDetector from './ConfigLanguageDetector'; |
||||
|
||||
/** |
||||
* List of detectors to use in their order. |
||||
* |
||||
* @type {[*]} |
||||
*/ |
||||
const detectors = [ 'querystring', 'localStorage', 'configLanguageDetector' ]; |
||||
|
||||
/** |
||||
* Allow i18n to detect the system language from the browser. |
||||
*/ |
||||
if (interfaceConfig.LANG_DETECTION) { |
||||
detectors.push('navigator'); |
||||
} |
||||
|
||||
/** |
||||
* The language detectors. |
||||
*/ |
||||
const browser = new Browser(null, { |
||||
order: detectors, |
||||
lookupQuerystring: 'lang', |
||||
lookupLocalStorage: 'language', |
||||
caches: [ 'localStorage' ] |
||||
}); |
||||
|
||||
/** |
||||
* adds a language detector that just checks the config |
||||
*/ |
||||
browser.addDetector(ConfigLanguageDetector); |
||||
|
||||
export default browser; |
@ -1,46 +0,0 @@ |
||||
/* global interfaceConfig */ |
||||
import i18n from 'i18next'; |
||||
import XHR from 'i18next-xhr-backend'; |
||||
import { DEFAULT_LANG, languages } from './constants'; |
||||
import languagesR from '../../../../lang/languages.json'; |
||||
import mainR from '../../../../lang/main.json'; |
||||
|
||||
import LanguageDetector from './LanguageDetector'; |
||||
|
||||
/** |
||||
* Default options to initialize i18next. |
||||
* |
||||
* @enum {string} |
||||
*/ |
||||
const defaultOptions = { |
||||
compatibilityAPI: 'v1', |
||||
compatibilityJSON: 'v1', |
||||
fallbackLng: DEFAULT_LANG, |
||||
load: 'unspecific', |
||||
resGetPath: 'lang/__ns__-__lng__.json', |
||||
ns: { |
||||
namespaces: [ 'main', 'languages' ], |
||||
defaultNs: 'main' |
||||
}, |
||||
lngWhitelist: languages.getLanguages(), |
||||
fallbackOnNull: true, |
||||
fallbackOnEmpty: true, |
||||
useDataAttrOptions: true, |
||||
app: typeof interfaceConfig === 'undefined' |
||||
? 'Jitsi Meet' : interfaceConfig.APP_NAME |
||||
}; |
||||
|
||||
i18n.use(XHR) |
||||
.use(LanguageDetector) |
||||
.use({ |
||||
type: 'postProcessor', |
||||
name: 'resolveAppName', |
||||
process: (res, key) => i18n.t(key, { app: defaultOptions.app }) |
||||
}) |
||||
.init(defaultOptions); |
||||
|
||||
// adds default language which is preloaded from code
|
||||
i18n.addResourceBundle(DEFAULT_LANG, 'main', mainR, true, true); |
||||
i18n.addResourceBundle(DEFAULT_LANG, 'languages', languagesR, true, true); |
||||
|
||||
export default i18n; |
@ -1,13 +0,0 @@ |
||||
import languages from '../../../../service/translation/languages'; |
||||
|
||||
/** |
||||
* The default language globally for the project. |
||||
* |
||||
* @type {string} the default language globally for the project. |
||||
*/ |
||||
export const DEFAULT_LANG = languages.EN; |
||||
|
||||
/** |
||||
* Exports the list of languages currently supported. |
||||
*/ |
||||
export { languages }; |
@ -1,32 +0,0 @@ |
||||
import { translate as reactTranslate } from 'react-i18next'; |
||||
import React from 'react'; |
||||
|
||||
/** |
||||
* Wrap a translatable component. |
||||
* |
||||
* @param {Component} component - The component to wrap. |
||||
* @returns {Component} The wrapped component. |
||||
*/ |
||||
export function translate(component) { |
||||
// use the default list of namespaces
|
||||
return reactTranslate([ 'main', 'languages' ], { wait: true })(component); |
||||
} |
||||
|
||||
/** |
||||
* Translates key and prepares data to be passed to dangerouslySetInnerHTML. |
||||
* Used when translation text contains html. |
||||
* |
||||
* @param {func} t - Translate function. |
||||
* @param {string} key - The key to translate. |
||||
* @param {Array} options - Optional options. |
||||
* @returns {XML} A span using dangerouslySetInnerHTML to insert html text. |
||||
*/ |
||||
export function translateToHTML(t, key, options = {}) { |
||||
/* eslint-disable react/no-danger */ |
||||
return ( |
||||
<span |
||||
dangerouslySetInnerHTML = {{ __html: t(key, options) }} /> |
||||
); |
||||
|
||||
/* eslint-enable react/no-danger */ |
||||
} |
@ -1,3 +0,0 @@ |
||||
export { default as i18n } from './Translation'; |
||||
export * from './constants'; |
||||
export * from './functions'; |
@ -1,27 +0,0 @@ |
||||
export default { |
||||
getLanguages : function () { |
||||
var languages = []; |
||||
for (var lang in this) |
||||
{ |
||||
if (typeof this[lang] === "string") |
||||
languages.push(this[lang]); |
||||
} |
||||
return languages; |
||||
}, |
||||
EN: "en", |
||||
|
||||
BG: "bg", |
||||
DE: "de", |
||||
ES: "es", |
||||
FR: "fr", |
||||
HY: "hy", |
||||
IT: "it", |
||||
OC: "oc", |
||||
PL: "pl", |
||||
PTBR: "ptBR", |
||||
RU: "ru", |
||||
SK: "sk", |
||||
SL: "sl", |
||||
SV: "sv", |
||||
TR: "tr" |
||||
}; |
Loading…
Reference in new issue