chore: add ObjectTrack zone friendly name support

This commit is contained in:
ZhaiSoul 2025-10-23 13:57:32 +00:00
parent 450623e927
commit 17e89da6ca
3 changed files with 39 additions and 14 deletions

View File

@ -11,6 +11,7 @@ import {
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";
import { resolveZoneName } from "@/hooks/use-zone-friendly-name";
type ObjectTrackOverlayProps = {
camera: string;
@ -127,6 +128,9 @@ export default function ObjectTrackOverlay({
?.filter((event) => event.data.box !== undefined)
.map((event) => {
const [left, top, width, height] = event.data.box!;
event.data.zones_friendly_names = event?.data?.zones?.map((zone) => {
return resolveZoneName(config, zone);
});
return {
x: left + width / 2, // Center x
@ -136,7 +140,7 @@ export default function ObjectTrackOverlay({
};
}) || []
);
}, [objectTimeline]);
}, [config, objectTimeline]);
// final object path with timeline points included
const pathPoints = useMemo(() => {

View File

@ -7,7 +7,10 @@ import {
} from "@/components/ui/tooltip";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { getLifecycleItemDescription } from "@/utils/lifecycleUtil";
import { useTranslation } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
import { resolveZoneName } from "@/hooks/use-zone-friendly-name";
import { FrigateConfig } from "@/types/frigateConfig";
import useSWR from "swr";
type ObjectPathProps = {
positions?: Position[];
@ -42,16 +45,25 @@ export function ObjectPath({
visible = true,
}: ObjectPathProps) {
const { t } = useTranslation(["views/explore"]);
const { data: config } = useSWR<FrigateConfig>("config");
const getAbsolutePositions = useCallback(() => {
if (!imgRef.current || !positions) return [];
const imgRect = imgRef.current.getBoundingClientRect();
return positions.map((pos) => ({
x: pos.x * imgRect.width,
y: pos.y * imgRect.height,
timestamp: pos.timestamp,
lifecycle_item: pos.lifecycle_item,
}));
}, [positions, imgRef]);
return positions.map((pos) => {
if (config && pos.lifecycle_item) {
pos.lifecycle_item.data.zones_friendly_names =
pos.lifecycle_item?.data.zones.map((zone) => {
return resolveZoneName(config, zone);
});
}
return {
x: pos.x * imgRect.width,
y: pos.y * imgRect.height,
timestamp: pos.timestamp,
lifecycle_item: pos.lifecycle_item,
};
});
}, [imgRef, positions, config]);
const generateStraightPath = useCallback((points: Position[]) => {
if (!points || points.length < 2) return "";
@ -103,9 +115,11 @@ export function ObjectPath({
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" className="smart-capitalize">
{pos.lifecycle_item
? getLifecycleItemDescription(pos.lifecycle_item)
: t("objectLifecycle.trackedPoint")}
<Trans>
{pos.lifecycle_item
? getLifecycleItemDescription(pos.lifecycle_item)
: t("objectLifecycle.trackedPoint")}
</Trans>
</TooltipContent>
</TooltipPortal>
</Tooltip>

View File

@ -9,7 +9,7 @@ import {
formatUnixTimestampToDateTime,
formatSecondsToDuration,
} from "@/utils/dateUtil";
import { useTranslation } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
import AnnotationOffsetSlider from "@/components/overlay/detail/AnnotationOffsetSlider";
import { FrigateConfig } from "@/types/frigateConfig";
import useSWR from "swr";
@ -27,6 +27,7 @@ import { getTranslatedLabel } from "@/utils/i18n";
import EventMenu from "@/components/timeline/EventMenu";
import { FrigatePlusDialog } from "@/components/overlay/dialog/FrigatePlusDialog";
import { cn } from "@/lib/utils";
import { resolveZoneName } from "@/hooks/use-zone-friendly-name";
type DetailStreamProps = {
reviewItems?: ReviewSegment[];
@ -503,6 +504,10 @@ function LifecycleItem({ event, isActive, onSeek }: LifecycleItemProps) {
const { t } = useTranslation("views/events");
const { data: config } = useSWR<FrigateConfig>("config");
event.data.zones_friendly_names = event?.data?.zones?.map((zone) => {
return resolveZoneName(config, zone);
});
const formattedEventTimestamp = config
? formatUnixTimestampToDateTime(event.timestamp ?? 0, {
timezone: config.ui.timezone,
@ -536,7 +541,9 @@ function LifecycleItem({ event, isActive, onSeek }: LifecycleItemProps) {
<LifecycleIcon lifecycleItem={event} className="size-3" />
</div>
<div className="flex w-full flex-row justify-between">
<div>{getLifecycleItemDescription(event)}</div>
<Trans>
<div>{getLifecycleItemDescription(event)}</div>
</Trans>
<div className={cn("p-1 text-xs")}>{formattedEventTimestamp}</div>
</div>
</div>