diff --git a/src/features/dashboard/Dashboard.tsx b/src/features/dashboard/Dashboard.tsx index 1759209..f5b6e08 100644 --- a/src/features/dashboard/Dashboard.tsx +++ b/src/features/dashboard/Dashboard.tsx @@ -12,7 +12,7 @@ const Dashboard = () => { const mostRecent = sightingList[0]; return ( -
+
diff --git a/src/features/dashboard/components/videoFeed/VideoFeed.tsx b/src/features/dashboard/components/videoFeed/VideoFeed.tsx index 2f776ea..a66c4d8 100644 --- a/src/features/dashboard/components/videoFeed/VideoFeed.tsx +++ b/src/features/dashboard/components/videoFeed/VideoFeed.tsx @@ -8,12 +8,12 @@ type VideoFeedProps = { mostRecentSighting: SightingType; isLoading: boolean; size: { width: number; height: number }; - modeSetting?: number; isModal?: boolean; }; const VideoFeed = ({ mostRecentSighting, isLoading, size, modeSetting, isModal = false }: VideoFeedProps) => { + console.log(size); const { state: cameraSettings, dispatch } = useCameraSettingsContext(); const contextMode = cameraSettings.mode; const [localMode, setLocalMode] = useState(0); diff --git a/src/features/setup/Setup.tsx b/src/features/setup/Setup.tsx new file mode 100644 index 0000000..16fe731 --- /dev/null +++ b/src/features/setup/Setup.tsx @@ -0,0 +1,11 @@ +import VideoFeedSetup from "./components/videofeed/VideoFeedSetup"; + +const Setup = () => { + return ( +
+ +
+ ); +}; + +export default Setup; diff --git a/src/features/setup/components/videofeed/VideoFeedSetup.tsx b/src/features/setup/components/videofeed/VideoFeedSetup.tsx new file mode 100644 index 0000000..54ff8db --- /dev/null +++ b/src/features/setup/components/videofeed/VideoFeedSetup.tsx @@ -0,0 +1,41 @@ +import { Stage, Layer, Image } from "react-konva"; +import { useCreateVideoPreviewSnapshot } from "../../hooks/useCreatePreviewImage"; +import { useEffect, type RefObject } from "react"; +import { useCameraSettingsContext } from "../../../../app/context/CameraSettingsContext"; + +const VideoFeedSetup = () => { + const { latestBitmapRef, isLoading } = useCreateVideoPreviewSnapshot(); + const { state, dispatch } = useCameraSettingsContext(); + const size = state.imageSize; + + const draw = (bmp: RefObject): ImageBitmap | null => { + if (!bmp || !bmp.current) { + return null; + } + const image = bmp.current; + return image; + }; + const image = draw(latestBitmapRef); + + useEffect(() => { + const updateSize = () => { + const width = window.innerWidth * 0.48; + const height = (width * 2) / 3; + dispatch({ type: "SET_IMAGE_SIZE", payload: { width, height } }); + }; + updateSize(); + window.addEventListener("resize", updateSize); + return () => window.removeEventListener("resize", updateSize); + }, []); + + if (isLoading) return <>Loading...; + return ( +
+ + {image && } + +
+ ); +}; + +export default VideoFeedSetup; diff --git a/src/features/setup/hooks/useCreatePreviewImage.ts b/src/features/setup/hooks/useCreatePreviewImage.ts new file mode 100644 index 0000000..b8bb928 --- /dev/null +++ b/src/features/setup/hooks/useCreatePreviewImage.ts @@ -0,0 +1,25 @@ +import { useEffect, useRef } from "react"; +import { useVideoPreview } from "./useVideoPreview"; + +export const useCreateVideoPreviewSnapshot = () => { + const { videoPreviewQuery } = useVideoPreview(); + const latestBitmapRef = useRef(null); + const isLoading = videoPreviewQuery?.isPending; + const imageBlob = videoPreviewQuery?.data; + + useEffect(() => { + async function createImageBitmapFromBlob() { + if (!imageBlob) return; + + try { + const bitmap = await createImageBitmap(imageBlob); + latestBitmapRef.current = bitmap; + } catch (error) { + console.log(error); + } + } + createImageBitmapFromBlob(); + }, [imageBlob]); + + return { latestBitmapRef, isLoading, imageURL: imageBlob ? URL.createObjectURL(imageBlob) : null }; +}; diff --git a/src/features/setup/hooks/useVideoPreview.ts b/src/features/setup/hooks/useVideoPreview.ts new file mode 100644 index 0000000..bb2e433 --- /dev/null +++ b/src/features/setup/hooks/useVideoPreview.ts @@ -0,0 +1,19 @@ +import { useQuery } from "@tanstack/react-query"; +import { cambase } from "../../../app/config"; + +const fetchVideoPreview = async () => { + const response = await fetch(`${cambase}/Colour-preview`); + if (!response.ok) { + throw new Error("Failed to fetch video preview"); + } + return response.blob(); +}; + +export const useVideoPreview = () => { + const videoPreviewQuery = useQuery({ + queryKey: ["videoPreview"], + queryFn: fetchVideoPreview, + refetchInterval: 100, + }); + return { videoPreviewQuery }; +}; diff --git a/src/routes/setup.tsx b/src/routes/setup.tsx index 636d6ff..c587df6 100644 --- a/src/routes/setup.tsx +++ b/src/routes/setup.tsx @@ -1,9 +1,10 @@ import { createFileRoute } from "@tanstack/react-router"; +import Setup from "../features/setup/Setup"; export const Route = createFileRoute("/setup")({ component: RouteComponent, }); function RouteComponent() { - return
Hello "/setup"!
; + return ; }