2019-11-11 14:10:05 +05:30
|
|
|
// @flow
|
2019-11-27 14:33:32 +05:30
|
|
|
import type { IntlShape } from 'react-intl';
|
|
|
|
import { createIntl, createIntlCache } from 'react-intl';
|
2019-11-11 14:10:05 +05:30
|
|
|
import captcha from 'services/captcha';
|
|
|
|
import locales from 'i18n/index.json';
|
|
|
|
|
|
|
|
import intlPolyfill from './intlPolyfill';
|
|
|
|
|
|
|
|
const SUPPORTED_LANGUAGES = Object.keys(locales);
|
|
|
|
const DEFAULT_LANGUAGE = 'en';
|
|
|
|
|
|
|
|
function getBrowserPreferredLanguages(): string[] {
|
2019-11-27 14:33:32 +05:30
|
|
|
return [].concat(navigator.languages || []).concat(navigator.language || []);
|
2019-11-11 14:10:05 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
function detectLanguage(
|
2019-11-27 14:33:32 +05:30
|
|
|
userLanguages: string[],
|
|
|
|
availableLanguages: string[],
|
|
|
|
defaultLanguage: string,
|
2019-11-11 14:10:05 +05:30
|
|
|
): string {
|
2019-11-27 14:33:32 +05:30
|
|
|
return (
|
|
|
|
userLanguages
|
|
|
|
.map(lang =>
|
|
|
|
lang
|
|
|
|
.split('-')
|
|
|
|
.shift()
|
|
|
|
.toLowerCase(),
|
|
|
|
)
|
|
|
|
.find(lang => availableLanguages.indexOf(lang) !== -1) || defaultLanguage
|
|
|
|
);
|
2019-11-11 14:10:05 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
const cache = createIntlCache();
|
|
|
|
|
|
|
|
let intl: IntlShape;
|
|
|
|
|
|
|
|
class I18N {
|
2019-11-27 14:33:32 +05:30
|
|
|
detectLanguage(lang: string): string {
|
|
|
|
return detectLanguage(
|
|
|
|
[lang].concat(getBrowserPreferredLanguages()).filter(item => !!item),
|
|
|
|
SUPPORTED_LANGUAGES,
|
|
|
|
DEFAULT_LANGUAGE,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
getIntl(): IntlShape {
|
|
|
|
if (!intl) {
|
|
|
|
intl = createIntl(
|
|
|
|
{
|
|
|
|
locale: 'en',
|
|
|
|
messages: {},
|
|
|
|
},
|
|
|
|
cache,
|
|
|
|
);
|
2019-11-11 14:10:05 +05:30
|
|
|
}
|
|
|
|
|
2019-11-27 14:33:32 +05:30
|
|
|
return intl;
|
|
|
|
}
|
|
|
|
|
|
|
|
async changeLocale(locale: string = DEFAULT_LANGUAGE): Promise<IntlShape> {
|
|
|
|
const { messages } = await this.require(locale);
|
|
|
|
|
|
|
|
captcha.setLang(locale);
|
|
|
|
|
|
|
|
intl = createIntl(
|
|
|
|
{
|
|
|
|
locale,
|
|
|
|
messages,
|
|
|
|
},
|
|
|
|
cache,
|
|
|
|
);
|
|
|
|
|
|
|
|
return intl;
|
|
|
|
}
|
|
|
|
|
|
|
|
async ensureIntl() {
|
|
|
|
await intlPolyfill('en');
|
|
|
|
}
|
|
|
|
|
|
|
|
async require(
|
|
|
|
locale: string,
|
|
|
|
): Promise<{
|
|
|
|
locale: string,
|
|
|
|
messages: { [string]: string },
|
|
|
|
}> {
|
|
|
|
const [{ default: messages }] = await Promise.all([
|
|
|
|
import(/* webpackChunkName: "locale-[request]" */ `i18n/${locale}.json`),
|
|
|
|
intlPolyfill(locale),
|
|
|
|
]);
|
|
|
|
|
|
|
|
return {
|
|
|
|
locale,
|
|
|
|
messages,
|
|
|
|
};
|
|
|
|
}
|
2019-11-11 14:10:05 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
export default new I18N();
|