All files / src/sections/VerifyAccountHolder_v2/hooks useManageCamera.ts

85.71% Statements 48/56
61.11% Branches 11/18
88.88% Functions 8/9
88.67% Lines 47/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116      97x 97x 97x   97x   97x 97x 97x 97x   97x 4x 4x 4x     2x     2x       2x         2x         2x 2x   2x       2x   4x       97x 3x 3x   3x   3x 3x   3x 3x 3x     3x 3x       97x 11x         11x 1x 1x   1x       97x 1x   97x                                       29x 3x 3x 1x   2x 2x      
import { useRef, useState } from "react";
 
export default function useManageCamera(config?: MediaStreamConstraints) {
  const [stream, setStream] = useState<MediaStream | null>(null);
  const [image, setImage] = useState<string | null>(null);
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const [cameraPermission, setCameraPermission] =
    useState<PermissionState | null>(null);
 
  const [isLoading, setIsloading] = useState(false);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const [isSessionActive, setIsSessionActive] = useState(false);
  const [streamLoading, setStreamLoading] = useState(false);
 
  const requestCameraAccess = async () => {
    try {
      setStreamLoading(true);
      const permissionStatus = await navigator.permissions.query({
        name: "camera" as PermissionName,
      });
      setCameraPermission(permissionStatus.state); // "granted" | "denied" | "prompt"
 
      // Listen to future changes (e.g., user changes permissions in browser settings)
      permissionStatus.onchange = () => {
        setCameraPermission(permissionStatus.state);
      };
 
      Iif (permissionStatus.state === "denied") {
        console.warn("Camera access denied by user.");
        return;
      }
 
      const mediaStream = await navigator.mediaDevices.getUserMedia({
        video: config?.video ? config.video : true,
        audio: config?.audio ? config.audio : false,
      });
 
      setStream(mediaStream);
      setIsSessionActive(true);
 
      Iif (videoRef.current) {
        videoRef.current.srcObject = mediaStream;
      }
    } catch (error) {
      console.error("Error accessing camera:", error);
    } finally {
      setStreamLoading(false);
    }
  };
 
  const takePicture = () => {
    const video = videoRef.current;
    const canvas = canvasRef.current;
 
    Iif (!video || !canvas) return;
 
    const context = canvas.getContext("2d");
    Iif (!context) return;
 
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    context.drawImage(video, 0, 0, canvas.width, canvas.height);
 
    // Convert canvas image to a data URL
    const imageDataUrl = canvas.toDataURL("image/png");
    setImage(imageDataUrl);
  };
 
  // Stop the camera stream
  const stopCamera = () => {
    Iif (videoRef.current) {
      videoRef.current.pause();
      videoRef.current.srcObject = null;
    }
 
    if (stream) {
      stream.getTracks().forEach((track) => {
        track.stop();
      });
      setStream(null);
    }
  };
 
  const handleEndSession = () => {
    setIsSessionActive(false);
  };
  return {
    requestCameraAccess,
    takePicture,
    stopCamera,
    videoRef,
    canvasRef,
    image,
    stream,
    setImage,
    isLoading,
    isSessionActive,
    handleEndSession,
    setIsloading,
    disabled: cameraPermission === "denied",
    streamLoading,
  };
}
 
export type UseManageCameraType = ReturnType<typeof useManageCamera>;
 
export const checkIfCameraExists = async (): Promise<boolean> => {
  try {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.some((device) => device.kind === "videoinput");
  } catch (error) {
    console.error("Error checking for camera:", error);
    return false;
  }
};