// Die Übersicht — Laufwerke, Warteschlange, Speicher und Bilanz, Verlauf, // Ereignisse. Und die Dialoge: Sie leben im Zustand DIESES Bereichs, nicht // in der Kachel (5.4.0: ein leerer Takt der Wache räumte sonst Kachel UND // Dialog ab). import { useState } from 'react' import type { HauptStatus } from '../../gemeinsam/nachrichten' import { IconDisc, LAUFENDE_PHASEN } from '../bausteine' import { AendernDialog } from '../dialoge/AendernDialog' import { TitelWahlDialog } from '../dialoge/TitelWahlDialog' import { automatikStopp, titelLesen, type Verbindung } from '../kernverbindung' import { KompressionsKarte } from './KompressionsKarte' import { LaufwerkKachel } from './LaufwerkKachel' import { SpeicherKarte } from './SpeicherKarte' import { VerlaufKarte } from './VerlaufKarte' export function Uebersicht({ verbindung, haupt, systemFehler, aufRohDateien, }: { verbindung: Verbindung haupt: HauptStatus | null systemFehler: string[] aufRohDateien: () => void }) { // Sagt ein Update-Knopf NEIN, steht der Grund daneben (R4) — ein Knopf, // der nichts tut und nichts sagt, ist schlimmer als kein Knopf. const [updateHinweis, setUpdateHinweis] = useState('') const [dialog, setDialog] = useState<{ art: 'titel' | 'aendern'; id: string } | null>(null) const einRipLaeuft = Object.values(verbindung.rips).some((r) => LAUFENDE_PHASEN.includes(r.phase)) return ( <> {systemFehler.length > 0 && (
{systemFehler.map((zeile, i) => (

✗ {zeile}

))}
)} {/* § 6.8: Ein verfügbares Update ist eine SICHTBARE Karte, kein Satz in den Einstellungen. Der Commander musste es am 01.09.2026 suchen — gefunden hat er es nicht. */} {haupt !== null && haupt.update.neueVersion.length > 0 && (
Update verfügbar — Version {haupt.update.neueVersion} du hast {haupt.version}

{haupt.update.text}

{haupt.update.fortschritt >= 0 && !haupt.update.bereit && (
)} {haupt.update.neuerungen.length > 0 && (

Was neu ist

{haupt.update.neuerungen}

)} {haupt.update.bereit && (
… oder einfach nichts tun: Beim nächsten Beenden passiert es von selbst.
)} {updateHinweis.length > 0 &&

{updateHinweis}

}
)}
{verbindung.laufwerke.length === 0 ? (

{verbindung.verbunden ? 'Kein optisches Laufwerk gefunden.' : 'Warte auf den Kern …'}

) : (
{verbindung.laufwerke.map((geraet) => { const ripVorgangId = verbindung.rips[geraet.id]?.vorgangId ?? '' const laeuft = verbindung.vorgaenge?.kompression.laeuft ?? null const wartend = verbindung.vorgaenge?.kompression.wartend ?? [] return ( v.id === ripVorgangId)} kompression={laeuft !== null && laeuft.vorgangId === ripVorgangId ? laeuft : null} wartePlatz={wartend.findIndex((w) => w.vorgangId === ripVorgangId) + 1} automatik={verbindung.automatik[geraet.id]} aufRippen={() => { // Der Nutzer entscheidet selbst — ein Countdown endet. automatikStopp(geraet.id) // Erst die Titel lesen (20-120 s), dann waehlen lassen. setDialog({ art: 'titel', id: geraet.id }) titelLesen(geraet.id) }} aufAendern={() => { automatikStopp(geraet.id) setDialog({ art: 'aendern', id: geraet.id }) }} /> ) })}
)}
{verbindung.vorgaenge !== null && (
)}
{verbindung.vorgaenge !== null && (
)} {dialog !== null && dialog.art === 'titel' && ( l.id === dialog.id)?.typ ?? 'bluray'} stand={verbindung.discTitel[dialog.id]} info={verbindung.discInfos[dialog.id]} einstellungen={verbindung.einstellungen} regel={verbindung.vorgaenge?.regel ?? ''} speicher={verbindung.speicher} schliessen={() => setDialog(null)} /> )} {dialog !== null && dialog.art === 'aendern' && ( setDialog(null)} /> )} {verbindung.meldungen.length > 0 && (
EREIGNISSE
{verbindung.meldungen.map((zeile, i) => (

{zeile}

))}
)} ) }