mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-05 22:57:40 +03:00
Merge pull request #107 from ibs0d/claude/persist-camera-order-BkmUM
Persist camera order in Fit to Screen mode across reloads
This commit is contained in:
commit
00ca5bafc0
@ -138,6 +138,10 @@ export default function DraggableGridLayout({
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [fitCameraOrder, setFitCameraOrder] = useUserPersistence<string[]>(
|
||||||
|
`${cameraGroup}-fit-camera-order`,
|
||||||
|
);
|
||||||
|
|
||||||
const [group] = useUserPersistedOverlayState(
|
const [group] = useUserPersistedOverlayState(
|
||||||
"cameraGroup",
|
"cameraGroup",
|
||||||
"default" as string,
|
"default" as string,
|
||||||
@ -458,25 +462,34 @@ export default function DraggableGridLayout({
|
|||||||
const h = w;
|
const h = w;
|
||||||
const colsPerRow = fitGridParams.colsPerRow;
|
const colsPerRow = fitGridParams.colsPerRow;
|
||||||
|
|
||||||
return cameraNames.map((name, index) => ({
|
// Применить сохранённый порядок если он валиден
|
||||||
|
// (содержит ровно те же камеры, что и текущий набор)
|
||||||
|
let orderedNames = cameraNames;
|
||||||
|
if (fitCameraOrder) {
|
||||||
|
const savedSet = new Set(fitCameraOrder);
|
||||||
|
const currentSet = new Set(cameraNames);
|
||||||
|
if (
|
||||||
|
savedSet.size === currentSet.size &&
|
||||||
|
cameraNames.every((name) => savedSet.has(name))
|
||||||
|
) {
|
||||||
|
orderedNames = fitCameraOrder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderedNames.map((name, index) => ({
|
||||||
i: name,
|
i: name,
|
||||||
x: (index % colsPerRow) * w,
|
x: (index % colsPerRow) * w,
|
||||||
y: Math.floor(index / colsPerRow) * h,
|
y: Math.floor(index / colsPerRow) * h,
|
||||||
w,
|
w,
|
||||||
h,
|
h,
|
||||||
}));
|
}));
|
||||||
}, [fitToScreen, fitGridParams, cameras, includeBirdseye, birdseyeConfig]);
|
}, [fitToScreen, fitGridParams, cameras, includeBirdseye, birdseyeConfig, fitCameraOrder]);
|
||||||
|
|
||||||
const [fitLayoutOverride, setFitLayoutOverride] = useState<Layout | undefined>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFitLayoutOverride(undefined);
|
// Сбросить сохранённый порядок только если изменился набор камер
|
||||||
}, [
|
// (добавили/удалили камеру), не при изменении размера окна
|
||||||
fitGridParams?.gridUnitsPerCam,
|
setFitCameraOrder(undefined);
|
||||||
fitGridParams?.colsPerRow,
|
}, [cameras, includeBirdseye]);
|
||||||
cameras,
|
|
||||||
includeBirdseye,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleFitDragStop = useCallback(
|
const handleFitDragStop = useCallback(
|
||||||
(
|
(
|
||||||
@ -492,7 +505,8 @@ export default function DraggableGridLayout({
|
|||||||
const colsPerRow = fitGridParams.colsPerRow;
|
const colsPerRow = fitGridParams.colsPerRow;
|
||||||
const draggedId = newItem.i;
|
const draggedId = newItem.i;
|
||||||
|
|
||||||
const currentOrder = fitLayoutOverride ?? fitLayout ?? [];
|
// Текущий порядок из fitLayout (уже учитывает fitCameraOrder)
|
||||||
|
const currentOrder = fitLayout ?? [];
|
||||||
const orderedNames = [...currentOrder]
|
const orderedNames = [...currentOrder]
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.y !== b.y) return a.y - b.y;
|
if (a.y !== b.y) return a.y - b.y;
|
||||||
@ -514,44 +528,30 @@ export default function DraggableGridLayout({
|
|||||||
|
|
||||||
const sourceIndex = orderedNames.indexOf(draggedId);
|
const sourceIndex = orderedNames.indexOf(draggedId);
|
||||||
|
|
||||||
const snapBack = orderedNames.map((name, index) => ({
|
|
||||||
i: name,
|
|
||||||
x: (index % colsPerRow) * w,
|
|
||||||
y: Math.floor(index / colsPerRow) * w,
|
|
||||||
w,
|
|
||||||
h: w,
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (sourceIndex === -1 || sourceIndex === targetIndex) {
|
if (sourceIndex === -1 || sourceIndex === targetIndex) {
|
||||||
setFitLayoutOverride(snapBack);
|
// Snap back — пересохранить текущий порядок чтобы layout обновился
|
||||||
|
setFitCameraOrder([...orderedNames]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap
|
||||||
const newOrder = [...orderedNames];
|
const newOrder = [...orderedNames];
|
||||||
[newOrder[sourceIndex], newOrder[targetIndex]] = [
|
[newOrder[sourceIndex], newOrder[targetIndex]] = [
|
||||||
newOrder[targetIndex],
|
newOrder[targetIndex],
|
||||||
newOrder[sourceIndex],
|
newOrder[sourceIndex],
|
||||||
];
|
];
|
||||||
|
|
||||||
const normalized = newOrder.map((name, index) => ({
|
setFitCameraOrder(newOrder);
|
||||||
i: name,
|
|
||||||
x: (index % colsPerRow) * w,
|
|
||||||
y: Math.floor(index / colsPerRow) * w,
|
|
||||||
w,
|
|
||||||
h: w,
|
|
||||||
}));
|
|
||||||
|
|
||||||
setFitLayoutOverride(normalized);
|
|
||||||
},
|
},
|
||||||
[fitToScreen, fitGridParams, fitLayoutOverride, fitLayout],
|
[fitToScreen, fitGridParams, fitLayout, setFitCameraOrder],
|
||||||
);
|
);
|
||||||
|
|
||||||
const activeGridLayout = useMemo(() => {
|
const activeGridLayout = useMemo(() => {
|
||||||
if (fitToScreen) {
|
if (fitToScreen) {
|
||||||
return fitLayoutOverride ?? fitLayout ?? currentGridLayout;
|
return fitLayout ?? currentGridLayout;
|
||||||
}
|
}
|
||||||
return currentGridLayout;
|
return currentGridLayout;
|
||||||
}, [fitToScreen, fitLayoutOverride, fitLayout, currentGridLayout]);
|
}, [fitToScreen, fitLayout, currentGridLayout]);
|
||||||
|
|
||||||
const handleResize = (
|
const handleResize = (
|
||||||
_layout: Layout,
|
_layout: Layout,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user