mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
Merge branch 'master' into karma
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import ta from 'timeago.js';
|
||||
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';
|
||||
@@ -12,8 +15,8 @@ import 'moment/locale/fr';
|
||||
import 'moment/locale/nl';
|
||||
import 'moment/locale/pt-br';
|
||||
|
||||
import { createStorage } from 'coral-framework/services/storage';
|
||||
|
||||
// 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';
|
||||
@@ -24,6 +27,7 @@ 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';
|
||||
@@ -35,8 +39,9 @@ import pt_BR from '../../../locales/pt_BR.yml';
|
||||
import zh_CN from '../../../locales/zh_CN.yml';
|
||||
import zh_TW from '../../../locales/zh_TW.yml';
|
||||
|
||||
const defaultLanguage = process.env.TALK_DEFAULT_LANG;
|
||||
const translations = {
|
||||
export const defaultLocale = process.env.TALK_DEFAULT_LANG.replace(/-/g, '_');
|
||||
|
||||
export const translations = {
|
||||
...ar,
|
||||
...en,
|
||||
...da,
|
||||
@@ -49,84 +54,62 @@ const translations = {
|
||||
...zh_TW,
|
||||
};
|
||||
|
||||
let lang;
|
||||
let timeagoInstance;
|
||||
export const supportedLocales = Object.keys(translations);
|
||||
|
||||
function setLocale(storage, locale) {
|
||||
storage.setItem('locale', locale);
|
||||
}
|
||||
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.
|
||||
function detectLanguage(storage) {
|
||||
try {
|
||||
const lang = storage.getItem('locale') || navigator.language;
|
||||
if (lang) {
|
||||
return lang;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
'Error while trying to detect language, will fallback to',
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
console.warn('Could not detect language, will fallback to', defaultLanguage);
|
||||
return defaultLanguage;
|
||||
}
|
||||
|
||||
// getLocale will get the users locale from the local detector and parse it to a
|
||||
// format we can work with.
|
||||
function getLocale(storage) {
|
||||
// Get the language from the local detector.
|
||||
const lang = detectLanguage(storage);
|
||||
|
||||
// Some language strings come with additional subtags as defined in:
|
||||
//
|
||||
// https://www.ietf.org/rfc/bcp/bcp47.txt
|
||||
//
|
||||
// So we should strip that off if we find it.
|
||||
return lang.split('-')[0];
|
||||
}
|
||||
const detectLanguage = () =>
|
||||
first(
|
||||
negotiateLanguages(navigator.languages, supportedLocales, {
|
||||
defaultLocale,
|
||||
strategy: 'lookup',
|
||||
})
|
||||
);
|
||||
|
||||
export function setupTranslations() {
|
||||
// Setup the translation framework with the storage.
|
||||
const storage = createStorage('localStorage');
|
||||
// locale
|
||||
LOCALE = detectLanguage();
|
||||
|
||||
const locale = getLocale(storage);
|
||||
setLocale(storage, locale);
|
||||
|
||||
// Setting moment
|
||||
moment.locale(locale);
|
||||
|
||||
// Extract language key.
|
||||
lang = locale.split('-')[0];
|
||||
|
||||
// Check if we have a translation in this language.
|
||||
if (!(lang in translations)) {
|
||||
lang = defaultLanguage;
|
||||
}
|
||||
// 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('nl_NL', nlTA);
|
||||
ta.register('pt_BR', pt_BRTA);
|
||||
ta.register('zh_CN', zh_CNTA);
|
||||
ta.register('zh_TW', zh_TWTA);
|
||||
|
||||
timeagoInstance = ta();
|
||||
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 timeagoInstance.format(new Date(time), lang);
|
||||
return TIMEAGO_INSTANCE.format(new Date(time), LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,24 +123,24 @@ export function timeago(time) {
|
||||
*/
|
||||
export function t(key, ...replacements) {
|
||||
let translation;
|
||||
if (has(translations[lang], key)) {
|
||||
translation = get(translations[lang], key);
|
||||
if (has(translations[LOCALE], key)) {
|
||||
translation = get(translations[LOCALE], key);
|
||||
} else if (has(translations['en'], key)) {
|
||||
translation = get(translations['en'], key);
|
||||
console.warn(`${lang}.${key} language key not set`);
|
||||
console.warn(`${LOCALE}.${key} language key not set`);
|
||||
}
|
||||
|
||||
if (translation) {
|
||||
// replace any {n} with the arguments passed to this method
|
||||
replacements.forEach((str, i) => {
|
||||
translation = translation.replace(new RegExp(`\\{${i}\\}`, 'g'), str);
|
||||
});
|
||||
|
||||
return translation;
|
||||
} else {
|
||||
console.warn(`${lang}.${key} and en.${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;
|
||||
|
||||
Reference in New Issue
Block a user