import SwiftUI import FlixyDesign /// Was auf dem Fernseher zu sehen ist. /// /// **Nur der Zustandswechsel, keine Navigation.** Das ist alles, was von /// `RootView` auf tvOS übrig bleibt: dort sind es 556 Zeilen Seitenleiste, /// Tab-Anpassung, gemessene Statusleistenhöhe und Mini-Player-Übergang, und /// nichts davon gibt es hier. Deshalb eine eigene Datei und kein `#if` in der /// bestehenden — ein `#if` wäre kein Zweig gewesen, sondern ein zweiter Rumpf /// in derselben Datei. struct TVRootView: View { @Environment(FlixySession.self) private var session @Environment(PlaybackCoordinator.self) private var playback var body: some View { ZStack { Color.flixyCanvas.ignoresSafeArea() switch session.phase { case .launching: ProgressView() case .signedOut, .authenticating, .choosingServer: // Plex bietet die erste Fassung nicht an: die Anmeldung dort // läuft über ein Browserfenster, und das gibt es auf tvOS // nicht. Alle drei Zustände führen deshalb zur // Jellyfin-Anmeldung. TVSignInView() case .connecting(let name): verbinden(mit: name) case .failed(let meldung): fehlgeschlagen(meldung) case .ready: TVHomeView() } } .task { await session.restore() } // **Hier und nicht in der Startseite.** Von einer Kachel, aus dem // Aufmacher und aus der Detailseite wird dasselbe gestartet; läge der // Übergang weiter innen, gäbe es ihn dreimal. // // `fullScreenCover(item:)` gibt es auf tvOS seit 14, und // `PlaybackRequest` ist bereits `Identifiable`. .fullScreenCover( item: Binding( get: { playback.request }, set: { if $0 == nil { playback.close() } } ) ) { request in TVPlayerScreen(request: request) } } private func verbinden(mit name: String) -> some View { VStack(spacing: FlixySpacing.regular) { ProgressView() Text(name).font(.flixyRowHeader).foregroundStyle(.white) } } private func fehlgeschlagen(_ meldung: String) -> some View { VStack(spacing: FlixySpacing.regular) { Text(meldung).font(.flixyBody).foregroundStyle(.white) HStack(spacing: FlixySpacing.regular) { Button("action.retry") { Task { await session.retry() } } Button("action.signOut") { session.signOut() } } } .frame(maxWidth: 900) } }