import { useApiHost } from "@/api"; import { useEffect, useMemo, useRef, useState } from "react"; import useSWR from "swr"; import ActivityIndicator from "../indicators/activity-indicator"; import { useResizeObserver } from "@/hooks/resize-observer"; type CameraImageProps = { className?: string; camera: string; onload?: () => void; searchParams?: string; }; export default function CameraImage({ className, camera, onload, searchParams = "", }: CameraImageProps) { const { data: config } = useSWR("config"); const apiHost = useApiHost(); const [hasLoaded, setHasLoaded] = useState(false); const containerRef = useRef(null); const imgRef = useRef(null); const { name } = config ? config.cameras[camera] : ""; const enabled = config ? config.cameras[camera].enabled : "True"; const [isPortraitImage, setIsPortraitImage] = useState(false); const [{ width: containerWidth, height: containerHeight }] = useResizeObserver(containerRef); const requestHeight = useMemo(() => { if (!config || containerHeight == 0) { return 360; } return Math.min( config.cameras[camera].detect.height, Math.round(containerHeight * 1.1), ); }, [config, camera, containerHeight]); useEffect(() => { if (!config || !imgRef.current) { return; } imgRef.current.src = `${apiHost}api/${name}/latest.jpg?h=${requestHeight}${ searchParams ? `&${searchParams}` : "" }`; }, [apiHost, name, imgRef, searchParams, requestHeight, config]); return (
{enabled ? ( { setHasLoaded(true); if (imgRef.current) { const { naturalHeight, naturalWidth } = imgRef.current; setIsPortraitImage( naturalWidth / naturalHeight < containerWidth / containerHeight, ); } if (onload) { onload(); } }} /> ) : (
Camera is disabled in config, no stream or snapshot available!
)} {!hasLoaded && enabled ? (
) : null}
); }