mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-18 18:01:14 +03:00
mask/zone bugfixes
- fix websocket crash when creating a new mask or zone before a name is assigned - fix deleted masks and zones not disappearing from the list until navigating away - fix deleting profile override not reverting to the base mask in the list - fix inertia defaulting to nan
This commit is contained in:
parent
a7f70e1334
commit
1365fbe16c
@ -74,9 +74,11 @@ export default function MotionMaskEditPane({
|
|||||||
}
|
}
|
||||||
}, [polygons, activePolygonIndex]);
|
}, [polygons, activePolygonIndex]);
|
||||||
|
|
||||||
|
const maskCamera = polygon?.camera || "";
|
||||||
|
const maskName = polygon?.name || "";
|
||||||
const { send: sendMotionMaskState } = useMotionMaskState(
|
const { send: sendMotionMaskState } = useMotionMaskState(
|
||||||
polygon?.camera || "",
|
maskCamera,
|
||||||
polygon?.name || "",
|
maskName,
|
||||||
);
|
);
|
||||||
|
|
||||||
const cameraConfig = useMemo(() => {
|
const cameraConfig = useMemo(() => {
|
||||||
@ -250,8 +252,8 @@ export default function MotionMaskEditPane({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
updateConfig();
|
updateConfig();
|
||||||
// Only publish WS state for base config
|
// Only publish WS state for base config when mask has a name
|
||||||
if (!editingProfile) {
|
if (!editingProfile && maskName) {
|
||||||
sendMotionMaskState(enabled ? "ON" : "OFF");
|
sendMotionMaskState(enabled ? "ON" : "OFF");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -291,6 +293,7 @@ export default function MotionMaskEditPane({
|
|||||||
cameraConfig,
|
cameraConfig,
|
||||||
t,
|
t,
|
||||||
sendMotionMaskState,
|
sendMotionMaskState,
|
||||||
|
maskName,
|
||||||
editingProfile,
|
editingProfile,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -80,9 +80,10 @@ export default function ObjectMaskEditPane({
|
|||||||
}
|
}
|
||||||
}, [polygons, activePolygonIndex]);
|
}, [polygons, activePolygonIndex]);
|
||||||
|
|
||||||
|
const maskName = polygon?.name || "";
|
||||||
const { send: sendObjectMaskState } = useObjectMaskState(
|
const { send: sendObjectMaskState } = useObjectMaskState(
|
||||||
polygon?.camera || "",
|
polygon?.camera || "",
|
||||||
polygon?.name || "",
|
maskName,
|
||||||
);
|
);
|
||||||
|
|
||||||
const cameraConfig = useMemo(() => {
|
const cameraConfig = useMemo(() => {
|
||||||
@ -256,8 +257,8 @@ export default function ObjectMaskEditPane({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
updateConfig();
|
updateConfig();
|
||||||
// Only publish WS state for base config
|
// Only publish WS state for base config when mask has a name
|
||||||
if (!editingProfile) {
|
if (!editingProfile && maskName) {
|
||||||
sendObjectMaskState(enabled ? "ON" : "OFF");
|
sendObjectMaskState(enabled ? "ON" : "OFF");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -300,6 +301,7 @@ export default function ObjectMaskEditPane({
|
|||||||
cameraConfig,
|
cameraConfig,
|
||||||
t,
|
t,
|
||||||
sendObjectMaskState,
|
sendObjectMaskState,
|
||||||
|
maskName,
|
||||||
editingProfile,
|
editingProfile,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -51,6 +51,7 @@ type PolygonItemProps = {
|
|||||||
setLoadingPolygonIndex: (index: number | undefined) => void;
|
setLoadingPolygonIndex: (index: number | undefined) => void;
|
||||||
editingProfile?: string | null;
|
editingProfile?: string | null;
|
||||||
allProfileNames?: string[];
|
allProfileNames?: string[];
|
||||||
|
onDeleted?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function PolygonItem({
|
export default function PolygonItem({
|
||||||
@ -67,6 +68,7 @@ export default function PolygonItem({
|
|||||||
setLoadingPolygonIndex,
|
setLoadingPolygonIndex,
|
||||||
editingProfile,
|
editingProfile,
|
||||||
allProfileNames,
|
allProfileNames,
|
||||||
|
onDeleted,
|
||||||
}: PolygonItemProps) {
|
}: PolygonItemProps) {
|
||||||
const { t } = useTranslation("views/settings");
|
const { t } = useTranslation("views/settings");
|
||||||
const { data: config, mutate: updateConfig } =
|
const { data: config, mutate: updateConfig } =
|
||||||
@ -169,6 +171,7 @@ export default function PolygonItem({
|
|||||||
{ position: "top-center" },
|
{ position: "top-center" },
|
||||||
);
|
);
|
||||||
updateConfig();
|
updateConfig();
|
||||||
|
onDeleted?.();
|
||||||
} else {
|
} else {
|
||||||
toast.error(
|
toast.error(
|
||||||
t("toast.save.error.title", {
|
t("toast.save.error.title", {
|
||||||
@ -234,6 +237,7 @@ export default function PolygonItem({
|
|||||||
{ position: "top-center" },
|
{ position: "top-center" },
|
||||||
);
|
);
|
||||||
updateConfig();
|
updateConfig();
|
||||||
|
onDeleted?.();
|
||||||
} else {
|
} else {
|
||||||
toast.error(
|
toast.error(
|
||||||
t("toast.save.error.title", {
|
t("toast.save.error.title", {
|
||||||
@ -267,6 +271,7 @@ export default function PolygonItem({
|
|||||||
index,
|
index,
|
||||||
setLoadingPolygonIndex,
|
setLoadingPolygonIndex,
|
||||||
editingProfile,
|
editingProfile,
|
||||||
|
onDeleted,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -91,10 +91,8 @@ export default function ZoneEditPane({
|
|||||||
}
|
}
|
||||||
}, [polygons, activePolygonIndex]);
|
}, [polygons, activePolygonIndex]);
|
||||||
|
|
||||||
const { send: sendZoneState } = useZoneState(
|
const zoneName = polygon?.name || "";
|
||||||
polygon?.camera || "",
|
const { send: sendZoneState } = useZoneState(polygon?.camera || "", zoneName);
|
||||||
polygon?.name || "",
|
|
||||||
);
|
|
||||||
|
|
||||||
const cameraConfig = useMemo(() => {
|
const cameraConfig = useMemo(() => {
|
||||||
if (polygon?.camera && config) {
|
if (polygon?.camera && config) {
|
||||||
@ -303,8 +301,8 @@ export default function ZoneEditPane({
|
|||||||
resolvedZoneData?.enabled !== undefined
|
resolvedZoneData?.enabled !== undefined
|
||||||
? resolvedZoneData.enabled
|
? resolvedZoneData.enabled
|
||||||
: (polygon?.enabled ?? true),
|
: (polygon?.enabled ?? true),
|
||||||
inertia: resolvedZoneData?.inertia,
|
inertia: resolvedZoneData?.inertia ?? 3,
|
||||||
loitering_time: resolvedZoneData?.loitering_time,
|
loitering_time: resolvedZoneData?.loitering_time ?? 0,
|
||||||
isFinished: polygon?.isFinished ?? false,
|
isFinished: polygon?.isFinished ?? false,
|
||||||
objects: polygon?.objects ?? [],
|
objects: polygon?.objects ?? [],
|
||||||
speedEstimation: !!(lineA || lineB || lineC || lineD),
|
speedEstimation: !!(lineA || lineB || lineC || lineD),
|
||||||
@ -516,8 +514,8 @@ export default function ZoneEditPane({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
updateConfig();
|
updateConfig();
|
||||||
// Only publish WS state for base config (not profiles)
|
// Only publish WS state for base config when zone has a name
|
||||||
if (!editingProfile) {
|
if (!editingProfile && zoneName) {
|
||||||
sendZoneState(enabled ? "ON" : "OFF");
|
sendZoneState(enabled ? "ON" : "OFF");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -201,6 +201,16 @@ export default function MasksAndZonesView({
|
|||||||
setUnsavedChanges(false);
|
setUnsavedChanges(false);
|
||||||
}, [editingPolygons, setUnsavedChanges]);
|
}, [editingPolygons, setUnsavedChanges]);
|
||||||
|
|
||||||
|
const handlePolygonDeleted = useCallback(() => {
|
||||||
|
// Temporarily clear the edit pane guard so the useEffect that
|
||||||
|
// rebuilds editingPolygons from config will run when the fresh
|
||||||
|
// config arrives via updateConfig(). This handles all cases:
|
||||||
|
// base deletes, profile override deletes (which revert to base),
|
||||||
|
// and profile-only deletes.
|
||||||
|
setEditPane(undefined);
|
||||||
|
setActivePolygonIndex(undefined);
|
||||||
|
}, [setEditPane, setActivePolygonIndex]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return;
|
return;
|
||||||
@ -843,6 +853,7 @@ export default function MasksAndZonesView({
|
|||||||
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
||||||
editingProfile={currentEditingProfile}
|
editingProfile={currentEditingProfile}
|
||||||
allProfileNames={profileState?.allProfileNames}
|
allProfileNames={profileState?.allProfileNames}
|
||||||
|
onDeleted={handlePolygonDeleted}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -919,6 +930,7 @@ export default function MasksAndZonesView({
|
|||||||
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
||||||
editingProfile={currentEditingProfile}
|
editingProfile={currentEditingProfile}
|
||||||
allProfileNames={profileState?.allProfileNames}
|
allProfileNames={profileState?.allProfileNames}
|
||||||
|
onDeleted={handlePolygonDeleted}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -995,6 +1007,7 @@ export default function MasksAndZonesView({
|
|||||||
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
setLoadingPolygonIndex={setLoadingPolygonIndex}
|
||||||
editingProfile={currentEditingProfile}
|
editingProfile={currentEditingProfile}
|
||||||
allProfileNames={profileState?.allProfileNames}
|
allProfileNames={profileState?.allProfileNames}
|
||||||
|
onDeleted={handlePolygonDeleted}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user