2025-11-27 11:43:10 +00:00
|
|
|
import type { CameraFeedAction, CameraFeedState, PaintedCell } from "../../types/types";
|
2025-12-17 14:19:23 +00:00
|
|
|
import { CAMERA_IDS, DEFAULT_REGIONS, type CameraID } from "../config/cameraConfig";
|
2025-11-27 10:43:56 +00:00
|
|
|
|
|
|
|
|
export const initialState: CameraFeedState = {
|
2025-12-17 14:19:23 +00:00
|
|
|
cameraFeedID: CAMERA_IDS[0],
|
|
|
|
|
paintedCells: CAMERA_IDS.reduce(
|
|
|
|
|
(acc, id) => {
|
|
|
|
|
acc[id] = new Map<string, PaintedCell>();
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{} as Record<string, Map<string, PaintedCell>>,
|
|
|
|
|
),
|
|
|
|
|
regionsByCamera: CAMERA_IDS.reduce(
|
|
|
|
|
(acc, id) => {
|
|
|
|
|
acc[id] = DEFAULT_REGIONS;
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{} as Record<string, { name: string; brushColour: string }[]>,
|
|
|
|
|
),
|
2025-11-27 16:16:15 +00:00
|
|
|
|
|
|
|
|
selectedRegionIndex: 0,
|
2025-12-17 14:19:23 +00:00
|
|
|
modeByCamera: CAMERA_IDS.reduce(
|
|
|
|
|
(acc, id) => {
|
|
|
|
|
acc[id] = "painter";
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{} as Record<CameraID, string>,
|
|
|
|
|
),
|
|
|
|
|
zoomLevel: CAMERA_IDS.reduce(
|
|
|
|
|
(acc, id) => {
|
|
|
|
|
acc[id] = 1;
|
|
|
|
|
return acc;
|
|
|
|
|
},
|
|
|
|
|
{} as Record<CameraID, number>,
|
|
|
|
|
),
|
2025-11-27 10:43:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function reducer(state: CameraFeedState, action: CameraFeedAction) {
|
|
|
|
|
switch (action.type) {
|
|
|
|
|
case "SET_CAMERA_FEED":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
cameraFeedID: action.payload,
|
|
|
|
|
};
|
2025-11-27 16:16:15 +00:00
|
|
|
case "CHANGE_MODE":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
modeByCamera: {
|
|
|
|
|
...state.modeByCamera,
|
|
|
|
|
[action.payload.cameraFeedID]: action.payload.mode,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
case "SET_SELECTED_REGION_INDEX":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
selectedRegionIndex: action.payload,
|
|
|
|
|
};
|
|
|
|
|
case "SET_SELECTED_REGION_COLOUR":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
regionsByCamera: {
|
|
|
|
|
...state.regionsByCamera,
|
|
|
|
|
[action.payload.cameraFeedID]: state.regionsByCamera[action.payload.cameraFeedID].map((region) =>
|
|
|
|
|
region.name === action.payload.regionName ? { ...region, brushColour: action.payload.newColour } : region,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
case "ADD_NEW_REGION":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
regionsByCamera: {
|
|
|
|
|
...state.regionsByCamera,
|
|
|
|
|
[action.payload.cameraFeedID]: [
|
|
|
|
|
...state.regionsByCamera[action.payload.cameraFeedID],
|
|
|
|
|
{ name: action.payload.regionName, brushColour: action.payload.brushColour },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
case "REMOVE_REGION":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
regionsByCamera: {
|
|
|
|
|
...state.regionsByCamera,
|
|
|
|
|
[action.payload.cameraFeedID]: state.regionsByCamera[action.payload.cameraFeedID].filter(
|
|
|
|
|
(region) => region.name !== action.payload.regionName,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
case "RESET_PAINTED_CELLS":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
paintedCells: {
|
|
|
|
|
...state.paintedCells,
|
|
|
|
|
[state.cameraFeedID]: new Map<string, PaintedCell>(),
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-12-08 10:59:46 +00:00
|
|
|
case "SET_CAMERA_FEED_DATA":
|
|
|
|
|
return {
|
|
|
|
|
...action.cameraState,
|
|
|
|
|
};
|
|
|
|
|
case "RESET_CAMERA_FEED":
|
|
|
|
|
return {
|
|
|
|
|
...initialState,
|
|
|
|
|
};
|
2025-12-09 08:47:21 +00:00
|
|
|
case "SET_ZOOM_LEVEL":
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
zoomLevel: {
|
|
|
|
|
...state.zoomLevel,
|
|
|
|
|
[action.payload.cameraFeedID]: action.payload.zoomLevel,
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-11-27 10:43:56 +00:00
|
|
|
default:
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
}
|