mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-04 20:47:42 +03:00
Support automatic language selection
This commit is contained in:
parent
9291543705
commit
41c36b1610
@ -34,7 +34,7 @@ import {
|
|||||||
useTheme,
|
useTheme,
|
||||||
} from "@/context/theme-provider";
|
} from "@/context/theme-provider";
|
||||||
import { IoColorPalette } from "react-icons/io5";
|
import { IoColorPalette } from "react-icons/io5";
|
||||||
import { useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useRestart } from "@/api/ws";
|
import { useRestart } from "@/api/ws";
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
@ -62,6 +62,7 @@ import { toast } from "sonner";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { supportedLanguageKeys } from "@/lib/const";
|
||||||
|
|
||||||
type GeneralSettingsProps = {
|
type GeneralSettingsProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -75,20 +76,13 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
|
|||||||
|
|
||||||
// languages
|
// languages
|
||||||
|
|
||||||
const languages = [
|
const languages = useMemo(
|
||||||
{ code: "en", label: t("menu.language.en") },
|
() =>
|
||||||
{ code: "es", label: t("menu.language.es") },
|
supportedLanguageKeys.map((key) => {
|
||||||
{ code: "fr", label: t("menu.language.fr") },
|
return { code: key, label: t(`menu.language.${key}`) };
|
||||||
{ code: "de", label: t("menu.language.de") },
|
}),
|
||||||
{ code: "it", label: t("menu.language.it") },
|
[t],
|
||||||
{ code: "nl", label: t("menu.language.nl") },
|
);
|
||||||
{ code: "nb-NO", label: t("menu.language.nb") },
|
|
||||||
{ code: "tr", label: t("menu.language.tr") },
|
|
||||||
{ code: "pl", label: t("menu.language.pl") },
|
|
||||||
{ code: "zh-CN", label: t("menu.language.zhCN") },
|
|
||||||
{ code: "yue-Hant", label: t("menu.language.yue") },
|
|
||||||
{ code: "ru", label: t("menu.language.ru") },
|
|
||||||
];
|
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { supportedLanguageKeys } from "@/lib/const";
|
||||||
|
|
||||||
type LanguageProviderState = {
|
type LanguageProviderState = {
|
||||||
language: string;
|
language: string;
|
||||||
systemLanguage: string;
|
|
||||||
setLanguage: (language: string) => void;
|
setLanguage: (language: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: LanguageProviderState = {
|
const initialState: LanguageProviderState = {
|
||||||
language: i18next.language || "en",
|
language: i18next.language || "en",
|
||||||
systemLanguage: "en",
|
|
||||||
setLanguage: () => null,
|
setLanguage: () => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,10 +25,22 @@ export function LanguageProvider({
|
|||||||
defaultLanguage?: string;
|
defaultLanguage?: string;
|
||||||
storageKey?: string;
|
storageKey?: string;
|
||||||
}) {
|
}) {
|
||||||
|
const systemLanguage = useMemo<string>(() => {
|
||||||
|
if (typeof window === "undefined") return defaultLanguage;
|
||||||
|
|
||||||
|
const systemLanguage = window.navigator.language;
|
||||||
|
|
||||||
|
if (supportedLanguageKeys.includes(systemLanguage)) {
|
||||||
|
return systemLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultLanguage;
|
||||||
|
}, [defaultLanguage]);
|
||||||
|
|
||||||
const [language, setLanguage] = useState<string>(() => {
|
const [language, setLanguage] = useState<string>(() => {
|
||||||
try {
|
try {
|
||||||
const storedData = localStorage.getItem(storageKey);
|
const storedData = localStorage.getItem(storageKey);
|
||||||
const newLanguage = storedData || defaultLanguage;
|
const newLanguage = storedData || systemLanguage;
|
||||||
i18next.changeLanguage(newLanguage);
|
i18next.changeLanguage(newLanguage);
|
||||||
return newLanguage;
|
return newLanguage;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -39,11 +50,6 @@ export function LanguageProvider({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const systemLanguage = useMemo<string>(() => {
|
|
||||||
if (typeof window === "undefined") return "en";
|
|
||||||
return window.navigator.language;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// set document lang for smart capitalization
|
// set document lang for smart capitalization
|
||||||
document.documentElement.lang = language;
|
document.documentElement.lang = language;
|
||||||
@ -54,7 +60,6 @@ export function LanguageProvider({
|
|||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
language,
|
language,
|
||||||
systemLanguage,
|
|
||||||
setLanguage: (language: string) => {
|
setLanguage: (language: string) => {
|
||||||
localStorage.setItem(storageKey, language);
|
localStorage.setItem(storageKey, language);
|
||||||
setLanguage(language);
|
setLanguage(language);
|
||||||
|
|||||||
14
web/src/lib/const.ts
Normal file
14
web/src/lib/const.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export const supportedLanguageKeys = [
|
||||||
|
"en",
|
||||||
|
"es",
|
||||||
|
"fr",
|
||||||
|
"de",
|
||||||
|
"it",
|
||||||
|
"nl",
|
||||||
|
"nb-NO",
|
||||||
|
"tr",
|
||||||
|
"pl",
|
||||||
|
"zh-CN",
|
||||||
|
"yue-Hant",
|
||||||
|
"ru",
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue
Block a user