mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-07-26 13:47:03 +02:00
Support automatic language selection based on system language (#17953)
* Support automatic language selection * Handle non-matching keys * Cleanup * Handle region specific language codes from browser * Fix passing in requestor
This commit is contained in:
parent
9291543705
commit
e57dde7bb0
@ -120,7 +120,7 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
if self.config.face_recognition.enabled:
|
||||
self.realtime_processors.append(
|
||||
FaceRealTimeProcessor(
|
||||
self.config, self.event_metadata_publisher, metrics
|
||||
self.config, self.requestor, self.event_metadata_publisher, metrics
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -34,7 +34,7 @@ import {
|
||||
useTheme,
|
||||
} from "@/context/theme-provider";
|
||||
import { IoColorPalette } from "react-icons/io5";
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useRestart } from "@/api/ws";
|
||||
import {
|
||||
Tooltip,
|
||||
@ -62,6 +62,7 @@ import { toast } from "sonner";
|
||||
import axios from "axios";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { supportedLanguageKeys } from "@/lib/const";
|
||||
|
||||
type GeneralSettingsProps = {
|
||||
className?: string;
|
||||
@ -75,20 +76,21 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
|
||||
|
||||
// languages
|
||||
|
||||
const languages = [
|
||||
{ code: "en", label: t("menu.language.en") },
|
||||
{ code: "es", label: t("menu.language.es") },
|
||||
{ code: "fr", label: t("menu.language.fr") },
|
||||
{ code: "de", label: t("menu.language.de") },
|
||||
{ code: "it", label: t("menu.language.it") },
|
||||
{ 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") },
|
||||
];
|
||||
const languages = useMemo(() => {
|
||||
// Handle language keys that aren't directly used for translation key
|
||||
const specialKeyMap: { [key: string]: string } = {
|
||||
"nb-NO": "nb",
|
||||
"yue-Hant": "yue",
|
||||
"zh-CN": "zhCN",
|
||||
};
|
||||
|
||||
return supportedLanguageKeys.map((key) => {
|
||||
return {
|
||||
code: key,
|
||||
label: t(`menu.language.${specialKeyMap[key] || key}`),
|
||||
};
|
||||
});
|
||||
}, [t]);
|
||||
|
||||
// settings
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { createContext, useContext, useState, useEffect, useMemo } from "react";
|
||||
import i18next from "i18next";
|
||||
import { supportedLanguageKeys } from "@/lib/const";
|
||||
|
||||
type LanguageProviderState = {
|
||||
language: string;
|
||||
systemLanguage: string;
|
||||
setLanguage: (language: string) => void;
|
||||
};
|
||||
|
||||
const initialState: LanguageProviderState = {
|
||||
language: i18next.language || "en",
|
||||
systemLanguage: "en",
|
||||
setLanguage: () => null,
|
||||
};
|
||||
|
||||
@ -26,10 +25,31 @@ export function LanguageProvider({
|
||||
defaultLanguage?: string;
|
||||
storageKey?: string;
|
||||
}) {
|
||||
const systemLanguage = useMemo<string>(() => {
|
||||
if (typeof window === "undefined") return defaultLanguage;
|
||||
|
||||
const systemLanguage = window.navigator.language;
|
||||
|
||||
if (supportedLanguageKeys.includes(systemLanguage)) {
|
||||
return systemLanguage;
|
||||
}
|
||||
|
||||
// browser languages may include a -REGION (ex: en-US)
|
||||
if (systemLanguage.includes("-")) {
|
||||
const shortenedSystemLanguage = systemLanguage.split("-")[0];
|
||||
|
||||
if (supportedLanguageKeys.includes(shortenedSystemLanguage)) {
|
||||
return shortenedSystemLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultLanguage;
|
||||
}, [defaultLanguage]);
|
||||
|
||||
const [language, setLanguage] = useState<string>(() => {
|
||||
try {
|
||||
const storedData = localStorage.getItem(storageKey);
|
||||
const newLanguage = storedData || defaultLanguage;
|
||||
const newLanguage = storedData || systemLanguage;
|
||||
i18next.changeLanguage(newLanguage);
|
||||
return newLanguage;
|
||||
} catch (error) {
|
||||
@ -39,11 +59,6 @@ export function LanguageProvider({
|
||||
}
|
||||
});
|
||||
|
||||
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;
|
||||
@ -54,7 +69,6 @@ export function LanguageProvider({
|
||||
|
||||
const value = {
|
||||
language,
|
||||
systemLanguage,
|
||||
setLanguage: (language: string) => {
|
||||
localStorage.setItem(storageKey, 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