Kamera-Ersatzweg, Sitzungs-Fortsetzung und Sperre während Erkennung

Drei zusammenhängende Verhaltensfehler rund um main.js behoben:

- Kamerafehler ruft die Dateiauswahl nicht mehr ohne Nutzergeste auf
  (Handy-Browser blockieren das). Stattdessen zeigt scan-view.js eine
  sichtbare, dauerhaft eingeblendete Schaltfläche "Bild auswählen"; der
  Kamera-Hinweis wird nicht mehr von der OCR-Verfügbarkeitsanzeige
  überschrieben.
- Eine beim Start gefundene, gesicherte Sitzung wird nicht mehr
  stillschweigend übernommen, sondern über den neuen Dialog
  askResumeSession (resume-dialog.js, nach dem Muster von
  ambiguous-dialog.js) zur Fortsetzung angeboten. Fortsetzen zeigt den
  tatsächlich letzten Eintrag, Verwerfen löscht den gesicherten Stand.
- Während einer laufenden Erkennung sind Sitzungsliste und Rückgängig-
  Fläche gesperrt; zusätzlich bucht ein durch einen zwischenzeitlichen
  Sitzungswechsel verspätetes Erkennungsergebnis nicht mehr in die neue,
  leere Sitzung (targetSession-Vergleich in processCapture).
- Auch ohne erfasste Stapel bleibt die Sitzungsliste (und damit "Sitzung
  beenden") über eine Schaltfläche in der Stapel-Leiste erreichbar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
vchuser
2026-07-28 18:09:42 +02:00
co-authored by Claude Opus 5
parent 00bc62f546
commit 2e8bd29a33
3 changed files with 179 additions and 20 deletions
+22 -1
View File
@@ -10,6 +10,7 @@ export function renderScanView(root, { onCapture, onUndo, onOpenList, onPickFile
</div>
<div class="status" id="status"></div>
<button class="action capture" id="capture">Modul scannen</button>
<button class="action secondary" id="pick-file-button" hidden>Bild auswählen</button>
<div class="stacks" id="stacks"></div>
<div class="last">
<span id="last">Noch nichts erfasst</span>
@@ -22,9 +23,14 @@ export function renderScanView(root, { onCapture, onUndo, onOpenList, onPickFile
const lastEl = root.querySelector('#last');
const statusEl = root.querySelector('#status');
const fileEl = root.querySelector('#file');
const pickFileButtonEl = root.querySelector('#pick-file-button');
root.querySelector('#capture').addEventListener('click', onCapture);
root.querySelector('#undo').addEventListener('click', onUndo);
// Klick auf die sichtbare Schaltflaeche ist selbst die Nutzergeste, die
// die versteckte Dateiauswahl oeffnen darf - anders als ein Aufruf aus dem
// Code heraus, den Handy-Browser blockieren.
pickFileButtonEl.addEventListener('click', () => fileEl.click());
fileEl.addEventListener('change', () => {
if (fileEl.files[0]) onPickFile(fileEl.files[0]);
fileEl.value = '';
@@ -37,7 +43,12 @@ export function renderScanView(root, { onCapture, onUndo, onOpenList, onPickFile
setStacks(stacks) {
stacksEl.innerHTML = '';
if (stacks.length === 0) {
stacksEl.textContent = 'Noch keine Stapel';
// Auch ohne erfasste Stapel muss die Sitzungsliste erreichbar
// bleiben - darueber liegt der einzige Weg zu "Sitzung beenden".
const button = document.createElement('button');
button.textContent = 'Noch keine Stapel';
button.addEventListener('click', onOpenList);
stacksEl.appendChild(button);
return;
}
for (const stack of stacks) {
@@ -61,5 +72,15 @@ export function renderScanView(root, { onCapture, onUndo, onOpenList, onPickFile
openFilePicker() {
fileEl.click();
},
/**
* Blendet die Ersatzweg-Schaltflaeche "Bild auswaehlen" ein oder aus.
* Wird eingeblendet, wenn die Kamera nicht zur Verfuegung steht, und
* bleibt dann dauerhaft sichtbar.
* @param {boolean} visible
*/
setFilePickerVisible(visible) {
pickFileButtonEl.hidden = !visible;
},
};
}