saleor-dashboard/src/components/Locale/Locale.tsx

187 lines
4.3 KiB
TypeScript
Raw Normal View History

2019-10-16 15:35:19 +00:00
import useLocalStorage from "@saleor/hooks/useLocalStorage";
import React from "react";
import { IntlProvider } from "react-intl";
2019-08-29 13:59:29 +00:00
2019-09-10 16:02:31 +00:00
export enum Locale {
2019-08-29 13:59:29 +00:00
AR = "ar",
AZ = "az",
BG = "bg",
BN = "bn",
CA = "ca",
CS = "cs",
DA = "da",
DE = "de",
EL = "el",
2019-09-10 16:02:31 +00:00
EN = "en",
2019-08-29 13:59:29 +00:00
ES = "es",
ES_CO = "es-CO",
2019-08-29 13:59:29 +00:00
ET = "et",
FA = "fa",
FR = "fr",
HI = "hi",
HU = "hu",
HY = "hy",
ID = "id",
IS = "is",
IT = "it",
JA = "ja",
KO = "ko",
MN = "mn",
NB = "nb",
NL = "nl",
PL = "pl",
PT = "pt",
PT_BR = "pt-BR",
2019-08-29 13:59:29 +00:00
RO = "ro",
RU = "ru",
SK = "sk",
SL = "sl",
SQ = "sq",
SR = "sr",
SV = "sv",
TH = "th",
TR = "tr",
UK = "uk",
VI = "vi",
ZH_HANS = "zh-Hans",
ZH_HANT = "zh-Hant"
2019-08-27 12:05:53 +00:00
}
2020-02-13 11:50:39 +00:00
interface StructuredMessage {
context?: string;
string: string;
}
type LocaleMessages = Record<string, StructuredMessage>;
2019-08-27 12:05:53 +00:00
2019-10-16 15:18:29 +00:00
export const localeNames: Record<Locale, string> = {
[Locale.AR]: "العربيّة",
[Locale.AZ]: "Azərbaycanca",
[Locale.BG]: "български",
[Locale.BN]: "বাংলা",
[Locale.CA]: "català",
[Locale.CS]: "česky",
[Locale.DA]: "dansk",
[Locale.DE]: "Deutsch",
[Locale.EL]: "Ελληνικά",
[Locale.EN]: "English",
[Locale.ES]: "español",
[Locale.ES_CO]: "español de Colombia",
[Locale.ET]: "eesti",
[Locale.FA]: "فارسی",
[Locale.FR]: "français",
[Locale.HI]: "Hindi",
[Locale.HU]: "Magyar",
[Locale.HY]: "հայերեն",
[Locale.ID]: "Bahasa Indonesia",
[Locale.IS]: "Íslenska",
[Locale.IT]: "italiano",
[Locale.JA]: "日本語",
[Locale.KO]: "한국어",
[Locale.MN]: "Mongolian",
[Locale.NB]: "norsk (bokmål)",
[Locale.NL]: "Nederlands",
[Locale.PL]: "polski",
[Locale.PT]: "Português",
[Locale.PT_BR]: "Português Brasileiro",
[Locale.RO]: "Română",
[Locale.RU]: "Русский",
[Locale.SK]: "Slovensky",
[Locale.SL]: "Slovenščina",
[Locale.SQ]: "shqip",
[Locale.SR]: "српски",
[Locale.SV]: "svenska",
[Locale.TH]: "ภาษาไทย",
[Locale.TR]: "Türkçe",
[Locale.UK]: "Українська",
[Locale.VI]: "Tiếng Việt",
[Locale.ZH_HANS]: "简体中文",
[Locale.ZH_HANT]: "繁體中文"
};
2020-02-13 11:58:45 +00:00
const dotSeparator = "_dot_";
2020-02-13 11:50:39 +00:00
const sepRegExp = new RegExp(dotSeparator, "g");
function getKeyValueJson(messages: LocaleMessages): Record<string, string> {
if (messages) {
const keyValueMessages: Record<string, string> = {};
return Object.entries(messages).reduce((acc, [id, msg]) => {
acc[id.replace(sepRegExp, ".")] = msg.string;
return acc;
}, keyValueMessages);
}
}
2019-09-10 16:02:31 +00:00
export function getMatchingLocale(languages: readonly string[]): Locale {
2019-08-27 12:05:53 +00:00
const localeEntries = Object.entries(Locale);
2019-09-10 16:02:31 +00:00
for (const preferredLocale of languages) {
2019-08-27 12:05:53 +00:00
for (const localeEntry of localeEntries) {
if (localeEntry[1].toLowerCase() === preferredLocale.toLowerCase()) {
return Locale[localeEntry[0]];
2019-08-14 16:21:41 +00:00
}
}
2019-08-27 12:05:53 +00:00
}
2019-09-04 14:01:26 +00:00
return undefined;
2019-08-27 12:05:53 +00:00
}
2019-10-16 15:18:29 +00:00
const defaultLocale = Locale.EN;
export interface LocaleContextType {
locale: Locale;
setLocale: (locale: Locale) => void;
}
export const LocaleContext = React.createContext<LocaleContextType>({
locale: defaultLocale,
setLocale: () => undefined
});
const { Consumer: LocaleConsumer, Provider: RawLocaleProvider } = LocaleContext;
2019-08-27 12:05:53 +00:00
const LocaleProvider: React.FC = ({ children }) => {
2019-10-16 15:35:19 +00:00
const [locale, setLocale] = useLocalStorage(
"locale",
2019-09-10 16:02:31 +00:00
getMatchingLocale(navigator.languages) || defaultLocale
);
const [messages, setMessages] = React.useState(undefined);
React.useEffect(() => {
async function changeLocale() {
if (locale !== defaultLocale) {
// It seems like Webpack is unable to use aliases for lazy imports
const mod = await import(`../../../locale/${locale}.json`);
setMessages(mod.default);
} else {
setMessages(undefined);
}
2020-09-04 02:40:28 +00:00
}
changeLocale();
}, [locale]);
2019-08-13 11:26:34 +00:00
return (
2019-08-29 13:59:29 +00:00
<IntlProvider
defaultLocale={defaultLocale}
locale={locale}
2020-09-04 02:40:28 +00:00
messages={getKeyValueJson(messages)}
2019-08-29 13:59:29 +00:00
onError={err => {
if (!err.includes("[React Intl] Missing message: ")) {
console.error(err);
}
}}
key={locale}
>
2019-10-16 15:18:29 +00:00
<RawLocaleProvider
value={{
locale,
setLocale
}}
>
{children}
</RawLocaleProvider>
2019-08-13 11:26:34 +00:00
</IntlProvider>
);
2019-06-19 14:40:52 +00:00
};
2019-08-16 13:55:04 +00:00
export { LocaleConsumer, LocaleProvider, RawLocaleProvider };