feat: Implement hybrid barcode scanner with real-time camera support and image upload fallback

This commit is contained in:
2026-06-01 11:55:28 +02:00
parent 20e5d3bb9a
commit 997c7b42d5
7 changed files with 626 additions and 144 deletions
+32 -20
View File
@@ -413,7 +413,10 @@
</div>
<div class="qr-container">
<button id="scanButton" class="scan-button" aria-controls="qr-reader" aria-expanded="false">Barcode scannen</button>
<div id="qr-reader"></div>
<div id="qr-reader" style="display: none;">
<video id="qr-reader-video" playsinline style="width: 100%; max-width: 500px; border-radius: 8px; display: none;"></video>
<canvas id="qr-reader-canvas" style="display: none;"></canvas>
</div>
</div>
<div id="table-view-header" class="table-view-header" aria-hidden="true">
<span>Name</span>
@@ -526,7 +529,8 @@
window.isDebug = false; // Set to true only for development environment
</script>
<script src="https://unpkg.com/html5-qrcode@2.0.9/dist/html5-qrcode.min.js"></script>
<script src="https://unpkg.com/@zxing/library@latest/umd/index.min.js"></script>
<script src="/static/js/scanner.js"></script>
<script>
// Global state
const highlightItemId = (window.serverVars && window.serverVars.highlightItemId && window.serverVars.highlightItemId !== 'null')
@@ -539,7 +543,7 @@
document.addEventListener('DOMContentLoaded', function() {
const scanButton = document.getElementById('scanButton');
const qrReader = document.getElementById('qr-reader');
let html5QrcodeScanner = null;
let hybridScanner = null;
if (!scanButton || !qrReader) return;
@@ -553,28 +557,36 @@
if (qrReader.style.display !== 'block') {
qrReader.style.display = 'block';
html5QrcodeScanner = new Html5QrcodeScanner(
'qr-reader', { fps: 10, qrbox: 250 }
);
html5QrcodeScanner.render((decodedText) => {
html5QrcodeScanner.clear();
qrReader.style.display = 'none';
// Put scanned code into the search box and trigger search
const searchInput = document.getElementById('code-search');
if (searchInput) {
searchInput.value = decodedText;
searchByCode();
}
hybridScanner = new HybridScanner({
videoId: 'qr-reader-video',
canvasId: 'qr-reader-canvas',
formats: ['QR_CODE', 'CODE_128', 'EAN_13', 'EAN_8', 'CODE_39'],
fps: 10,
facingMode: 'environment',
onSuccess: function(decodedText) {
hybridScanner.stop();
qrReader.style.display = 'none';
// Put scanned code into the search box and trigger search
const searchInput = document.getElementById('code-search');
if (searchInput) {
searchInput.value = decodedText;
searchByCode();
}
setScannerUi(false);
setScannerUi(false);
},
onError: function(error) {
console.error('Scanner error:', error);
}
});
hybridScanner.start();
setScannerUi(true);
} else {
if (html5QrcodeScanner) {
html5QrcodeScanner.clear();
if (hybridScanner) {
hybridScanner.stop();
hybridScanner = null;
}
qrReader.style.display = 'none';
setScannerUi(false);