diff --git a/Web/templates/library_table.html b/Web/templates/library_table.html
index a26af68..ad0e00f 100644
--- a/Web/templates/library_table.html
+++ b/Web/templates/library_table.html
@@ -805,74 +805,92 @@
deleteLibraryItem(itemId);
}
- // =========================================================================
- // 3. CORE SCANNER ROUTING ENGINE (QUAGGA2)
- // =========================================================================
- function startScanner(targetCallback) {
- const readerWrap = document.getElementById('scanReaderWrap');
+ async function startScanner(callback = null) {
+ if (scannerRunning) {
+ console.warn("Scanner is already running. Stopping it first...");
+ await stopScanner();
+ }
+
+ activeScannerCallback = callback;
+
+ const scannerWrap = document.querySelector('.library-scan-reader-wrap');
const toggleBtn = document.getElementById('toggleScannerBtn');
- activeScannerCallback = targetCallback;
+ // 1. CRITICAL FIX: Make the container visible BEFORE Quagga initializes
+ // Quagga cannot calculate video dimensions if display is 'none'
+ if (scannerWrap) {
+ scannerWrap.style.display = 'block';
+ }
- if (readerWrap) readerWrap.style.display = 'block';
- setScanStatus('Initializing camera...', 'warn');
-
- const scannerContainer = document.querySelector('.library-scan-reader-wrap');
- scannerContainer.style.display = 'block';
+ setScanStatus('Starte Kamera...', 'warn');
- Quagga.init({
- inputStream: {
- name: "Live",
- type: "LiveStream",
- target: document.querySelector('.library-scan-reader'),
- constraints: {
- width: 640,
- height: 480,
- facingMode: "environment"
+ // 2. Initialize Quagga with a slight delay to allow the DOM to render the block
+ setTimeout(() => {
+ Quagga.init({
+ inputStream: {
+ name: "Live",
+ type: "LiveStream",
+ // This MUST match the inner div where the video should appear
+ target: document.querySelector('.library-scan-reader'),
+ constraints: {
+ width: 640,
+ height: 480,
+ facingMode: "environment" // Prefer back camera on mobile
+ }
},
- },
- decoder: {
- readers: [
- "code_128_reader",
- "ean_reader",
- "code_39_reader",
- "upc_reader",
- "codabar_reader",
- "i2of5_reader"
- ]
- }
- }, function(err) {
- if (err) {
- console.error('Scanner start failed:', err);
- if (readerWrap) readerWrap.style.display = 'none';
- const detail = (err && (err.message || err.name)) ? ` (${err.message || err.name})` : '';
- setScanStatus(`Scanner konnte nicht gestartet werden${detail}`, 'error');
- return;
- }
+ locator: {
+ patchSize: "medium",
+ halfSample: true
+ },
+ decoder: {
+ // Keep only the barcode types you actually use to improve performance
+ readers: ["code_128_reader", "ean_reader", "code_39_reader"]
+ },
+ locate: true
+ }, function(err) {
+ if (err) {
+ // This will finally log the actual error (e.g., NotAllowedError) if permissions fail
+ console.error("Quagga initialization failed:", err);
+ setScanStatus('Kamera-Fehler: ' + (err.name || err), 'error');
- Quagga.start();
- scannerRunning = true;
+ if (scannerWrap) scannerWrap.style.display = 'none';
+ scannerRunning = false;
+ return;
+ }
- if (!targetCallback && toggleBtn) {
- toggleBtn.textContent = 'Scanner stoppen';
- }
- setScanStatus('Scanner aktiv. Jetzt Code scannen.', 'warn');
- });
+ Quagga.start();
+ scannerRunning = true;
+ setScanStatus('Scanner bereit.', 'ok');
+
+ if (toggleBtn) {
+ toggleBtn.textContent = 'Scanner stoppen';
+ }
+ });
+ }, 50);
}
- function stopScanner() {
+ async function stopScanner() {
if (!scannerRunning) return;
- const readerWrap = document.getElementById('scanReaderWrap');
- const toggleBtn = document.getElementById('toggleScannerBtn');
+ try {
+ Quagga.stop();
+ } catch (e) {
+ console.warn("Error stopping Quagga (it may not have been running):", e);
+ }
- Quagga.stop();
scannerRunning = false;
activeScannerCallback = null;
- if (readerWrap) readerWrap.style.display = 'none';
- if (toggleBtn) toggleBtn.textContent = 'Scanner starten';
- setScanStatus('Scanner gestoppt.', 'warn');
+ // Hide the container to free up UI space
+ const scannerWrap = document.querySelector('.library-scan-reader-wrap');
+ if (scannerWrap) {
+ scannerWrap.style.display = 'none';
+ }
+
+ const toggleBtn = document.getElementById('toggleScannerBtn');
+ if (toggleBtn) {
+ toggleBtn.textContent = 'Kamera Scanner'; // Reset button text
+ }
}
async function isStudentCardBarcode(code) {