Files
web2.0-frontend/src/i18n/index.tsx
T
2022-07-25 00:07:27 +03:00

106 lines
2.3 KiB
TypeScript

import React, {
createContext, useContext, useMemo, useReducer,
} from "react";
import fi from "./locales/fi/common.json";
import en from "./locales/en/common.json";
export type Lang = "fi" | "en";
const LOCAL_STORAGE_KEY = "locale";
type TranslateFunc = (key: string) => string;
const translateEn: TranslateFunc = (key) => {
const res = en[key];
if (!res) {
console.warn(`Locale 'en' has no key: ${key}!`);
}
return res || key;
};
const translateFi: TranslateFunc = (key) => {
const res = fi[key];
if (!res) {
// Silence warnings for Finnish
// console.warn(`Locale 'en' has no key: ${key}!`);
}
return res || key;
};
export const getTranslateFunc = (language: Lang): TranslateFunc => {
if (language === "en") return translateEn;
return translateFi;
};
interface Store {
language: Lang;
changeLanguage: React.Dispatch<Lang>,
}
let initialLanguage: Lang = "fi";
try {
const storedLang = localStorage.getItem(LOCAL_STORAGE_KEY) as Lang;
initialLanguage = storedLang;
} catch (err) {
// Just ignore if fails to get value from browser (server etc.)
}
const initialState: Store = {
language: initialLanguage,
changeLanguage: null,
};
const Reducer = (state: Store, action: Lang) => {
switch (action) {
case "fi":
return {
...state,
language: action,
};
case "en":
return {
...state,
language: action,
};
default:
return state;
}
};
const LocaleContext = createContext(initialState);
const LocaleStore: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, initialState);
const changeLanguage = (action: Lang) => {
dispatch(action);
try {
localStorage.setItem(LOCAL_STORAGE_KEY, action);
} catch (err) {
// Just ignore if fails to store value in user's browser
}
};
const localeValue = useMemo(() => ({ ...state, changeLanguage }), [state]);
return (
<LocaleContext.Provider value={localeValue}>
{children}
</LocaleContext.Provider>
);
};
export default LocaleStore;
const useTranslation = () => {
const { language, changeLanguage } = useContext(LocaleContext);
const t = getTranslateFunc(language);
return {
t,
i18n: {
language,
changeLanguage,
},
};
};
export { useTranslation };