diff --git a/web/src/components/overlay/dialog/FrigatePlusDialog.tsx b/web/src/components/overlay/dialog/FrigatePlusDialog.tsx new file mode 100644 index 000000000..3c5f3890d --- /dev/null +++ b/web/src/components/overlay/dialog/FrigatePlusDialog.tsx @@ -0,0 +1,123 @@ +import { baseUrl } from "@/api/baseUrl"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Event } from "@/types/event"; +import { FrigateConfig } from "@/types/frigateConfig"; +import axios from "axios"; +import { useCallback, useMemo } from "react"; +import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch"; +import useSWR from "swr"; + +type FrigatePlusDialogProps = { + upload?: Event; + onClose: () => void; + onEventUploaded: () => void; +}; +export function FrigatePlusDialog({ + upload, + onClose, + onEventUploaded, +}: FrigatePlusDialogProps) { + const { data: config } = useSWR("config"); + + // layout + + const grow = useMemo(() => { + if (!config || !upload) { + return ""; + } + + const camera = config.cameras[upload.camera]; + + if (!camera) { + return ""; + } + + if (camera.detect.width / camera.detect.height < 16 / 9) { + return "aspect-video object-contain"; + } + + return ""; + }, [config, upload]); + + // upload + + const onSubmitToPlus = useCallback( + async (falsePositive: boolean) => { + if (!upload) { + return; + } + + falsePositive + ? axios.put(`events/${upload.id}/false_positive`) + : axios.post(`events/${upload.id}/plus`, { + include_annotation: 1, + }); + + onEventUploaded(); + onClose(); + }, + [upload, onClose, onEventUploaded], + ); + + return ( + (!open ? onClose() : null)} + > + + + + Submit To Frigate+ + + Objects in locations you want to avoid are not false positives. + Submitting them as false positives will confuse the model. + + + + {upload?.id && ( + {`${upload?.label}`} + )} + + + + + + + + + + ); +} diff --git a/web/src/pages/SubmitPlus.tsx b/web/src/pages/SubmitPlus.tsx index d91bdb147..96fc21787 100644 --- a/web/src/pages/SubmitPlus.tsx +++ b/web/src/pages/SubmitPlus.tsx @@ -3,15 +3,8 @@ import { CamerasFilterButton } from "@/components/filter/CamerasFilterButton"; import { GeneralFilterContent } from "@/components/filter/ReviewFilterGroup"; import Chip from "@/components/indicators/Chip"; import ActivityIndicator from "@/components/indicators/activity-indicator"; +import { FrigatePlusDialog } from "@/components/overlay/dialog/FrigatePlusDialog"; import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from "@/components/ui/dialog"; import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer"; import { DropdownMenu, @@ -45,12 +38,11 @@ import { LuFolderX } from "react-icons/lu"; import { PiSlidersHorizontalFill } from "react-icons/pi"; import useSWR from "swr"; import useSWRInfinite from "swr/infinite"; -import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch"; const API_LIMIT = 100; export default function SubmitPlus() { - const { data: config } = useSWR("config"); + // title useEffect(() => { document.title = "Plus - Frigate"; @@ -155,77 +147,6 @@ export default function SubmitPlus() { [isValidating, isDone, size, setSize], ); - // layout - - const grow = useMemo(() => { - if (!config || !upload) { - return ""; - } - - const camera = config.cameras[upload.camera]; - - if (!camera) { - return ""; - } - - if (camera.detect.width / camera.detect.height < 16 / 9) { - return "aspect-video object-contain"; - } - - return ""; - }, [config, upload]); - - const onSubmitToPlus = useCallback( - async (falsePositive: boolean) => { - if (!upload) { - return; - } - - falsePositive - ? axios.put(`events/${upload.id}/false_positive`) - : axios.post(`events/${upload.id}/plus`, { - include_annotation: 1, - }); - - refresh( - (data: Event[][] | undefined) => { - if (!data) { - return data; - } - - let pageIndex = -1; - let index = -1; - - data.forEach((page, pIdx) => { - const search = page.findIndex((e) => e.id == upload.id); - - if (search != -1) { - pageIndex = pIdx; - index = search; - } - }); - - if (index == -1) { - return data; - } - - return [ - ...data.slice(0, pageIndex), - [ - ...data[pageIndex].slice(0, index), - { ...data[pageIndex][index], plus_id: "new_upload" }, - ...data[pageIndex].slice(index + 1), - ], - ...data.slice(pageIndex + 1), - ]; - }, - { revalidate: false, populateCache: true }, - ); - setUpload(undefined); - }, - [refresh, upload], - ); - return (
@@ -254,63 +175,46 @@ export default function SubmitPlus() { ) : ( <>
- (!open ? setUpload(undefined) : null)} - > - - - - Submit To Frigate+ - - Objects in locations you want to avoid are not false - positives. Submitting them as false positives will - confuse the model. - - - - {upload?.id && ( - {`${upload?.label}`} - )} - - - - - - - - - + setUpload(undefined)} + onEventUploaded={() => { + refresh( + (data: Event[][] | undefined) => { + if (!data || !upload) { + return data; + } + + let pageIndex = -1; + let index = -1; + + data.forEach((page, pIdx) => { + const search = page.findIndex((e) => e.id == upload.id); + + if (search != -1) { + pageIndex = pIdx; + index = search; + } + }); + + if (index == -1) { + return data; + } + + return [ + ...data.slice(0, pageIndex), + [ + ...data[pageIndex].slice(0, index), + { ...data[pageIndex][index], plus_id: "new_upload" }, + ...data[pageIndex].slice(index + 1), + ], + ...data.slice(pageIndex + 1), + ]; + }, + { revalidate: false, populateCache: true }, + ); + }} + /> {events?.map((event) => { if (event.data.type != "object" || event.plus_id) {