import { baseUrl } from "@/api/baseUrl"; import FilterCheckBox from "@/components/filter/FilterCheckBox"; 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, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Event } from "@/types/event"; import { FrigateConfig } from "@/types/frigateConfig"; import axios from "axios"; import { useCallback, useEffect, useMemo, useState } from "react"; import { isMobile } from "react-device-detect"; import { FaList, FaVideo } from "react-icons/fa"; import useSWR from "swr"; export default function SubmitPlus() { const { data: config } = useSWR("config"); useEffect(() => { document.title = "Plus - Frigate"; }, []); // filters const [selectedCameras, setSelectedCameras] = useState(); const [selectedLabels, setSelectedLabels] = useState(); // data const { data: events, mutate: refresh } = useSWR([ "events", { limit: 100, in_progress: 0, is_submitted: 0, cameras: selectedCameras ? selectedCameras.join(",") : null, labels: selectedLabels ? selectedLabels.join(",") : null, }, ]); const [upload, setUpload] = useState(); 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; } const index = data.findIndex((e) => e.id == upload.id); if (index == -1) { return data; } return [...data.slice(0, index), ...data.slice(index + 1)]; }, { revalidate: false, populateCache: true }, ); setUpload(undefined); }, [refresh, upload], ); return (
(!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?.label}`} {events?.map((event) => { if (event.data.type != "object") { return; } return (
setUpload(event)} >
); })}
); } const ATTRIBUTES = ["amazon", "face", "fedex", "license_plate", "ups"]; type PlusFilterGroupProps = { selectedCameras: string[] | undefined; setSelectedCameras: (cameras: string[] | undefined) => void; selectedLabels: string[] | undefined; setSelectedLabels: (cameras: string[] | undefined) => void; }; function PlusFilterGroup({ selectedCameras, setSelectedCameras, selectedLabels, setSelectedLabels, }: PlusFilterGroupProps) { const { data: config } = useSWR("config"); const allCameras = useMemo(() => { if (!config) { return []; } return Object.keys(config.cameras); }, [config]); const allLabels = useMemo(() => { if (!config) { return []; } const labels = new Set(); const cameras = selectedCameras || Object.keys(config.cameras); cameras.forEach((camera) => { const cameraConfig = config.cameras[camera]; cameraConfig.objects.track.forEach((label) => { if (!ATTRIBUTES.includes(label)) { labels.add(label); } }); }); return [...labels].sort(); }, [config, selectedCameras]); const [open, setOpen] = useState<"none" | "camera" | "label">("none"); const [currentCameras, setCurrentCameras] = useState( undefined, ); const [currentLabels, setCurrentLabels] = useState( undefined, ); const Menu = isMobile ? Drawer : DropdownMenu; const Trigger = isMobile ? DrawerTrigger : DropdownMenuTrigger; const Content = isMobile ? DrawerContent : DropdownMenuContent; return (
{ if (!open) { setCurrentCameras(selectedCameras); } setOpen(open ? "camera" : "none"); }} > Filter Cameras { if (isChecked) { setCurrentCameras(undefined); } }} />
{allCameras.map((item) => ( { if (isChecked) { const updatedCameras = currentCameras ? [...currentCameras] : []; updatedCameras.push(item); setCurrentCameras(updatedCameras); } else { const updatedCameras = currentCameras ? [...currentCameras] : []; // can not deselect the last item if (updatedCameras.length > 1) { updatedCameras.splice(updatedCameras.indexOf(item), 1); setCurrentCameras(updatedCameras); } } }} /> ))}
{ if (!open) { setCurrentLabels(selectedLabels); } setOpen(open ? "label" : "none"); }} > Filter Labels { if (isChecked) { setCurrentLabels(undefined); } }} />
{allLabels.map((item) => ( { if (isChecked) { const updatedLabels = currentLabels ? [...currentLabels] : []; updatedLabels.push(item); setCurrentLabels(updatedLabels); } else { const updatedLabels = currentLabels ? [...currentLabels] : []; // can not deselect the last item if (updatedLabels.length > 1) { updatedLabels.splice(updatedLabels.indexOf(item), 1); setCurrentLabels(updatedLabels); } } }} /> ))}
); }