feat(ui): Laufende Disc-Erkennung ist jetzt sichtbar
Ampel / ampel (push) Successful in 1m26s

Commander: „das die disc erkennung noch läuft muss sichtbar sein"

Er hat recht, und die Wartezeit ist gemessen: `makemkvcon info` laeuft an
einer Blu-ray in seine 120-Sekunden-Grenze (Disc nach 119 s erkannt). Zwei
Minuten, in denen NICHTS zu sehen war — weder die Disc noch ein Hinweis. Das
sah aus wie ein leeres Laufwerk, also wie ein Fehler.

## Der Zustand war da, er wurde nur weggeworfen

`_auto_prescan` legt beim Start `{"_laeuft": True}` in den Vorrat.
`laufwerke_mit_disc` liess so einen Eintrag KOMPLETT weg — damit keine
halbfertige Disc-Karte mit „Wird erkannt…" als Titel und einem „Rippen
starten"-Knopf erscheint. Richtig gedacht, falsch geloest.

Jetzt gibt es ein eigenes Feld `disc_wird_erkannt`. Die Oberflaeche kann
„wird gelesen" zeigen, ohne einen Titel zu behaupten, den es noch nicht gibt:
eine Karte mit Spinner ueber der Laufwerksliste und eine eigene Zeile im
Server-Status.

## Und der Haken dahinter

Genau waehrend der Erkennung ist die Laufwerks-Auskunft am teuersten:
makemkvcon haelt das Laufwerk, und `device_info` wartet mit. Gemessen:

    /devices waehrend des Scans     14,0 s
    Zeitgrenze des Schnappschusses   5,0 s   ->  devices = None

`None` heisst „konnte nicht nachsehen", und die Oberflaeche behaelt dann
ihren Stand — nach einem frischen Laden also GAR NICHTS. Die Anzeige waere
ausgerechnet in ihrer eigenen Phase leer geblieben.

`laufwerke_notdurft()` antwortet deshalb ohne ioctl: letzter bekannter Stand
plus die aktuelle Erkennungs-Marke aus dem Vorrat. Beim Kaltstart wenigstens
der Laufwerksname — die LISTE der Laufwerke ist billig, teuer ist erst das
Anfassen. Nichts wird erfunden: kein Typ, kein Modell. Und wer noch nie
erfolgreich gelesen hat, schweigt weiter mit `None`.

Im Browser gegengeprueft: „Disc wird gelesen — Laufwerk G:" mit Spinner,
Server-Status „Disc wird gelesen — das dauert bis zu zwei Minuten", danach
der richtige Titel.

859 Tests gruen, ruff sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-29 15:12:35 +02:00
co-authored by Claude Opus 5
parent dbb934d146
commit e67138e9ca
4 changed files with 244 additions and 3 deletions
@@ -36,6 +36,8 @@ interface Device {
serial?: string
model?: string
disc?: DiscInfo
/** Erkennung laeuft — noch kein Titel, aber auch kein leeres Laufwerk. */
disc_wird_erkannt?: boolean
}
function posterUrl(disc?: DiscInfo): string | null {
@@ -179,6 +181,34 @@ export default function DeviceDiscovery() {
</CardHeader>
<CardContent>
{/*
Die Erkennung LÄUFT NOCH — das muss man sehen.
Commander 29.08.2026: „das die disc erkennung noch läuft muss
sichtbar sein". An einer Blu-ray dauert sie rund zwei Minuten
(`makemkvcon info` läuft in seine 120-Sekunden-Grenze; gemessen:
Disc nach 119 s erkannt). Vorher war in dieser Zeit NICHTS zu
sehen — weder die Disc noch ein Hinweis. Das sah aus wie ein
leeres Laufwerk, also wie ein Fehler.
*/}
{devices.filter(d => d.disc_wird_erkannt).map(device => (
<div
key={`erkennung-${device.id}`}
className="mb-6 rounded-2xl border border-slate-700 bg-slate-900/60 px-5 py-4 flex items-center gap-3"
>
<RefreshCw size={18} className="animate-spin text-amber-400 flex-shrink-0" />
<div>
<p className="font-semibold text-slate-200">
Disc wird gelesen {device.name}
</p>
<p className="text-xs text-slate-400 mt-0.5">
Rippy liest Titel und Laufzeiten von der Disc. Das dauert bis
zu zwei Minuten; danach steht hier, was drin ist.
</p>
</div>
</div>
))}
{/* Disc-Karte: WAS liegt gerade im Laufwerk (Auto-Pre-Scan) */}
{devices.filter(d => d.status === 'ready' && d.disc).map(device => (
<div
+10 -1
View File
@@ -66,6 +66,9 @@ interface LaufwerkLive {
id: string
status: string
disc?: { title?: string, year?: number | null, disc_type?: string }
/** Die Erkennung laeuft noch — es gibt noch keinen Titel, aber auch kein
* leeres Laufwerk. Dauert an einer Blu-ray rund zwei Minuten. */
disc_wird_erkannt?: boolean
}
// Ein Ablageziel aus GET /storage-targets — Verzeichnisse unter /app/media
@@ -329,7 +332,13 @@ export default function Dashboard() {
: 'Rip läuft (MakeMKV, verlustfrei)')
: discImLaufwerk
? 'Disc erkannt — wartet auf „Rippen starten"'
: 'Bereit — kein Datenträger im Laufwerk'
// Zwischen „Disc eingelegt" und „erkannt" liegen rund zwei Minuten
// (makemkvcon info laeuft in seine 120-Sekunden-Grenze). Ohne diese
// Zeile stand dort „kein Datentraeger", und das sah aus wie ein
// Fehler (Commander 29.08.2026).
: laufwerke.some(l => l.disc_wird_erkannt)
? 'Disc wird gelesen — das dauert bis zu zwei Minuten'
: 'Bereit — kein Datenträger im Laufwerk'
const filteredJobs = jobs.filter(j => {
if (activeTab === 'active') return j.status === 'processing' || j.status === 'transcoding'