mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
SCANNER WORKS!!! JUST ADD THE MORE CLUE BUTTONS !!! AND NEXT CLUE ERROR CHECKING
This commit is contained in:
1 parent
02a0088d28
commit
a1c6e599c3
5 files changed
+174
-163
No files matched your search
@@ -18,14 +18,14 @@ export default function EnhancedQRScanner({
|
||||
const [torchEnabled, setTorchEnabled] = useState(false);
|
||||
const inputRef = useRef(null);
|
||||
const [cameraPermissionDenied, setCameraPermissionDenied] = useState(false);
|
||||
|
||||
// Define video constraints explicitly
|
||||
|
||||
// Define video constraints explicitly
|
||||
const videoConstraints = {
|
||||
facingMode: "environment",
|
||||
width: { min: 640, ideal: 1280, max: 1920 },
|
||||
height: { min: 480, ideal: 720, max: 1080 },
|
||||
};
|
||||
|
||||
|
||||
// Setup the zxing scanner hook with explicit video constraints
|
||||
const { ref, torch } = useZxing({
|
||||
onDecodeResult(result) {
|
||||
@@ -56,18 +56,18 @@ export default function EnhancedQRScanner({
|
||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||
throw new Error("MediaDevices API is not supported in this browser");
|
||||
}
|
||||
|
||||
|
||||
// Explicitly request video permission - important to avoid the error
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: false
|
||||
audio: false,
|
||||
});
|
||||
|
||||
|
||||
// If we got a stream, we have permission - release it immediately
|
||||
if (stream) {
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
stream.getTracks().forEach((track) => track.stop());
|
||||
}
|
||||
|
||||
|
||||
// Now enumerate devices to confirm we have video devices
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
const videoDevices = devices.filter(
|
||||
@@ -87,15 +87,20 @@ export default function EnhancedQRScanner({
|
||||
setInitialized(true);
|
||||
} catch (err) {
|
||||
console.error("Camera access error:", err);
|
||||
|
||||
|
||||
// Handle permission denied specifically
|
||||
if (err.name === "NotAllowedError" || err.name === "PermissionDeniedError") {
|
||||
if (
|
||||
err.name === "NotAllowedError" ||
|
||||
err.name === "PermissionDeniedError"
|
||||
) {
|
||||
setCameraPermissionDenied(true);
|
||||
setError("Camera permission denied. Please allow camera access in your browser settings.");
|
||||
setError(
|
||||
"Camera permission denied. Please allow camera access in your browser settings."
|
||||
);
|
||||
} else {
|
||||
setError(`Camera error: ${err.message}`);
|
||||
}
|
||||
|
||||
|
||||
setInitialized(true);
|
||||
}
|
||||
}
|
||||
@@ -125,7 +130,7 @@ export default function EnhancedQRScanner({
|
||||
// Show success visual
|
||||
setScanSuccess(true);
|
||||
setTimeout(() => setScanSuccess(false), 1500);
|
||||
|
||||
|
||||
// Call the onScan callback with the decoded text
|
||||
onScan(text);
|
||||
} catch (err) {
|
||||
@@ -137,17 +142,17 @@ export default function EnhancedQRScanner({
|
||||
const requestCameraAccess = async () => {
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
|
||||
// Explicitly request video permission
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: false
|
||||
audio: false,
|
||||
});
|
||||
|
||||
|
||||
// If we got a stream, we have permission
|
||||
if (stream) {
|
||||
// Release the stream since useZxing will request it again
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
stream.getTracks().forEach((track) => track.stop());
|
||||
setCameraActive(true);
|
||||
setCameraPermissionDenied(false);
|
||||
}
|
||||
@@ -244,16 +249,13 @@ export default function EnhancedQRScanner({
|
||||
<li>Select "Allow" for camera access</li>
|
||||
<li>Refresh this page</li>
|
||||
</ol>
|
||||
<button
|
||||
className="retry-button"
|
||||
onClick={requestCameraAccess}
|
||||
>
|
||||
<button className="retry-button" onClick={requestCameraAccess}>
|
||||
Request Camera Permission
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
className="retry-button"
|
||||
<button
|
||||
className="retry-button"
|
||||
onClick={() => {
|
||||
setError(null);
|
||||
requestCameraAccess();
|
||||
@@ -270,27 +272,27 @@ export default function EnhancedQRScanner({
|
||||
className={`scanner-container ${scanSuccess ? "scan-success" : ""}`}
|
||||
style={{ width, height }}
|
||||
>
|
||||
<video
|
||||
ref={ref}
|
||||
<video
|
||||
ref={ref}
|
||||
className="scanner-video"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "cover",
|
||||
}}
|
||||
/>
|
||||
{scanSuccess && <div className="scan-overlay">✓</div>}
|
||||
|
||||
|
||||
{/* Scanning frame to help user focus */}
|
||||
<div className="scanning-frame"></div>
|
||||
|
||||
|
||||
{/* Add flashlight toggle button if available */}
|
||||
{torch && (
|
||||
<button
|
||||
className={`torch-button ${torchEnabled ? 'active' : ''}`}
|
||||
<button
|
||||
className={`torch-button ${torchEnabled ? "active" : ""}`}
|
||||
onClick={toggleTorch}
|
||||
>
|
||||
{torchEnabled ? '💡 Off' : '💡 On'}
|
||||
{torchEnabled ? "💡 Off" : "💡 On"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -338,7 +340,7 @@ export default function EnhancedQRScanner({
|
||||
border-radius: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.permission-help {
|
||||
margin-top: 12px;
|
||||
background-color: #f8f8f8;
|
||||
@@ -347,17 +349,17 @@ export default function EnhancedQRScanner({
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.permission-help p {
|
||||
margin: 0 0 8px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.permission-help ol {
|
||||
margin: 0 0 10px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
|
||||
.permission-help li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
@@ -397,7 +399,7 @@ export default function EnhancedQRScanner({
|
||||
background-color: #f5f5f5;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
.scanning-frame {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
||||
@@ -18,16 +18,19 @@ export const ensureScannerCompatibility = () => {
|
||||
|
||||
// Polyfill for older browsers that don't implement getUserMedia
|
||||
if (!navigator.mediaDevices.getUserMedia) {
|
||||
navigator.mediaDevices.getUserMedia = function(constraints) {
|
||||
const getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||
|
||||
navigator.mediaDevices.getUserMedia = function (constraints) {
|
||||
const getUserMedia =
|
||||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||
|
||||
// Return a rejected promise if getUserMedia is not implemented
|
||||
if (!getUserMedia) {
|
||||
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
|
||||
return Promise.reject(
|
||||
new Error("getUserMedia is not implemented in this browser")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
getUserMedia.call(navigator, constraints, resolve, reject);
|
||||
});
|
||||
};
|
||||
@@ -50,29 +53,31 @@ export const ensureScannerCompatibility = () => {
|
||||
export const checkCameraAvailability = async () => {
|
||||
try {
|
||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||
return { available: false, error: 'MediaDevices API not supported' };
|
||||
return { available: false, error: "MediaDevices API not supported" };
|
||||
}
|
||||
|
||||
|
||||
// Try to access the camera with explicit video request
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: false
|
||||
audio: false,
|
||||
});
|
||||
|
||||
|
||||
// If we get here, camera is available - stop the stream
|
||||
if (stream) {
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
stream.getTracks().forEach((track) => track.stop());
|
||||
}
|
||||
|
||||
|
||||
return { available: true };
|
||||
} catch (error) {
|
||||
return {
|
||||
available: false,
|
||||
error: error.message,
|
||||
name: error.name,
|
||||
permission: error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError'
|
||||
? 'denied'
|
||||
: 'unknown'
|
||||
permission:
|
||||
error.name === "NotAllowedError" ||
|
||||
error.name === "PermissionDeniedError"
|
||||
? "denied"
|
||||
: "unknown",
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user