mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
clean up
This commit is contained in:
parent
1ba4502b07
commit
f92de9af2e
@ -28,110 +28,36 @@ import { Link } from "react-router-dom";
|
|||||||
type MasksAndZoneProps = {
|
type MasksAndZoneProps = {
|
||||||
selectedCamera: string;
|
selectedCamera: string;
|
||||||
selectedZoneMask?: PolygonType[];
|
selectedZoneMask?: PolygonType[];
|
||||||
isEditing: boolean;
|
|
||||||
setIsEditing: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
unsavedChanges: boolean;
|
|
||||||
setUnsavedChanges: React.Dispatch<React.SetStateAction<boolean>>;
|
setUnsavedChanges: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function MasksAndZones({
|
export default function MasksAndZones({
|
||||||
selectedCamera,
|
selectedCamera,
|
||||||
selectedZoneMask,
|
selectedZoneMask,
|
||||||
isEditing,
|
|
||||||
setIsEditing,
|
|
||||||
unsavedChanges,
|
|
||||||
setUnsavedChanges,
|
setUnsavedChanges,
|
||||||
}: MasksAndZoneProps) {
|
}: MasksAndZoneProps) {
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const [allPolygons, setAllPolygons] = useState<Polygon[]>([]);
|
const [allPolygons, setAllPolygons] = useState<Polygon[]>([]);
|
||||||
const [editingPolygons, setEditingPolygons] = useState<Polygon[]>([]);
|
const [editingPolygons, setEditingPolygons] = useState<Polygon[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
// const [zoneObjects, setZoneObjects] = useState<ZoneObjects[]>([]);
|
|
||||||
const [activePolygonIndex, setActivePolygonIndex] = useState<
|
const [activePolygonIndex, setActivePolygonIndex] = useState<
|
||||||
number | undefined
|
number | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const [hoveredPolygonIndex, setHoveredPolygonIndex] = useState<number | null>(
|
const [hoveredPolygonIndex, setHoveredPolygonIndex] = useState<number | null>(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
// const polygonTypes = [
|
|
||||||
// "zone",
|
|
||||||
// "motion_mask",
|
|
||||||
// "object_mask",
|
|
||||||
// undefined,
|
|
||||||
// ] as const;
|
|
||||||
|
|
||||||
// type EditPaneType = (typeof polygonTypes)[number];
|
|
||||||
const [editPane, setEditPane] = useState<PolygonType | undefined>(undefined);
|
const [editPane, setEditPane] = useState<PolygonType | undefined>(undefined);
|
||||||
|
|
||||||
// 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 cameraConfig = useMemo(() => {
|
const cameraConfig = useMemo(() => {
|
||||||
if (config && selectedCamera) {
|
if (config && selectedCamera) {
|
||||||
return config.cameras[selectedCamera];
|
return config.cameras[selectedCamera];
|
||||||
}
|
}
|
||||||
}, [config, selectedCamera]);
|
}, [config, selectedCamera]);
|
||||||
|
|
||||||
// const saveZoneObjects = useCallback(
|
|
||||||
// (camera: string, zoneName: string, newObjects?: string[]) => {
|
|
||||||
// setZoneObjects((prevZoneObjects) =>
|
|
||||||
// prevZoneObjects.map((zoneObject) => {
|
|
||||||
// if (
|
|
||||||
// zoneObject.camera === camera &&
|
|
||||||
// zoneObject.zoneName === zoneName
|
|
||||||
// ) {
|
|
||||||
// console.log("found", camera, "with", zoneName);
|
|
||||||
// console.log("new objects", newObjects);
|
|
||||||
// console.log("new zoneobject", {
|
|
||||||
// ...zoneObject,
|
|
||||||
// objects: newObjects ?? [],
|
|
||||||
// });
|
|
||||||
// // Replace objects with newObjects if provided
|
|
||||||
// return {
|
|
||||||
// ...zoneObject,
|
|
||||||
// objects: newObjects ?? [],
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// return zoneObject; // Keep original object
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// [setZoneObjects],
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const saveZoneObjects = useCallback(
|
|
||||||
// (camera: string, zoneName: string, objects?: string[]) => {
|
|
||||||
// setZoneObjects((prevZoneObjects) => {
|
|
||||||
// const updatedZoneObjects = prevZoneObjects.map((zoneObject) => {
|
|
||||||
// if (
|
|
||||||
// zoneObject.camera === camera &&
|
|
||||||
// zoneObject.zoneName === zoneName
|
|
||||||
// ) {
|
|
||||||
// return { ...zoneObject, objects: objects || [] };
|
|
||||||
// }
|
|
||||||
// return zoneObject;
|
|
||||||
// });
|
|
||||||
// return updatedZoneObjects;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// [setZoneObjects],
|
|
||||||
// );
|
|
||||||
|
|
||||||
const [{ width: containerWidth, height: containerHeight }] =
|
const [{ width: containerWidth, height: containerHeight }] =
|
||||||
useResizeObserver(containerRef);
|
useResizeObserver(containerRef);
|
||||||
|
|
||||||
// const { width: detectWidth, height: detectHeight } = cameraConfig
|
|
||||||
// ? cameraConfig.detect
|
|
||||||
// : { width: 1, height: 1 };
|
|
||||||
const aspectRatio = useMemo(() => {
|
const aspectRatio = useMemo(() => {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -216,7 +142,6 @@ export default function MasksAndZones({
|
|||||||
{
|
{
|
||||||
points: [],
|
points: [],
|
||||||
isFinished: false,
|
isFinished: false,
|
||||||
// isUnsaved: true,
|
|
||||||
type,
|
type,
|
||||||
typeIndex: 9999,
|
typeIndex: 9999,
|
||||||
name: "",
|
name: "",
|
||||||
@ -228,35 +153,27 @@ export default function MasksAndZones({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = useCallback(() => {
|
const handleCancel = useCallback(() => {
|
||||||
// console.log("handling cancel");
|
|
||||||
setEditPane(undefined);
|
setEditPane(undefined);
|
||||||
// console.log("all", allPolygons);
|
|
||||||
// console.log("editing", editingPolygons);
|
|
||||||
// setAllPolygons(allPolygons.filter((poly) => !poly.isUnsaved));
|
|
||||||
setEditingPolygons([...allPolygons]);
|
setEditingPolygons([...allPolygons]);
|
||||||
setActivePolygonIndex(undefined);
|
setActivePolygonIndex(undefined);
|
||||||
setHoveredPolygonIndex(null);
|
setHoveredPolygonIndex(null);
|
||||||
}, [allPolygons]);
|
}, [allPolygons]);
|
||||||
|
|
||||||
const handleSave = useCallback(() => {
|
const handleSave = useCallback(() => {
|
||||||
// console.log("handling save");
|
|
||||||
setAllPolygons([...(editingPolygons ?? [])]);
|
setAllPolygons([...(editingPolygons ?? [])]);
|
||||||
|
|
||||||
// setEditPane(undefined);
|
|
||||||
setHoveredPolygonIndex(null);
|
setHoveredPolygonIndex(null);
|
||||||
}, [editingPolygons]);
|
}, [editingPolygons]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(isLoading);
|
|
||||||
console.log("edit pane", editPane);
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isLoading && editPane !== undefined) {
|
if (!isLoading && editPane !== undefined) {
|
||||||
console.log("setting");
|
|
||||||
setActivePolygonIndex(undefined);
|
setActivePolygonIndex(undefined);
|
||||||
setEditPane(undefined);
|
setEditPane(undefined);
|
||||||
}
|
}
|
||||||
|
// we know that these deps are correct
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isLoading]);
|
}, [isLoading]);
|
||||||
|
|
||||||
const handleCopyCoordinates = useCallback(
|
const handleCopyCoordinates = useCallback(
|
||||||
@ -276,8 +193,6 @@ export default function MasksAndZones({
|
|||||||
[allPolygons, scaledHeight, scaledWidth],
|
[allPolygons, scaledHeight, scaledWidth],
|
||||||
);
|
);
|
||||||
|
|
||||||
// useEffect(() => {}, [editPane]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cameraConfig && containerRef.current && scaledWidth && scaledHeight) {
|
if (cameraConfig && containerRef.current && scaledWidth && scaledHeight) {
|
||||||
const zones = Object.entries(cameraConfig.zones).map(
|
const zones = Object.entries(cameraConfig.zones).map(
|
||||||
@ -295,7 +210,6 @@ export default function MasksAndZones({
|
|||||||
scaledHeight,
|
scaledHeight,
|
||||||
),
|
),
|
||||||
isFinished: true,
|
isFinished: true,
|
||||||
// isUnsaved: false,
|
|
||||||
color: zoneData.color,
|
color: zoneData.color,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -338,6 +252,7 @@ export default function MasksAndZones({
|
|||||||
: cameraConfig.objects.mask
|
: cameraConfig.objects.mask
|
||||||
? [cameraConfig.objects.mask]
|
? [cameraConfig.objects.mask]
|
||||||
: [];
|
: [];
|
||||||
|
// TODO: check to see if this is necessary
|
||||||
if (
|
if (
|
||||||
cameraConfig.objects.mask !== null &&
|
cameraConfig.objects.mask !== null &&
|
||||||
cameraConfig.objects.mask !== undefined
|
cameraConfig.objects.mask !== undefined
|
||||||
@ -360,28 +275,15 @@ export default function MasksAndZones({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (globalObjectMasks && !Array.isArray(globalObjectMasks)) {
|
|
||||||
// globalObjectMasks = [globalObjectMasks];
|
|
||||||
// }
|
|
||||||
|
|
||||||
console.log("global", globalObjectMasks);
|
|
||||||
|
|
||||||
const globalObjectMasksCount = globalObjectMasks.length;
|
const globalObjectMasksCount = globalObjectMasks.length;
|
||||||
|
|
||||||
console.log("filters", cameraConfig.objects.filters);
|
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
objectMasks = Object.entries(cameraConfig.objects.filters)
|
objectMasks = Object.entries(cameraConfig.objects.filters)
|
||||||
.filter(([_, { mask }]) => mask || Array.isArray(mask))
|
.filter(([, { mask }]) => mask || Array.isArray(mask))
|
||||||
.flatMap(([objectName, { mask }]): Polygon[] => {
|
.flatMap(([objectName, { mask }]): Polygon[] => {
|
||||||
console.log("index", index);
|
|
||||||
console.log("outer", objectName, mask);
|
|
||||||
|
|
||||||
const maskArray = Array.isArray(mask) ? mask : mask ? [mask] : [];
|
const maskArray = Array.isArray(mask) ? mask : mask ? [mask] : [];
|
||||||
|
|
||||||
return maskArray.flatMap((maskItem, subIndex) => {
|
return maskArray.flatMap((maskItem, subIndex) => {
|
||||||
const maskItemString = maskItem;
|
const maskItemString = maskItem;
|
||||||
|
|
||||||
const newMask = {
|
const newMask = {
|
||||||
type: "object_mask" as PolygonType,
|
type: "object_mask" as PolygonType,
|
||||||
typeIndex: subIndex,
|
typeIndex: subIndex,
|
||||||
@ -413,11 +315,6 @@ export default function MasksAndZones({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(Object.entries(cameraConfig.objects.filters));
|
|
||||||
|
|
||||||
console.log("final object masks", objectMasks);
|
|
||||||
|
|
||||||
// console.log("setting all and editing");
|
|
||||||
setAllPolygons([
|
setAllPolygons([
|
||||||
...zones,
|
...zones,
|
||||||
...motionMasks,
|
...motionMasks,
|
||||||
@ -430,46 +327,18 @@ export default function MasksAndZones({
|
|||||||
...globalObjectMasks,
|
...globalObjectMasks,
|
||||||
...objectMasks,
|
...objectMasks,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// setZoneObjects(
|
|
||||||
// Object.entries(cameraConfig.zones).map(([name, zoneData]) => ({
|
|
||||||
// camera: cameraConfig.name,
|
|
||||||
// zoneName: name,
|
|
||||||
// objects: Object.keys(zoneData.filters),
|
|
||||||
// })),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
// we know that these deps are correct
|
// we know that these deps are correct
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [cameraConfig, containerRef, scaledHeight, scaledWidth]);
|
}, [cameraConfig, containerRef, scaledHeight, scaledWidth]);
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log("editing polygons changed:", editingPolygons);
|
|
||||||
// }, [editingPolygons]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editPane === undefined) {
|
if (editPane === undefined) {
|
||||||
setEditingPolygons([...allPolygons]);
|
setEditingPolygons([...allPolygons]);
|
||||||
setIsEditing(false);
|
|
||||||
// console.log("edit pane undefined, all", allPolygons);
|
|
||||||
} else {
|
|
||||||
setIsEditing(true);
|
|
||||||
}
|
}
|
||||||
// we know that these deps are correct
|
// we know that these deps are correct
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [setEditingPolygons, setIsEditing, allPolygons]);
|
}, [setEditingPolygons, allPolygons]);
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log(
|
|
||||||
// "config zone objects",
|
|
||||||
// Object.entries(cameraConfig.zones).map(([name, zoneData]) => ({
|
|
||||||
// camera: cameraConfig.name,
|
|
||||||
// zoneName: name,
|
|
||||||
// objects: Object.keys(zoneData.filters),
|
|
||||||
// })),
|
|
||||||
// );
|
|
||||||
// console.log("component zone objects", zoneObjects);
|
|
||||||
// }, [zoneObjects]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedCamera) {
|
if (selectedCamera) {
|
||||||
@ -586,12 +455,10 @@ export default function MasksAndZones({
|
|||||||
key={index}
|
key={index}
|
||||||
polygon={polygon}
|
polygon={polygon}
|
||||||
index={index}
|
index={index}
|
||||||
activePolygonIndex={activePolygonIndex}
|
|
||||||
hoveredPolygonIndex={hoveredPolygonIndex}
|
hoveredPolygonIndex={hoveredPolygonIndex}
|
||||||
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
||||||
setActivePolygonIndex={setActivePolygonIndex}
|
setActivePolygonIndex={setActivePolygonIndex}
|
||||||
setEditPane={setEditPane}
|
setEditPane={setEditPane}
|
||||||
setAllPolygons={setAllPolygons}
|
|
||||||
handleCopyCoordinates={handleCopyCoordinates}
|
handleCopyCoordinates={handleCopyCoordinates}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -658,12 +525,10 @@ export default function MasksAndZones({
|
|||||||
key={index}
|
key={index}
|
||||||
polygon={polygon}
|
polygon={polygon}
|
||||||
index={index}
|
index={index}
|
||||||
activePolygonIndex={activePolygonIndex}
|
|
||||||
hoveredPolygonIndex={hoveredPolygonIndex}
|
hoveredPolygonIndex={hoveredPolygonIndex}
|
||||||
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
||||||
setActivePolygonIndex={setActivePolygonIndex}
|
setActivePolygonIndex={setActivePolygonIndex}
|
||||||
setEditPane={setEditPane}
|
setEditPane={setEditPane}
|
||||||
setAllPolygons={setAllPolygons}
|
|
||||||
handleCopyCoordinates={handleCopyCoordinates}
|
handleCopyCoordinates={handleCopyCoordinates}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -729,12 +594,10 @@ export default function MasksAndZones({
|
|||||||
key={index}
|
key={index}
|
||||||
polygon={polygon}
|
polygon={polygon}
|
||||||
index={index}
|
index={index}
|
||||||
activePolygonIndex={activePolygonIndex}
|
|
||||||
hoveredPolygonIndex={hoveredPolygonIndex}
|
hoveredPolygonIndex={hoveredPolygonIndex}
|
||||||
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
setHoveredPolygonIndex={setHoveredPolygonIndex}
|
||||||
setActivePolygonIndex={setActivePolygonIndex}
|
setActivePolygonIndex={setActivePolygonIndex}
|
||||||
setEditPane={setEditPane}
|
setEditPane={setEditPane}
|
||||||
setAllPolygons={setAllPolygons}
|
|
||||||
handleCopyCoordinates={handleCopyCoordinates}
|
handleCopyCoordinates={handleCopyCoordinates}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -743,85 +606,6 @@ export default function MasksAndZones({
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* <Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead className="w-[100px]">Name</TableHead>
|
|
||||||
<TableHead className="max-w-[200px]">Coordinates</TableHead>
|
|
||||||
<TableHead>Edit</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{allPolygons.map((polygon, index) => (
|
|
||||||
<TableRow key={index}>
|
|
||||||
<TableCell className="font-medium">
|
|
||||||
{polygon.name}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="max-w-[200px] text-wrap">
|
|
||||||
<code>
|
|
||||||
{JSON.stringify(
|
|
||||||
interpolatePoints(
|
|
||||||
polygon.points,
|
|
||||||
scaledWidth,
|
|
||||||
scaledHeight,
|
|
||||||
cameraConfig.detect.width,
|
|
||||||
cameraConfig.detect.height,
|
|
||||||
),
|
|
||||||
null,
|
|
||||||
0,
|
|
||||||
)}
|
|
||||||
</code>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<div
|
|
||||||
className="cursor-pointer"
|
|
||||||
onClick={() => setActivePolygonIndex(index)}
|
|
||||||
>
|
|
||||||
<LuPencil className="size-4 text-white" />
|
|
||||||
</div>
|
|
||||||
<ZoneObjectSelector
|
|
||||||
camera={polygon.camera}
|
|
||||||
zoneName={polygon.name}
|
|
||||||
allLabels={allLabels}
|
|
||||||
updateLabelFilter={(objects) =>
|
|
||||||
saveZoneObjects(polygon.camera, polygon.name, objects)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
<div>
|
|
||||||
scaled width: {scaledWidth}, scaled height: {scaledHeight},
|
|
||||||
container width: {containerWidth}, container height:
|
|
||||||
{containerHeight}
|
|
||||||
</div>
|
|
||||||
<ZoneControls
|
|
||||||
camera={cameraConfig.name}
|
|
||||||
polygons={allPolygons}
|
|
||||||
setPolygons={setAllPolygons}
|
|
||||||
activePolygonIndex={activePolygonIndex}
|
|
||||||
setActivePolygonIndex={setActivePolygonIndex}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-col justify-center items-center m-auto w-[30%] bg-secondary">
|
|
||||||
<pre style={{ whiteSpace: "pre-wrap" }}>
|
|
||||||
{JSON.stringify(
|
|
||||||
allPolygons &&
|
|
||||||
allPolygons.map((polygon) =>
|
|
||||||
interpolatePoints(
|
|
||||||
polygon.points,
|
|
||||||
scaledWidth,
|
|
||||||
scaledHeight,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
null,
|
|
||||||
0,
|
|
||||||
)}
|
|
||||||
</pre>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
|
|||||||
@ -92,13 +92,6 @@ export default function MotionMaskEditPane({
|
|||||||
if (!scaledWidth || !scaledHeight || !polygon || !cameraConfig) {
|
if (!scaledWidth || !scaledHeight || !polygon || !cameraConfig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// console.log("loitering time", loitering_time);
|
|
||||||
// const alertsZones = config?.cameras[camera]?.review.alerts.required_zones;
|
|
||||||
|
|
||||||
// const detectionsZones =
|
|
||||||
// config?.cameras[camera]?.review.detections.required_zones;
|
|
||||||
|
|
||||||
// console.log("out of try except", mutatedConfig);
|
|
||||||
|
|
||||||
const coordinates = flattenPoints(
|
const coordinates = flattenPoints(
|
||||||
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
||||||
@ -110,14 +103,11 @@ export default function MotionMaskEditPane({
|
|||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
console.log("are we an array?", Array.isArray(cameraConfig.motion.mask));
|
|
||||||
console.log("index", index);
|
|
||||||
const editingMask = polygon.name.length > 0;
|
const editingMask = polygon.name.length > 0;
|
||||||
|
|
||||||
// editing existing mask, not creating a new one
|
// editing existing mask, not creating a new one
|
||||||
if (editingMask) {
|
if (editingMask) {
|
||||||
index = polygon.typeIndex;
|
index = polygon.typeIndex;
|
||||||
console.log("editing, index", index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredMask = (
|
const filteredMask = (
|
||||||
@ -125,15 +115,8 @@ export default function MotionMaskEditPane({
|
|||||||
? cameraConfig.motion.mask
|
? cameraConfig.motion.mask
|
||||||
: [cameraConfig.motion.mask]
|
: [cameraConfig.motion.mask]
|
||||||
).filter((_, currentIndex) => currentIndex !== index);
|
).filter((_, currentIndex) => currentIndex !== index);
|
||||||
console.log("filtered", filteredMask);
|
|
||||||
|
|
||||||
// if (editingMask) {
|
|
||||||
// if (index != null) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
filteredMask.splice(index, 0, coordinates);
|
filteredMask.splice(index, 0, coordinates);
|
||||||
console.log("filtered after splice", filteredMask);
|
|
||||||
|
|
||||||
const queryString = filteredMask
|
const queryString = filteredMask
|
||||||
.map((pointsArray) => {
|
.map((pointsArray) => {
|
||||||
@ -144,16 +127,6 @@ export default function MotionMaskEditPane({
|
|||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
console.log("polygon", polygon);
|
|
||||||
console.log(queryString);
|
|
||||||
|
|
||||||
// console.log(
|
|
||||||
// `config/set?cameras.${polygon?.camera}.motion.mask=${coordinates}&${queryString}`,
|
|
||||||
// );
|
|
||||||
console.log("motion masks", cameraConfig.motion.mask);
|
|
||||||
console.log("new coords", coordinates);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.put(`config/set?${queryString}`, {
|
.put(`config/set?${queryString}`, {
|
||||||
requires_restart: 0,
|
requires_restart: 0,
|
||||||
@ -163,7 +136,6 @@ export default function MotionMaskEditPane({
|
|||||||
toast.success(`${polygon.name || "Motion Mask"} has been saved.`, {
|
toast.success(`${polygon.name || "Motion Mask"} has been saved.`, {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
});
|
});
|
||||||
// setChangedValue(false);
|
|
||||||
updateConfig();
|
updateConfig();
|
||||||
} else {
|
} else {
|
||||||
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
||||||
@ -180,23 +152,20 @@ export default function MotionMaskEditPane({
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
}, [updateConfig, polygon, scaledWidth, scaledHeight, setIsLoading]);
|
}, [
|
||||||
|
updateConfig,
|
||||||
|
polygon,
|
||||||
|
scaledWidth,
|
||||||
|
scaledHeight,
|
||||||
|
setIsLoading,
|
||||||
|
cameraConfig,
|
||||||
|
]);
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||||
if (activePolygonIndex === undefined || !values || !polygons) {
|
if (activePolygonIndex === undefined || !values || !polygons) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
// polygons[activePolygonIndex].name = values.name;
|
|
||||||
// console.log("form values", values);
|
|
||||||
// console.log(
|
|
||||||
// "string",
|
|
||||||
|
|
||||||
// flattenPoints(
|
|
||||||
// interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
|
||||||
// ).join(","),
|
|
||||||
// );
|
|
||||||
// console.log("active polygon", polygons[activePolygonIndex]);
|
|
||||||
|
|
||||||
saveToConfig();
|
saveToConfig();
|
||||||
if (onSave) {
|
if (onSave) {
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import { LuExternalLink } from "react-icons/lu";
|
|||||||
|
|
||||||
type MotionTunerProps = {
|
type MotionTunerProps = {
|
||||||
selectedCamera: string;
|
selectedCamera: string;
|
||||||
|
setUnsavedChanges: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type MotionSettings = {
|
type MotionSettings = {
|
||||||
@ -41,7 +42,10 @@ type MotionSettings = {
|
|||||||
improve_contrast?: boolean;
|
improve_contrast?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function MotionTuner({ selectedCamera }: MotionTunerProps) {
|
export default function MotionTuner({
|
||||||
|
selectedCamera,
|
||||||
|
setUnsavedChanges,
|
||||||
|
}: MotionTunerProps) {
|
||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
useSWR<FrigateConfig>("config");
|
useSWR<FrigateConfig>("config");
|
||||||
const [changedValue, setChangedValue] = useState(false);
|
const [changedValue, setChangedValue] = useState(false);
|
||||||
|
|||||||
@ -63,17 +63,6 @@ export default function ObjectMaskEditPane({
|
|||||||
}: ObjectMaskEditPaneProps) {
|
}: ObjectMaskEditPaneProps) {
|
||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
useSWR<FrigateConfig>("config");
|
useSWR<FrigateConfig>("config");
|
||||||
// const { data: config } = useSWR<FrigateConfig>("config");
|
|
||||||
|
|
||||||
// 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 polygon = useMemo(() => {
|
const polygon = useMemo(() => {
|
||||||
if (polygons && activePolygonIndex !== undefined) {
|
if (polygons && activePolygonIndex !== undefined) {
|
||||||
@ -129,22 +118,10 @@ export default function ObjectMaskEditPane({
|
|||||||
const saveToConfig = useCallback(
|
const saveToConfig = useCallback(
|
||||||
async (
|
async (
|
||||||
{ objects: form_objects }: ObjectMaskFormValuesType, // values submitted via the form
|
{ objects: form_objects }: ObjectMaskFormValuesType, // values submitted via the form
|
||||||
objects: string[],
|
|
||||||
) => {
|
) => {
|
||||||
if (!scaledWidth || !scaledHeight || !polygon || !cameraConfig) {
|
if (!scaledWidth || !scaledHeight || !polygon || !cameraConfig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// console.log("loitering time", loitering_time);
|
|
||||||
// const alertsZones = config?.cameras[camera]?.review.alerts.required_zones;
|
|
||||||
|
|
||||||
// const detectionsZones =
|
|
||||||
// config?.cameras[camera]?.review.detections.required_zones;
|
|
||||||
|
|
||||||
// console.log("out of try except", mutatedConfig);
|
|
||||||
|
|
||||||
console.log("form objects:", form_objects);
|
|
||||||
console.log("objects:", objects);
|
|
||||||
console.log(cameraConfig.objects.filters);
|
|
||||||
|
|
||||||
const coordinates = flattenPoints(
|
const coordinates = flattenPoints(
|
||||||
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
||||||
@ -183,9 +160,6 @@ export default function ObjectMaskEditPane({
|
|||||||
index = polygon.typeIndex;
|
index = polygon.typeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("are we an array?", Array.isArray(configObject));
|
|
||||||
console.log("index", index);
|
|
||||||
|
|
||||||
// editing existing mask, not creating a new one
|
// editing existing mask, not creating a new one
|
||||||
if (editingMask) {
|
if (editingMask) {
|
||||||
index = polygon.typeIndex;
|
index = polygon.typeIndex;
|
||||||
@ -195,10 +169,7 @@ export default function ObjectMaskEditPane({
|
|||||||
Array.isArray(configObject) ? configObject : [configObject as string]
|
Array.isArray(configObject) ? configObject : [configObject as string]
|
||||||
).filter((_, currentIndex) => currentIndex !== index);
|
).filter((_, currentIndex) => currentIndex !== index);
|
||||||
|
|
||||||
console.log("filtered", filteredMask);
|
|
||||||
|
|
||||||
filteredMask.splice(index, 0, coordinates);
|
filteredMask.splice(index, 0, coordinates);
|
||||||
console.log("filtered after splice", filteredMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
queryString = filteredMask
|
queryString = filteredMask
|
||||||
@ -212,18 +183,7 @@ export default function ObjectMaskEditPane({
|
|||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
console.log("polygon", polygon);
|
|
||||||
console.log(queryString);
|
|
||||||
|
|
||||||
// console.log(
|
|
||||||
// `config/set?cameras.${polygon?.camera}.objects.mask=${coordinates}&${queryString}`,
|
|
||||||
// );
|
|
||||||
// console.log("object masks", cameraConfig.objects.mask);
|
|
||||||
// console.log("new coords", coordinates);
|
|
||||||
// return;
|
|
||||||
|
|
||||||
if (!queryString) {
|
if (!queryString) {
|
||||||
console.log("no query string");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +196,6 @@ export default function ObjectMaskEditPane({
|
|||||||
toast.success(`${polygon.name || "Object Mask"} has been saved.`, {
|
toast.success(`${polygon.name || "Object Mask"} has been saved.`, {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
});
|
});
|
||||||
// setChangedValue(false);
|
|
||||||
updateConfig();
|
updateConfig();
|
||||||
} else {
|
} else {
|
||||||
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
||||||
@ -254,7 +213,14 @@ export default function ObjectMaskEditPane({
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[updateConfig, polygon, scaledWidth, scaledHeight, setIsLoading],
|
[
|
||||||
|
updateConfig,
|
||||||
|
polygon,
|
||||||
|
scaledWidth,
|
||||||
|
scaledHeight,
|
||||||
|
setIsLoading,
|
||||||
|
cameraConfig,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||||
@ -262,21 +228,8 @@ export default function ObjectMaskEditPane({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
// polygons[activePolygonIndex].name = values.name;
|
|
||||||
// console.log("form values", values);
|
|
||||||
// console.log(
|
|
||||||
// "string",
|
|
||||||
|
|
||||||
// flattenPoints(
|
saveToConfig(values as ObjectMaskFormValuesType);
|
||||||
// interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
|
||||||
// ).join(","),
|
|
||||||
// );
|
|
||||||
// console.log("active polygon", polygons[activePolygonIndex]);
|
|
||||||
|
|
||||||
saveToConfig(
|
|
||||||
values as ObjectMaskFormValuesType,
|
|
||||||
polygons[activePolygonIndex].objects,
|
|
||||||
);
|
|
||||||
if (onSave) {
|
if (onSave) {
|
||||||
onSave();
|
onSave();
|
||||||
}
|
}
|
||||||
|
|||||||
31
web/src/components/settings/ObjectSettings.tsx
Normal file
31
web/src/components/settings/ObjectSettings.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import DebugCameraImage from "../camera/DebugCameraImage";
|
||||||
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
|
import useSWR from "swr";
|
||||||
|
import ActivityIndicator from "../indicators/activity-indicator";
|
||||||
|
|
||||||
|
type ObjectSettingsProps = {
|
||||||
|
selectedCamera?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ObjectSettings({
|
||||||
|
selectedCamera,
|
||||||
|
}: ObjectSettingsProps) {
|
||||||
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
|
const cameraConfig = useMemo(() => {
|
||||||
|
if (config && selectedCamera) {
|
||||||
|
return config.cameras[selectedCamera];
|
||||||
|
}
|
||||||
|
}, [config, selectedCamera]);
|
||||||
|
|
||||||
|
if (!cameraConfig) {
|
||||||
|
return <ActivityIndicator />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-50">
|
||||||
|
<DebugCameraImage cameraConfig={cameraConfig} className="size-full" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import React, { useMemo, useRef, useState, useEffect } from "react";
|
import React, { useMemo, useRef, useState, useEffect } from "react";
|
||||||
import PolygonDrawer from "./PolygonDrawer";
|
import PolygonDrawer from "./PolygonDrawer";
|
||||||
import { Stage, Layer, Image, Text, Circle } from "react-konva";
|
import { Stage, Layer, Image } from "react-konva";
|
||||||
import Konva from "konva";
|
import Konva from "konva";
|
||||||
import type { KonvaEventObject } from "konva/lib/Node";
|
import type { KonvaEventObject } from "konva/lib/Node";
|
||||||
import { Polygon, PolygonType } from "@/types/canvas";
|
import { Polygon, PolygonType } from "@/types/canvas";
|
||||||
import { useApiHost } from "@/api";
|
import { useApiHost } from "@/api";
|
||||||
import { getAveragePoint, flattenPoints } from "@/utils/canvasUtil";
|
import { flattenPoints } from "@/utils/canvasUtil";
|
||||||
|
|
||||||
type PolygonCanvasProps = {
|
type PolygonCanvasProps = {
|
||||||
camera: string;
|
camera: string;
|
||||||
@ -203,7 +203,6 @@ export function PolygonCanvas({
|
|||||||
(polygon, index) =>
|
(polygon, index) =>
|
||||||
(selectedZoneMask === undefined ||
|
(selectedZoneMask === undefined ||
|
||||||
selectedZoneMask.includes(polygon.type)) && (
|
selectedZoneMask.includes(polygon.type)) && (
|
||||||
<React.Fragment key={index}>
|
|
||||||
<PolygonDrawer
|
<PolygonDrawer
|
||||||
key={index}
|
key={index}
|
||||||
points={polygon.points}
|
points={polygon.points}
|
||||||
@ -212,45 +211,11 @@ export function PolygonCanvas({
|
|||||||
isHovered={index === hoveredPolygonIndex}
|
isHovered={index === hoveredPolygonIndex}
|
||||||
isFinished={polygon.isFinished}
|
isFinished={polygon.isFinished}
|
||||||
color={polygon.color}
|
color={polygon.color}
|
||||||
name={polygon.name}
|
|
||||||
handlePointDragMove={handlePointDragMove}
|
handlePointDragMove={handlePointDragMove}
|
||||||
handleGroupDragEnd={handleGroupDragEnd}
|
handleGroupDragEnd={handleGroupDragEnd}
|
||||||
handleMouseOverStartPoint={handleMouseOverStartPoint}
|
handleMouseOverStartPoint={handleMouseOverStartPoint}
|
||||||
handleMouseOutStartPoint={handleMouseOutStartPoint}
|
handleMouseOutStartPoint={handleMouseOutStartPoint}
|
||||||
/>
|
/>
|
||||||
{index === hoveredPolygonIndex && (
|
|
||||||
<>
|
|
||||||
<Circle
|
|
||||||
x={
|
|
||||||
getAveragePoint(flattenPoints(polygon.points)).x //-
|
|
||||||
//(polygon.name.length * 16 * 0.6) / 2
|
|
||||||
}
|
|
||||||
y={
|
|
||||||
getAveragePoint(flattenPoints(polygon.points)).y //-
|
|
||||||
//16 / 2
|
|
||||||
}
|
|
||||||
radius={2}
|
|
||||||
fill="red"
|
|
||||||
/>
|
|
||||||
<Text
|
|
||||||
text={polygon.name}
|
|
||||||
// align="left"
|
|
||||||
// verticalAlign="top"
|
|
||||||
align="center"
|
|
||||||
verticalAlign="middle"
|
|
||||||
x={
|
|
||||||
getAveragePoint(flattenPoints(polygon.points)).x //-
|
|
||||||
//(polygon.name.length * 16 * 0.6) / 2
|
|
||||||
}
|
|
||||||
y={
|
|
||||||
getAveragePoint(flattenPoints(polygon.points)).y //-
|
|
||||||
//16 / 2
|
|
||||||
}
|
|
||||||
fontSize={16}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|||||||
@ -1,11 +1,6 @@
|
|||||||
import { useCallback, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
import { Line, Circle, Group, Text } from "react-konva";
|
import { Line, Circle, Group } from "react-konva";
|
||||||
import {
|
import { minMax, toRGBColorString, dragBoundFunc } from "@/utils/canvasUtil";
|
||||||
minMax,
|
|
||||||
toRGBColorString,
|
|
||||||
dragBoundFunc,
|
|
||||||
getAveragePoint,
|
|
||||||
} from "@/utils/canvasUtil";
|
|
||||||
import type { KonvaEventObject } from "konva/lib/Node";
|
import type { KonvaEventObject } from "konva/lib/Node";
|
||||||
import Konva from "konva";
|
import Konva from "konva";
|
||||||
import { Vector2d } from "konva/lib/types";
|
import { Vector2d } from "konva/lib/types";
|
||||||
@ -17,7 +12,6 @@ type PolygonDrawerProps = {
|
|||||||
isHovered: boolean;
|
isHovered: boolean;
|
||||||
isFinished: boolean;
|
isFinished: boolean;
|
||||||
color: number[];
|
color: number[];
|
||||||
name: string;
|
|
||||||
handlePointDragMove: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
|
handlePointDragMove: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
|
||||||
handleGroupDragEnd: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
|
handleGroupDragEnd: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
|
||||||
handleMouseOverStartPoint: (
|
handleMouseOverStartPoint: (
|
||||||
@ -34,7 +28,6 @@ export default function PolygonDrawer({
|
|||||||
isActive,
|
isActive,
|
||||||
isHovered,
|
isHovered,
|
||||||
isFinished,
|
isFinished,
|
||||||
name,
|
|
||||||
color,
|
color,
|
||||||
handlePointDragMove,
|
handlePointDragMove,
|
||||||
handleGroupDragEnd,
|
handleGroupDragEnd,
|
||||||
@ -93,8 +86,6 @@ export default function PolygonDrawer({
|
|||||||
[color],
|
[color],
|
||||||
);
|
);
|
||||||
|
|
||||||
// console.log(groupRef.current?.height());
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
name="polygon"
|
name="polygon"
|
||||||
@ -157,26 +148,6 @@ export default function PolygonDrawer({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{groupRef.current && (
|
|
||||||
<Text
|
|
||||||
text={name}
|
|
||||||
// align="left"
|
|
||||||
// verticalAlign="top"
|
|
||||||
width={groupRef.current.width()}
|
|
||||||
height={groupRef.current.height()}
|
|
||||||
align="center"
|
|
||||||
verticalAlign="middle"
|
|
||||||
x={
|
|
||||||
getAveragePoint(flattenedPoints).x //-
|
|
||||||
//(polygon.name.length * 16 * 0.6) / 2
|
|
||||||
}
|
|
||||||
y={
|
|
||||||
getAveragePoint(flattenedPoints).y //-
|
|
||||||
//16 / 2
|
|
||||||
}
|
|
||||||
fontSize={16}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,7 @@ import { reviewQueries } from "@/utils/zoneEdutUtil";
|
|||||||
|
|
||||||
type PolygonItemProps = {
|
type PolygonItemProps = {
|
||||||
polygon: Polygon;
|
polygon: Polygon;
|
||||||
setAllPolygons: React.Dispatch<React.SetStateAction<Polygon[]>>;
|
|
||||||
index: number;
|
index: number;
|
||||||
activePolygonIndex: number | undefined;
|
|
||||||
hoveredPolygonIndex: number | null;
|
hoveredPolygonIndex: number | null;
|
||||||
setHoveredPolygonIndex: (index: number | null) => void;
|
setHoveredPolygonIndex: (index: number | null) => void;
|
||||||
setActivePolygonIndex: (index: number | undefined) => void;
|
setActivePolygonIndex: (index: number | undefined) => void;
|
||||||
@ -48,9 +46,7 @@ type PolygonItemProps = {
|
|||||||
|
|
||||||
export default function PolygonItem({
|
export default function PolygonItem({
|
||||||
polygon,
|
polygon,
|
||||||
setAllPolygons,
|
|
||||||
index,
|
index,
|
||||||
activePolygonIndex,
|
|
||||||
hoveredPolygonIndex,
|
hoveredPolygonIndex,
|
||||||
setHoveredPolygonIndex,
|
setHoveredPolygonIndex,
|
||||||
setActivePolygonIndex,
|
setActivePolygonIndex,
|
||||||
@ -60,6 +56,7 @@ export default function PolygonItem({
|
|||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
useSWR<FrigateConfig>("config");
|
useSWR<FrigateConfig>("config");
|
||||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const cameraConfig = useMemo(() => {
|
const cameraConfig = useMemo(() => {
|
||||||
if (polygon?.camera && config) {
|
if (polygon?.camera && config) {
|
||||||
@ -93,14 +90,11 @@ export default function PolygonItem({
|
|||||||
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}`;
|
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}`;
|
||||||
}
|
}
|
||||||
if (polygon.type == "motion_mask") {
|
if (polygon.type == "motion_mask") {
|
||||||
console.log("deleting", polygon.typeIndex);
|
|
||||||
|
|
||||||
const filteredMask = (
|
const filteredMask = (
|
||||||
Array.isArray(cameraConfig.motion.mask)
|
Array.isArray(cameraConfig.motion.mask)
|
||||||
? cameraConfig.motion.mask
|
? cameraConfig.motion.mask
|
||||||
: [cameraConfig.motion.mask]
|
: [cameraConfig.motion.mask]
|
||||||
).filter((_, currentIndex) => currentIndex !== polygon.typeIndex);
|
).filter((_, currentIndex) => currentIndex !== polygon.typeIndex);
|
||||||
console.log(filteredMask);
|
|
||||||
|
|
||||||
url = filteredMask
|
url = filteredMask
|
||||||
.map((pointsArray) => {
|
.map((pointsArray) => {
|
||||||
@ -115,21 +109,14 @@ export default function PolygonItem({
|
|||||||
// deleting last mask
|
// deleting last mask
|
||||||
url = `cameras.${polygon?.camera}.motion.mask&`;
|
url = `cameras.${polygon?.camera}.motion.mask&`;
|
||||||
}
|
}
|
||||||
console.log(url);
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// url = `config/set?cameras.${polygon.camera}.motion.mask`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (polygon.type == "object_mask") {
|
if (polygon.type == "object_mask") {
|
||||||
console.log("deleting", polygon.typeIndex, polygon);
|
|
||||||
let configObject;
|
let configObject;
|
||||||
let globalMask = false;
|
let globalMask = false;
|
||||||
console.log("polygon objects", polygon.objects, !polygon.objects);
|
|
||||||
|
|
||||||
// global mask on camera for all objects
|
// global mask on camera for all objects
|
||||||
if (!polygon.objects.length) {
|
if (!polygon.objects.length) {
|
||||||
console.log("deleting global");
|
|
||||||
configObject = cameraConfig.objects.mask;
|
configObject = cameraConfig.objects.mask;
|
||||||
globalMask = true;
|
globalMask = true;
|
||||||
} else {
|
} else {
|
||||||
@ -152,28 +139,13 @@ export default function PolygonItem({
|
|||||||
Array.isArray(configObject) ? configObject : [configObject]
|
Array.isArray(configObject) ? configObject : [configObject]
|
||||||
).filter((_, currentIndex) => currentIndex !== polygon.typeIndex);
|
).filter((_, currentIndex) => currentIndex !== polygon.typeIndex);
|
||||||
} else {
|
} else {
|
||||||
console.log("not globals config object:", configObject);
|
|
||||||
|
|
||||||
filteredMask = (
|
filteredMask = (
|
||||||
Array.isArray(configObject) ? configObject : [configObject]
|
Array.isArray(configObject) ? configObject : [configObject]
|
||||||
)
|
)
|
||||||
.filter((mask) => !globalObjectMasksArray.includes(mask))
|
.filter((mask) => !globalObjectMasksArray.includes(mask))
|
||||||
.filter((_, currentIndex) => {
|
.filter((_, currentIndex) => currentIndex !== polygon.typeIndex);
|
||||||
console.log(
|
|
||||||
"current index",
|
|
||||||
currentIndex,
|
|
||||||
"global length:",
|
|
||||||
globalObjectMasksArray.length,
|
|
||||||
"polygon typeindex",
|
|
||||||
polygon.typeIndex,
|
|
||||||
);
|
|
||||||
|
|
||||||
return currentIndex !== polygon.typeIndex;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("filtered:", filteredMask);
|
|
||||||
|
|
||||||
url = filteredMask
|
url = filteredMask
|
||||||
.map((pointsArray) => {
|
.map((pointsArray) => {
|
||||||
const coordinates = flattenPoints(
|
const coordinates = flattenPoints(
|
||||||
@ -191,13 +163,10 @@ export default function PolygonItem({
|
|||||||
? `cameras.${polygon?.camera}.objects.mask&`
|
? `cameras.${polygon?.camera}.objects.mask&`
|
||||||
: `cameras.${polygon?.camera}.objects.filters.${polygon.objects[0]}.mask`;
|
: `cameras.${polygon?.camera}.objects.filters.${polygon.objects[0]}.mask`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("url:", url);
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// url = `config/set?cameras.${polygon.camera}.motion.mask`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
await axios
|
await axios
|
||||||
.put(`config/set?${url}`, { requires_restart: 0 })
|
.put(`config/set?${url}`, { requires_restart: 0 })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@ -205,7 +174,6 @@ export default function PolygonItem({
|
|||||||
toast.success(`${polygon?.name} has been deleted.`, {
|
toast.success(`${polygon?.name} has been deleted.`, {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
});
|
});
|
||||||
// setChangedValue(false);
|
|
||||||
updateConfig();
|
updateConfig();
|
||||||
} else {
|
} else {
|
||||||
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
||||||
@ -220,40 +188,13 @@ export default function PolygonItem({
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
// setIsLoading(false);
|
setIsLoading(false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[updateConfig, cameraConfig],
|
[updateConfig, cameraConfig],
|
||||||
);
|
);
|
||||||
|
|
||||||
const reindexPolygons = (arr: Polygon[]): Polygon[] => {
|
const handleDelete = () => {
|
||||||
const typeCounters: { [type: string]: number } = {};
|
|
||||||
|
|
||||||
return arr.map((obj) => {
|
|
||||||
if (!typeCounters[obj.type]) {
|
|
||||||
typeCounters[obj.type] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newObj: Polygon = {
|
|
||||||
...obj,
|
|
||||||
typeIndex: typeCounters[obj.type],
|
|
||||||
};
|
|
||||||
typeCounters[obj.type]++;
|
|
||||||
return newObj;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (type: string, typeIndex: number) => {
|
|
||||||
// setAllPolygons((oldPolygons) => {
|
|
||||||
// console.log("old polygons", oldPolygons);
|
|
||||||
// const filteredPolygons = oldPolygons.filter(
|
|
||||||
// (polygon) =>
|
|
||||||
// !(polygon.type === type && polygon.typeIndex === typeIndex),
|
|
||||||
// );
|
|
||||||
// console.log("filtered", filteredPolygons);
|
|
||||||
// // console.log("reindexed", reindexPolygons(filteredPolygons));
|
|
||||||
// return filteredPolygons;
|
|
||||||
// });
|
|
||||||
setActivePolygonIndex(undefined);
|
setActivePolygonIndex(undefined);
|
||||||
saveToConfig(polygon);
|
saveToConfig(polygon);
|
||||||
};
|
};
|
||||||
@ -307,9 +248,7 @@ export default function PolygonItem({
|
|||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction onClick={handleDelete}>
|
||||||
onClick={() => handleDelete(polygon.type, polygon.typeIndex)}
|
|
||||||
>
|
|
||||||
Delete
|
Delete
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
@ -334,7 +273,10 @@ export default function PolygonItem({
|
|||||||
<DropdownMenuItem onClick={() => handleCopyCoordinates(index)}>
|
<DropdownMenuItem onClick={() => handleCopyCoordinates(index)}>
|
||||||
Copy
|
Copy
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={() => setDeleteDialogOpen(true)}>
|
<DropdownMenuItem
|
||||||
|
disabled={isLoading}
|
||||||
|
onClick={() => setDeleteDialogOpen(true)}
|
||||||
|
>
|
||||||
Delete
|
Delete
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
@ -378,7 +320,7 @@ export default function PolygonItem({
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer size-[15px]"
|
className="cursor-pointer size-[15px]"
|
||||||
onClick={() => setDeleteDialogOpen(true)}
|
onClick={() => !isLoading && setDeleteDialogOpen(true)}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
|
|||||||
@ -156,33 +156,6 @@ export default function ZoneEditPane({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// const [changedValue, setChangedValue] = useState(false);
|
|
||||||
|
|
||||||
// const requiredDetectionZones = useMemo(
|
|
||||||
// () => cameraConfig?.review.detections.required_zones,
|
|
||||||
// [cameraConfig],
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const requiredAlertZones = useMemo(
|
|
||||||
// () => cameraConfig?.review.alerts.required_zones,
|
|
||||||
// [cameraConfig],
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const [alertQueries, setAlertQueries] = useState("");
|
|
||||||
// const [detectionQueries, setDetectionQueries] = useState("");
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log("config updated!", config);
|
|
||||||
// }, [config]);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log("camera config updated!", cameraConfig);
|
|
||||||
// }, [cameraConfig]);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log("required zones updated!", requiredZones);
|
|
||||||
// }, [requiredZones]);
|
|
||||||
|
|
||||||
const saveToConfig = useCallback(
|
const saveToConfig = useCallback(
|
||||||
async (
|
async (
|
||||||
{
|
{
|
||||||
@ -198,11 +171,6 @@ export default function ZoneEditPane({
|
|||||||
if (!scaledWidth || !scaledHeight || !polygon) {
|
if (!scaledWidth || !scaledHeight || !polygon) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// console.log("loitering time", loitering_time);
|
|
||||||
// const alertsZones = config?.cameras[camera]?.review.alerts.required_zones;
|
|
||||||
|
|
||||||
// const detectionsZones =
|
|
||||||
// config?.cameras[camera]?.review.detections.required_zones;
|
|
||||||
let mutatedConfig = config;
|
let mutatedConfig = config;
|
||||||
|
|
||||||
const renamingZone = zoneName != polygon.name && polygon.name != "";
|
const renamingZone = zoneName != polygon.name && polygon.name != "";
|
||||||
@ -231,8 +199,6 @@ export default function ZoneEditPane({
|
|||||||
|
|
||||||
// Wait for the config to be updated
|
// Wait for the config to be updated
|
||||||
mutatedConfig = await updateConfig();
|
mutatedConfig = await updateConfig();
|
||||||
// console.log("this should be updated...", mutatedConfig.cameras);
|
|
||||||
// console.log("check original config object...", config);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(`Failed to save config changes.`, {
|
toast.error(`Failed to save config changes.`, {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
@ -241,12 +207,9 @@ export default function ZoneEditPane({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("out of try except", mutatedConfig);
|
|
||||||
|
|
||||||
const coordinates = flattenPoints(
|
const coordinates = flattenPoints(
|
||||||
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
||||||
).join(",");
|
).join(",");
|
||||||
// const foo = config.cameras["doorbell"].zones["outside"].objects;
|
|
||||||
|
|
||||||
let objectQueries = objects
|
let objectQueries = objects
|
||||||
.map(
|
.map(
|
||||||
@ -263,7 +226,6 @@ export default function ZoneEditPane({
|
|||||||
|
|
||||||
// deleting objects
|
// deleting objects
|
||||||
if (!objectQueries && !same_objects && !renamingZone) {
|
if (!objectQueries && !same_objects && !renamingZone) {
|
||||||
// console.log("deleting objects");
|
|
||||||
objectQueries = `&cameras.${polygon?.camera}.zones.${zoneName}.objects`;
|
objectQueries = `&cameras.${polygon?.camera}.zones.${zoneName}.objects`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,14 +240,6 @@ export default function ZoneEditPane({
|
|||||||
.required_zones || [],
|
.required_zones || [],
|
||||||
);
|
);
|
||||||
|
|
||||||
// console.log("object queries:", objectQueries);
|
|
||||||
// console.log("alert queries:", alertQueries);
|
|
||||||
// console.log("detection queries:", detectionQueries);
|
|
||||||
|
|
||||||
// console.log(
|
|
||||||
// `config/set?cameras.${polygon?.camera}.zones.${name}.coordinates=${coordinates}&cameras.${polygon?.camera}.zones.${name}.inertia=${inertia}&cameras.${polygon?.camera}.zones.${name}.loitering_time=${loitering_time}${objectQueries}${alertQueries}${detectionQueries}`,
|
|
||||||
// );
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.put(
|
.put(
|
||||||
`config/set?cameras.${polygon?.camera}.zones.${zoneName}.coordinates=${coordinates}&cameras.${polygon?.camera}.zones.${zoneName}.inertia=${inertia}&cameras.${polygon?.camera}.zones.${zoneName}.loitering_time=${loitering_time}${objectQueries}${alertQueries}${detectionQueries}`,
|
`config/set?cameras.${polygon?.camera}.zones.${zoneName}.coordinates=${coordinates}&cameras.${polygon?.camera}.zones.${zoneName}.inertia=${inertia}&cameras.${polygon?.camera}.zones.${zoneName}.loitering_time=${loitering_time}${objectQueries}${alertQueries}${detectionQueries}`,
|
||||||
@ -296,7 +250,6 @@ export default function ZoneEditPane({
|
|||||||
toast.success(`Zone (${zoneName}) has been saved.`, {
|
toast.success(`Zone (${zoneName}) has been saved.`, {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
});
|
});
|
||||||
// setChangedValue(false);
|
|
||||||
updateConfig();
|
updateConfig();
|
||||||
} else {
|
} else {
|
||||||
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
toast.error(`Failed to save config changes: ${res.statusText}`, {
|
||||||
@ -330,16 +283,6 @@ export default function ZoneEditPane({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
// polygons[activePolygonIndex].name = values.name;
|
|
||||||
// console.log("form values", values);
|
|
||||||
// console.log(
|
|
||||||
// "string",
|
|
||||||
|
|
||||||
// flattenPoints(
|
|
||||||
// interpolatePoints(polygon.points, scaledWidth, scaledHeight, 1, 1),
|
|
||||||
// ).join(","),
|
|
||||||
// );
|
|
||||||
// console.log("active polygon", polygons[activePolygonIndex]);
|
|
||||||
|
|
||||||
saveToConfig(
|
saveToConfig(
|
||||||
values as ZoneFormValuesType,
|
values as ZoneFormValuesType,
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
// import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
||||||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
||||||
import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer";
|
import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer";
|
||||||
import MotionTuner from "@/components/settings/MotionTuner";
|
import MotionTuner from "@/components/settings/MotionTuner";
|
||||||
@ -13,7 +12,6 @@ import MasksAndZones from "@/components/settings/MasksAndZones";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import useOptimisticState from "@/hooks/use-optimistic-state";
|
import useOptimisticState from "@/hooks/use-optimistic-state";
|
||||||
import Logo from "@/components/Logo";
|
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import { FaVideo } from "react-icons/fa";
|
import { FaVideo } from "react-icons/fa";
|
||||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||||
@ -22,6 +20,7 @@ import General from "@/components/settings/General";
|
|||||||
import FilterSwitch from "@/components/filter/FilterSwitch";
|
import FilterSwitch from "@/components/filter/FilterSwitch";
|
||||||
import { ZoneMaskFilterButton } from "@/components/filter/ZoneMaskFilter";
|
import { ZoneMaskFilterButton } from "@/components/filter/ZoneMaskFilter";
|
||||||
import { PolygonType } from "@/types/canvas";
|
import { PolygonType } from "@/types/canvas";
|
||||||
|
import ObjectSettings from "@/components/settings/ObjectSettings";
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const settingsViews = [
|
const settingsViews = [
|
||||||
@ -37,7 +36,7 @@ export default function Settings() {
|
|||||||
|
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
// TODO: confirm leave page
|
||||||
const [unsavedChanges, setUnsavedChanges] = useState(false);
|
const [unsavedChanges, setUnsavedChanges] = useState(false);
|
||||||
|
|
||||||
const cameras = useMemo(() => {
|
const cameras = useMemo(() => {
|
||||||
@ -50,7 +49,7 @@ export default function Settings() {
|
|||||||
.sort((aConf, bConf) => aConf.ui.order - bConf.ui.order);
|
.sort((aConf, bConf) => aConf.ui.order - bConf.ui.order);
|
||||||
}, [config]);
|
}, [config]);
|
||||||
|
|
||||||
const [selectedCamera, setSelectedCamera] = useState<string>();
|
const [selectedCamera, setSelectedCamera] = useState<string>("");
|
||||||
|
|
||||||
const [filterZoneMask, setFilterZoneMask] = useState<PolygonType[]>();
|
const [filterZoneMask, setFilterZoneMask] = useState<PolygonType[]>();
|
||||||
|
|
||||||
@ -58,6 +57,8 @@ export default function Settings() {
|
|||||||
if (cameras.length) {
|
if (cameras.length) {
|
||||||
setSelectedCamera(cameras[0].name);
|
setSelectedCamera(cameras[0].name);
|
||||||
}
|
}
|
||||||
|
// only run once
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -77,7 +78,7 @@ export default function Settings() {
|
|||||||
{Object.values(settingsViews).map((item) => (
|
{Object.values(settingsViews).map((item) => (
|
||||||
<ToggleGroupItem
|
<ToggleGroupItem
|
||||||
key={item}
|
key={item}
|
||||||
className={`flex items-center justify-between gap-2 ${pageToggle == item ? "" : "*:text-gray-500"}`}
|
className={`flex items-center justify-between gap-2 ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
|
||||||
value={item}
|
value={item}
|
||||||
aria-label={`Select ${item}`}
|
aria-label={`Select ${item}`}
|
||||||
>
|
>
|
||||||
@ -105,19 +106,21 @@ export default function Settings() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-col items-start w-full h-full md:h-dvh md:pb-24">
|
<div className="mt-2 flex flex-col items-start w-full h-full md:h-dvh md:pb-24">
|
||||||
{page == "general" && <General />}
|
{page == "general" && <General />}
|
||||||
{page == "objects" && <></>}
|
{page == "objects" && (
|
||||||
|
<ObjectSettings selectedCamera={selectedCamera} />
|
||||||
|
)}
|
||||||
{page == "masks / zones" && (
|
{page == "masks / zones" && (
|
||||||
<MasksAndZones
|
<MasksAndZones
|
||||||
selectedCamera={selectedCamera}
|
selectedCamera={selectedCamera}
|
||||||
selectedZoneMask={filterZoneMask}
|
selectedZoneMask={filterZoneMask}
|
||||||
isEditing={isEditing}
|
|
||||||
setIsEditing={setIsEditing}
|
|
||||||
unsavedChanges={unsavedChanges}
|
|
||||||
setUnsavedChanges={setUnsavedChanges}
|
setUnsavedChanges={setUnsavedChanges}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{page == "motion tuner" && (
|
{page == "motion tuner" && (
|
||||||
<MotionTuner selectedCamera={selectedCamera} />
|
<MotionTuner
|
||||||
|
selectedCamera={selectedCamera}
|
||||||
|
setUnsavedChanges={setUnsavedChanges}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,24 +10,9 @@ export const reviewQueries = (
|
|||||||
let detectionQueries = "";
|
let detectionQueries = "";
|
||||||
let same_alerts = false;
|
let same_alerts = false;
|
||||||
let same_detections = false;
|
let same_detections = false;
|
||||||
// const foo = config;
|
|
||||||
|
|
||||||
// console.log("config in func", config.cameras);
|
|
||||||
// console.log("config as foo in func", foo.cameras);
|
|
||||||
// console.log("cameraconfig in func", cameraConfig);
|
|
||||||
// console.log("required zones in func", requiredZones);
|
|
||||||
// console.log("name", name);
|
|
||||||
// console.log("alerts", alertsZones);
|
|
||||||
// console.log("detections", detectionsZones);
|
|
||||||
// console.log(
|
|
||||||
// "orig detections",
|
|
||||||
// foo?.cameras[camera]?.review.detections.required_zones,
|
|
||||||
// );
|
|
||||||
|
|
||||||
const alerts = new Set<string>(alertsZones || []);
|
const alerts = new Set<string>(alertsZones || []);
|
||||||
// config?.cameras[camera].review.alerts.required_zones.forEach((zone) => {
|
|
||||||
// alerts.add(zone);
|
|
||||||
// });
|
|
||||||
if (review_alerts) {
|
if (review_alerts) {
|
||||||
alerts.add(name);
|
alerts.add(name);
|
||||||
} else {
|
} else {
|
||||||
@ -40,9 +25,6 @@ export const reviewQueries = (
|
|||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
const detections = new Set<string>(detectionsZones || []);
|
const detections = new Set<string>(detectionsZones || []);
|
||||||
// config?.cameras[camera].review.detections.required_zones.forEach((zone) => {
|
|
||||||
// detections.add(zone);
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (review_detections) {
|
if (review_detections) {
|
||||||
detections.add(name);
|
detections.add(name);
|
||||||
@ -57,36 +39,10 @@ export const reviewQueries = (
|
|||||||
)
|
)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
// console.log("dets set", detections);
|
|
||||||
|
|
||||||
// const updatedConfig = updateConfig({
|
|
||||||
// ...config,
|
|
||||||
// cameras: {
|
|
||||||
// ...config.cameras,
|
|
||||||
// [camera]: {
|
|
||||||
// ...config.cameras[camera],
|
|
||||||
// review: {
|
|
||||||
// ...config.cameras[camera].review,
|
|
||||||
// detection: {
|
|
||||||
// ...config.cameras[camera].review.detection,
|
|
||||||
// required_zones: [...detections],
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// console.log(updatedConfig);
|
|
||||||
|
|
||||||
// console.log("alert queries", alertQueries);
|
|
||||||
// console.log("detection queries", detectionQueries);
|
|
||||||
|
|
||||||
if (!alertQueries && !same_alerts) {
|
if (!alertQueries && !same_alerts) {
|
||||||
// console.log("deleting alerts");
|
|
||||||
alertQueries = `&cameras.${camera}.review.alerts`;
|
alertQueries = `&cameras.${camera}.review.alerts`;
|
||||||
}
|
}
|
||||||
if (!detectionQueries && !same_detections) {
|
if (!detectionQueries && !same_detections) {
|
||||||
// console.log("deleting detection");
|
|
||||||
detectionQueries = `&cameras.${camera}.review.detections`;
|
detectionQueries = `&cameras.${camera}.review.detections`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user