Files
rondevu-demo/src/components/QRScanner.jsx
Bas van den Aakster 9f9068e7c7 Refactor app into components and add file upload progress
Components created:
- Header: App header with GitHub links
- ActionSelector: Step 1 - Choose create/join/scan
- MethodSelector: Step 2 - Choose connection method
- ConnectionForm: Step 3 - Enter connection details
- ChatView: Step 4 - Connected chat interface
- Message: Individual message display (text/file)
- QRScanner: QR code scanning component
- QRCodeDisplay: QR code display component
- FileUploadProgress: Progress bar for file uploads

Features:
- Clean component separation with props
- File upload progress bar with percentage
- Cancel upload functionality
- Disabled file button during upload
- Visual progress indicator with gradient
- All logic remains in App.jsx for state management
2025-11-07 22:26:19 +01:00

75 lines
2.0 KiB
JavaScript

import { useRef, useEffect } from 'react';
import { BrowserQRCodeReader } from '@zxing/library';
function QRScanner({ onScan, onCancel, log }) {
const videoRef = useRef(null);
const scannerRef = useRef(null);
useEffect(() => {
startScanning();
return () => {
stopScanning();
};
}, []);
const startScanning = async () => {
try {
scannerRef.current = new BrowserQRCodeReader();
log('Starting QR scanner...', 'info');
const videoInputDevices = await scannerRef.current.listVideoInputDevices();
if (videoInputDevices.length === 0) {
log('No camera found', 'error');
return;
}
// Prefer back camera (environment-facing)
let selectedDeviceId = videoInputDevices[0].deviceId;
const backCamera = videoInputDevices.find(device =>
device.label.toLowerCase().includes('back') ||
device.label.toLowerCase().includes('rear') ||
device.label.toLowerCase().includes('environment')
);
if (backCamera) {
selectedDeviceId = backCamera.deviceId;
log('Using back camera', 'info');
} else {
log('Back camera not found, using default', 'info');
}
scannerRef.current.decodeFromVideoDevice(
selectedDeviceId,
videoRef.current,
(result, err) => {
if (result) {
const scannedId = result.getText();
log(`Scanned: ${scannedId}`, 'success');
stopScanning();
onScan(scannedId);
}
}
);
} catch (error) {
log(`Scanner error: ${error.message}`, 'error');
}
};
const stopScanning = () => {
if (scannerRef.current) {
scannerRef.current.reset();
log('Scanner stopped', 'info');
}
};
return (
<div className="scanner-container">
<video ref={videoRef} className="scanner-video" />
<button className="back-button" onClick={onCancel}> Cancel</button>
</div>
);
}
export default QRScanner;