Improve handling of label types

This commit is contained in:
Nicolas Mowen 2025-10-15 12:40:25 -06:00
parent 88c2376fe4
commit 5b9b138035
5 changed files with 36 additions and 12 deletions

View File

@ -150,7 +150,7 @@ export default function SearchThumbnail({
.filter(
(item) => item !== undefined && !item.includes("-verified"),
)
.map((text) => getTranslatedLabel(text))
.map((text) => getTranslatedLabel(text, searchResult.data.type))
.sort()
.join(", ")
.replaceAll("-verified", "")}

View File

@ -29,6 +29,8 @@ export type SearchSortType =
| "score_desc"
| "relevance";
export type EventType = "object" | "audio" | "manual";
export type SearchResult = {
id: string;
camera: string;
@ -54,7 +56,7 @@ export type SearchResult = {
box: number[];
area: number;
ratio: number;
type: "object" | "audio" | "manual";
type: EventType;
description?: string;
average_estimated_speed: number;
velocity_angle: number;

View File

@ -1,10 +1,18 @@
import i18n, { t } from "i18next";
import { initReactI18next } from "react-i18next";
import HttpBackend from "i18next-http-backend";
import { EventType } from "@/types/search";
export const getTranslatedLabel = (label: string) => {
export const getTranslatedLabel = (
label: string,
type: EventType = "object",
) => {
if (!label) return "";
if (type === "manual") {
return label;
}
const normalize = (s: string) =>
s
.trim()
@ -15,8 +23,9 @@ export const getTranslatedLabel = (label: string) => {
const key = normalize(label);
if (i18n.exists(key, { ns: "objects" })) return t(key, { ns: "objects" });
if (i18n.exists(key, { ns: "audio" })) return t(key, { ns: "audio" });
if (type === "audio") {
return t(`audio.${key}`, { ns: "audio" });
}
// fallback
return t(key, { ns: "objects" });

View File

@ -11,7 +11,7 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { SearchResult } from "@/types/search";
import { EventType, SearchResult } from "@/types/search";
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
import useImageLoaded from "@/hooks/use-image-loaded";
import ActivityIndicator from "@/components/indicators/activity-indicator";
@ -110,7 +110,8 @@ export default function ExploreView({
key={label}
searchResults={filteredEvents}
isValidating={isValidating}
objectType={label}
label={label}
labelType={filteredEvents[0]?.data?.type || "object"}
setSearchDetail={setSearchDetail}
mutate={mutate}
setSimilaritySearch={setSimilaritySearch}
@ -122,7 +123,8 @@ export default function ExploreView({
}
type ThumbnailRowType = {
objectType: string;
label: string;
labelType: EventType;
searchResults?: SearchResult[];
isValidating: boolean;
setSearchDetail: (search: SearchResult | undefined) => void;
@ -132,7 +134,8 @@ type ThumbnailRowType = {
};
function ThumbnailRow({
objectType,
label,
labelType,
searchResults,
isValidating,
setSearchDetail,
@ -153,7 +156,7 @@ function ThumbnailRow({
return (
<div className="rounded-lg bg-background_alt p-2 md:px-4">
<div className="flex flex-row items-center text-lg smart-capitalize">
{getTranslatedLabel(objectType)}
{getTranslatedLabel(label, labelType)}
{searchResults && (
<span className="ml-3 text-sm text-secondary-foreground">
{t("trackedObjectsCount", {

View File

@ -100,7 +100,12 @@ export default function CameraSettingsView({
const alertsLabels = useMemo(() => {
return cameraConfig?.review.alerts.labels
? cameraConfig.review.alerts.labels
.map((label) => getTranslatedLabel(label))
.map((label) =>
getTranslatedLabel(
label,
cameraConfig?.audio?.listen?.includes(label) ? "audio" : "object",
),
)
.join(", ")
: "";
}, [cameraConfig]);
@ -108,7 +113,12 @@ export default function CameraSettingsView({
const detectionsLabels = useMemo(() => {
return cameraConfig?.review.detections.labels
? cameraConfig.review.detections.labels
.map((label) => getTranslatedLabel(label))
.map((label) =>
getTranslatedLabel(
label,
cameraConfig?.audio?.listen?.includes(label) ? "audio" : "object",
),
)
.join(", ")
: "";
}, [cameraConfig]);