Compare commits

..

3 Commits

Author SHA1 Message Date
Aiirondev_dev c4b3850369 Merge remote-tracking branch 'origin/main'
Release Inventarsystem / release-docker (push) Successful in 2m15s
2026-08-16 20:06:12 +02:00
Aiirondev_dev 28e9487fe1 Improved implementation of the Klassen processing to havbe the already existing ones in a dropdown. 2026-08-16 20:06:05 +02:00
Aiirondev_dev fe075938d7 resolve camara scan stream failure
Release Inventarsystem / release-docker (push) Successful in 2m15s
2026-08-16 15:57:12 +02:00
2 changed files with 79 additions and 55 deletions
+71 -53
View File
@@ -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) {
+8 -2
View File
@@ -293,9 +293,15 @@
</div>
<div class="form-group">
<label for="class_name">Klasse</label>
<input type="text" id="class_name" name="class_name"
<input type="text" id="class_name" name="class_name" list="class_list"
value="{{ form_data.get('class_name', '') }}"
placeholder="z.B. 10A">
placeholder="z.B. 10A (Tippen oder Auswählen)">
<datalist id="class_list">
{% for cls in available_classes %}
<option value="{{ cls }}">
{% endfor %}
</datalist>
</div>
</div>