changes to the physical scanner processing
Release Inventarsystem / release-docker (push) Successful in 12m48s
Release Inventarsystem / release-docker (push) Successful in 12m48s
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user