diff --git a/app/(main)/clue/[clueId]/page.js b/app/(main)/clue/[clueId]/page.js index fe37aef..9709f04 100644 --- a/app/(main)/clue/[clueId]/page.js +++ b/app/(main)/clue/[clueId]/page.js @@ -567,9 +567,9 @@ export default function CluePage({ params }) { {/* QR Scanner Section */}

Scan QR Code

- diff --git a/clue_hunt.db b/clue_hunt.db index 84414f5..e678017 100644 Binary files a/clue_hunt.db and b/clue_hunt.db differ diff --git a/components/EnhancedQRScanner.js b/components/EnhancedQRScanner.js index e4a6ec5..f011680 100644 --- a/components/EnhancedQRScanner.js +++ b/components/EnhancedQRScanner.js @@ -19,7 +19,7 @@ export default function EnhancedQRScanner({ const [cameraPermissionDenied, setCameraPermissionDenied] = useState(false); const cameraStreamRef = useRef(null); const [retryCount, setRetryCount] = useState(0); - + // We're keeping torchEnabled state but only using it if torch is enabled const [torchEnabled, setTorchEnabled] = useState(false); const inputRef = useRef(null); @@ -50,15 +50,16 @@ export default function EnhancedQRScanner({ try { // Release any stream that might be stored in our ref if (cameraStreamRef.current) { - cameraStreamRef.current.getTracks().forEach(track => { + cameraStreamRef.current.getTracks().forEach((track) => { track.stop(); }); cameraStreamRef.current = null; console.log("Released existing camera resources"); } - + // Also try to find and release any active video tracks that might be running - navigator.mediaDevices.getUserMedia({ audio: false, video: false }) + navigator.mediaDevices + .getUserMedia({ audio: false, video: false }) .catch(() => { // This intentionally fails but helps release resources in some browsers }); @@ -180,13 +181,13 @@ export default function EnhancedQRScanner({ try { setError(null); setCameraActive(false); - + // First release any existing camera resources releaseCameraResources(); - + // Add a small delay to ensure resources are properly released - await new Promise(resolve => setTimeout(resolve, 500)); - + await new Promise((resolve) => setTimeout(resolve, 500)); + // Now try to get fresh camera access const stream = await navigator.mediaDevices.getUserMedia({ video: true, @@ -197,20 +198,20 @@ export default function EnhancedQRScanner({ if (stream) { // Store the stream reference for potential future release cameraStreamRef.current = stream; - + // Release this stream since useZxing will request its own stream.getTracks().forEach((track) => track.stop()); - + setCameraActive(true); setCameraPermissionDenied(false); setRetryCount(0); // Reset retry count on success } } catch (err) { console.error("Failed to get camera permission:", err); - + // Increment retry count - setRetryCount(prev => prev + 1); - + setRetryCount((prev) => prev + 1); + if ( err.name === "NotAllowedError" || err.name === "PermissionDeniedError" @@ -224,9 +225,13 @@ export default function EnhancedQRScanner({ err.name === "TrackStartError" || retryCount < 2 // Try a few times before showing hardware error ) { - setError(`Camera temporarily unavailable. Please try again in a few moments.`); + setError( + `Camera temporarily unavailable. Please try again in a few moments.` + ); } else { - setError(`Camera error: ${err.message}. You may need to restart your browser or device.`); + setError( + `Camera error: ${err.message}. You may need to restart your browser or device.` + ); } } }; @@ -242,10 +247,13 @@ export default function EnhancedQRScanner({ // Handle camera errors const handleError = (error) => { console.error("QR Scanner error:", error); - + // Don't immediately deactivate camera on all errors // Some errors can be temporary - if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") { + if ( + error.name === "NotAllowedError" || + error.name === "PermissionDeniedError" + ) { setCameraActive(false); } @@ -327,10 +335,7 @@ export default function EnhancedQRScanner({
) : ( - )}