feat(v5): 5.5.0 — Kern und Oberfläche aufgeteilt, Übersicht und Einstellungen neu, Erst-Einrichtung mit Poster-Kulisse
Commander-Wünsche vom 02.09.2026 vor der Freigabe von 5.4.0 (die deshalb nie veröffentlicht wurde): Kern: kern/index.ts ist nur noch Bootstrap und Router; Dienste in kern/dienste/ (Einstellungen, Werkzeuge, Laufwerke, Erkennung, Vorgänge, Speicher, Benachrichtigung, Automatik), Kontext in kern/kontext.ts, Protokoll-Datei in gemeinsam/protokoll.ts, Platz-Rechnung in gemeinsam/platz.ts. Oberfläche: fenster/App.tsx ist nur noch der Rahmen; bausteine.tsx, dialoge/, uebersicht/ (LaufwerkKachel, KompressionsKarte, SpeicherKarte, VerlaufKarte), einstellungen/ (Karten je Funktion, SprachAuswahl), einrichtung/ (ErstEinrichtung, PosterHintergrund). Neu: Bibliothek weg, dafür Verlauf; Speicher-und-Bilanz-Karte (statfs); LED-Fußleiste; MakeMKV-Kopf in die Einstellungen; Sprach-Chips mit Dropdown statt Allgemeinem Preset; Karten Automatik/Benachrichtigung/Allgemein/Update; Durchsuchen bei Werkzeugen; Arbeitsordner lokal (Encode dort, dann in die Ablage); Platz-Prüfung vor dem Rip (Dialog und Kern); Automatik mit Countdown; Serien-Merker über Discs; Rettungs-Abbild mit Nullen nur nach gesehenen Lesefehlern (kern/rip/rettung.ts, Phase rettet, iso:-Quelle); Warteschlange pausieren; Discord/Telegram-Benachrichtigung; Protokoll-Datei je Tag; Fensterlage 80 % mittig, gemerkt; Erst-Einrichtung in acht Schritten vor dem Poster-Grid. Beweise: 413 Tests (neu: speicher, benachrichtigung, automatik, rettung, fensterlage, protokoll, kleinkram-550), drei Typprüfungen, Klick-Beweis mit 29 Schritten inklusive Erst-Einrichtung (zweiter Start mit RIPPY_START_BEREICH=einrichtung), Bilder beweise/klick/01…09. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
6678c81592
commit
3dc6798c79
@@ -8,8 +8,8 @@
|
||||
// Laufwerksliste: Sie ändert sich NUR durch eine neue Liste vom Kern.
|
||||
import {
|
||||
istKernNachricht,
|
||||
type AutomatikStand,
|
||||
type BeschaffungStand,
|
||||
type BibliothekEintrag,
|
||||
type DiscInfoStand,
|
||||
type FensterNachricht,
|
||||
type GeraeteInfo,
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type RipAuftragOptionen,
|
||||
type RipAuftragTitel,
|
||||
type RipStatus,
|
||||
type SpeicherStand,
|
||||
type TitelStand,
|
||||
type VorgaengeStand,
|
||||
type WerkzeugAuskunft,
|
||||
@@ -46,7 +47,6 @@ export interface Verbindung {
|
||||
ripProtokoll: Record<string, string[]>
|
||||
einstellungen: Record<string, string>
|
||||
werkzeuge: WerkzeugAuskunft | null
|
||||
bibliothek: BibliothekEintrag[]
|
||||
schluessel: {
|
||||
quelle: string
|
||||
angenommen: boolean | null
|
||||
@@ -63,6 +63,12 @@ export interface Verbindung {
|
||||
vorgaenge: VorgaengeStand | null
|
||||
/** Was das Windows-Protokoll je Laufwerk sagt (5.4.0) — bleibt stehen. */
|
||||
gesundheit: Record<string, LaufwerkBericht>
|
||||
/** Freier Platz an Arbeitsordner und Ablage (5.5.0). */
|
||||
speicher: SpeicherStand | null
|
||||
/** Automatik-Countdown je Laufwerk (5.5.0). */
|
||||
automatik: Record<string, AutomatikStand>
|
||||
/** Poster für den Hintergrund der Erst-Einrichtung (5.5.0). */
|
||||
poster: string[]
|
||||
/** Kurze Ereigniszeilen (neueste zuerst): Disc rein/raus, Auswurf, Fehler. */
|
||||
meldungen: string[]
|
||||
}
|
||||
@@ -71,7 +77,7 @@ type Horcher = (stand: Verbindung) => void
|
||||
|
||||
const MAX_MELDUNGEN = 30
|
||||
|
||||
const stand: Verbindung = {
|
||||
export const LEERE_VERBINDUNG: Verbindung = {
|
||||
verbunden: false,
|
||||
kern: null,
|
||||
pongLatenzMs: null,
|
||||
@@ -84,13 +90,17 @@ const stand: Verbindung = {
|
||||
ripProtokoll: {},
|
||||
einstellungen: {},
|
||||
werkzeuge: null,
|
||||
bibliothek: [],
|
||||
schluessel: null,
|
||||
beschaffung: null,
|
||||
vorgaenge: null,
|
||||
gesundheit: {},
|
||||
speicher: null,
|
||||
automatik: {},
|
||||
poster: [],
|
||||
meldungen: [],
|
||||
}
|
||||
|
||||
const stand: Verbindung = { ...LEERE_VERBINDUNG }
|
||||
const horcher = new Set<Horcher>()
|
||||
let gestartet = false
|
||||
let port: MessagePort | null = null
|
||||
@@ -103,8 +113,9 @@ function kopie(): Verbindung {
|
||||
discInfos: { ...stand.discInfos },
|
||||
vorschlaege: { ...stand.vorschlaege },
|
||||
einstellungen: { ...stand.einstellungen },
|
||||
bibliothek: [...stand.bibliothek],
|
||||
gesundheit: { ...stand.gesundheit },
|
||||
automatik: { ...stand.automatik },
|
||||
poster: [...stand.poster],
|
||||
meldungen: [...stand.meldungen],
|
||||
}
|
||||
}
|
||||
@@ -140,6 +151,8 @@ function kernNachricht(nachricht: KernNachricht): void {
|
||||
meldung(`Disc erkannt in ${ereignis.geraet.name} — ${ereignis.geraet.typ}`)
|
||||
} else if (ereignis.art === 'disc-entnommen') {
|
||||
meldung(`Disc entnommen aus ${ereignis.geraet.name}`)
|
||||
const { [ereignis.geraet.id]: _weg, ...rest } = stand.automatik
|
||||
stand.automatik = rest
|
||||
} else if (ereignis.art === 'laufwerk-weg') {
|
||||
meldung(`Laufwerk ${ereignis.id}: nicht mehr da`)
|
||||
}
|
||||
@@ -184,9 +197,6 @@ function kernNachricht(nachricht: KernNachricht): void {
|
||||
case 'werkzeuge':
|
||||
stand.werkzeuge = nachricht.auskunft
|
||||
break
|
||||
case 'bibliothek':
|
||||
stand.bibliothek = nachricht.eintraege
|
||||
break
|
||||
case 'schluessel-status':
|
||||
stand.schluessel = nachricht.stand
|
||||
if (nachricht.stand.angenommen === false) meldung(`⚠ MakeMKV-Schlüssel: ${nachricht.stand.text}`)
|
||||
@@ -207,9 +217,18 @@ function kernNachricht(nachricht: KernNachricht): void {
|
||||
meldung(`Laufwerk ${nachricht.id}: ${nachricht.bericht.text}`)
|
||||
}
|
||||
break
|
||||
case 'speicher':
|
||||
stand.speicher = nachricht.stand
|
||||
break
|
||||
case 'automatik':
|
||||
stand.automatik = { ...stand.automatik, [nachricht.stand.id]: nachricht.stand }
|
||||
break
|
||||
case 'poster-vorschau':
|
||||
stand.poster = nachricht.pfade
|
||||
break
|
||||
case 'rip-status': {
|
||||
stand.rips = { ...stand.rips, [nachricht.status.id]: nachricht.status }
|
||||
const laeuft = ['liest-info', 'rippt', 'komprimiert', 'legt-ab'].includes(nachricht.status.phase)
|
||||
const laeuft = ['liest-info', 'rettet', 'rippt', 'komprimiert', 'legt-ab'].includes(nachricht.status.phase)
|
||||
if (laeuft && stand.ripStart[nachricht.status.id] === undefined) {
|
||||
stand.ripStart = { ...stand.ripStart, [nachricht.status.id]: Date.now() }
|
||||
// Ein NEUER Vorgang beginnt — das Protokoll des alten weicht.
|
||||
@@ -257,8 +276,8 @@ function portAnnehmen(neuerPort: MessagePort): void {
|
||||
senden({ art: 'ping', zeit: Date.now() })
|
||||
senden({ art: 'einstellungen-laden' })
|
||||
senden({ art: 'werkzeuge-laden' })
|
||||
senden({ art: 'bibliothek-laden' })
|
||||
senden({ art: 'vorgaenge-laden' })
|
||||
senden({ art: 'speicher-laden' })
|
||||
melden()
|
||||
}
|
||||
|
||||
@@ -324,6 +343,10 @@ export function ripAbbrechen(id: string): void {
|
||||
anKern({ art: 'rip-abbruch', id }, `Rip-Abbruch ${id}`)
|
||||
}
|
||||
|
||||
export function rettungStarten(id: string): void {
|
||||
anKern({ art: 'rettung-start', id }, `Rettungs-Abbild ${id}`)
|
||||
}
|
||||
|
||||
export function metadatenSuchen(id: string, text: string): void {
|
||||
senden({ art: 'metadaten-suchen', id, text })
|
||||
}
|
||||
@@ -372,3 +395,28 @@ export function fremdenOrdnerLoeschen(ordner: string): void {
|
||||
export function laufwerkPruefen(id: string): void {
|
||||
anKern({ art: 'laufwerk-pruefen', id }, `Laufwerk ${id} prüfen`)
|
||||
}
|
||||
|
||||
// ── 5.5.0 ───────────────────────────────────────────────────────────────
|
||||
export function kompressionPause(an: boolean): void {
|
||||
anKern({ art: 'kompression-pause', an }, an ? 'Kompression anhalten' : 'Kompression weiter')
|
||||
}
|
||||
|
||||
export function automatikStopp(id: string): void {
|
||||
senden({ art: 'automatik-stopp', id })
|
||||
}
|
||||
|
||||
export function automatikJetzt(id: string): void {
|
||||
anKern({ art: 'automatik-jetzt', id }, 'Automatik jetzt')
|
||||
}
|
||||
|
||||
export function benachrichtigungTesten(): void {
|
||||
anKern({ art: 'benachrichtigung-testen' }, 'Testnachricht')
|
||||
}
|
||||
|
||||
export function posterLaden(): void {
|
||||
senden({ art: 'poster-laden' })
|
||||
}
|
||||
|
||||
export function speicherLaden(): void {
|
||||
senden({ art: 'speicher-laden' })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user