From 6219c25c67dc4f1df855afe34671d82349d71305 Mon Sep 17 00:00:00 2001 From: ZhaiSoul <842607283@qq.com> Date: Mon, 27 Oct 2025 07:39:46 +0000 Subject: [PATCH] refactor: refactor zones_friendly_names --- .../components/overlay/ObjectTrackOverlay.tsx | 26 ++++++++++++------- .../components/overlay/detail/ObjectPath.tsx | 13 +++++++--- web/src/components/timeline/DetailStream.tsx | 12 ++++++--- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/web/src/components/overlay/ObjectTrackOverlay.tsx b/web/src/components/overlay/ObjectTrackOverlay.tsx index 0643d2ed4..633c6070c 100644 --- a/web/src/components/overlay/ObjectTrackOverlay.tsx +++ b/web/src/components/overlay/ObjectTrackOverlay.tsx @@ -71,8 +71,11 @@ export default function ObjectTrackOverlay({ { revalidateOnFocus: false }, ); + const getZonesFriendlyNames = (zones: string[], config: FrigateConfig) => { + return zones?.map((zone) => resolveZoneName(config, zone)) ?? []; + }; + const timelineResults = useMemo(() => { - // Group timeline entries by source_id if (!timelineData) return selectedObjectIds.map(() => []); const grouped: Record = {}; @@ -83,9 +86,19 @@ export default function ObjectTrackOverlay({ grouped[entry.source_id].push(entry); } - // Return timeline arrays in the same order as selectedObjectIds - return selectedObjectIds.map((id) => grouped[id] || []); - }, [selectedObjectIds, timelineData]); + return selectedObjectIds.map((id) => { + const entries = grouped[id] || []; + return entries.map((event) => ({ + ...event, + data: { + ...event.data, + zones_friendly_names: config + ? getZonesFriendlyNames(event.data?.zones, config) + : [], + }, + })); + }); + }, [selectedObjectIds, timelineData, config]); const typeColorMap = useMemo( () => ({ @@ -157,11 +170,6 @@ export default function ObjectTrackOverlay({ ) .map((event: ObjectLifecycleSequence) => { 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 y: top + height, // Bottom y diff --git a/web/src/components/overlay/detail/ObjectPath.tsx b/web/src/components/overlay/detail/ObjectPath.tsx index ba20dd93b..5498dec76 100644 --- a/web/src/components/overlay/detail/ObjectPath.tsx +++ b/web/src/components/overlay/detail/ObjectPath.tsx @@ -51,10 +51,15 @@ export function ObjectPath({ const imgRect = imgRef.current.getBoundingClientRect(); return positions.map((pos) => { if (config && pos.lifecycle_item?.data?.zones) { - pos.lifecycle_item.data.zones_friendly_names = - pos.lifecycle_item.data.zones.map((zone) => { - return resolveZoneName(config, zone); - }); + pos.lifecycle_item = { + ...pos.lifecycle_item, + data: { + ...pos.lifecycle_item.data, + zones_friendly_names: pos.lifecycle_item.data.zones.map((zone) => { + return resolveZoneName(config, zone); + }), + }, + }; } return { x: pos.x * imgRect.width, diff --git a/web/src/components/timeline/DetailStream.tsx b/web/src/components/timeline/DetailStream.tsx index ee60a566d..1c3e221ce 100644 --- a/web/src/components/timeline/DetailStream.tsx +++ b/web/src/components/timeline/DetailStream.tsx @@ -558,9 +558,15 @@ function LifecycleItem({ const { t } = useTranslation("views/events"); const { data: config } = useSWR("config"); - item.data.zones_friendly_names = item?.data?.zones?.map((zone) => { - return resolveZoneName(config, zone); - }); + item = { + ...item, + data: { + ...item.data, + zones_friendly_names: item?.data?.zones?.map((zone) => { + return resolveZoneName(config, zone); + }), + }, + }; const aspectRatio = useMemo(() => { if (!config || !item?.camera) {