fix: improve QR scanning a bit

This commit is contained in:
trafficlunar 2025-07-14 13:59:22 +01:00
parent 8b4842b584
commit ac1e29586f

View file

@ -28,7 +28,7 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
const cameraItems = devices.map((device) => ({ const cameraItems = devices.map((device) => ({
value: device.deviceId, value: device.deviceId,
label: device.label || `Camera ${device.deviceId.slice(-5)}`, label: device.label || `Camera ${devices.indexOf(device) + 1}`,
})); }));
const { const {
@ -73,6 +73,7 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
// Cancel animation frame to stop scanning // Cancel animation frame to stop scanning
if (requestRef.current) { if (requestRef.current) {
cancelAnimationFrame(requestRef.current); cancelAnimationFrame(requestRef.current);
requestRef.current = null;
} }
setQrBytesRaw(code.binaryData!); setQrBytesRaw(code.binaryData!);
@ -115,8 +116,15 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
}, [isOpen, selectedDeviceId]); }, [isOpen, selectedDeviceId]);
useEffect(() => { useEffect(() => {
if (!isOpen && !permissionGranted) return; if (!isOpen || !permissionGranted) return;
requestRef.current = requestAnimationFrame(scanQRCode); requestRef.current = requestAnimationFrame(scanQRCode);
return () => {
if (requestRef.current) {
cancelAnimationFrame(requestRef.current);
}
};
}, [isOpen, permissionGranted, scanQRCode]); }, [isOpen, permissionGranted, scanQRCode]);
if (!isOpen) return null; if (!isOpen) return null;
@ -191,12 +199,18 @@ export default function QrScanner({ isOpen, setIsOpen, setQrBytesRaw }: Props) {
) : ( ) : (
<> <>
<Webcam <Webcam
key={selectedDeviceId}
ref={webcamRef} ref={webcamRef}
audio={false} audio={false}
videoConstraints={{ videoConstraints={{
deviceId: selectedDeviceId ? { exact: selectedDeviceId } : undefined, deviceId: selectedDeviceId ? { exact: selectedDeviceId } : undefined,
facingMode: { ideal: "environment" }, facingMode: { ideal: "environment" },
}} }}
onUserMedia={async () => {
const newDevices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = newDevices.filter((d) => d.kind === "videoinput");
setDevices(videoDevices);
}}
className="size-full object-cover rounded-2xl border-2 border-amber-500" className="size-full object-cover rounded-2xl border-2 border-amber-500"
/> />
<QrFinder /> <QrFinder />