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 keyboardScanBuffer = '';
let keyboardLastKeyAt = 0; let keyboardLastKeyAt = 0;
const KEYBOARD_SCAN_INTERCHAR_MS = 100; // max time between keystrokes to consider them one scan const KEYBOARD_SCAN_INTERCHAR_MS = 100; // max time between keystrokes to consider them one scan
const physicalScanQueue = [];
let keyboardScanProcessing = false;
let editLibraryState = { let editLibraryState = {
itemId: '', itemId: '',
seriesGroupId: '', seriesGroupId: '',
@@ -1188,38 +1190,49 @@
// Only active when explicitly enabled // Only active when explicitly enabled
if (!keyboardScannerEnabled) return; 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(); const now = Date.now();
// If Enter/Return pressed -> finalize buffer // If Enter/Return pressed -> finalize buffer
if (e.key === 'Enter') { if (e.key === 'Enter') {
e.preventDefault();
const code = keyboardScanBuffer.trim(); const code = keyboardScanBuffer.trim();
keyboardScanBuffer = ''; keyboardScanBuffer = '';
keyboardLastKeyAt = 0; keyboardLastKeyAt = 0;
if (!code) return; if (!code) return;
// Process exactly like a camera scan - centralized logic handles the rest! // Scanner keystrokes must not be submitted into the focused form field.
handleScanSuccess(code); processPhysicalScan(code);
return; return;
} }
// Only accept common printable characters; ignore modifier keys // Physical scanners in this workflow emit numeric codes only.
if (e.key.length === 1) { if (e.key.length === 1 && /\d/.test(e.key)) {
// If time gap too big, start new buffer // If time gap too big, start new buffer
if (keyboardLastKeyAt && (now - keyboardLastKeyAt) > KEYBOARD_SCAN_INTERCHAR_MS) { if (keyboardLastKeyAt && (now - keyboardLastKeyAt) > KEYBOARD_SCAN_INTERCHAR_MS) {
keyboardScanBuffer = ''; keyboardScanBuffer = '';
} }
keyboardScanBuffer += e.key; keyboardScanBuffer += e.key;
keyboardLastKeyAt = now; 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(); 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; const scannedCode = typeof normalizeScannedCode === "function" ? normalizeScannedCode(decodedText) : decodedText;
if (!scannedCode) return; if (!scannedCode) return;
@@ -1235,26 +1248,27 @@
// 1. Modus: Nur Rückgabe // 1. Modus: Nur Rückgabe
if (mode === 'return_only') { if (mode === 'return_only') {
returnByCode(scannedCode); await returnByCode(scannedCode);
return; return;
} }
// 2. Modus: Nur Ausweis // 2. Modus: Nur Ausweis
if (mode === 'card_only') { if (mode === 'card_only') {
setActiveStudentCard(scannedCode); 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; return;
} }
// 3. Modus: Schnellmodus (1x Ausweis, 1x Buch) // 3. Modus: Schnellmodus (1x Ausweis, 1x Buch)
if (mode === 'quick_toggle') { if (mode === 'quick_toggle') {
processQuickToggleScan(scannedCode); await processQuickToggleScan(scannedCode);
return; return;
} }
// 4. Modus: Dauermodus (1x Ausweis, Nx Bücher) // 4. Modus: Dauermodus (1x Ausweis, Nx Bücher)
if (mode === 'continuous') { if (mode === 'continuous') {
processContinuousScan(scannedCode); await processContinuousScan(scannedCode);
return; return;
} }
} }
@@ -1341,7 +1355,8 @@
// 2. Wenn kein Ausweis gesetzt ist, wird der Code als Ausweis interpretiert // 2. Wenn kein Ausweis gesetzt ist, wird der Code als Ausweis interpretiert
if (!activeStudentCardId) { if (!activeStudentCardId) {
setActiveStudentCard(scannedCode); 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; return;
} }