diff --git a/src/components/Scanner.tsx b/src/components/Scanner.tsx index 7c0bc18..4c93a60 100644 --- a/src/components/Scanner.tsx +++ b/src/components/Scanner.tsx @@ -1,22 +1,32 @@ "use client"; import { useEffect, useState } from "react"; import { QrReader } from "react-qr-reader"; + // Override console.error // This is a hack to suppress the warning about missing defaultProps in react-qr-reader const error = console.error; +const manual = "manual"; + console.error = (...args: any) => { if (/defaultProps/.test(args[0])) return; error(...args); }; + function Scanner({ onResult }: { onResult: (result: string) => void }) { useEffect(() => { getUserCameraList(); }, []); async function getUserCameraList() { - await navigator.mediaDevices.getUserMedia({ - audio: false, - video: true, - }); + try { + await navigator.mediaDevices.getUserMedia({ + audio: false, + video: true, + }); + } catch (e) { + setCurrentCamera(manual); + console.log(e); + return; + } let devices = await navigator.mediaDevices.enumerateDevices(); devices = devices.filter((device) => device.kind == "videoinput"); @@ -35,8 +45,9 @@ function Scanner({ onResult }: { onResult: (result: string) => void }) { setCurrentCamera(devices[0].deviceId); } } + const [cameras, setCameras] = useState([]); - const [currentCamera, setCurrentCamera] = useState(null); + const [currentCamera, setCurrentCamera] = useState(manual); return (
@@ -45,6 +56,7 @@ function Scanner({ onResult }: { onResult: (result: string) => void }) { value={currentCamera || ""} className="absolute left-0 right-0 top-4 z-[1] m-auto w-[256px] rounded-md bg-white/75 p-2 shadow-md outline-0 backdrop-blur-lg" > + {cameras.map((camera) => (
); } +function Manual({ onResult }: { onResult: (result: string) => void }) { + const [value, setValue] = useState(""); + return ( +
{ + e.preventDefault(); + onResult(value); + }} + className="flex h-full w-full flex-col items-center justify-center gap-4 bg-sitcon-color8" + > + setValue(e.target.value.toUpperCase())} + className="rounded-md p-2 px-6 py-4 text-3xl shadow-md outline-0" + placeholder="Code" + /> + +
+ ); +} + +function FromCamera({ + currentCamera, + onResult, +}: { + currentCamera: string; + onResult: (result: string) => void; +}) { + return ( + { + const text = result?.getText(); + if (text) { + onResult(text); + } + }} + constraints={{ + deviceId: currentCamera!, + }} + videoStyle={{ + objectFit: "cover", + height: "100%", + width: "100%", + position: "relative", + }} + videoContainerStyle={{ + height: "100%", + width: "100%", + padding: "0", + }} + containerStyle={{ + height: "100%", + width: "100%", + }} + /> + ); +} + export default Scanner;