// Copyright 2025 The Casdoor Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import {Button, Modal, Progress, message} from "antd"; import React, {useState} from "react"; import i18next from "i18next"; const FaceRecognitionCommonModal = (props) => { const {visible, onOk, onCancel} = props; const videoRef = React.useRef(); const canvasRef = React.useRef(); const [percent, setPercent] = useState(0); const mediaStreamRef = React.useRef(null); const [isCameraCaptured, setIsCameraCaptured] = useState(false); const [capturedImageArray, setCapturedImageArray] = useState([]); React.useEffect(() => { if (isCameraCaptured) { let count = 0; let count2 = 0; const interval = setInterval(() => { count++; if (videoRef.current) { videoRef.current.srcObject = mediaStreamRef.current; videoRef.current.play(); const interval2 = setInterval(() => { if (!visible) { clearInterval(interval); setPercent(0); } count2++; if (count2 >= 8) { clearInterval(interval2); setPercent(0); onOk(capturedImageArray); } else if (count2 > 3) { setPercent((count2 - 4) * 20); const canvas = document.createElement("canvas"); canvas.width = videoRef.current.videoWidth; canvas.height = videoRef.current.videoHeight; const context = canvas.getContext("2d"); context.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height); const b64 = canvas.toDataURL("image/png"); capturedImageArray.push(b64); setCapturedImageArray(capturedImageArray); } }, 1000); clearInterval(interval); } if (count >= 30) { clearInterval(interval); } }, 100); } else { mediaStreamRef.current?.getTracks().forEach(track => track.stop()); if (videoRef.current) { videoRef.current.srcObject = null; } } }, [isCameraCaptured]); React.useEffect(() => { if (visible) { navigator.mediaDevices .getUserMedia({video: {facingMode: "user"}}) .then((stream) => { mediaStreamRef.current = stream; setIsCameraCaptured(true); }).catch((error) => { handleCameraError(error); }); } else { setIsCameraCaptured(false); setCapturedImageArray([]); } }, [visible]); const handleCameraError = (error) => { if (error instanceof DOMException) { if (error.name === "NotFoundError" || error.name === "DevicesNotFoundError") { message.error(i18next.t("login:Please ensure that you have a camera device for facial recognition")); } else if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") { message.error(i18next.t("login:Please provide permission to access the camera")); } else if (error.name === "NotReadableError" || error.name === "TrackStartError") { message.error(i18next.t("login:The camera is currently in use by another webpage")); } else if (error.name === "TypeError") { message.error(i18next.t("login:Please load the webpage using HTTPS, otherwise the camera cannot be accessed")); } else { message.error(error.message); } } }; return
{ onOk(capturedImageArray); }}> Ok , , ]} destroyOnClose={true} open={visible}>
{
}
; }; export default FaceRecognitionCommonModal;