106 lines
2.3 KiB
TypeScript
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 };
|