Files
Flaro/FlixyTV/FlixyTVApp.swift
T
ScarriffleandClaude Opus 5 1552e5f2b9 Am Fernseher steht der Code vorn, nicht das Passwort
Schritt drei: anmelden. Die Oberfläche ist neu, das Modell dahinter ist
dasselbe wie am Telefon — `JellyfinSignInModel`, unverändert bis auf
einen Wert im Initialisierer.

**Die eine Verhaltensänderung.** Nach gefundenem Server sprang der Weg
bisher immer zu Benutzername und Passwort, mit der Begründung, ein
Passwortspeicher fülle beide Felder in einer Sekunde. Vor einem
Fernseher stimmt daran kein Wort: es gibt keinen Passwortspeicher, man
tippt mit dem Steuerkreuz, und das Gerät, auf dem man den Code
bestätigt, liegt sowieso auf dem Sofa. Also `preferring: .quickConnect`
— ein Wert im Initialisierer und keine Plattformbedingung mitten in
`findServer()`. Welcher Fall gilt, weiß die Oberfläche; das Modell
nicht. Der Vorgabewert hält iOS unverändert.

Der sechsstellige Code steht in 96 Punkt mit Sperrung: er wird aus drei
Metern abgelesen und in ein Telefon getippt. In Fliesstextgrösse wäre
das eine Zumutung. Beide Wege bleiben erreichbar — für Server, auf denen
Quick Connect abgeschaltet ist, und für den Fall, dass gerade kein
zweites Gerät zur Hand ist.

**Und der Beweis, dass die geteilte Schicht trägt.** Gegen die
Jellyfin-Attrappe im Simulator: die App verbindet sich, lädt die drei
Mediatheken und zeigt sie. FlixySession, JellyfinBackend, die
Zustandsmaschine der Anmeldung — alles unverändert, alles über
Pfadeinträge geteilt, keine Zeile kopiert.

Die Startseite ist noch eine Liste von Namen. Sie kommt in Schritt vier;
hier steht sie, damit die Wurzel vollständig ist und die Anmeldung für
sich prüfbar bleibt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-29 17:56:50 +02:00

78 lines
3.2 KiB
Swift

import SwiftUI
import FlixyDesign
import FlixyPlayback
import MediaKit
import JellyfinKit
import PlexKit
/// Die App auf dem Fernseher.
///
/// **Eine eigene Wurzel statt eines Zweigs in `FlixyApp`.** Der Unterschied
/// zwischen Telefon und Fernseher ist keine Feinheit der Darstellung, sondern
/// die Bedienart: kein Finger, keine Grössenklasse, keine Werkzeugleiste, kein
/// Ziehen zum Aktualisieren, keine halbhohen Sheets — und dafür ein Fokus, den
/// es auf iOS gar nicht gibt. Ein `#if os(tvOS)` in der bestehenden Wurzel
/// wäre kein Zweig, sondern ein zweiter Rumpf in derselben Datei, und der
/// nächste, der die iOS-Seite ändert, bräche die andere, ohne es zu merken.
///
/// **Die Modelle dagegen werden geteilt**, nicht kopiert: `Flixy/Session/`
/// kommt über einen Pfadeintrag in `project.yml` mit. Die Naht verläuft
/// zwischen Modell und Ansicht, nicht zwischen den Plattformen.
///
/// **Kein SwiftData und kein Download-Koordinator.** Der `ModelContainer` der
/// iOS-App trägt ausschliesslich Downloads, und die gibt es hier nicht — damit
/// fällt beides weg.
@main
struct FlixyTVApp: App {
@State private var session: FlixySession
@State private var theme = FlixyTheme()
@State private var playback = PlaybackCoordinator()
@State private var playbackSettings = PlaybackSettings()
@State private var languages = LanguagePreferences()
@State private var quickPlay = QuickPlay()
@State private var subtitleAppearance = SubtitleAppearance()
@State private var homeLayout = HomeLayoutSettings()
@State private var diagnostics = PlaybackDiagnostics()
/// Beobachtet die Verbindung. Lebt hier, damit der Beobachter einmal läuft
/// statt bei jedem Öffnen des Players neu zu starten.
///
/// Ein Apple TV hängt fast immer am Kabel oder an festem WLAN — aber
/// „fast" ist kein Grund, die Entscheidungen des Players zu raten.
@State private var network = NetworkConditions()
init() {
_session = State(initialValue: FlixySession(
identity: PlexClientIdentity.current(
product: Branding.plexProduct,
version: Branding.version
),
jellyfinIdentity: JellyfinIdentity.current(
client: Branding.appName,
version: Branding.version
),
tokenStore: KeychainTokenStore(service: Branding.keychainService)
))
}
var body: some Scene {
WindowGroup {
TVRootView()
.environment(session)
.environment(theme)
.environment(playback)
.environment(playbackSettings)
.environment(languages)
.environment(quickPlay)
.environment(subtitleAppearance)
.environment(homeLayout)
.environment(diagnostics)
.environment(network)
.flixyAccent(theme)
.tint(theme.accentColor)
// Ein Fernseher ist immer dunkel. Der Schalter in der
// Info.plist gilt fürs System, diese Zeile für die Vorschauen.
.preferredColorScheme(.dark)
}
}
}