Refactor camera feed handling to support dynamic camera IDs and improve context management
This commit is contained in:
@@ -28,6 +28,7 @@ const CameraPanel = ({ tabIndex, isResetAllModalOpen, handleClose, setIsResetMod
|
||||
return "B";
|
||||
case 2:
|
||||
return "C";
|
||||
//Add more cases if more cameras are added
|
||||
default:
|
||||
return "A";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import Card from "../../../../ui/Card";
|
||||
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
|
||||
import "react-tabs/style/react-tabs.css";
|
||||
import CameraPanel from "./CameraPanel";
|
||||
import { CAMERA_IDS } from "../../../../app/config/cameraConfig";
|
||||
|
||||
type CameraSettingsProps = {
|
||||
setTabIndex: (tabIndex: number) => void;
|
||||
@@ -12,7 +13,6 @@ type CameraSettingsProps = {
|
||||
};
|
||||
|
||||
const CameraSettings = ({
|
||||
tabIndex,
|
||||
setTabIndex,
|
||||
isResetAllModalOpen,
|
||||
handleClose,
|
||||
@@ -26,34 +26,20 @@ const CameraSettings = ({
|
||||
onSelect={(index) => setTabIndex(index)}
|
||||
>
|
||||
<TabList>
|
||||
<Tab>Camera A</Tab>
|
||||
<Tab>Camera B</Tab>
|
||||
<Tab>Camera C</Tab>
|
||||
{CAMERA_IDS.map((id) => (
|
||||
<Tab key={id}>Camera {id}</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
<TabPanel>
|
||||
<CameraPanel
|
||||
tabIndex={tabIndex}
|
||||
isResetAllModalOpen={isResetAllModalOpen}
|
||||
handleClose={handleClose}
|
||||
setIsResetModalOpen={setIsResetModalOpen}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<CameraPanel
|
||||
tabIndex={tabIndex}
|
||||
isResetAllModalOpen={isResetAllModalOpen}
|
||||
handleClose={handleClose}
|
||||
setIsResetModalOpen={setIsResetModalOpen}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<CameraPanel
|
||||
tabIndex={tabIndex}
|
||||
isResetAllModalOpen={isResetAllModalOpen}
|
||||
handleClose={handleClose}
|
||||
setIsResetModalOpen={setIsResetModalOpen}
|
||||
/>
|
||||
</TabPanel>
|
||||
{CAMERA_IDS.map((id, index) => (
|
||||
<TabPanel key={id}>
|
||||
<CameraPanel
|
||||
tabIndex={index}
|
||||
isResetAllModalOpen={isResetAllModalOpen}
|
||||
handleClose={handleClose}
|
||||
setIsResetModalOpen={setIsResetModalOpen}
|
||||
/>
|
||||
</TabPanel>
|
||||
))}
|
||||
</Tabs>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -4,17 +4,14 @@ import { useCameraFeedContext } from "../../../../app/context/CameraFeedContext"
|
||||
import { useColourDectection } from "../../hooks/useColourDetection";
|
||||
import { useBlackBoard } from "../../../../hooks/useBlackBoard";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
useCameraFeedASocket,
|
||||
useCameraFeedBSocket,
|
||||
useCameraFeedCSocket,
|
||||
} from "../../../../app/context/WebSocketContext";
|
||||
import { useCameraFeedSocket } from "../../../../app/context/WebSocketContext";
|
||||
import type { CameraID } from "../../../../app/config/cameraConfig";
|
||||
|
||||
type RegionSelectorProps = {
|
||||
regions: Region[];
|
||||
selectedRegionIndex: number;
|
||||
mode: string;
|
||||
cameraFeedID: "A" | "B" | "C";
|
||||
cameraFeedID: CameraID;
|
||||
isResetAllModalOpen: boolean;
|
||||
handleClose: () => void;
|
||||
setIsResetModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
@@ -33,26 +30,24 @@ const RegionSelector = ({
|
||||
const { state, dispatch } = useCameraFeedContext();
|
||||
const { blackboardMutation } = useBlackBoard();
|
||||
const paintedCells = state.paintedCells[cameraFeedID];
|
||||
const cameraASocket = useCameraFeedASocket();
|
||||
const cameraBSocket = useCameraFeedBSocket();
|
||||
const cameraCSocket = useCameraFeedCSocket();
|
||||
const cameraSocket = useCameraFeedSocket();
|
||||
|
||||
const getCurrentSocket = () => {
|
||||
switch (cameraFeedID) {
|
||||
case "A":
|
||||
return cameraASocket;
|
||||
return cameraSocket;
|
||||
case "B":
|
||||
return cameraBSocket;
|
||||
return cameraSocket;
|
||||
case "C":
|
||||
return cameraCSocket;
|
||||
return cameraSocket;
|
||||
}
|
||||
};
|
||||
|
||||
const socket = getCurrentSocket();
|
||||
|
||||
const getMagnificationLevel = () => {
|
||||
const test = socket.data;
|
||||
if (!socket.data) return null;
|
||||
const test = socket?.data;
|
||||
if (!socket?.data) return null;
|
||||
console.log(test);
|
||||
if (!test || !test.magnificationLevel) return "1x";
|
||||
return test?.magnificationLevel;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { CameraID } from "../../../../../app/config/cameraConfig";
|
||||
import { useCameraFeedContext } from "../../../../../app/context/CameraFeedContext";
|
||||
import SliderComponent from "../../../../../ui/SliderComponent";
|
||||
import { useCameraZoom } from "../../../hooks/useCameraZoom";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
type CameraControlsProps = {
|
||||
cameraFeedID: "A" | "B" | "C";
|
||||
cameraFeedID: CameraID;
|
||||
};
|
||||
|
||||
const CameraControls = ({ cameraFeedID }: CameraControlsProps) => {
|
||||
|
||||
@@ -3,13 +3,10 @@ import { Stage, Layer, Image, Shape } from "react-konva";
|
||||
import type { KonvaEventObject } from "konva/lib/Node";
|
||||
import { useCreateVideoSnapshot } from "../../hooks/useGetvideoSnapshots";
|
||||
import { useCameraFeedContext } from "../../../../app/context/CameraFeedContext";
|
||||
import {
|
||||
useCameraFeedASocket,
|
||||
useCameraFeedBSocket,
|
||||
useCameraFeedCSocket,
|
||||
} from "../../../../app/context/WebSocketContext";
|
||||
import { useCameraFeedSocket } from "../../../../app/context/WebSocketContext";
|
||||
import { ReadyState } from "react-use-websocket";
|
||||
import { toast } from "sonner";
|
||||
import type { CameraID } from "../../../../app/config/cameraConfig";
|
||||
|
||||
const BACKEND_WIDTH = 640;
|
||||
const BACKEND_HEIGHT = 360;
|
||||
@@ -41,22 +38,20 @@ const VideoFeedGridPainter = () => {
|
||||
const currentScale = stageSize.width / BACKEND_WIDTH;
|
||||
const size = BACKEND_CELL_SIZE * currentScale;
|
||||
|
||||
const cameraASocket = useCameraFeedASocket();
|
||||
const cameraBSocket = useCameraFeedBSocket();
|
||||
const cameraCSocket = useCameraFeedCSocket();
|
||||
const cameraSocket = useCameraFeedSocket();
|
||||
|
||||
const getCurrentSocket = () => {
|
||||
switch (cameraFeedID) {
|
||||
case "A":
|
||||
return cameraASocket;
|
||||
return cameraSocket;
|
||||
case "B":
|
||||
return cameraBSocket;
|
||||
return cameraSocket;
|
||||
case "C":
|
||||
return cameraCSocket;
|
||||
return cameraSocket;
|
||||
}
|
||||
};
|
||||
|
||||
const handleZoomClick = (e: KonvaEventObject<MouseEvent>, cameraFeedID: "A" | "B" | "C") => {
|
||||
const handleZoomClick = (e: KonvaEventObject<MouseEvent>, cameraFeedID: CameraID) => {
|
||||
if (mode !== "zoom") return;
|
||||
const socket = getCurrentSocket();
|
||||
const stage = e.target.getStage();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import { CAMBASE } from "../../../utils/config";
|
||||
import type { CameraZoomConfig } from "../../../types/types";
|
||||
import type { CameraID } from "../../../app/config/cameraConfig";
|
||||
|
||||
const fetchZoomLevel = async (cameraFeedID: string) => {
|
||||
const response = await fetch(`${CAMBASE}/api/fetch-config?id=Camera${cameraFeedID}-onvif-controller`);
|
||||
@@ -34,7 +35,7 @@ const postZoomLevel = async (zoomConfig: CameraZoomConfig) => {
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const useCameraZoom = (cameraFeedID: "A" | "B" | "C") => {
|
||||
export const useCameraZoom = (cameraFeedID: CameraID) => {
|
||||
const cameraZoomQuery = useQuery({
|
||||
queryKey: ["cameraZoom", cameraFeedID],
|
||||
queryFn: () => fetchZoomLevel(cameraFeedID),
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useGetSystemHealth } from "../hooks/useGetSystemHealth";
|
||||
import CameraStatus from "./cameraStatus/CameraStatus";
|
||||
import SystemHealthCard from "./systemHealth/SystemHealthCard";
|
||||
import SystemStatusCard from "./systemStatus/SystemStatusCard";
|
||||
import { CAMERA_IDS } from "../../../app/config/cameraConfig";
|
||||
|
||||
const DashboardGrid = () => {
|
||||
const { query } = useGetSystemHealth();
|
||||
@@ -26,30 +27,35 @@ const DashboardGrid = () => {
|
||||
channelA: [],
|
||||
channelB: [],
|
||||
channelC: [],
|
||||
// todo: check if more cameras will be added later
|
||||
default: [],
|
||||
},
|
||||
);
|
||||
|
||||
const categoryA = statusCategories?.channelA ?? [];
|
||||
const categoryB = statusCategories?.channelB ?? [];
|
||||
const categoryC = statusCategories?.channelC ?? [];
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-rows-2 md:grid-cols-2 gap-4">
|
||||
<SystemStatusCard />
|
||||
<SystemHealthCard
|
||||
startTime={startTime}
|
||||
uptime={uptime}
|
||||
statuses={statuses}
|
||||
isLoading={isLoading}
|
||||
isError={isError}
|
||||
dateUpdatedAt={dateUpdatedAt}
|
||||
refetch={refetch}
|
||||
/>
|
||||
<div className="grid grid-cols-1 md:col-span-2 md:grid-cols-3 gap-x-4">
|
||||
<CameraStatus title="Camera A" category={categoryA} isError={isError} />
|
||||
<CameraStatus title="Camera B" category={categoryB} isError={isError} />
|
||||
<CameraStatus title="Camera C" category={categoryC} isError={isError} />
|
||||
<div className="grid grid-cols-1 md:grid-rows-0 md:grid-cols-2 gap-4 md:col-span-2">
|
||||
<SystemStatusCard />
|
||||
<SystemHealthCard
|
||||
startTime={startTime}
|
||||
uptime={uptime}
|
||||
statuses={statuses}
|
||||
isLoading={isLoading}
|
||||
isError={isError}
|
||||
dateUpdatedAt={dateUpdatedAt}
|
||||
refetch={refetch}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:col-span-2 md:grid-cols-[repeat(3,1fr)] gap-x-4">
|
||||
{CAMERA_IDS.map((cameraID) => (
|
||||
<CameraStatus
|
||||
key={cameraID}
|
||||
title={`Camera ${cameraID}`}
|
||||
category={statusCategories?.[`channel${cameraID}`] ?? []}
|
||||
isError={isError}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ const SystemHealthCard = ({
|
||||
refetch,
|
||||
}: SystemOverviewProps) => {
|
||||
return (
|
||||
<Card className="p-4">
|
||||
<Card className="p-4 ">
|
||||
<CardHeader title="System Health" refetch={refetch} icon={faArrowsRotate} />
|
||||
<SystemHealth
|
||||
startTime={startTime}
|
||||
|
||||
@@ -29,7 +29,7 @@ const SystemStatusCard = () => {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Card className="p-4">
|
||||
<Card className="p-4 ">
|
||||
<CardHeader title="System Status" />
|
||||
{stats ? (
|
||||
<div className="grid grid-cols-2 grid-rows-2 gap-4 col-span-2">
|
||||
|
||||
Reference in New Issue
Block a user