- Enhanced camera feed state management with region handling and mode changes

This commit is contained in:
2025-11-27 16:16:15 +00:00
parent f7dbde4511
commit bf31f94b32
7 changed files with 190 additions and 135 deletions

View File

@@ -1,33 +1,45 @@
import { useEffect } from "react";
import { useCameraFeedContext } from "../../../../app/context/CameraFeedContext";
import RegionSelector from "./RegionSelector";
type CameraPanelProps = {
tabIndex: number;
};
const CameraPanel = ({ tabIndex }: CameraPanelProps) => {
const { dispatch } = useCameraFeedContext();
const { state, dispatch } = useCameraFeedContext();
const cameraFeedID = state.cameraFeedID;
const regions = state.regionsByCamera[cameraFeedID];
const selectedRegionIndex = state.selectedRegionIndex;
const mode = state.modeByCamera[cameraFeedID];
useEffect(() => {
const mapIndextoCameraId = () => {
switch (tabIndex) {
case 1:
case 0:
return "A";
case 2:
case 1:
return "B";
case 3:
case 2:
return "C";
default:
return null;
return "A";
}
};
const cameraId = mapIndextoCameraId();
console.log(cameraId);
dispatch({ type: "SET_CAMERA_FEED", payload: cameraId });
}, [dispatch, tabIndex]);
return <div>CameraPanel</div>;
return (
<RegionSelector
regions={regions}
selectedRegionIndex={selectedRegionIndex}
mode={mode}
cameraFeedID={cameraFeedID}
/>
);
};
export default CameraPanel;

View File

@@ -1,38 +1,14 @@
import Card from "../../../../ui/Card";
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import "react-tabs/style/react-tabs.css";
import RegionSelector from "./RegionSelector";
import type { PaintedCell, Region } from "../../../../types/types";
import type { RefObject } from "react";
import CameraPanel from "./CameraPanel";
type CameraSettingsProps = {
regions: Region[];
selectedRegionIndex: number;
onSelectRegion: (index: number) => void;
onChangeRegionColour: (index: number, colour: string) => void;
mode: string;
onSelectMode: (mode: string) => void;
setTabIndex: (tabIndex: number) => void;
tabIndex: number;
paintedCells: RefObject<Map<string, PaintedCell>>;
onAddRegion: () => void;
OnRemoveRegion: () => void;
};
const CameraSettings = ({
regions,
selectedRegionIndex,
onSelectRegion,
onChangeRegionColour,
mode,
onSelectMode,
tabIndex,
setTabIndex,
paintedCells,
onAddRegion,
OnRemoveRegion,
}: CameraSettingsProps) => {
const CameraSettings = ({ tabIndex, setTabIndex }: CameraSettingsProps) => {
return (
<Card className="p-4 col-span-3 row-span-5 col-start-3 md:col-span-3 md:row-span-5 max-h-screen overflow-auto">
<Tabs
@@ -41,24 +17,10 @@ const CameraSettings = ({
onSelect={(index) => setTabIndex(index)}
>
<TabList>
<Tab>Target Detection</Tab>
<Tab>Camera 1</Tab>
<Tab>Camera 2</Tab>
<Tab>Camera 3</Tab>
<Tab>Camera A</Tab>
<Tab>Camera B</Tab>
<Tab>Camera C</Tab>
</TabList>
<TabPanel>
<RegionSelector
regions={regions}
selectedRegionIndex={selectedRegionIndex}
onSelectRegion={onSelectRegion}
onChangeRegionColour={onChangeRegionColour}
mode={mode}
onSelectMode={onSelectMode}
paintedCells={paintedCells}
onAddRegion={onAddRegion}
OnRemoveRegion={OnRemoveRegion}
/>
</TabPanel>
<TabPanel>
<CameraPanel tabIndex={tabIndex} />
</TabPanel>

View File

@@ -1,45 +1,57 @@
import ColourPicker from "./ColourPicker";
import type { PaintedCell, Region } from "../../../../types/types";
import type { RefObject } from "react";
import ColourPicker from "./ColourPicker";
import { useCameraFeedContext } from "../../../../app/context/CameraFeedContext";
type RegionSelectorProps = {
regions: Region[];
selectedRegionIndex: number;
onSelectRegion: (index: number) => void;
onChangeRegionColour: (index: number, colour: string) => void;
mode: string;
onSelectMode: (mode: string) => void;
paintedCells: RefObject<Map<string, PaintedCell>>;
onAddRegion: () => void;
OnRemoveRegion: () => void;
cameraFeedID: "A" | "B" | "C";
};
const RegionSelector = ({
regions,
selectedRegionIndex,
onSelectRegion,
onChangeRegionColour,
mode,
onSelectMode,
paintedCells,
onAddRegion,
OnRemoveRegion,
}: RegionSelectorProps) => {
const RegionSelector = ({ regions, selectedRegionIndex, mode, cameraFeedID }: RegionSelectorProps) => {
const { dispatch } = useCameraFeedContext();
const handleChange = (e: { target: { value: string } }) => {
onSelectMode(e.target.value);
dispatch({ type: "CHANGE_MODE", payload: { cameraFeedID: cameraFeedID, mode: e.target.value } });
};
const handleAddClick = () => {
onAddRegion();
const handleAddRegionClick = () => {
const regionName = `Region ${regions.length + 1}`;
dispatch({
type: "ADD_NEW_REGION",
payload: { cameraFeedID: cameraFeedID, regionName: regionName, brushColour: "#ffffff" },
});
};
const handleResetClick = () => {
const map = paintedCells.current;
map.clear();
const handleResetRegion = () => {
dispatch({
type: "RESET_PAINTED_CELLS",
payload: { cameraFeedID: cameraFeedID, paintedCells: new Map<string, PaintedCell>() },
});
};
const handleRemoveClick = () => {
OnRemoveRegion();
dispatch({
type: "REMOVE_REGION",
payload: { cameraFeedID: cameraFeedID, regionName: regions[selectedRegionIndex].name },
});
};
const handleModeChange = (newMode: string) => {
dispatch({ type: "CHANGE_MODE", payload: { cameraFeedID: cameraFeedID, mode: newMode } });
};
const handleRegionSelect = (index: number) => {
dispatch({ type: "SET_SELECTED_REGION_INDEX", payload: index });
};
const handleRegionColourChange = (index: number, newColour: string) => {
const regionName = regions[index].name;
dispatch({
type: "SET_SELECTED_REGION_COLOUR",
payload: { cameraFeedID: cameraFeedID, regionName: regionName, newColour: newColour },
});
};
return (
@@ -84,7 +96,7 @@ const RegionSelector = ({
<div className="p-2 border border-gray-600 rounded-lg flex flex-col">
<h2 className="text-2xl mb-2">Region Select</h2>
<>
{regions.map((region, idx) => {
{regions?.map((region, idx) => {
const isSelected = selectedRegionIndex === idx;
const inputId = `region-${idx}`;
return (
@@ -102,20 +114,20 @@ const RegionSelector = ({
name="region"
className="sr-only"
onChange={() => {
onSelectMode("painter");
onSelectRegion(idx);
handleModeChange("painter");
handleRegionSelect(idx);
}}
/>
<span className="text-xl">{region.name}</span>
</div>
<ColourPicker colour={region.brushColour} setColour={(c: string) => onChangeRegionColour(idx, c)} />
<ColourPicker colour={region.brushColour} setColour={(c: string) => handleRegionColourChange(idx, c)} />
<p className="text-slate-400">{region.brushColour}</p>
</label>
);
})}
</>
<div className=" mx-auto flex flex-row gap-4 mt-4">
<button className="border border-blue-900 bg-blue-700 px-4 rounded-md" onClick={handleAddClick}>
<button className="border border-blue-900 bg-blue-700 px-4 rounded-md" onClick={handleAddRegionClick}>
Add Region
</button>
<button className="border border-red-900 px-4 rounded-md" onClick={handleRemoveClick}>
@@ -128,10 +140,10 @@ const RegionSelector = ({
<div className="flex flex-col">
<h2 className="text-2xl mb-2">Actions</h2>
<button
onClick={handleResetClick}
onClick={handleResetRegion}
className="mt-2 px-4 py-2 border border-red-600 rounded-md text-white bg-red-600 w-full md:w-[40%] hover:bg-red-700 hover:cursor-pointer"
>
Reset Regions
Reset Region
</button>
</div>
</div>