From 840d567d22b7974f90caf86773eb6ef0e726330c Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 26 Oct 2025 07:27:07 -0500 Subject: [PATCH] UI tweaks (#20675) * spacing tweaks and add link to explore for plate * clear selected objects when changing cameras * plate link and spacing in object lifecycle * set tabindex to prevent tooltip from showing on reopen * show month and day in object lifecycle timestamp --- .../overlay/detail/ObjectLifecycle.tsx | 37 ++++++++++------- web/src/components/timeline/DetailStream.tsx | 40 +++++++++++++------ web/src/context/detail-stream-context.tsx | 5 +++ 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/web/src/components/overlay/detail/ObjectLifecycle.tsx b/web/src/components/overlay/detail/ObjectLifecycle.tsx index 761be65ae..954f9cd6d 100644 --- a/web/src/components/overlay/detail/ObjectLifecycle.tsx +++ b/web/src/components/overlay/detail/ObjectLifecycle.tsx @@ -41,7 +41,7 @@ import { ContextMenuItem, ContextMenuTrigger, } from "@/components/ui/context-menu"; -import { useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import { ObjectPath } from "./ObjectPath"; import { getLifecycleItemDescription } from "@/utils/lifecycleUtil"; import { IoPlayCircleOutline } from "react-icons/io5"; @@ -289,10 +289,10 @@ export default function ObjectLifecycle({ timezone: config.ui.timezone, date_format: config.ui.time_format == "24hour" - ? t("time.formattedTimestampHourMinuteSecond.24hour", { + ? t("time.formattedTimestamp.24hour", { ns: "common", }) - : t("time.formattedTimestampHourMinuteSecond.12hour", { + : t("time.formattedTimestamp.12hour", { ns: "common", }), time_style: "medium", @@ -305,10 +305,10 @@ export default function ObjectLifecycle({ timezone: config.ui.timezone, date_format: config.ui.time_format == "24hour" - ? t("time.formattedTimestampHourMinuteSecond.24hour", { + ? t("time.formattedTimestamp.24hour", { ns: "common", }) - : t("time.formattedTimestampHourMinuteSecond.12hour", { + : t("time.formattedTimestamp.12hour", { ns: "common", }), time_style: "medium", @@ -412,6 +412,7 @@ export default function ObjectLifecycle({ return (
+ {!fullscreen && (
@@ -832,10 +838,12 @@ function LifecycleIconRow({ />
-
+
-
{getLifecycleItemDescription(item)}
-
+
+ {getLifecycleItemDescription(item)} +
+
{t("objectLifecycle.lifecycleItemDesc.header.ratio")} @@ -893,8 +901,9 @@ function LifecycleIconRow({ )}
- -
{formattedEventTimestamp}
+
+
+
{formattedEventTimestamp}
diff --git a/web/src/components/timeline/DetailStream.tsx b/web/src/components/timeline/DetailStream.tsx index 87f65967b..727f1bbed 100644 --- a/web/src/components/timeline/DetailStream.tsx +++ b/web/src/components/timeline/DetailStream.tsx @@ -22,6 +22,7 @@ import EventMenu from "@/components/timeline/EventMenu"; import { FrigatePlusDialog } from "@/components/overlay/dialog/FrigatePlusDialog"; import { cn } from "@/lib/utils"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import { Link } from "react-router-dom"; type DetailStreamProps = { reviewItems?: ReviewSegment[]; @@ -499,15 +500,22 @@ function EventList({ }} role="button" > - {label} - {event.data?.recognized_license_plate && ( - <> - ·{" "} - - {event.data.recognized_license_plate} - - - )} +
+ {label} + {event.data?.recognized_license_plate && ( + <> + · +
+ + {event.data.recognized_license_plate} + +
+ + )} +
@@ -615,10 +623,11 @@ function LifecycleItem({ )} />
-
+ +
-
+
{getLifecycleItemDescription(item)}
@@ -638,7 +647,9 @@ function LifecycleItem({ {areaPx !== undefined && areaPct !== undefined ? ( - {areaPx} {t("pixels", { ns: "common" })} · {areaPct}% + {areaPx} {t("pixels", { ns: "common" })}{" "} + ·{" "} + {areaPct}% ) : ( N/A @@ -648,7 +659,10 @@ function LifecycleItem({
-
{formattedEventTimestamp}
+
+ +
+
{formattedEventTimestamp}
); diff --git a/web/src/context/detail-stream-context.tsx b/web/src/context/detail-stream-context.tsx index aa7b2478b..a148833e7 100644 --- a/web/src/context/detail-stream-context.tsx +++ b/web/src/context/detail-stream-context.tsx @@ -58,6 +58,11 @@ export function DetailStreamProvider({ setAnnotationOffset(cfgOffset); }, [config, camera]); + // Clear selected objects when exiting detail mode or changing cameras + useEffect(() => { + setSelectedObjectIds([]); + }, [isDetailMode, camera]); + const value: DetailStreamContextType = { selectedObjectIds, currentTime,