mirror of
https://github.com/wassname/talk.git
synced 2026-08-01 13:00:55 +08:00
183 lines
5.2 KiB
JavaScript
183 lines
5.2 KiB
JavaScript
import { negotiateLanguages } from 'fluent-langneg/compat';
|
|
|
|
import has from 'lodash/has';
|
|
import get from 'lodash/get';
|
|
import merge from 'lodash/merge';
|
|
import first from 'lodash/first';
|
|
import isUndefined from 'lodash/isUndefined';
|
|
|
|
import moment from 'moment';
|
|
import 'moment/locale/ar';
|
|
import 'moment/locale/da';
|
|
import 'moment/locale/de';
|
|
import 'moment/locale/es';
|
|
import 'moment/locale/fr';
|
|
import 'moment/locale/he';
|
|
import 'moment/locale/it';
|
|
import 'moment/locale/nl';
|
|
import 'moment/locale/pt-br';
|
|
|
|
// timeago
|
|
import ta from 'timeago.js';
|
|
import arTA from 'timeago.js/locales/ar';
|
|
import daTA from 'timeago.js/locales/da';
|
|
import deTA from 'timeago.js/locales/de';
|
|
import esTA from 'timeago.js/locales/es';
|
|
import frTA from 'timeago.js/locales/fr';
|
|
import heTA from 'timeago.js/locales/he';
|
|
import itTA from 'timeago.js/locales/it';
|
|
import nlTA from 'timeago.js/locales/nl';
|
|
import pt_BRTA from 'timeago.js/locales/pt_BR';
|
|
import zh_CNTA from 'timeago.js/locales/zh_CN';
|
|
import zh_TWTA from 'timeago.js/locales/zh_TW';
|
|
|
|
// locales
|
|
import ar from '../../../locales/ar.yml';
|
|
import en from '../../../locales/en.yml';
|
|
import da from '../../../locales/da.yml';
|
|
import de from '../../../locales/de.yml';
|
|
import es from '../../../locales/es.yml';
|
|
import fr from '../../../locales/fr.yml';
|
|
import he from '../../../locales/he.yml';
|
|
import it from '../../../locales/it.yml';
|
|
import nl_NL from '../../../locales/nl_NL.yml';
|
|
import pt_BR from '../../../locales/pt_BR.yml';
|
|
import zh_CN from '../../../locales/zh_CN.yml';
|
|
import zh_TW from '../../../locales/zh_TW.yml';
|
|
|
|
// the list of languages that are whitelisted. If false, all languages that are
|
|
// supported by Talk will be enabled.
|
|
const whitelistedLanguages =
|
|
process.env.TALK_WHITELISTED_LANGUAGES &&
|
|
process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim());
|
|
|
|
// The default language. If the whitelisted languages is specified and the
|
|
// default language is not in that list, then the first language in the
|
|
// whitelisted list will be used as the default.
|
|
export const defaultLocale = whitelistedLanguages
|
|
? !whitelistedLanguages.includes(process.env.TALK_DEFAULT_LANG)
|
|
? whitelistedLanguages[0]
|
|
: process.env.TALK_DEFAULT_LANG
|
|
: process.env.TALK_DEFAULT_LANG;
|
|
|
|
export const translations = {
|
|
...ar,
|
|
...en,
|
|
...da,
|
|
...de,
|
|
...es,
|
|
...fr,
|
|
...he,
|
|
...it,
|
|
...nl_NL,
|
|
...pt_BR,
|
|
...zh_CN,
|
|
...zh_TW,
|
|
};
|
|
|
|
export const supportedLocales = Object.keys(translations);
|
|
|
|
let LOCALE;
|
|
let TIMEAGO_INSTANCE;
|
|
|
|
// detectLanguage will try to get the locale from storage if available,
|
|
// otherwise will try to get it from the navigator, otherwise, it will fallback
|
|
// to the default language.
|
|
const detectLanguage = () => {
|
|
var browserLanguages = navigator.languages;
|
|
//IE11 and MS-EDGE do not provide navigator.languages
|
|
if (!browserLanguages) {
|
|
browserLanguages = [navigator.language];
|
|
}
|
|
return first(
|
|
negotiateLanguages(
|
|
browserLanguages,
|
|
whitelistedLanguages || supportedLocales,
|
|
{
|
|
defaultLocale,
|
|
strategy: 'lookup',
|
|
}
|
|
)
|
|
);
|
|
};
|
|
|
|
export function setupTranslations() {
|
|
// locale
|
|
LOCALE = detectLanguage();
|
|
|
|
// moment
|
|
moment.locale(LOCALE);
|
|
|
|
// timeago
|
|
ta.register('ar', arTA);
|
|
ta.register('es', esTA);
|
|
ta.register('da', daTA);
|
|
ta.register('de', deTA);
|
|
ta.register('fr', frTA);
|
|
ta.register('he', heTA);
|
|
ta.register('it', itTA);
|
|
ta.register('nl_NL', nlTA);
|
|
ta.register('pt_BR', pt_BRTA);
|
|
ta.register('zh_CN', zh_CNTA);
|
|
ta.register('zh_TW', zh_TWTA);
|
|
TIMEAGO_INSTANCE = ta();
|
|
}
|
|
|
|
/**
|
|
* loadTranslations will load the new language pack into the existing ones.
|
|
*
|
|
* @param {Object} newTranslations translation object to merge into the existing
|
|
* languages.
|
|
*/
|
|
export function loadTranslations(newTranslations) {
|
|
// Merge the new translations into the existing translations.
|
|
merge(translations, newTranslations);
|
|
|
|
// Push new languages into the supportedLocales array.
|
|
Object.keys(newTranslations).forEach(language => {
|
|
if (!supportedLocales.includes(language)) {
|
|
supportedLocales.push(language);
|
|
}
|
|
});
|
|
}
|
|
|
|
export function timeago(time) {
|
|
return TIMEAGO_INSTANCE.format(new Date(time), LOCALE);
|
|
}
|
|
|
|
/**
|
|
* Expose the translation function
|
|
*
|
|
* it takes a string with the translation key and returns
|
|
* the translation value or the key itself if not found
|
|
* it works with nested translations (my.page.title)
|
|
*
|
|
* any extra parameters are optional and replace a variable marked by {0}, {1}, etc in the translation.
|
|
*/
|
|
export function t(key, ...replacements) {
|
|
let translation;
|
|
if (has(translations[LOCALE], key)) {
|
|
translation = get(translations[LOCALE], key);
|
|
} else if (has(translations['en'], key)) {
|
|
translation = get(translations['en'], key);
|
|
console.warn(`${LOCALE}.${key} language key not set`);
|
|
}
|
|
|
|
if (!translation) {
|
|
console.warn(`${LOCALE}.${key} and en.${key} language key not set`);
|
|
return key;
|
|
}
|
|
|
|
// Handle replacements in the translation string.
|
|
return translation.replace(
|
|
/{(\d+)}/g,
|
|
(match, number) =>
|
|
!isUndefined(replacements[number]) ? replacements[number] : match
|
|
);
|
|
}
|
|
|
|
export default t;
|
|
|
|
// Setup the translations globally as soon as this module runs.
|
|
setupTranslations();
|