import React, { useState, useEffect, useRef } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import jsQR from "https://esm.sh/jsqr";
function App() {
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [qrCode, setQrCode] = useState<string | null>(null);
const [qrInfo, setQrInfo] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
const [debug, setDebug] = useState<string[]>([]);
const addDebug = (message: string) => {
setDebug(prev => [...prev, `${new Date().toISOString()}: ${message}`]);
};
useEffect(() => {
const startCamera = async () => {
try {
addDebug("Attempting to access camera...");
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } });
addDebug("Camera access granted.");
if (videoRef.current) {
videoRef.current.srcObject = stream;
addDebug("Video source set.");
videoRef.current.onloadedmetadata = () => {
addDebug(`Video dimensions: ${videoRef.current!.videoWidth}x${videoRef.current!.videoHeight}`);
};
} else {
addDebug("Video ref is null.");
}
} catch (error) {
console.error("Error accessing camera:", error);
setError(`Error accessing camera: ${error}`);
addDebug(`Camera access error: ${error}`);
}
};
startCamera();
return () => {
if (videoRef.current && videoRef.current.srcObject) {
const tracks = (videoRef.current.srcObject as MediaStream).getTracks();
tracks.forEach(track => track.stop());
addDebug("Camera stopped.");
}
};
}, []);
useEffect(() => {
const scanQRCode = () => {
if (videoRef.current && canvasRef.current) {
const video = videoRef.current;
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
if (context && video.readyState === video.HAVE_ENOUGH_DATA) {
canvas.height = video.videoHeight;
canvas.width = video.videoWidth;
context.drawImage(video, 0, 0, canvas.width, canvas.height);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
addDebug(`Scanning frame: ${canvas.width}x${canvas.height}`);
const code = jsQR(imageData.data, imageData.width, imageData.height);
if (code) {
setQrCode(code.data);
setQrInfo({
location: code.location,
version: code.version,
moduleSize: code.moduleSize,
});
addDebug(`QR Code found: ${code.data}`);
}
} else {
addDebug(`Video not ready. ReadyState: ${video.readyState}`);
}
} else {
addDebug("Video or canvas ref is null.");
}
requestAnimationFrame(scanQRCode);
};
scanQRCode();
}, []);
return (
<div>