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,