From 24a1874225cf6260136c9f5f768af3a013e99603 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 9 Oct 2025 08:49:42 -0600 Subject: [PATCH] UI Tweaks (#20403) * Fix context menu link to debug * Use genai title for tooltip when available --- web/src/components/card/AnimatedEventCard.tsx | 36 +++++++++++-------- web/src/components/menu/LiveContextMenu.tsx | 4 +-- web/src/hooks/use-overlay-state.tsx | 17 +++++++-- web/src/types/ws.ts | 2 +- web/src/views/live/LiveCameraView.tsx | 9 +++++ web/src/views/live/LiveDashboardView.tsx | 6 +++- 6 files changed, 52 insertions(+), 22 deletions(-) diff --git a/web/src/components/card/AnimatedEventCard.tsx b/web/src/components/card/AnimatedEventCard.tsx index a04804641..20d39efe2 100644 --- a/web/src/components/card/AnimatedEventCard.tsx +++ b/web/src/components/card/AnimatedEventCard.tsx @@ -50,6 +50,27 @@ export function AnimatedEventCard({ fetchPreviews: !currentHour, }); + const tooltipText = useMemo(() => { + if (event?.data?.metadata?.title) { + return event.data.metadata.title; + } + + return ( + `${[ + ...new Set([ + ...(event.data.objects || []), + ...(event.data.sub_labels || []), + ...(event.data.audio || []), + ]), + ] + .filter((item) => item !== undefined && !item.includes("-verified")) + .map((text) => text.charAt(0).toUpperCase() + text.substring(1)) + .sort() + .join(", ") + .replaceAll("-verified", "")} ` + t("detected") + ); + }, [event, t]); + // visibility const [windowVisible, setWindowVisible] = useState(true); @@ -220,20 +241,7 @@ export function AnimatedEventCard({ )} - - {`${[ - ...new Set([ - ...(event.data.objects || []), - ...(event.data.sub_labels || []), - ...(event.data.audio || []), - ]), - ] - .filter((item) => item !== undefined && !item.includes("-verified")) - .map((text) => text.charAt(0).toUpperCase() + text.substring(1)) - .sort() - .join(", ") - .replaceAll("-verified", "")} ` + t("detected")} - + {tooltipText} ); } diff --git a/web/src/components/menu/LiveContextMenu.tsx b/web/src/components/menu/LiveContextMenu.tsx index 8641365a3..aaf43c087 100644 --- a/web/src/components/menu/LiveContextMenu.tsx +++ b/web/src/components/menu/LiveContextMenu.tsx @@ -355,9 +355,7 @@ export default function LiveContextMenu({
navigate(`/settings?page=debug&camera=${camera}`) - : undefined + isEnabled ? () => navigate(`?debug=true#${camera}`) : undefined } >
diff --git a/web/src/hooks/use-overlay-state.tsx b/web/src/hooks/use-overlay-state.tsx index 585afd542..ab4b7fcfe 100644 --- a/web/src/hooks/use-overlay-state.tsx +++ b/web/src/hooks/use-overlay-state.tsx @@ -112,7 +112,8 @@ export function useSearchEffect( callback: (value: string) => boolean, ) { const location = useLocation(); - const [searchParams, setSearchParams] = useSearchParams(); + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); const param = useMemo(() => { const param = searchParams.get(key); @@ -132,7 +133,17 @@ export function useSearchEffect( const remove = callback(param[1]); if (remove) { - setSearchParams(undefined, { state: location.state, replace: true }); + navigate(location.pathname + location.hash, { + state: location.state, + replace: true, + }); } - }, [param, location.state, callback, setSearchParams]); + }, [ + param, + location.state, + location.pathname, + location.hash, + callback, + navigate, + ]); } diff --git a/web/src/types/ws.ts b/web/src/types/ws.ts index 3a464a275..1120aec67 100644 --- a/web/src/types/ws.ts +++ b/web/src/types/ws.ts @@ -30,7 +30,7 @@ type FrigateObjectState = { }; export interface FrigateReview { - type: "new" | "update" | "end"; + type: "new" | "update" | "end" | "genai"; before: ReviewSegment; after: ReviewSegment; } diff --git a/web/src/views/live/LiveCameraView.tsx b/web/src/views/live/LiveCameraView.tsx index 1e427435c..5fd514bc4 100644 --- a/web/src/views/live/LiveCameraView.tsx +++ b/web/src/views/live/LiveCameraView.tsx @@ -111,6 +111,7 @@ import { Trans, useTranslation } from "react-i18next"; import { useDocDomain } from "@/hooks/use-doc-domain"; import PtzControlPanel from "@/components/overlay/PtzControlPanel"; import ObjectSettingsView from "../settings/ObjectSettingsView"; +import { useSearchEffect } from "@/hooks/use-overlay-state"; type LiveCameraViewProps = { config?: FrigateConfig; @@ -274,6 +275,14 @@ export default function LiveCameraView({ const [showStats, setShowStats] = useState(false); const [debug, setDebug] = useState(false); + useSearchEffect("debug", (value: string) => { + if (value === "true") { + setDebug(true); + } + + return true; + }); + const [fullResolution, setFullResolution] = useState({ width: 0, height: 0, diff --git a/web/src/views/live/LiveDashboardView.tsx b/web/src/views/live/LiveDashboardView.tsx index ddd6ccd51..69f4c0d53 100644 --- a/web/src/views/live/LiveDashboardView.tsx +++ b/web/src/views/live/LiveDashboardView.tsx @@ -114,7 +114,11 @@ export default function LiveDashboardView({ // if event is ended and was saved, update events list if (eventUpdate.after.severity == "alert") { - if (eventUpdate.type == "end" || eventUpdate.type == "new") { + if ( + eventUpdate.type == "end" || + eventUpdate.type == "new" || + eventUpdate.type == "genai" + ) { setTimeout( () => updateEvents(), eventUpdate.type == "end" ? 1000 : 6000,