Add camera zoom functionality and refactor blackboard data fetching

- Introduced `useCameraZoom` hook for managing camera zoom operations.
- Refactored `useCameraBlackboard` to improve data fetching function naming.
- Updated `CameraSettingFields` to utilize new zoom functionality and handle zoom level changes.
- Removed unnecessary console logs from `Dashboard`.
This commit is contained in:
2025-10-01 10:59:10 +01:00
parent 3903ff1cb8
commit 6f2bc96ac7
5 changed files with 60 additions and 9 deletions

View File

@@ -3,12 +3,15 @@ import type {
CameraConfig, CameraConfig,
CameraSettingErrorValues, CameraSettingErrorValues,
CameraSettingValues, CameraSettingValues,
ZoomInOptions,
ZoomLevel, ZoomLevel,
} from "../../types/types"; } from "../../types/types";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons"; import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons";
import CardHeader from "../UI/CardHeader"; import CardHeader from "../UI/CardHeader";
import { useCameraZoom } from "../../hooks/useCameraZoom";
import { useCameraBlackboard } from "../../hooks/useCameraBlackboard";
type CameraSettingsProps = { type CameraSettingsProps = {
initialData: CameraConfig; initialData: CameraConfig;
@@ -24,7 +27,9 @@ const CameraSettingFields = ({
onZoomLevelChange, onZoomLevelChange,
}: CameraSettingsProps) => { }: CameraSettingsProps) => {
const [showPwd, setShowPwd] = useState(false); const [showPwd, setShowPwd] = useState(false);
console.log(initialData); const { mutation } = useCameraZoom();
const { mutation: blackboardMuation, query: blackboardQuery } =
useCameraBlackboard();
const initialValues = useMemo<CameraSettingValues>( const initialValues = useMemo<CameraSettingValues>(
() => ({ () => ({
friendlyName: initialData?.id ?? "", friendlyName: initialData?.id ?? "",
@@ -32,6 +37,7 @@ const CameraSettingFields = ({
userName: "", userName: "",
password: "", password: "",
id: initialData?.id, id: initialData?.id,
//TODO: update zoomlevel to query data
zoom: zoomLevel?.level ? zoomLevel.level : 1, zoom: zoomLevel?.level ? zoomLevel.level : 1,
}), }),
[initialData?.id, initialData?.propURI?.value, zoomLevel?.level] [initialData?.id, initialData?.propURI?.value, zoomLevel?.level]
@@ -41,23 +47,42 @@ const CameraSettingFields = ({
const errors: CameraSettingErrorValues = {}; const errors: CameraSettingErrorValues = {};
if (!values.friendlyName) errors.friendlyName = "Required"; if (!values.friendlyName) errors.friendlyName = "Required";
if (!values.cameraAddress) errors.cameraAddress = "Required"; if (!values.cameraAddress) errors.cameraAddress = "Required";
if (!values.userName) errors.userName = "Required";
if (!values.password) errors.password = "Required";
return errors; return errors;
}; };
const handleSubmit = (values: CameraSettingValues) => { const handleSubmit = (values: CameraSettingValues) => {
console.log(values);
updateCameraConfig(values); updateCameraConfig(values);
}; };
const handleRadioButtonChange = (levelNumber: number) => { const handleRadioButtonChange = async (levelNumber: number) => {
if (!onZoomLevelChange || !zoomLevel) return; if (!onZoomLevelChange || !zoomLevel) return;
onZoomLevelChange({ onZoomLevelChange({
...zoomLevel, ...zoomLevel,
level: zoomLevel?.level !== levelNumber ? levelNumber : zoomLevel?.level, level: zoomLevel?.level !== levelNumber ? levelNumber : zoomLevel?.level,
}); });
const cameraControllerSide =
initialData?.id === "CameraA" ? "CameraControllerA" : "CameraControllerB";
const zoomInOptions: ZoomInOptions = {
camera: cameraControllerSide,
multiplier: levelNumber,
};
mutation.mutate(zoomInOptions);
if (!blackboardQuery.data.cameraZoom) {
blackboardMuation.mutate({
operation: "INSERT",
path: "cameraZoom",
value: zoomInOptions,
});
} else {
blackboardMuation.mutate({
operation: "APPEND",
path: "cameraZoom",
value: zoomInOptions,
});
}
}; };
return ( return (

View File

@@ -2,7 +2,7 @@ import { useMutation, useQuery } from "@tanstack/react-query";
import { CAM_BASE } from "../utils/config"; import { CAM_BASE } from "../utils/config";
import type { CameraBlackBoardOptions } from "../types/types"; import type { CameraBlackBoardOptions } from "../types/types";
const getBlackboardData = async () => { const getAllBlackboardData = async () => {
const response = await fetch(`${CAM_BASE}/api/blackboard`); const response = await fetch(`${CAM_BASE}/api/blackboard`);
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to fetch blackboard data"); throw new Error("Failed to fetch blackboard data");
@@ -25,7 +25,7 @@ const viewBlackboardData = async (options: CameraBlackBoardOptions) => {
export const useCameraBlackboard = () => { export const useCameraBlackboard = () => {
const query = useQuery({ const query = useQuery({
queryKey: ["cameraBlackboard"], queryKey: ["cameraBlackboard"],
queryFn: getBlackboardData, queryFn: getAllBlackboardData,
}); });
const mutation = useMutation({ const mutation = useMutation({

View File

@@ -0,0 +1,22 @@
import { useMutation } from "@tanstack/react-query";
import { CAM_BASE } from "../utils/config";
import type { ZoomInOptions } from "../types/types";
async function zoomIn(options: ZoomInOptions) {
const response = await fetch(
`${CAM_BASE}/Ip${options.camera}-command?magnification=${options.multiplier}x`
);
if (!response.ok) {
throw new Error("Cannot reach camera zoom endpoint");
}
return;
}
export const useCameraZoom = () => {
const mutation = useMutation({
mutationKey: ["zoomIn"],
mutationFn: (options: ZoomInOptions) => zoomIn(options),
});
return { mutation };
};

View File

@@ -7,7 +7,6 @@ const Dashboard = () => {
const mode = import.meta.env.MODE; const mode = import.meta.env.MODE;
const base_url = `${CAM_BASE}/SightingList/sightingSummary?mostRecentRef=`; const base_url = `${CAM_BASE}/SightingList/sightingSummary?mostRecentRef=`;
console.log(mode); console.log(mode);
console.log(base_url);
return ( return (
<SightingFeedProvider url={base_url}> <SightingFeedProvider url={base_url}>
<div className="mx-auto flex flex-col lg:flex-row gap-2 px-1 sm:px-2 lg:px-0 w-full min-h-screen"> <div className="mx-auto flex flex-col lg:flex-row gap-2 px-1 sm:px-2 lg:px-0 w-full min-h-screen">

View File

@@ -261,3 +261,8 @@ export type ZoomLevel = {
py: number; py: number;
level?: number; level?: number;
}; };
export type ZoomInOptions = {
camera: string;
multiplier: number;
};