changes to the physical scanner processing
Release Inventarsystem / release-docker (push) Successful in 12m48s

This commit is contained in:
2026-09-08 18:19:40 +02:00
parent b16ad56b98
commit 0114fec928
+30 -15
View File
@@ -843,6 +843,8 @@
let keyboardScanBuffer = '';
let keyboardLastKeyAt = 0;
const KEYBOARD_SCAN_INTERCHAR_MS = 100; // max time between keystrokes to consider them one scan
const physicalScanQueue = [];
let keyboardScanProcessing = false;
let editLibraryState = {
itemId: '',
seriesGroupId: '',
@@ -1188,38 +1190,49 @@
// Only active when explicitly enabled
if (!keyboardScannerEnabled) return;
// Ignore if focus is in an input/textarea/contenteditable to avoid interfering with typing
const active = document.activeElement;
if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)) return;
const now = Date.now();
// If Enter/Return pressed -> finalize buffer
if (e.key === 'Enter') {
e.preventDefault();
const code = keyboardScanBuffer.trim();
keyboardScanBuffer = '';
keyboardLastKeyAt = 0;
if (!code) return;
// Process exactly like a camera scan - centralized logic handles the rest!
handleScanSuccess(code);
// Scanner keystrokes must not be submitted into the focused form field.
processPhysicalScan(code);
return;
}
// Only accept common printable characters; ignore modifier keys
if (e.key.length === 1) {
// Physical scanners in this workflow emit numeric codes only.
if (e.key.length === 1 && /\d/.test(e.key)) {
// If time gap too big, start new buffer
if (keyboardLastKeyAt && (now - keyboardLastKeyAt) > KEYBOARD_SCAN_INTERCHAR_MS) {
keyboardScanBuffer = '';
}
keyboardScanBuffer += e.key;
keyboardLastKeyAt = now;
// Prevent default so scanner input doesn't accidentally move focus or trigger shortcuts
// Prevent default so scanner input is captured even while an input has focus.
e.preventDefault();
}
}
function handleScanSuccess(decodedText) {
async function processPhysicalScan(code) {
physicalScanQueue.push(code);
if (keyboardScanProcessing) return;
keyboardScanProcessing = true;
try {
while (physicalScanQueue.length > 0) {
await handleScanSuccess(physicalScanQueue.shift());
}
} finally {
keyboardScanProcessing = false;
}
}
async function handleScanSuccess(decodedText) {
const scannedCode = typeof normalizeScannedCode === "function" ? normalizeScannedCode(decodedText) : decodedText;
if (!scannedCode) return;
@@ -1235,26 +1248,27 @@
// 1. Modus: Nur Rückgabe
if (mode === 'return_only') {
returnByCode(scannedCode);
await returnByCode(scannedCode);
return;
}
// 2. Modus: Nur Ausweis
if (mode === 'card_only') {
setActiveStudentCard(scannedCode);
setScanStatus(`Ausweis gesetzt: ${activeStudentCardId}`, 'ok');
setScanStatus(`Ausweis gesetzt: ${activeStudentCardId}. Bitte den nächsten Ausweis scannen.`, 'ok');
showSmallConfirm(`Ausweis erkannt: ${activeStudentCardId}. Sie können den nächsten scannen.`, 'ok');
return;
}
// 3. Modus: Schnellmodus (1x Ausweis, 1x Buch)
if (mode === 'quick_toggle') {
processQuickToggleScan(scannedCode);
await processQuickToggleScan(scannedCode);
return;
}
// 4. Modus: Dauermodus (1x Ausweis, Nx Bücher)
if (mode === 'continuous') {
processContinuousScan(scannedCode);
await processContinuousScan(scannedCode);
return;
}
}
@@ -1341,7 +1355,8 @@
// 2. Wenn kein Ausweis gesetzt ist, wird der Code als Ausweis interpretiert
if (!activeStudentCardId) {
setActiveStudentCard(scannedCode);
setScanStatus(`Ausweis gesetzt: ${activeStudentCardId}`, 'ok');
setScanStatus(`Ausweis gesetzt: ${activeStudentCardId}. Bitte den nächsten Mediencode scannen.`, 'ok');
showSmallConfirm(`Ausweis erkannt: ${activeStudentCardId}. Bitte jetzt den nächsten Mediencode scannen.`, 'ok');
return;
}