import Heading from "@/components/ui/heading"; import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { FrigateConfig } from "@/types/frigateConfig"; import useSWR from "swr"; import ActivityIndicator from "@/components/indicators/activity-indicator"; import { useEffect, useMemo, useRef, useState } from "react"; import { PolygonCanvas } from "./PolygonCanvas"; import { Polygon } from "@/types/canvas"; import { interpolatePoints } from "@/utils/canvasUtil"; import { isDesktop } from "react-device-detect"; import PolygonControls from "./PolygonControls"; import { Skeleton } from "../ui/skeleton"; import { useResizeObserver } from "@/hooks/resize-observer"; import { LuPencil } from "react-icons/lu"; const parseCoordinates = (coordinatesString: string) => { const coordinates = coordinatesString.split(","); const points = []; for (let i = 0; i < coordinates.length; i += 2) { const x = parseInt(coordinates[i], 10); const y = parseInt(coordinates[i + 1], 10); points.push([x, y]); } return points; }; export default function SettingsZones() { const { data: config } = useSWR("config"); const [zonePolygons, setZonePolygons] = useState([]); const [activePolygonIndex, setActivePolygonIndex] = useState( null, ); const containerRef = useRef(null); const cameras = useMemo(() => { if (!config) { return []; } return Object.values(config.cameras) .filter((conf) => conf.ui.dashboard && conf.enabled) .sort((aConf, bConf) => aConf.ui.order - bConf.ui.order); }, [config]); const [selectedCamera, setSelectedCamera] = useState(cameras[0].name); const cameraConfig = useMemo(() => { if (config && selectedCamera) { return config.cameras[selectedCamera]; } }, [config, selectedCamera]); const grow = useMemo(() => { if (!cameraConfig) { return; } const aspectRatio = cameraConfig.detect.width / cameraConfig.detect.height; if (aspectRatio > 2) { return "aspect-wide"; } else if (aspectRatio < 16 / 9) { if (isDesktop) { return "size-full aspect-tall"; } else { return "size-full"; } } else { return "size-full aspect-video"; } }, [cameraConfig]); const [{ width: containerWidth, height: containerHeight }] = useResizeObserver(containerRef); const { width, height } = cameraConfig ? cameraConfig.detect : { width: 1, height: 1 }; const aspectRatio = width / height; const stretch = false; const fitAspect = 0.75; const scaledHeight = useMemo(() => { const scaledHeight = aspectRatio < (fitAspect ?? 0) ? Math.floor(containerHeight) : Math.floor(containerWidth / aspectRatio); const finalHeight = stretch ? scaledHeight : Math.min(scaledHeight, height); if (finalHeight > 0) { return finalHeight; } return 100; }, [ aspectRatio, containerWidth, containerHeight, fitAspect, height, stretch, ]); const scaledWidth = useMemo( () => Math.ceil(scaledHeight * aspectRatio), [scaledHeight, aspectRatio], ); useEffect(() => { if (cameraConfig && containerRef.current) { setZonePolygons( Object.entries(cameraConfig.zones).map(([name, zoneData]) => ({ name, points: interpolatePoints( parseCoordinates(zoneData.coordinates), cameraConfig.detect.width, cameraConfig.detect.height, scaledWidth, scaledHeight, ), isFinished: true, })), ); } // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps }, [cameraConfig, containerRef]); if (!cameraConfig && !selectedCamera) { return ; } return ( <> Zones
{cameraConfig && (
{cameraConfig ? ( ) : ( )}
Name Coordinates Edit {zonePolygons.map((polygon, index) => ( {polygon.name} {JSON.stringify( interpolatePoints( polygon.points, scaledWidth, scaledHeight, cameraConfig.detect.width, cameraConfig.detect.height, ), null, 0, )} {" "}
setActivePolygonIndex(index)} >
))}
scaled width: {scaledWidth}, scaled height: {scaledHeight}, container width: {containerWidth}, container height: {containerHeight}
                {JSON.stringify(
                  zonePolygons &&
                    zonePolygons.map((polygon) =>
                      interpolatePoints(
                        polygon.points,
                        scaledWidth,
                        scaledHeight,
                        1,
                        1,
                      ),
                    ),
                  null,
                  0,
                )}
              
)} ); }