From 4f358c376fa4051f545de43929eb77e87a581052 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 15 Jan 2026 15:08:01 -0600 Subject: [PATCH] tweaks --- web/public/locales/en/views/settings.json | 3 +- .../settings/MotionMaskEditPane.tsx | 4 +-- .../settings/ObjectMaskEditPane.tsx | 15 ++------- web/src/components/settings/PolygonCanvas.tsx | 2 ++ web/src/components/settings/PolygonDrawer.tsx | 31 +++++++++++++++++++ web/src/components/settings/PolygonItem.tsx | 4 +-- web/src/components/settings/ZoneEditPane.tsx | 2 +- web/src/views/settings/MasksAndZonesView.tsx | 9 +++--- 8 files changed, 47 insertions(+), 23 deletions(-) diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 468684052..bd0d8b77c 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -514,7 +514,7 @@ } }, "motionMaskLabel": "Motion Mask {{number}}", - "objectMaskLabel": "Object Mask {{number}} ({{label}})", + "objectMaskLabel": "Object Mask {{number}}", "form": { "zoneName": { "error": { @@ -636,6 +636,7 @@ }, "add": "New Motion Mask", "edit": "Edit Motion Mask", + "defaultName": "Motion Mask {{number}}", "context": { "title": "Motion masks are used to prevent unwanted types of motion from triggering detection (example: tree branches, camera timestamps). Motion masks should be used very sparingly, over-masking will make it more difficult for objects to be tracked." }, diff --git a/web/src/components/settings/MotionMaskEditPane.tsx b/web/src/components/settings/MotionMaskEditPane.tsx index bc5fb61af..a06f8e475 100644 --- a/web/src/components/settings/MotionMaskEditPane.tsx +++ b/web/src/components/settings/MotionMaskEditPane.tsx @@ -85,7 +85,7 @@ export default function MotionMaskEditPane({ const count = polygons.filter((poly) => poly.type == "motion_mask").length; return t("masksAndZones.motionMasks.defaultName", { - number: count + 1, + number: count, }); }, [polygons, t]); @@ -96,7 +96,7 @@ export default function MotionMaskEditPane({ const count = polygons.filter((poly) => poly.type == "motion_mask").length; - return `motion_mask_${count + 1}`; + return `motion_mask_${count}`; }, [polygons]); const polygonArea = useMemo(() => { diff --git a/web/src/components/settings/ObjectMaskEditPane.tsx b/web/src/components/settings/ObjectMaskEditPane.tsx index ff9336d9f..0aaf6ef0a 100644 --- a/web/src/components/settings/ObjectMaskEditPane.tsx +++ b/web/src/components/settings/ObjectMaskEditPane.tsx @@ -90,19 +90,10 @@ export default function ObjectMaskEditPane({ const count = polygons.filter((poly) => poly.type == "object_mask").length; - let objectType = ""; - const objects = polygon?.objects[0]; - if (objects === undefined) { - objectType = t("masksAndZones.zones.allObjects"); - } else { - objectType = getTranslatedLabel(objects); - } - return t("masksAndZones.objectMaskLabel", { - number: count + 1, - label: objectType, + number: count, }); - }, [polygons, polygon, t]); + }, [polygons, t]); const defaultId = useMemo(() => { if (!polygons) { @@ -111,7 +102,7 @@ export default function ObjectMaskEditPane({ const count = polygons.filter((poly) => poly.type == "object_mask").length; - return `object_mask_${count + 1}`; + return `object_mask_${count}`; }, [polygons]); const formSchema = z.object({ diff --git a/web/src/components/settings/PolygonCanvas.tsx b/web/src/components/settings/PolygonCanvas.tsx index 307393eae..cee0952c1 100644 --- a/web/src/components/settings/PolygonCanvas.tsx +++ b/web/src/components/settings/PolygonCanvas.tsx @@ -321,6 +321,7 @@ export function PolygonCanvas({ isActive={index === activePolygonIndex} isHovered={index === hoveredPolygonIndex} isFinished={polygon.isFinished} + enabled={polygon.enabled} color={polygon.color} handlePointDragMove={handlePointDragMove} handleGroupDragEnd={handleGroupDragEnd} @@ -350,6 +351,7 @@ export function PolygonCanvas({ isActive={true} isHovered={activePolygonIndex === hoveredPolygonIndex} isFinished={polygons[activePolygonIndex].isFinished} + enabled={polygons[activePolygonIndex].enabled} color={polygons[activePolygonIndex].color} handlePointDragMove={handlePointDragMove} handleGroupDragEnd={handleGroupDragEnd} diff --git a/web/src/components/settings/PolygonDrawer.tsx b/web/src/components/settings/PolygonDrawer.tsx index 9cc5649a6..dc15b9cc4 100644 --- a/web/src/components/settings/PolygonDrawer.tsx +++ b/web/src/components/settings/PolygonDrawer.tsx @@ -24,6 +24,7 @@ type PolygonDrawerProps = { isActive: boolean; isHovered: boolean; isFinished: boolean; + enabled?: boolean; color: number[]; handlePointDragMove: (e: KonvaEventObject) => void; handleGroupDragEnd: (e: KonvaEventObject) => void; @@ -39,6 +40,7 @@ export default function PolygonDrawer({ isActive, isHovered, isFinished, + enabled = true, color, handlePointDragMove, handleGroupDragEnd, @@ -53,6 +55,26 @@ export default function PolygonDrawer({ const groupRef = useRef(null); const [cursor, setCursor] = useState("default"); + const patternCanvas = useMemo(() => { + if (enabled) { + return undefined; + } + + const canvas = document.createElement("canvas"); + canvas.width = 10; + canvas.height = 10; + const ctx = canvas.getContext("2d"); + if (ctx) { + ctx.strokeStyle = "rgba(0, 0, 0, 0.3)"; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(10, 0); + ctx.lineTo(0, 10); + ctx.stroke(); + } + return canvas as unknown as HTMLImageElement; + }, [enabled]); + const handleMouseOverPoint = ( e: KonvaEventObject, ) => { @@ -180,6 +202,15 @@ export default function PolygonDrawer({ : setCursor("default") } /> + {!enabled && isFinished && ( + + )} {isFinished && isActive && ( setHoveredPolygonIndex(index)} onMouseLeave={() => setHoveredPolygonIndex(null)} diff --git a/web/src/components/settings/ZoneEditPane.tsx b/web/src/components/settings/ZoneEditPane.tsx index a4797b645..4b694b10a 100644 --- a/web/src/components/settings/ZoneEditPane.tsx +++ b/web/src/components/settings/ZoneEditPane.tsx @@ -454,7 +454,7 @@ export default function ZoneEditPane({ friendlyNameQuery = `&cameras.${polygon?.camera}.zones.${zoneName}.friendly_name=${encodeURIComponent(friendly_name)}`; } - const enabledQuery = `&cameras.${polygon?.camera}.zones.${zoneName}.enabled=${enabled}`; + const enabledQuery = `&cameras.${polygon?.camera}.zones.${zoneName}.enabled=${enabled ? "True" : "False"}`; axios .put( diff --git a/web/src/views/settings/MasksAndZonesView.tsx b/web/src/views/settings/MasksAndZonesView.tsx index 54e329f44..052b706bb 100644 --- a/web/src/views/settings/MasksAndZonesView.tsx +++ b/web/src/views/settings/MasksAndZonesView.tsx @@ -169,6 +169,7 @@ export default function MasksAndZonesView({ objects: [], camera: selectedCamera, color: polygonColor, + enabled: true, }, ]); }; @@ -242,7 +243,7 @@ export default function MasksAndZonesView({ distances: zoneData.distances?.map((distance) => parseFloat(distance)) ?? [], isFinished: true, - color: zoneData.enabled ? zoneData.color : [100, 100, 100], + color: zoneData.color, }), ); @@ -269,7 +270,7 @@ export default function MasksAndZonesView({ ), distances: [], isFinished: true, - color: maskData.enabled ? [0, 0, 255] : [100, 100, 100], + color: [0, 0, 255], }), ); @@ -292,7 +293,7 @@ export default function MasksAndZonesView({ ), distances: [], isFinished: true, - color: maskData.enabled ? [128, 128, 128] : [80, 80, 80], + color: [128, 128, 128], }), ); @@ -329,7 +330,7 @@ export default function MasksAndZonesView({ ), distances: [], isFinished: true, - color: maskData.enabled ? [128, 128, 128] : [80, 80, 80], + color: [128, 128, 128], }; objectMaskIndex++; return [newMask];