// @flow import type { IntlShape } from 'react-intl'; import { createIntl, createIntlCache } from 'react-intl'; 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[] { return [].concat(navigator.languages || []).concat(navigator.language || []); } function detectLanguage( userLanguages: string[], availableLanguages: string[], defaultLanguage: string, ): string { return ( userLanguages .map(lang => lang .split('-') .shift() .toLowerCase(), ) .find(lang => availableLanguages.indexOf(lang) !== -1) || defaultLanguage ); } const cache = createIntlCache(); let intl: IntlShape; class I18N { 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, ); } return intl; } async changeLocale(locale: string = DEFAULT_LANGUAGE): Promise { 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, }; } } export default new I18N();