diff --git a/web/public/locales/en/components/dialog.json b/web/public/locales/en/components/dialog.json index 07dbc31ff..38a0ff22d 100644 --- a/web/public/locales/en/components/dialog.json +++ b/web/public/locales/en/components/dialog.json @@ -8,6 +8,24 @@ "button": "Force Reload Now" } }, + "explore": { + "plus": { + "submitToPlus": { + "label": "Submit To Frigate+", + "desc": "Objects in locations you want to avoid are not false positives. Submitting them as false positives will confuse the model." + }, + "review": { + "true_one": "This is a {{label}}", + "true_other": "This is an {{label}}", + "false_one": "This is not a {{label}}", + "false_other": "This is not an {{label}}", + "state.submitted": "Submitted" + } + }, + "video": { + "viewInHistory": "View in History" + } + }, "export": { "time": { "fromTimeline": "Select from Timeline", diff --git a/web/public/locales/en/views/explore.json b/web/public/locales/en/views/explore.json index 96d7d2002..f83b69d3d 100644 --- a/web/public/locales/en/views/explore.json +++ b/web/public/locales/en/views/explore.json @@ -7,6 +7,19 @@ "object_lifecycle": "object lifecycle" }, "details": { + "item": { + "title": "Review Item Details", + "desc": "Review item details", + "button": { + "share": "Share this review item", + "viewInExplore": "View in Explore" + }, + "tips": { + "mismatch_one": "{{count}} unavailable object was detected and included in this review item. Those objects either did not qualify as an alert or detection or have already been cleaned up/deleted.", + "mismatch_other": "{{count}} unavailable objects were detected and included in this review item. Those objects either did not qualify as an alert or detection or have already been cleaned up/deleted.", + "hasMissingObjects": "Adjust your configuration if you want Frigate to save tracked objects for the following labels: {{objects}}" + } + }, "label": "Label", "editSubLable": "Edit sub label", "editSubLable.desc": "Enter a new sub label for this {{label}}", @@ -14,7 +27,9 @@ "topScore": "Top Score", "topScore.info": "The top score is the highest median score for the tracked object, so this may differ from the score shown on the search result thumbnail.", "estimatedSpeed": "Estimated Speed", + "objects": "Objects", "camera": "Camera", + "zones": "Zones", "timestamp": "Timestamp", "button": { "findSimilar": "Find Similar" @@ -52,6 +67,10 @@ "submitToPlus": { "label": "Submit to Frigate+", "aria": "Submit to Frigate Plus" + }, + "viewInHistory": { + "label": "View in History", + "aria": "View in History" } }, "dialog": { diff --git a/web/public/locales/zh-CN/components/dialog.json b/web/public/locales/zh-CN/components/dialog.json index bf14f3542..7d24d214d 100644 --- a/web/public/locales/zh-CN/components/dialog.json +++ b/web/public/locales/zh-CN/components/dialog.json @@ -8,6 +8,24 @@ "button": "强制刷新" } }, + "explore": { + "plus": { + "submitToPlus": { + "label": "提交至 Frigate+", + "desc": "您希望避开的地点中的物体不应被视为误报。若将其作为误报提交,可能会导致AI模型容易混淆相关物体的识别。" + }, + "review": { + "true_one": "这是 {{label}}", + "true_other": "这是 {{label}}", + "false_one": "这不是 {{label}}", + "false_other": "这不是 {{label}}", + "state.submitted": "已提交" + } + }, + "video": { + "viewInHistory": "在历史中查看" + } + }, "export": { "time": { "fromTimeline": "从时间线选择", diff --git a/web/public/locales/zh-CN/components/input.json b/web/public/locales/zh-CN/components/input.json new file mode 100644 index 000000000..544b7b4dd --- /dev/null +++ b/web/public/locales/zh-CN/components/input.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/web/public/locales/zh-CN/views/explore.json b/web/public/locales/zh-CN/views/explore.json index 09370a3cf..ff8937722 100644 --- a/web/public/locales/zh-CN/views/explore.json +++ b/web/public/locales/zh-CN/views/explore.json @@ -7,6 +7,19 @@ "object_lifecycle": "对象生命周期" }, "details": { + "item": { + "title": "回放项目详情", + "desc": "回放项目详情", + "button": { + "share": "分享该回放", + "viewInExplore": "在探测中查看" + }, + "tips": { + "mismatch_one": "检测到 {{count}} 个不可用的对象,并已包含在此审核项中。这些对象可能未达到警告或检测标准,或者已被清理/删除。", + "mismatch_other": "检测到 {{count}} 个不可用的对象,并已包含在此审核项中。这些对象可能未达到警告或检测标准,或者已被清理/删除。", + "hasMissingObjects": "如果希望 Frigate 保存以下标签的跟踪对象,请调整您的配置:{{objects}}" + } + }, "label": "标签", "editSubLable": "编辑子标签", "editSubLable.desc": "为 {{label}} 输入新的子标签", @@ -14,7 +27,9 @@ "topScore": "最高得分", "topScore.info": "最高分是跟踪对象的最高中位数得分,因此可能与搜索结果缩略图上显示的得分不同。", "estimatedSpeed": "预计速度", + "objects": "对象", "camera": "摄像头", + "zones": "区域", "timestamp": "时间", "button": { "findSimilar": "查找相似项" @@ -52,6 +67,10 @@ "submitToPlus": { "label": "提交至 Frigate+", "aria": "提交至 Frigate Plus" + }, + "viewInHistory": { + "label": "在历史记录中查看", + "aria": "在历史记录中查看" } }, "dialog": { diff --git a/web/src/components/overlay/detail/ReviewDetailDialog.tsx b/web/src/components/overlay/detail/ReviewDetailDialog.tsx index 9f967ef28..c014d2ad7 100644 --- a/web/src/components/overlay/detail/ReviewDetailDialog.tsx +++ b/web/src/components/overlay/detail/ReviewDetailDialog.tsx @@ -42,7 +42,7 @@ import { DownloadVideoButton } from "@/components/button/DownloadVideoButton"; import { TooltipPortal } from "@radix-ui/react-tooltip"; import { LuSearch } from "react-icons/lu"; import useKeyboardListener from "@/hooks/use-keyboard-listener"; -import { t } from "i18next"; +import { Trans, useTranslation } from "react-i18next"; type ReviewDetailDialogProps = { review?: ReviewSegment; @@ -52,6 +52,7 @@ export default function ReviewDetailDialog({ review, setReview, }: ReviewDetailDialogProps) { + const { t } = useTranslation(["views/explore"]); const { data: config } = useSWR("config", { revalidateOnFocus: false, }); @@ -96,8 +97,8 @@ export default function ReviewDetailDialog({ const formattedDate = useFormattedTimestamp( review?.start_time ?? 0, config?.ui.time_format == "24hour" - ? t("time.formattedTimestampWithYear.24hour") - : t("time.formattedTimestampWithYear"), + ? t("time.formattedTimestampWithYear.24hour", { ns: "common" }) + : t("time.formattedTimestampWithYear", { ns: "common" }), config?.ui.timezone, ); @@ -178,8 +179,10 @@ export default function ReviewDetailDialog({ {pane == "overview" && (
- Review Item Details - Review item details + {t("details.item.title")} + + {t("details.item.desc")} +
- Share this review item + + {t("details.item.button.share")} + @@ -212,7 +217,9 @@ export default function ReviewDetailDialog({ /> - Download + + {t("button.download", { ns: "common" })} +
@@ -223,19 +230,25 @@ export default function ReviewDetailDialog({
-
Camera
+
+ {t("details.camera")} +
{review.camera.replaceAll("_", " ")}
-
Timestamp
+
+ {t("details.timestamp")} +
{formattedDate}
-
Objects
+
+ {t("details.objects")} +
{events?.map((event) => { return ( @@ -261,7 +274,9 @@ export default function ReviewDetailDialog({
- View in Explore + + {t("details.item.button.viewInExplore")} +
@@ -271,7 +286,9 @@ export default function ReviewDetailDialog({
{review.data.zones.length > 0 && (
-
Zones
+
+ {t("details.zones")} +
{review.data.zones.map((zone) => { return ( @@ -295,18 +312,23 @@ export default function ReviewDetailDialog({ (events?.length ?? 0) - (review?.data.detections.length ?? 0), ); - const objectLabel = - detectedCount === 1 ? "object was" : "objects were"; - return `${detectedCount} unavailable ${objectLabel} detected and included in this review item.`; - })()}{" "} - Those objects either did not qualify as an alert or detection - or have already been cleaned up/deleted. + return t("details.item.tips.mismatch", { + count: detectedCount, + }); + })()} {missingObjects.length > 0 && (
- Adjust your configuration if you want Frigate to save - tracked objects for the following labels:{" "} - {missingObjects.join(", ")} + t(x, { ns: "objects" })) + .join(", "), + }} + > + details.item.tips.hasMissingObjects +
)}
@@ -349,6 +371,8 @@ function EventItem({ setSelectedEvent, setUpload, }: EventItemProps) { + const { t } = useTranslation(["views/explore"]); + const { data: config } = useSWR("config", { revalidateOnFocus: false, }); @@ -418,7 +442,9 @@ function EventItem({ - Download + + {t("button.download", { ns: "common" })} + {event.has_snapshot && @@ -436,7 +462,9 @@ function EventItem({ - Submit to Frigate+ + + {t("itemMenu.submitToPlus.label")} + )} @@ -453,7 +481,9 @@ function EventItem({ - View Object Lifecycle + + {t("itemMenu.viewObjectLifecycle.label")} + )} @@ -471,7 +501,9 @@ function EventItem({ - Find Similar + + {t("itemMenu.findSimilar.label")} + )}
diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx index 3ffe4f331..d47f214b9 100644 --- a/web/src/components/overlay/detail/SearchDetailDialog.tsx +++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx @@ -578,8 +578,8 @@ function ObjectDetailsTab({
{averageEstimatedSpeed}{" "} {config?.ui.unit_system == "imperial" - ? t("unit.speed.mph") - : t("unit.speed.kph")}{" "} + ? t("unit.speed.mph", { ns: "common" }) + : t("unit.speed.kph", { ns: "common" })}{" "} {velocityAngle != undefined && ( {config?.semantic_search.enabled && search.data.type == "object" && ( )}
@@ -855,12 +855,10 @@ export function ObjectSnapshotTab({ "text-lg font-semibold leading-none tracking-tight" } > - Submit To Frigate+ + {t("explore.submitToPlus.label")}
- Objects in locations you want to avoid are not false - positives. Submitting them as false positives will - confuse the model. + {t("explore.submitToPlus.desc")}
@@ -875,9 +873,13 @@ export function ObjectSnapshotTab({ onSubmitToPlus(false); }} > - This is{" "} - {/^[aeiou]/i.test(search?.label || "") ? "an" : "a"}{" "} - {search?.label} + {/^[aeiou]/i.test(search?.label || "") + ? t("explore.plus.review.true_other", { + label: search?.label, + }) + : t("explore.plus.review.true_one", { + label: search?.label, + })} )} @@ -898,7 +904,7 @@ export function ObjectSnapshotTab({ {state == "submitted" && (
- Submitted + {t("explore.plus.review.state.submitted")}
)} @@ -917,6 +923,7 @@ type VideoTabProps = { }; export function VideoTab({ search }: VideoTabProps) { + const { t } = useTranslation(["views/explore"]); const navigate = useNavigate(); const { data: reviewItem } = useSWR([ `review/event/${search.id}`, @@ -951,7 +958,9 @@ export function VideoTab({ search }: VideoTabProps) { - View in History + + {t("itemMenu.viewInHistory.label")} + @@ -966,7 +975,9 @@ export function VideoTab({ search }: VideoTabProps) { - Download + + {t("button.download", { ns: "common" })} +