diff --git a/frigate/http.py b/frigate/http.py index d7ee87d2f..0c263cbe1 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -770,7 +770,7 @@ def hourly_timeline_activity(camera_name: str): hours[int(key.timestamp())].append( [ recording.start_time + (recording.duration / 2), - recording.motion, + max(recording.motion, recording.objects), data_type, ] ) diff --git a/web/src/components/card/TimelineItemCard.tsx b/web/src/components/card/TimelineItemCard.tsx index 9aa13c9e4..bb8e82e8c 100644 --- a/web/src/components/card/TimelineItemCard.tsx +++ b/web/src/components/card/TimelineItemCard.tsx @@ -21,7 +21,7 @@ export default function TimelineItemCard({ return ( -
+
{relevantPreview && ( )}
-
+
{getTimelineItemDescription(timeline)}
diff --git a/web/src/views/history/DesktopTimelineView.tsx b/web/src/views/history/DesktopTimelineView.tsx index a7fd4d954..53addfa2b 100644 --- a/web/src/views/history/DesktopTimelineView.tsx +++ b/web/src/views/history/DesktopTimelineView.tsx @@ -36,6 +36,7 @@ export default function DesktopTimelineView({ const playerRef = useRef(undefined); const previewRef = useRef(undefined); + const initialScrollRef = useRef(null); const [scrubbing, setScrubbing] = useState(false); const [focusedItem, setFocusedItem] = useState( @@ -120,6 +121,13 @@ export default function DesktopTimelineView({ [annotationOffset, recordings, playerRef] ); + // handle scrolling to initial timeline item + useEffect(() => { + if (initialScrollRef.current != null) { + initialScrollRef.current.scrollIntoView(); + } + }, [initialScrollRef]); + // handle seeking to next frame when seek is finished useEffect(() => { if (seeking) { @@ -305,7 +313,7 @@ export default function DesktopTimelineView({ )}
-
+
{selectedPlayback.timelineItems.map((timeline) => { return (
{timelineStack.playbackItems.map((timeline) => { + const isInitiallySelected = + initialPlayback.range.start == timeline.range.start; const isSelected = timeline.range.start == selectedPlayback.range.start; const graphData = timelineGraphData[timeline.range.start]; return (
setSelectedPlayback(timeline)} + doubleClickHandler={() => { + setScrubbing(false); + setSelectedPlayback(timeline); + }} /> {isSelected && graphData && (