From cae304e07ffdeb1a089b570f4e69fe580cd07341 Mon Sep 17 00:00:00 2001
From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
Date: Sun, 6 Oct 2024 12:43:36 -0500
Subject: [PATCH] Revamp object snapshot tab (#14180)
* Revamp object snapshot tab
* Make snapshots and thumbnails left justified in the review pane
---
.../overlay/detail/ReviewDetailDialog.tsx | 2 +-
.../overlay/detail/SearchDetailDialog.tsx | 146 +++++++++++++++++-
2 files changed, 141 insertions(+), 7 deletions(-)
diff --git a/web/src/components/overlay/detail/ReviewDetailDialog.tsx b/web/src/components/overlay/detail/ReviewDetailDialog.tsx
index 62486b9da..ae0397470 100644
--- a/web/src/components/overlay/detail/ReviewDetailDialog.tsx
+++ b/web/src/components/overlay/detail/ReviewDetailDialog.tsx
@@ -279,7 +279,7 @@ function EventItem({
<>
setHovered(true) : undefined}
diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx
index 4fac46421..f27023f02 100644
--- a/web/src/components/overlay/detail/SearchDetailDialog.tsx
+++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx
@@ -1,4 +1,4 @@
-import { isDesktop, isIOS, isMobile } from "react-device-detect";
+import { isDesktop, isIOS, isMobile, isSafari } from "react-device-detect";
import { SearchResult } from "@/types/search";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
@@ -20,7 +20,6 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
-import { FrigatePlusDialog } from "../dialog/FrigatePlusDialog";
import { Event } from "@/types/event";
import HlsVideoPlayer from "@/components/player/HlsVideoPlayer";
import { baseUrl } from "@/api/baseUrl";
@@ -28,6 +27,7 @@ import { cn } from "@/lib/utils";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import { ASPECT_VERTICAL_LAYOUT, ASPECT_WIDE_LAYOUT } from "@/types/record";
import {
+ FaCheckCircle,
FaChevronDown,
FaHistory,
FaImage,
@@ -59,6 +59,10 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
+import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
+import { Card, CardContent } from "@/components/ui/card";
+import useImageLoaded from "@/hooks/use-image-loaded";
+import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
const SEARCH_TABS = [
"details",
@@ -209,15 +213,13 @@ export default function SearchDetailDialog({
/>
)}
{page == "snapshot" && (
-
{}}
onEventUploaded={() => {
search.plus_id = "new_upload";
}}
@@ -459,6 +461,138 @@ function ObjectDetailsTab({
);
}
+type ObjectSnapshotTabProps = {
+ search: Event;
+ onEventUploaded: () => void;
+};
+function ObjectSnapshotTab({
+ search,
+ onEventUploaded,
+}: ObjectSnapshotTabProps) {
+ type SubmissionState = "reviewing" | "uploading" | "submitted";
+
+ const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
+
+ // upload
+
+ const [state, setState] = useState(
+ search?.plus_id ? "submitted" : "reviewing",
+ );
+
+ useEffect(
+ () => setState(search?.plus_id ? "submitted" : "reviewing"),
+ [search],
+ );
+
+ const onSubmitToPlus = useCallback(
+ async (falsePositive: boolean) => {
+ if (!search) {
+ return;
+ }
+
+ falsePositive
+ ? axios.put(`events/${search.id}/false_positive`)
+ : axios.post(`events/${search.id}/plus`, {
+ include_annotation: 1,
+ });
+
+ setState("submitted");
+ onEventUploaded();
+ },
+ [search, onEventUploaded],
+ );
+
+ return (
+
+
+
+
+
+
+ {search?.id && (
+ {
+ onImgLoad();
+ }}
+ />
+ )}
+
+
+
+
+
+ Submit To Frigate+
+
+
+ Objects in locations you want to avoid are not false
+ positives. Submitting them as false positives will confuse
+ the model.
+
+
+
+
+ {state == "reviewing" && (
+ <>
+
+
+ >
+ )}
+ {state == "uploading" &&
}
+ {state == "submitted" && (
+
+
+ Submitted
+
+ )}
+
+
+
+
+
+
+
+ );
+}
+
type VideoTabProps = {
search: SearchResult;
config?: FrigateConfig;