From f9a37d4f4f92494f0d6fcce96b12d978424a864e Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 27 Sep 2026 18:21:46 -0500 Subject: [PATCH] remember last selected history sidebar tab (#24488) The History view always opened on Timeline unless the link carried a tab. The selected tab is now saved with useUserPersistence and used as the default when no tab is passed. Notification and shared review links no longer default to "timeline", so they pick up the saved tab too, and `?tab=` still overrides it. --- web/src/pages/Events.tsx | 3 +-- web/src/views/recording/RecordingView.tsx | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/web/src/pages/Events.tsx b/web/src/pages/Events.tsx index c83413c152..22074d00e8 100644 --- a/web/src/pages/Events.tsx +++ b/web/src/pages/Events.tsx @@ -132,8 +132,7 @@ export default function Events() { setMotionSearchDay(normalizedDay); }, []); - const [notificationTab, setNotificationTab] = - useState("timeline"); + const [notificationTab, setNotificationTab] = useState(); const getReviewDayBounds = useCallback((date: Date) => { const now = Date.now() / 1000; diff --git a/web/src/views/recording/RecordingView.tsx b/web/src/views/recording/RecordingView.tsx index 1498ba531f..1d9657f705 100644 --- a/web/src/views/recording/RecordingView.tsx +++ b/web/src/views/recording/RecordingView.tsx @@ -14,6 +14,7 @@ import { Button } from "@/components/ui/button"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import { useOverlayState } from "@/hooks/use-overlay-state"; import { usePersistence } from "@/hooks/use-persistence"; +import { useUserPersistence } from "@/hooks/use-user-persistence"; import { useResizeObserver } from "@/hooks/resize-observer"; import { DEFAULT_DRAWER_FEATURES, ExportMode } from "@/types/filter"; import { FrigateConfig } from "@/types/frigateConfig"; @@ -182,9 +183,19 @@ export function RecordingView({ false, ); - const [timelineType, setTimelineType] = useOverlayState( + const [savedTimelineType, setSavedTimelineType] = + useUserPersistence("recordingTimelineType"); + const [timelineType, setOverlayTimelineType] = useOverlayState( "timelineType", - recording?.timelineType ?? "timeline", + recording?.timelineType ?? savedTimelineType ?? "timeline", + ); + + const setTimelineType = useCallback( + (value: TimelineType, replace?: boolean) => { + setOverlayTimelineType(value, replace); + setSavedTimelineType(value); + }, + [setOverlayTimelineType, setSavedTimelineType], ); const chunkedTimeRange = useMemo(