diff --git a/web/src/components/overlay/ObjectTrackOverlay.tsx b/web/src/components/overlay/ObjectTrackOverlay.tsx index 2c4414c30..bce733a20 100644 --- a/web/src/components/overlay/ObjectTrackOverlay.tsx +++ b/web/src/components/overlay/ObjectTrackOverlay.tsx @@ -18,6 +18,7 @@ type ObjectTrackOverlayProps = { videoHeight: number; className?: string; onSeekToTime?: (timestamp: number) => void; + objectTimeline?: ObjectLifecycleSequence[]; }; export default function ObjectTrackOverlay({ @@ -28,17 +29,10 @@ export default function ObjectTrackOverlay({ videoHeight, className, onSeekToTime, + objectTimeline, }: ObjectTrackOverlayProps) { const { data: config } = useSWR("config"); - // Fetch timeline data for the selected object - const { data: objectTimeline } = useSWR([ - "timeline", - { - source_id: selectedObjectId, - }, - ]); - // Fetch the full event data to get saved path points const { data: eventData } = useSWR(["event_ids", { ids: selectedObjectId }]); @@ -158,9 +152,8 @@ export default function ObjectTrackOverlay({ return pathPoints.map((point) => { // Find the corresponding timeline entry for this point const timelineEntry = objectTimeline?.find( - (entry) => Math.abs(entry.timestamp - point.timestamp) < 0.1, + (entry) => entry.timestamp == point.timestamp, ); - return { x: point.x * videoWidth, y: point.y * videoHeight, diff --git a/web/src/components/player/HlsVideoPlayer.tsx b/web/src/components/player/HlsVideoPlayer.tsx index 143824ae7..69c51a45f 100644 --- a/web/src/components/player/HlsVideoPlayer.tsx +++ b/web/src/components/player/HlsVideoPlayer.tsx @@ -77,8 +77,13 @@ export default function HlsVideoPlayer({ }: HlsVideoPlayerProps) { const { t } = useTranslation("components/player"); const { data: config } = useSWR("config"); - const { selectedObjectId, currentTime, camera, isActivityMode } = - useActivityStream(); + const { + selectedObjectId, + selectedObjectTimeline, + currentTime, + camera, + isActivityMode, + } = useActivityStream(); // playback @@ -327,6 +332,7 @@ export default function HlsVideoPlayer({ onSeekToTime(timestamp); } }} + objectTimeline={selectedObjectTimeline} /> )} diff --git a/web/src/contexts/ActivityStreamContext.tsx b/web/src/contexts/ActivityStreamContext.tsx index afc7b1ac6..3c95cbffa 100644 --- a/web/src/contexts/ActivityStreamContext.tsx +++ b/web/src/contexts/ActivityStreamContext.tsx @@ -1,7 +1,9 @@ -import React, { createContext, useContext, useState } from "react"; +import React, { createContext, useContext, useState, useMemo } from "react"; +import { ObjectLifecycleSequence } from "@/types/timeline"; interface ActivityStreamContextType { selectedObjectId: string | undefined; + selectedObjectTimeline: ObjectLifecycleSequence[] | undefined; currentTime: number; camera: string; setSelectedObjectId: (id: string | undefined) => void; @@ -17,6 +19,7 @@ interface ActivityStreamProviderProps { isActivityMode: boolean; currentTime: number; camera: string; + timelineData: ObjectLifecycleSequence[]; } export function ActivityStreamProvider({ @@ -24,13 +27,20 @@ export function ActivityStreamProvider({ isActivityMode, currentTime, camera, + timelineData, }: ActivityStreamProviderProps) { const [selectedObjectId, setSelectedObjectId] = useState< string | undefined >(); + const selectedObjectTimeline = useMemo(() => { + if (!selectedObjectId || !timelineData) return undefined; + return timelineData.filter((item) => item.source_id === selectedObjectId); + }, [timelineData, selectedObjectId]); + const value: ActivityStreamContextType = { selectedObjectId, + selectedObjectTimeline, currentTime, camera, setSelectedObjectId, diff --git a/web/src/views/recording/RecordingView.tsx b/web/src/views/recording/RecordingView.tsx index 6b2afacad..6fb1a1fac 100644 --- a/web/src/views/recording/RecordingView.tsx +++ b/web/src/views/recording/RecordingView.tsx @@ -571,6 +571,7 @@ export function RecordingView({ isActivityMode={timelineType === "activity"} currentTime={currentTime} camera={mainCamera} + timelineData={timelineData} >