added more clue buttons and positioned them correctly, need to fix elapsed timer on clue page....

Error handling with clues improved.
This commit is contained in:
bobbert committed 2025-03-17 13:30:49 +00:00
1 parent 8a06fd4966
commit 4fa0419ba9
3 files changed
+29 -24

No files matched your search

+3 -3
View File
@@ -567,9 +567,9 @@ export default function CluePage({ params }) {
{/* QR Scanner Section */} {/* QR Scanner Section */}
<div className="scanner-section"> <div className="scanner-section">
<h2>Scan QR Code</h2> <h2>Scan QR Code</h2>
<EnhancedQRScanner <EnhancedQRScanner
onScan={handleScan} onScan={handleScan}
width={280} width={280}
height={280} height={280}
disableTorch={true} // Disable torch functionality disableTorch={true} // Disable torch functionality
/> />
BIN
View File
Binary file not shown.
+26 -21
View File
@@ -19,7 +19,7 @@ export default function EnhancedQRScanner({
const [cameraPermissionDenied, setCameraPermissionDenied] = useState(false); const [cameraPermissionDenied, setCameraPermissionDenied] = useState(false);
const cameraStreamRef = useRef(null); const cameraStreamRef = useRef(null);
const [retryCount, setRetryCount] = useState(0); const [retryCount, setRetryCount] = useState(0);
// We're keeping torchEnabled state but only using it if torch is enabled // We're keeping torchEnabled state but only using it if torch is enabled
const [torchEnabled, setTorchEnabled] = useState(false); const [torchEnabled, setTorchEnabled] = useState(false);
const inputRef = useRef(null); const inputRef = useRef(null);
@@ -50,15 +50,16 @@ export default function EnhancedQRScanner({
try { try {
// Release any stream that might be stored in our ref // Release any stream that might be stored in our ref
if (cameraStreamRef.current) { if (cameraStreamRef.current) {
cameraStreamRef.current.getTracks().forEach(track => { cameraStreamRef.current.getTracks().forEach((track) => {
track.stop(); track.stop();
}); });
cameraStreamRef.current = null; cameraStreamRef.current = null;
console.log("Released existing camera resources"); console.log("Released existing camera resources");
} }
// Also try to find and release any active video tracks that might be running // 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(() => { .catch(() => {
// This intentionally fails but helps release resources in some browsers // This intentionally fails but helps release resources in some browsers
}); });
@@ -180,13 +181,13 @@ export default function EnhancedQRScanner({
try { try {
setError(null); setError(null);
setCameraActive(false); setCameraActive(false);
// First release any existing camera resources // First release any existing camera resources
releaseCameraResources(); releaseCameraResources();
// Add a small delay to ensure resources are properly released // 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 // Now try to get fresh camera access
const stream = await navigator.mediaDevices.getUserMedia({ const stream = await navigator.mediaDevices.getUserMedia({
video: true, video: true,
@@ -197,20 +198,20 @@ export default function EnhancedQRScanner({
if (stream) { if (stream) {
// Store the stream reference for potential future release // Store the stream reference for potential future release
cameraStreamRef.current = stream; cameraStreamRef.current = stream;
// Release this stream since useZxing will request its own // Release this stream since useZxing will request its own
stream.getTracks().forEach((track) => track.stop()); stream.getTracks().forEach((track) => track.stop());
setCameraActive(true); setCameraActive(true);
setCameraPermissionDenied(false); setCameraPermissionDenied(false);
setRetryCount(0); // Reset retry count on success setRetryCount(0); // Reset retry count on success
} }
} catch (err) { } catch (err) {
console.error("Failed to get camera permission:", err); console.error("Failed to get camera permission:", err);
// Increment retry count // Increment retry count
setRetryCount(prev => prev + 1); setRetryCount((prev) => prev + 1);
if ( if (
err.name === "NotAllowedError" || err.name === "NotAllowedError" ||
err.name === "PermissionDeniedError" err.name === "PermissionDeniedError"
@@ -224,9 +225,13 @@ export default function EnhancedQRScanner({
err.name === "TrackStartError" || err.name === "TrackStartError" ||
retryCount < 2 // Try a few times before showing hardware error 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 { } 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 // Handle camera errors
const handleError = (error) => { const handleError = (error) => {
console.error("QR Scanner error:", error); console.error("QR Scanner error:", error);
// Don't immediately deactivate camera on all errors // Don't immediately deactivate camera on all errors
// Some errors can be temporary // Some errors can be temporary
if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") { if (
error.name === "NotAllowedError" ||
error.name === "PermissionDeniedError"
) {
setCameraActive(false); setCameraActive(false);
} }
@@ -327,10 +335,7 @@ export default function EnhancedQRScanner({
</button> </button>
</div> </div>
) : ( ) : (
<button <button className="retry-button" onClick={requestCameraAccess}>
className="retry-button"
onClick={requestCameraAccess}
>
Retry Camera Access Retry Camera Access
</button> </button>
)} )}