feat(v5): Oberflaeche 5.4.0 — Sprachen je Titel, Staffel/Folge, Vorschau, Kino-Banner v2, Roh-Dateien, Warteschlange

WAS: Der Auswahl-Dialog zeigt je Titel die gemessenen Ton- und
Untertitelspuren als Chips (vorbelegt aus der Einstellung, sonst alles,
was der Titel hat), Felder fuer Staffel und erste Folge, und zwei Zeilen
Zielpfad-Vorschau (gemeinsam/ablagepfad.ts — dieselbe Namensregel wie der
Kern). Die Dialoge leben jetzt im App-Zustand statt in der Kachel: ein
leerer Takt der Wache raeumte sonst Kachel UND Dialog ab.
Die Laufwerks-Kachel ist das Kino-Banner v2: Logo statt Text, Tagline,
Zeile Jahr/FSK/Laufzeit/Genre/Bewertung, Darsteller-Streifen, die
Hinweise der Nachpruefung, ein Knopf „Laufwerk pruefen" mit Urteil aus
dem Windows-Protokoll, und nach dem Rip der Stand der Kompression.
Neu in der Uebersicht: die Kompressions-Karte (laeuft/wartet, Abbruch).
Neu in den Einstellungen: „Roh-Dateien" mit Regel, Belegung, jedem
Vorgang (Neu komprimieren mit Preset, Roh loeschen) und Ordnern ohne
Vorgang; der Auswurf-Schalter in „Ablage"; der Datenbank-Pfad unter
„Programm". Das Haupt zeigt die Kompression in Taskleiste und Tray und
laesst Updates auch auf sie warten. Playwright kommt als Bau-Werkzeug
dazu (Commander-Ja nach Regel B; MIT, wird nicht ausgeliefert).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-01 22:13:22 +02:00
co-authored by Claude Fable 5.1
parent 3f7f962dff
commit e3ce8220f1
7 changed files with 1046 additions and 171 deletions
+46 -17
View File
@@ -94,6 +94,12 @@ function start(): void {
}
} else if (nachricht.art === 'installer-starten') {
void installerStarten(nachricht.pfad)
} else if (nachricht.art === 'vorgaenge') {
// 5.4.0: Die Kompression läuft OHNE Laufwerk weiter — Updates
// warten auch auf sie, und die Taskleiste zeigt ihren Fortschritt.
kompressionVerarbeiten(nachricht.stand.kompression.laeuft)
} else if (nachricht.art === 'kompression-ergebnis' && !smokeModus) {
toast(nachricht.ok ? 'Rippy ist fertig' : 'Rippy: Kompression fehlgeschlagen', `${nachricht.titel}: ${nachricht.text}`)
} else if (nachricht.art === 'disc-info' && nachricht.info.titel.length > 0 && !smokeModus) {
// Windows-Toast beim Erkennen (§ 7) — Klick holt das Fenster hoch.
toast(
@@ -109,6 +115,43 @@ function start(): void {
smokeModus,
)
// Die laufende Kompression (5.4.0) — ein eigener Schlüssel in den
// aktiven Vorgängen, weil sie an keinem Laufwerk mehr hängt.
const KOMPRESSION = 'kompression'
let kompressionStand: { titel: string; prozent: number } | null = null
function kompressionVerarbeiten(laeuft: { titel: string; prozent: number } | null): void {
kompressionStand = laeuft === null ? null : { titel: laeuft.titel, prozent: laeuft.prozent }
if (laeuft === null) aktiveVorgaenge.delete(KOMPRESSION)
else aktiveVorgaenge.add(KOMPRESSION)
anzeigeAktualisieren()
}
/** Taskleiste und Tray aus dem, was gerade läuft: ein Rip zuerst, sonst
* die Kompression — sonst nichts. */
let letzterRip: Extract<KernNachricht, { art: 'rip-status' }>['status'] | null = null
function anzeigeAktualisieren(): void {
const rip = letzterRip !== null && letzterRip.phase === 'rippt' ? letzterRip : null
if (fenster !== null && !fenster.isDestroyed()) {
if (rip !== null && rip.prozent >= 0) {
fenster.setProgressBar(rip.prozent / 100)
} else if (letzterRip !== null && letzterRip.phase === 'fehler') {
fenster.setProgressBar(1, { mode: 'error' })
} else if (kompressionStand !== null && kompressionStand.prozent >= 0) {
fenster.setProgressBar(kompressionStand.prozent / 100)
} else {
fenster.setProgressBar(-1)
}
}
if (rip !== null) {
trayHinweis(`rippt Laufwerk ${rip.id}${rip.prozent >= 0 ? ` (${rip.prozent} %)` : ''}`)
} else if (kompressionStand !== null) {
trayHinweis(`komprimiert „${kompressionStand.titel}"${kompressionStand.prozent >= 0 ? ` (${kompressionStand.prozent} %)` : ''}`)
} else {
trayHinweis('')
}
}
// § 7: Toasts, Taskleisten-Fortschritt und Tray-Zustand aus dem
// Rip-Status — die Information, die man will, ohne das Fenster zu öffnen.
function ripStatusVerarbeiten(status: Extract<KernNachricht, { art: 'rip-status' }>['status']): void {
@@ -117,25 +160,11 @@ function start(): void {
} else {
aktiveVorgaenge.delete(status.id)
}
if (fenster !== null && !fenster.isDestroyed()) {
if ((status.phase === 'rippt' || status.phase === 'komprimiert') && status.prozent >= 0) {
fenster.setProgressBar(status.prozent / 100)
} else if (status.phase === 'fehler') {
fenster.setProgressBar(1, { mode: 'error' })
} else {
fenster.setProgressBar(-1)
}
}
if (status.phase === 'rippt') {
trayHinweis(`rippt Laufwerk ${status.id}${status.prozent >= 0 ? ` (${status.prozent} %)` : ''}`)
} else if (status.phase === 'komprimiert') {
trayHinweis(`komprimiert Laufwerk ${status.id}${status.prozent >= 0 ? ` (${status.prozent} %)` : ''}`)
} else {
trayHinweis('')
}
letzterRip = status
anzeigeAktualisieren()
if (smokeModus) return
if (status.phase === 'fertig') {
toast('Rippy ist fertig', status.text)
toast('Rippy: Rip fertig', status.text)
} else if (status.phase === 'fehler') {
toast('Rippy: Fehler', status.text)
}