mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-06 21:44:13 +03:00
* Add plural variant to i18n selected key Weblate needs both keys to populate other languages * move smart capitalization logic into language provider * fix key
81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
|
import i18next from "i18next";
|
|
|
|
type LanguageProviderState = {
|
|
language: string;
|
|
systemLanguage: string;
|
|
setLanguage: (language: string) => void;
|
|
};
|
|
|
|
const initialState: LanguageProviderState = {
|
|
language: i18next.language || "en",
|
|
systemLanguage: "en",
|
|
setLanguage: () => null,
|
|
};
|
|
|
|
const LanguageProviderContext =
|
|
createContext<LanguageProviderState>(initialState);
|
|
|
|
export function LanguageProvider({
|
|
children,
|
|
defaultLanguage = "en",
|
|
storageKey = "frigate-ui-language",
|
|
...props
|
|
}: {
|
|
children: React.ReactNode;
|
|
defaultLanguage?: string;
|
|
storageKey?: string;
|
|
}) {
|
|
const [language, setLanguage] = useState<string>(() => {
|
|
try {
|
|
const storedData = localStorage.getItem(storageKey);
|
|
const newLanguage = storedData || defaultLanguage;
|
|
i18next.changeLanguage(newLanguage);
|
|
return newLanguage;
|
|
} catch (error) {
|
|
// eslint-disable-next-line no-console
|
|
console.error("Error retrieving language data from storage:", error);
|
|
return defaultLanguage;
|
|
}
|
|
});
|
|
|
|
const systemLanguage = useMemo<string>(() => {
|
|
if (typeof window === "undefined") return "en";
|
|
return window.navigator.language;
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
// set document lang for smart capitalization
|
|
document.documentElement.lang = language;
|
|
|
|
if (language === systemLanguage) return;
|
|
i18next.changeLanguage(language);
|
|
}, [language, systemLanguage]);
|
|
|
|
const value = {
|
|
language,
|
|
systemLanguage,
|
|
setLanguage: (language: string) => {
|
|
localStorage.setItem(storageKey, language);
|
|
setLanguage(language);
|
|
window.location.reload();
|
|
},
|
|
};
|
|
|
|
return (
|
|
<LanguageProviderContext.Provider {...props} value={value}>
|
|
{children}
|
|
</LanguageProviderContext.Provider>
|
|
);
|
|
}
|
|
|
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
export const useLanguage = () => {
|
|
const context = useContext(LanguageProviderContext);
|
|
|
|
if (context === undefined)
|
|
throw new Error("useLanguage must be used within a LanguageProvider");
|
|
|
|
return context;
|
|
};
|