import React, { useState, useEffect, useRef, useCallback, useContext, } from 'react'; import Webcam from 'react-webcam'; import FacingMode from '@constant/FacingMode'; import Loader from '@components/common/Loader'; import '@style/RootContainer.scss'; import RootContext from '@context/RootContext'; import { resetResults } from '@slice/RecognitionSlice'; import CameraOptions from './CameraOptions'; import Capture from './Capture'; const CAMERA_OPTIONS = { format: 'image/jpeg', minHeight: 1920, minWidth: 1080, quality: 0.75, defaultView: FacingMode.FRONT, }; const CameraContainer = () => { const { dispatch } = useContext(RootContext); const ref = useRef(null); const [imgSrc, setImgSrc] = useState(null); const [captureError, setCaptureError] = useState(null); const [videoInputs, setVideoInputs] = useState([]); const [resetCameraView, setResetCameraView] = useState(false); const [videoConstraints, setVideoConstraints] = useState({ facingMode: CAMERA_OPTIONS.defaultView, }); useEffect(() => { const gotDevices = (mediaDevices) => new Promise((resolve, reject) => { const availableVideoInputs = mediaDevices .filter(({ kind }) => kind === 'videoinput') .map(({ deviceId, label }) => ({ deviceId, label })); if (availableVideoInputs.length > 0) { resolve(availableVideoInputs); } else { reject(new Error('ERR::NO_MEDIA_TO_STREAM')); } }); navigator.mediaDevices .enumerateDevices() .then(gotDevices) .then((availableVideoInputs) => setVideoInputs({ availableVideoInputs })) .catch((err) => console.error(err)); }, []); const changeCameraView = () => { if (videoInputs.length === 1) { console.error('ERR::AVAILABLE_MEDIA_STREAMS_IS_1'); return; } setResetCameraView(true); setTimeout(() => { const { facingMode } = videoConstraints; const newFacingMode = facingMode === FacingMode.FRONT ? FacingMode.REAR : FacingMode.FRONT; setResetCameraView(false); setVideoConstraints({ ...videoConstraints, facingMode: newFacingMode }); }, 100); }; const capture = useCallback(() => { const imageSrc = ref.current.getScreenshot(); setImgSrc(imageSrc); if (!imageSrc) { setCaptureError(['Failed to capture camera. Please try again.']); } else { setCaptureError(null); } }, [ref, setImgSrc]); const onBackClick = () => { setImgSrc(null); dispatch(resetResults()); }; const cameraView = () => ( <>