develop #20

Merged
TobaOjo merged 2 commits from develop into main 2025-12-22 15:39:22 +00:00
7 changed files with 73 additions and 27 deletions

View File

@@ -22,7 +22,6 @@ const CameraSettingFields = ({
onZoomLevelChange, onZoomLevelChange,
}: CameraSettingsProps) => { }: CameraSettingsProps) => {
const [showPwd, setShowPwd] = useState(false); const [showPwd, setShowPwd] = useState(false);
const cameraControllerSide = initialData?.id === "CameraA" ? "CameraControllerA" : "CameraControllerB"; const cameraControllerSide = initialData?.id === "CameraA" ? "CameraControllerA" : "CameraControllerB";
const { mutation, query } = useCameraZoom({ camera: cameraControllerSide }); const { mutation, query } = useCameraZoom({ camera: cameraControllerSide });
const { cameraModeQuery, cameraModeMutation } = useCameraMode({ camera: cameraControllerSide }); const { cameraModeQuery, cameraModeMutation } = useCameraMode({ camera: cameraControllerSide });

View File

@@ -5,13 +5,13 @@ import { useSoundContext } from "../../../context/SoundContext";
import { toast } from "sonner"; import { toast } from "sonner";
import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard"; import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard";
import { useFileUpload } from "../../../hooks/useFileUpload"; import { useFileUpload } from "../../../hooks/useFileUpload";
import { useEffect, useRef } from "react";
const SoundUpload = () => { const SoundUpload = () => {
const { state, dispatch } = useSoundContext(); const { state, dispatch } = useSoundContext();
const { mutation } = useCameraBlackboard(); const { mutation } = useCameraBlackboard();
const { mutation: fileMutation } = useFileUpload({ const currentUrlRef = useRef<string | null>(null);
queryKey: state.sightingSound ? [state.sightingSound] : undefined, const { mutation: fileMutation } = useFileUpload();
});
const initialValues: SoundUploadValue = { const initialValues: SoundUploadValue = {
name: "", name: "",
@@ -43,6 +43,10 @@ const SoundUpload = () => {
value: updatedValues, value: updatedValues,
}); });
await fileMutation.mutateAsync(values.soundFile); await fileMutation.mutateAsync(values.soundFile);
if (currentUrlRef.current) {
URL.revokeObjectURL(currentUrlRef.current);
currentUrlRef.current = null;
}
if (result.reason !== "OK") { if (result.reason !== "OK") {
toast.error("Cannot update sound settings"); toast.error("Cannot update sound settings");
} }
@@ -54,6 +58,14 @@ const SoundUpload = () => {
dispatch({ type: "ADD", payload: values }); dispatch({ type: "ADD", payload: values });
}; };
useEffect(() => {
return () => {
if (currentUrlRef.current) {
URL.revokeObjectURL(currentUrlRef.current);
}
};
}, []);
return ( return (
<Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize> <Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize>
{({ setFieldValue, errors, setFieldError }) => ( {({ setFieldValue, errors, setFieldError }) => (
@@ -69,8 +81,12 @@ const SoundUpload = () => {
accept="audio/mpeg" accept="audio/mpeg"
className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5" className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5"
onChange={(e) => { onChange={(e) => {
if (currentUrlRef.current) {
URL.revokeObjectURL(currentUrlRef.current);
}
if (e.target?.files && e.target?.files[0]?.type === "audio/mpeg") { if (e.target?.files && e.target?.files[0]?.type === "audio/mpeg") {
const url = URL.createObjectURL(e.target.files[0]); currentUrlRef.current = URL.createObjectURL(e.target.files[0]);
const url = currentUrlRef.current;
setFieldValue("soundUrl", url); setFieldValue("soundUrl", url);
setFieldValue("name", e.target.files[0].name); setFieldValue("name", e.target.files[0].name);
setFieldValue("soundFileName", e.target.files[0].name); setFieldValue("soundFileName", e.target.files[0].name);

View File

@@ -7,19 +7,23 @@ import type { SystemValues, SystemValuesErrors } from "../../../types/types";
import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig"; import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig";
import { ValidateIPaddress } from "../../../utils/utils"; import { ValidateIPaddress } from "../../../utils/utils";
import { toast } from "sonner"; import { toast } from "sonner";
// import { useSystemStatus } from "../../../hooks/useSystemStatus";
const SystemConfigFields = () => { const SystemConfigFields = () => {
const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig(); const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig();
// const { systemStatusQuery } = useSystemStatus();
const { hardRebootMutation } = useReboots(); const { hardRebootMutation } = useReboots();
const { dnsQuery, dnsMutation } = useDNSSettings(); const { dnsQuery, dnsMutation } = useDNSSettings();
const sntpInterval = systemSettingsData?.sntpInterval;
const dnsPrimary = dnsQuery?.data?.propNameServerPrimary?.value; const dnsPrimary = dnsQuery?.data?.propNameServerPrimary?.value;
const dnsSecondary = dnsQuery?.data?.propNameServerSecondary?.value; const dnsSecondary = dnsQuery?.data?.propNameServerSecondary?.value;
const initialvalues: SystemValues = { const initialvalues: SystemValues = {
deviceName: systemSettingsData?.deviceName ?? "", deviceName: systemSettingsData?.deviceName ?? "",
timeZone: systemSettingsData?.timeZone ?? "", timeZone: systemSettingsData?.timeZone ?? "",
sntpServer: systemSettingsData?.sntpServer ?? "", sntpServer: systemSettingsData?.sntpServer ?? "",
sntpInterval: systemSettingsData?.sntpInterval ?? 60, sntpInterval: sntpInterval ?? 60,
serverPrimary: dnsPrimary ?? "", serverPrimary: dnsPrimary ?? "",
serverSecondary: dnsSecondary ?? "", serverSecondary: dnsSecondary ?? "",
softwareUpdate: null, softwareUpdate: null,

View File

@@ -19,7 +19,7 @@ const SystemFileUpload = ({ name, selectedFile }: SystemFileUploadProps) => {
opts: { opts: {
timeoutMs: 30000, timeoutMs: 30000,
fieldName: "upload", fieldName: "upload",
uploadUrl: "http://192.168.75.11/upload/software-update/2", uploadUrl: "http://192.168.75.11/upload/software-update/4",
}, },
}; };
uploadSettings(settings); uploadSettings(settings);

View File

@@ -1,12 +1,9 @@
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { CAM_BASE } from "../utils/config"; import { CAM_BASE } from "../utils/config";
import { toast } from "sonner"; import { toast } from "sonner";
import { getOrCacheBlob } from "../utils/cacheSound";
const camBase = import.meta.env.MODE !== "development" ? CAM_BASE : CAM_BASE;
type UseFileUploadProps = { const camBase = import.meta.env.MODE !== "development" ? CAM_BASE : CAM_BASE;
queryKey?: string[]; console.log(camBase);
};
const uploadFile = async (file: File) => { const uploadFile = async (file: File) => {
const form = new FormData(); const form = new FormData();
@@ -21,19 +18,7 @@ const uploadFile = async (file: File) => {
return response.text(); return response.text();
}; };
const getUploadFiles = async ({ queryKey }: { queryKey: string[] }) => { export const useFileUpload = () => {
const [, fileName] = queryKey;
const url = fileName;
return getOrCacheBlob(url);
};
export const useFileUpload = ({ queryKey }: UseFileUploadProps) => {
const query = useQuery({
queryKey: ["getUploadFiles", ...(queryKey ?? [])],
queryFn: () => getUploadFiles({ queryKey: ["getUploadFiles", ...(queryKey ?? [])] }),
enabled: !!queryKey,
});
const mutation = useMutation({ const mutation = useMutation({
mutationFn: (file: File) => uploadFile(file), mutationFn: (file: File) => uploadFile(file),
mutationKey: ["uploadFile"], mutationKey: ["uploadFile"],
@@ -41,5 +26,5 @@ export const useFileUpload = ({ queryKey }: UseFileUploadProps) => {
onSuccess: async (msg) => toast.success(msg), onSuccess: async (msg) => toast.success(msg),
}); });
return { query: queryKey ? query : undefined, mutation }; return { mutation };
}; };

View File

@@ -0,0 +1,22 @@
import { useQuery } from "@tanstack/react-query";
import { getOrCacheBlob } from "../utils/cacheSound";
type UseFileUploadProps = {
queryKey?: string[];
};
const getUploadFiles = async ({ queryKey }: { queryKey: string[] }) => {
const [, fileName] = queryKey;
const url = fileName;
return getOrCacheBlob(url);
};
export const useGetUploadedFiles = ({ queryKey }: UseFileUploadProps) => {
const query = useQuery({
queryKey: ["getUploadFiles", ...(queryKey ?? [])],
queryFn: () => getUploadFiles({ queryKey: ["getUploadFiles", ...(queryKey ?? [])] }),
enabled: !!queryKey,
});
return { query: queryKey ? query : undefined };
};

View File

@@ -0,0 +1,20 @@
import { useQuery } from "@tanstack/react-query";
import { CAM_BASE } from "../utils/config";
const fetchSystemStatus = async () => {
const response = await fetch(`${CAM_BASE}/sysstatus?func=getstatus`);
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
};
export const useSystemStatus = () => {
const systemStatusQuery = useQuery({
queryKey: ["get systemStatus"],
queryFn: fetchSystemStatus,
refetchInterval: 60000,
});
return { systemStatusQuery };
};