Compare commits
3 Commits
feature/mo
...
feature/se
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a99a15342 | |||
| 8dac436831 | |||
| 73c67ad992 |
@@ -12,7 +12,7 @@ const Dashboard = () => {
|
||||
const mostRecent = sightingList[0];
|
||||
|
||||
return (
|
||||
<div className="grid gird-cols-1 md:grid-cols-2 gap-2 md:gap-5">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-5">
|
||||
<div>
|
||||
<VideoFeed mostRecentSighting={mostRecent} isLoading={isLoading} size={size} />
|
||||
<PlateRead sighting={mostRecent} />
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
src/features/setup/Setup.tsx
Normal file
11
src/features/setup/Setup.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import VideoFeedSetup from "./components/videofeed/VideoFeedSetup";
|
||||
|
||||
const Setup = () => {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-5">
|
||||
<VideoFeedSetup />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Setup;
|
||||
41
src/features/setup/components/videofeed/VideoFeedSetup.tsx
Normal file
41
src/features/setup/components/videofeed/VideoFeedSetup.tsx
Normal file
@@ -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>): 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 (
|
||||
<div className="mt-[1%]">
|
||||
<Stage width={size.width} height={size.height}>
|
||||
<Layer>{image && <Image image={image} height={size.height} width={size.width} cornerRadius={10} />}</Layer>
|
||||
</Stage>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoFeedSetup;
|
||||
25
src/features/setup/hooks/useCreatePreviewImage.ts
Normal file
25
src/features/setup/hooks/useCreatePreviewImage.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useVideoPreview } from "./useVideoPreview";
|
||||
|
||||
export const useCreateVideoPreviewSnapshot = () => {
|
||||
const { videoPreviewQuery } = useVideoPreview();
|
||||
const latestBitmapRef = useRef<ImageBitmap | null>(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 };
|
||||
};
|
||||
19
src/features/setup/hooks/useVideoPreview.ts
Normal file
19
src/features/setup/hooks/useVideoPreview.ts
Normal file
@@ -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 };
|
||||
};
|
||||
@@ -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 <div className="">Hello "/setup"!</div>;
|
||||
return <Setup />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user