From 29087cfcbcde3f77d0bbf1b61989d21632527c85 Mon Sep 17 00:00:00 2001 From: ZhaiSoul <842607283@qq.com> Date: Sat, 15 Mar 2025 14:23:03 +0800 Subject: [PATCH] feat: add more document title i18n keys --- web/public/locales/en/common.json | 15 +++++- web/public/locales/en/views/configEditor.json | 1 + web/public/locales/en/views/explore.json | 1 + web/public/locales/en/views/faceLibrary.json | 1 + web/public/locales/en/views/settings.json | 40 +++++++++++++++- web/public/locales/en/views/system.json | 11 +++++ web/public/locales/zh-CN/common.json | 15 +++++- .../locales/zh-CN/views/configEditor.json | 1 + web/public/locales/zh-CN/views/explore.json | 1 + .../locales/zh-CN/views/faceLibrary.json | 1 + web/public/locales/zh-CN/views/settings.json | 35 +++++++++++++- web/public/locales/zh-CN/views/system.json | 11 +++++ web/src/components/card/ReviewCard.tsx | 24 +++++----- .../components/filter/CamerasFilterButton.tsx | 8 +++- web/src/pages/AccessDenied.tsx | 9 ++-- web/src/pages/ConfigEditor.tsx | 4 +- web/src/pages/FaceLibrary.tsx | 4 +- web/src/pages/Logs.tsx | 4 +- web/src/pages/NoMatch.tsx | 7 +-- web/src/pages/Settings.tsx | 25 ++++++---- web/src/pages/System.tsx | 5 +- web/src/views/explore/ExploreView.tsx | 5 +- web/src/views/settings/AuthenticationView.tsx | 4 +- .../settings/ClassificationSettingsView.tsx | 4 +- web/src/views/settings/MasksAndZonesView.tsx | 8 ++-- web/src/views/settings/MotionTunerView.tsx | 4 +- .../settings/NotificationsSettingsView.tsx | 48 ++++++++++++------- web/src/views/settings/ObjectSettingsView.tsx | 4 +- web/src/views/settings/UiSettingsView.tsx | 4 +- 29 files changed, 226 insertions(+), 78 deletions(-) diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 00334cf75..5c9936a7b 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -123,6 +123,8 @@ "live": "Live", "live.allCameras": "All Cameras", "live.cameras": "Cameras", + "live.cameras.count_one": "{{count}} Camera", + "live.cameras.count_other": "{{count}} Cameras", "review": "Review", "explore": "Explore", "export": "Export", @@ -156,5 +158,16 @@ "next": "Next", "next.label": "Go to next page", "more": "More pages" - } + }, + "accessDefined": { + "documentTitle": "Access Defined - Frigate", + "title": "Access Defined", + "desc": "You don't have permission to view this page." + }, + "notFound": { + "documentTitle": "Not Found - Frigate", + "title": "404", + "desc": "Page not found" + }, + "selectItem": "Select {{item}}" } diff --git a/web/public/locales/en/views/configEditor.json b/web/public/locales/en/views/configEditor.json index d62a7d376..eca79fcba 100644 --- a/web/public/locales/en/views/configEditor.json +++ b/web/public/locales/en/views/configEditor.json @@ -1,4 +1,5 @@ { + "documentTitle": "Config Editor - Frigate", "configEditor": "Config Editor", "copyConfig": "Copy Config", "saveAndRestart": "Save & Restart", diff --git a/web/public/locales/en/views/explore.json b/web/public/locales/en/views/explore.json index 2024b4956..a156afbbb 100644 --- a/web/public/locales/en/views/explore.json +++ b/web/public/locales/en/views/explore.json @@ -1,4 +1,5 @@ { + "documentTitle": "Explore - Frigate", "generativeAI": "Generative AI", "exploreIsUnavailable": { "title": "Explore is Unavailable", diff --git a/web/public/locales/en/views/faceLibrary.json b/web/public/locales/en/views/faceLibrary.json index ca3cba4e5..566c741e2 100644 --- a/web/public/locales/en/views/faceLibrary.json +++ b/web/public/locales/en/views/faceLibrary.json @@ -1,4 +1,5 @@ { + "documentTitle": "Face Library - Frigate", "uploadFaceImage": { "title": "Upload Face Image", "desc": "Upload an image to scan for faces and include for {{pageToggle}}" diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 884b5328c..3d4b6900c 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -1,7 +1,17 @@ { + "documentTitle": { + "default": "Settings - Frigate", + "authentication": "Authentication Settings - Frigate", + "camera": "Camera Settings - Frigate", + "classification": "Classification Settings - Frigate", + "masksAndZones": "Mask and Zone Editor - Frigate", + "motionTuner": "Motion Tuner - Frigate", + "object": "Object Settings - Frigate", + "general": "General Settings - Frigate" + }, "menu": { "uiSettings": "UI Settings", - "exploreSettings": "Explore Settings", + "classificationSettings": "Classification Settings", "cameraSettings": "Camera Settings", "masksAndZones": "Masks / Zones", "motionTuner": "Motion Tuner", @@ -9,6 +19,16 @@ "users": "Users", "notifications": "Notifications" }, + "dialog": { + "unsavedChanges": { + "title": "You have unsaved changes.", + "desc": "Do you want to save your changes before continuing?" + } + }, + "cameraSetting": { + "camera": "Camera", + "noCamera": "No Camera" + }, "general": { "title": "General Settings", "liveDashboard": { @@ -376,7 +396,10 @@ "desc": "Web push notifications require a secure context (https://...). This is a browser limitation. Access Frigate securely to use notifications.", "documentation": "Read the Documentation" }, - + "globalSettings": { + "title": "Global Settings", + "desc": "Temporarily suspend notifications for specific cameras on all registered devices." + }, "email": "Email", "email.placeholder": "e.g. example@email.com", "email.desc": "A valid email is required and will be used to notify you if there are any issues with the push service.", @@ -386,6 +409,19 @@ "deviceSpecific": "Device Specific Settings", "registerDevice": "Register This Device", "unregisterDevice": "Unregister This Device", + "sendTestNotification": "Send a test notification", + "active": "Notifications Active", + "suspended": "Notifications suspended {{time}}", + "suspendTime": { + "5minutes": "Suspend for 5 minutes", + "10minutes": "Suspend for 10 minutes", + "30minutes": "Suspend for 30 minutes", + "1hour": "Suspend for 1 hour", + "12hours": "Suspend for 12 hours", + "24hours": "Suspend for 24 hours", + "untilRestart": "Suspend until restart" + }, + "cancelSuspension": "Cancel Suspension", "toast": { "success": { "registered": "Successfully registered for notifications. Restarting Frigate is required before any notifications (including a test notification) can be sent.", diff --git a/web/public/locales/en/views/system.json b/web/public/locales/en/views/system.json index 78efe0719..47fcd423f 100644 --- a/web/public/locales/en/views/system.json +++ b/web/public/locales/en/views/system.json @@ -1,4 +1,15 @@ { + "documentTitle": { + "cameras": "Cameras Stats - Frigate", + "storage": "Storage Stats - Frigate", + "general": "General Stats - Frigate", + "features": "Features Stats- Frigate", + "logs": { + "frigate": "Frigate Logs - Frigate", + "go2rtc": "Go2RTC Logs - Frigate", + "nginx": "Nginx Logs - Frigate" + } + }, "title": "System", "metrics": "System metrics", "logs": { diff --git a/web/public/locales/zh-CN/common.json b/web/public/locales/zh-CN/common.json index 980e40e9f..a989d1a53 100644 --- a/web/public/locales/zh-CN/common.json +++ b/web/public/locales/zh-CN/common.json @@ -130,6 +130,8 @@ "live": "实时监控", "live.allCameras": "所有摄像头", "live.cameras": "摄像头", + "live.cameras.count_one": "{{count}} 个摄像头", + "live.cameras.count_other": "{{count}} 个摄像头", "review": "回放", "explore": "探测", "export": "导出", @@ -156,5 +158,16 @@ "admin": "管理员", "viewer": "查看者", "desc": "管理员可以完全访问 Frigate UI 的所有功能。查看者则仅限于在 UI 中查看摄像头、审核项和历史录像。" - } + }, + "accessDefined": { + "documentTitle": "没有权限 - Frigate", + "title": "没有权限", + "desc": "您没有权限查看此页面。" + }, + "notFound": { + "documentTitle": "没有找到页面 - Frigate", + "title": "404", + "desc": "页面未找到" + }, + "selectItem": "选择 {{item}}" } diff --git a/web/public/locales/zh-CN/views/configEditor.json b/web/public/locales/zh-CN/views/configEditor.json index a8ad9292d..9b37414a4 100644 --- a/web/public/locales/zh-CN/views/configEditor.json +++ b/web/public/locales/zh-CN/views/configEditor.json @@ -1,4 +1,5 @@ { + "documentTitle": "配置编辑器 - Frigate", "configEditor": "配置编辑器", "copyConfig": "复制配置", "saveAndRestart": "保存并重启", diff --git a/web/public/locales/zh-CN/views/explore.json b/web/public/locales/zh-CN/views/explore.json index e221680c2..557fe2cea 100644 --- a/web/public/locales/zh-CN/views/explore.json +++ b/web/public/locales/zh-CN/views/explore.json @@ -1,4 +1,5 @@ { + "documentTitle": "探索 - Frigate", "generativeAI": "生成式 AI", "exploreIsUnavailable": { "title": "探索功能不可用", diff --git a/web/public/locales/zh-CN/views/faceLibrary.json b/web/public/locales/zh-CN/views/faceLibrary.json index 72b26a95e..49273155e 100644 --- a/web/public/locales/zh-CN/views/faceLibrary.json +++ b/web/public/locales/zh-CN/views/faceLibrary.json @@ -1,4 +1,5 @@ { + "documentTitle": "人脸库 - Frigate", "uploadFaceImage": { "title": "上传人脸图片", "desc": "上传图片以扫描人脸并包含在{{pageToggle}}中" diff --git a/web/public/locales/zh-CN/views/settings.json b/web/public/locales/zh-CN/views/settings.json index e820d1e63..664796122 100644 --- a/web/public/locales/zh-CN/views/settings.json +++ b/web/public/locales/zh-CN/views/settings.json @@ -1,7 +1,23 @@ { + "documentTitle": { + "default": "设置 - Frigate", + "authentication": "身份验证设置 - Frigate", + "camera": "摄像头设置 - Frigate", + "classification": "分类设置 - Frigate", + "masksAndZones": "遮罩和区域编辑器 - Frigate", + "motionTuner": "运动调整器 - Frigate", + "object": "对象设置 - Frigate", + "general": "常规设置 - Frigate" + }, + "dialog": { + "unsavedChanges": { + "title": "你有未保存的更改。", + "desc": "是否要在继续之前保存更改?" + } + }, "menu": { "uiSettings": "界面设置", - "exploreSettings": "搜索设置", + "classificationSettings": "分类设置", "cameraSettings": "摄像头设置", "masksAndZones": "遮罩/ 区域", "motionTuner": "运动调整器", @@ -373,6 +389,10 @@ "desc": "Frigate 在浏览器中运行或作为 PWA 安装时,可以原生向您的设备发送推送通知。", "documentation": "阅读文档(英文)" }, + "globalSettings": { + "title": "全局设置", + "desc": "临时暂停所有已注册设备上特定摄像头的通知。" + }, "notificationUnavailable": { "title": "通知功能不可用", "desc": "网页推送通知需要安全连接(https://...)。这是浏览器的限制。请通过安全方式访问 Frigate 以使用通知功能。", @@ -387,6 +407,19 @@ "deviceSpecific": "设备专用设置", "registerDevice": "注册该设备", "unregisterDevice": "取消注册该设备", + "sendTestNotification": "发送测试通知", + "active": "通知已启用", + "suspended": "通知已暂停 {{time}}", + "suspendTime": { + "5minutes": "暂停 5 分钟", + "10minutes": "暂停 10 分钟", + "30minutes": "暂停 30 分钟", + "1hour": "暂停 1 小时", + "12hours": "暂停 12 小时", + "24hours": "暂停 24 小时", + "untilRestart": "暂停直到重启" + }, + "cancelSuspension": "取消暂停", "toast": { "success": { "registered": "已成功注册通知。需要重启 Frigate 才能发送任何通知(包括测试通知)。", diff --git a/web/public/locales/zh-CN/views/system.json b/web/public/locales/zh-CN/views/system.json index 20d6bba8d..e123d1880 100644 --- a/web/public/locales/zh-CN/views/system.json +++ b/web/public/locales/zh-CN/views/system.json @@ -1,4 +1,15 @@ { + "documentTitle": { + "cameras": "摄像头统计 - Frigate", + "storage": "存储统计 - Frigate", + "general": "常规统计 - Frigate", + "features": "功能统计 - Frigate", + "logs": { + "frigate": "Frigate 日志 - Frigate", + "go2rtc": "Go2RTC 日志 - Frigate", + "nginx": "Nginx 日志 - Frigate" + } + }, "title": "系统", "metrics": "系统指标", "logs": { diff --git a/web/src/components/card/ReviewCard.tsx b/web/src/components/card/ReviewCard.tsx index d1939dfe4..258dc75c7 100644 --- a/web/src/components/card/ReviewCard.tsx +++ b/web/src/components/card/ReviewCard.tsx @@ -288,24 +288,22 @@ export default function ReviewCard({ > - Confirm Delete + + {t("recording.confirmDelete.title")} + - Are you sure you want to delete all recorded video associated with - this review item? -
-
- Hold the Shift key to bypass this dialog in the future. + recording.confirmDelete.desc
setOptionsOpen(false)}> - Cancel + {t("button.cancel", { ns: "common" })} - Delete + {t("button.delete", { ns: "common" })}
@@ -318,7 +316,7 @@ export default function ReviewCard({ onClick={onExport} > -
Export
+
{t("recording.button.export")}
{!event.has_been_reviewed && (
-
Mark as reviewed
+
+ {t("recording.button.markAsReviewed")} +
)}
- {bypassDialogRef.current ? "Delete Now" : "Delete"} + {bypassDialogRef.current + ? t("recording.button.deleteNow") + : t("button.delete", { ns: "common" })}
diff --git a/web/src/components/filter/CamerasFilterButton.tsx b/web/src/components/filter/CamerasFilterButton.tsx index 4d279782d..d8277b5f8 100644 --- a/web/src/components/filter/CamerasFilterButton.tsx +++ b/web/src/components/filter/CamerasFilterButton.tsx @@ -44,8 +44,12 @@ export function CamerasFilterButton({ if (!selectedCameras || selectedCameras.length == 0) { return t("menu.live.allCameras", { ns: "common" }); } - - return `${selectedCameras.includes("birdseye") ? selectedCameras.length - 1 : selectedCameras.length} Camera${selectedCameras.length !== 1 ? "s" : ""}`; + return t("menu.live.cameras.count", { + count: selectedCameras.includes("birdseye") + ? selectedCameras.length - 1 + : selectedCameras.length, + ns: "common", + }); }, [selectedCameras, t]); // ui diff --git a/web/src/pages/AccessDenied.tsx b/web/src/pages/AccessDenied.tsx index 53d83282b..68d7a8a51 100644 --- a/web/src/pages/AccessDenied.tsx +++ b/web/src/pages/AccessDenied.tsx @@ -1,21 +1,20 @@ import Heading from "@/components/ui/heading"; +import { t } from "i18next"; import { useEffect } from "react"; import { FaExclamationTriangle } from "react-icons/fa"; export default function AccessDenied() { useEffect(() => { - document.title = "Access Denied - Frigate"; + document.title = t("accessDefined.documentTitle"); }, []); return (
- Access Denied + {t("accessDefined.title")} -

- You don't have permission to view this page. -

+

{t("accessDefined.desc")}

); } diff --git a/web/src/pages/ConfigEditor.tsx b/web/src/pages/ConfigEditor.tsx index 03e02c51a..f0efee90a 100644 --- a/web/src/pages/ConfigEditor.tsx +++ b/web/src/pages/ConfigEditor.tsx @@ -29,8 +29,8 @@ function ConfigEditor() { const apiHost = useApiHost(); useEffect(() => { - document.title = "Config Editor - Frigate"; - }, []); + document.title = t("documentTitle"); + }, [t]); const { data: config } = useSWR("config/raw"); diff --git a/web/src/pages/FaceLibrary.tsx b/web/src/pages/FaceLibrary.tsx index 5756967d1..33fbb69d1 100644 --- a/web/src/pages/FaceLibrary.tsx +++ b/web/src/pages/FaceLibrary.tsx @@ -38,8 +38,8 @@ export default function FaceLibrary() { // title useEffect(() => { - document.title = "Face Library - Frigate"; - }, []); + document.title = t("documentTitle"); + }, [t]); const [page, setPage] = useState(); const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100); diff --git a/web/src/pages/Logs.tsx b/web/src/pages/Logs.tsx index f9fb3c88c..a3e3f1fc8 100644 --- a/web/src/pages/Logs.tsx +++ b/web/src/pages/Logs.tsx @@ -49,8 +49,8 @@ function Logs() { const lastFetchedIndexRef = useRef(-1); useEffect(() => { - document.title = `${logService[0].toUpperCase()}${logService.substring(1)} Logs - Frigate`; - }, [logService]); + document.title = t("documentTitle.logs." + logService); + }, [logService, t]); useEffect(() => { if (tabsRef.current) { diff --git a/web/src/pages/NoMatch.tsx b/web/src/pages/NoMatch.tsx index 933794abb..513eec1b4 100644 --- a/web/src/pages/NoMatch.tsx +++ b/web/src/pages/NoMatch.tsx @@ -1,15 +1,16 @@ import Heading from "@/components/ui/heading"; +import { t } from "i18next"; import { useEffect } from "react"; function NoMatch() { useEffect(() => { - document.title = "Not Found - Frigate"; + document.title = t("notFound.documentTitle"); }, []); return ( <> - 404 -

Page not found

+ {t("notFound.title")} +

{t("notFound.desc")}

); } diff --git a/web/src/pages/Settings.tsx b/web/src/pages/Settings.tsx index 0ee657e00..92eb083de 100644 --- a/web/src/pages/Settings.tsx +++ b/web/src/pages/Settings.tsx @@ -185,8 +185,8 @@ export default function Settings() { }); useEffect(() => { - document.title = "Settings - Frigate"; - }, []); + document.title = t("documentTitle.default"); + }, [t]); return (
@@ -215,7 +215,10 @@ export default function Settings() { className={`flex scroll-mx-10 items-center justify-between gap-2 ${page == "uiSettings" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`} value={item} data-nav-item={item} - aria-label={`Select ${item}`} + aria-label={t("selectItem", { + item: t("menu." + item), + ns: "common", + })} >
{t("menu." + item)}
@@ -284,17 +287,19 @@ export default function Settings() { > - You have unsaved changes. + + {t("dialog.unsavedChanges.title")} + - Do you want to save your changes before continuing? + {t("dialog.unsavedChanges.desc")} handleDialog(false)}> - Cancel + {t("button.cancel", { ns: "common" })} handleDialog(true)}> - Save + {t("button.save", { ns: "common" })} @@ -319,6 +324,8 @@ function CameraSelectButton({ cameraEnabledStates, currentPage, }: CameraSelectButtonProps) { + const { t } = useTranslation(["views/settings"]); + const [open, setOpen] = useState(false); if (!allCameras.length) { @@ -334,7 +341,7 @@ function CameraSelectButton({
{selectedCamera == undefined - ? "No Camera" + ? t("cameraSetting.noCamera") : selectedCamera.replaceAll("_", " ")}
@@ -344,7 +351,7 @@ function CameraSelectButton({ {isMobile && ( <> - Camera + {t("cameraSetting.camera")} diff --git a/web/src/pages/System.tsx b/web/src/pages/System.tsx index 753946323..7881fd0d3 100644 --- a/web/src/pages/System.tsx +++ b/web/src/pages/System.tsx @@ -12,7 +12,6 @@ import Logo from "@/components/Logo"; import useOptimisticState from "@/hooks/use-optimistic-state"; import CameraMetrics from "@/views/system/CameraMetrics"; import { useHashState } from "@/hooks/use-overlay-state"; -import { capitalizeFirstLetter } from "@/utils/stringUtil"; import { Toaster } from "@/components/ui/sonner"; import { FrigateConfig } from "@/types/frigateConfig"; import FeatureMetrics from "@/views/system/FeatureMetrics"; @@ -54,9 +53,9 @@ function System() { useEffect(() => { if (pageToggle) { - document.title = `${capitalizeFirstLetter(pageToggle)} Stats - Frigate`; + document.title = t("documentTitle." + pageToggle); } - }, [pageToggle]); + }, [pageToggle, t]); // stats collection diff --git a/web/src/views/explore/ExploreView.tsx b/web/src/views/explore/ExploreView.tsx index 3caf60781..01ae4789a 100644 --- a/web/src/views/explore/ExploreView.tsx +++ b/web/src/views/explore/ExploreView.tsx @@ -36,11 +36,12 @@ export default function ExploreView({ setSimilaritySearch, onSelectSearch, }: ExploreViewProps) { + const { t } = useTranslation(["views/explore"]); // title useEffect(() => { - document.title = "Explore - Frigate"; - }, []); + document.title = t("documentTitle"); + }, [t]); // data diff --git a/web/src/views/settings/AuthenticationView.tsx b/web/src/views/settings/AuthenticationView.tsx index 2a3f13217..f84b34bbc 100644 --- a/web/src/views/settings/AuthenticationView.tsx +++ b/web/src/views/settings/AuthenticationView.tsx @@ -49,8 +49,8 @@ export default function AuthenticationView() { >(); useEffect(() => { - document.title = "Authentication Settings - Frigate"; - }, []); + document.title = t("documentTitle.authentication"); + }, [t]); const onSavePassword = useCallback( (user: string, password: string) => { diff --git a/web/src/views/settings/ClassificationSettingsView.tsx b/web/src/views/settings/ClassificationSettingsView.tsx index c34ef37ee..e93677833 100644 --- a/web/src/views/settings/ClassificationSettingsView.tsx +++ b/web/src/views/settings/ClassificationSettingsView.tsx @@ -193,8 +193,8 @@ export default function ClassificationSettingsView({ }, [changedValue]); useEffect(() => { - document.title = "Classification Settings - Frigate"; - }, []); + document.title = t("documentTitle.classification"); + }, [t]); if (!config) { return ; diff --git a/web/src/views/settings/MasksAndZonesView.tsx b/web/src/views/settings/MasksAndZonesView.tsx index 87e1233a1..d30901695 100644 --- a/web/src/views/settings/MasksAndZonesView.tsx +++ b/web/src/views/settings/MasksAndZonesView.tsx @@ -185,8 +185,8 @@ export default function MasksAndZonesView({ setActivePolygonIndex(undefined); setHoveredPolygonIndex(null); setUnsavedChanges(false); - document.title = "Mask and Zone Editor - Frigate"; - }, [allPolygons, setUnsavedChanges]); + document.title = t("documentTitle.masksAndZones"); + }, [allPolygons, setUnsavedChanges, t]); const handleSave = useCallback(() => { setAllPolygons([...(editingPolygons ?? [])]); @@ -425,8 +425,8 @@ export default function MasksAndZonesView({ }); useEffect(() => { - document.title = "Mask and Zone Editor - Frigate"; - }, []); + document.title = t("documentTitle.masksAndZones"); + }, [t]); if (!cameraConfig && !selectedCamera) { return ; diff --git a/web/src/views/settings/MotionTunerView.tsx b/web/src/views/settings/MotionTunerView.tsx index c57f470c2..d3f914df3 100644 --- a/web/src/views/settings/MotionTunerView.tsx +++ b/web/src/views/settings/MotionTunerView.tsx @@ -179,8 +179,8 @@ export default function MotionTunerView({ }, [changedValue, selectedCamera]); useEffect(() => { - document.title = "Motion Tuner - Frigate"; - }, []); + document.title = t("documentTitle.motionTuner"); + }, [t]); if (!cameraConfig && !selectedCamera) { return ; diff --git a/web/src/views/settings/NotificationsSettingsView.tsx b/web/src/views/settings/NotificationsSettingsView.tsx index f0e0d349b..039e342cb 100644 --- a/web/src/views/settings/NotificationsSettingsView.tsx +++ b/web/src/views/settings/NotificationsSettingsView.tsx @@ -560,10 +560,10 @@ export default function NotificationView({ {registration != null && registration.active && ( )}
@@ -573,14 +573,11 @@ export default function NotificationView({
- Global Settings + {t("notification.globalSettings.title")}
-

- Temporarily suspend notifications for specific cameras - on all registered devices. -

+

{t("notification.globalSettings.desc")}

@@ -680,12 +677,13 @@ export function CameraNotificationSwitch({ {!isSuspended ? (
- Notifications Active + {t("notification.active")}
) : (
- Notifications suspended{" "} - {formatSuspendedUntil(notificationSuspendUntil)} + {t("notification.suspended", { + time: formatSuspendedUntil(notificationSuspendUntil), + })}
)}
@@ -698,13 +696,27 @@ export function CameraNotificationSwitch({ - Suspend for 5 minutes - Suspend for 10 minutes - Suspend for 30 minutes - Suspend for 1 hour - Suspend for 12 hours - Suspend for 24 hours - Suspend until restart + + {t("notification.suspendTime.5minutes")} + + + {t("notification.suspendTime.10minutes")} + + + {t("notification.suspendTime.30minutes")} + + + {t("notification.suspendTime.1hour")} + + + {t("notification.suspendTime.12hour")} + + + {t("notification.suspendTime.24hour")} + + + {t("notification.suspendTime.untilRestart")} + ) : ( @@ -713,7 +725,7 @@ export function CameraNotificationSwitch({ size="sm" onClick={handleCancelSuspension} > - Cancel Suspension + {t("notification.cancelSuspension")} )} diff --git a/web/src/views/settings/ObjectSettingsView.tsx b/web/src/views/settings/ObjectSettingsView.tsx index 55717bedc..e4cccef0a 100644 --- a/web/src/views/settings/ObjectSettingsView.tsx +++ b/web/src/views/settings/ObjectSettingsView.tsx @@ -136,8 +136,8 @@ export default function ObjectSettingsView({ }, [options, optionsLoaded]); useEffect(() => { - document.title = "Object Settings - Frigate"; - }, []); + document.title = t("documentTitle.object"); + }, [t]); if (!cameraConfig) { return ; diff --git a/web/src/views/settings/UiSettingsView.tsx b/web/src/views/settings/UiSettingsView.tsx index 14d727523..c5b273027 100644 --- a/web/src/views/settings/UiSettingsView.tsx +++ b/web/src/views/settings/UiSettingsView.tsx @@ -86,8 +86,8 @@ export default function UiSettingsView() { }, [config, t]); useEffect(() => { - document.title = "General Settings - Frigate"; - }, []); + document.title = t("documentTitle.general"); + }, [t]); // settings