Files
Flaro/Flixy/Views/Settings/SettingsView.swift
T
GuidoandClaude Opus 5 9a69df4635 Phase 1: Anmeldung, Bibliothek, Detailseiten, Hybrid-Player
Die Datenschicht:
- plex.tv-Anmeldung über das PIN-Verfahren, Token im Schlüsselbund
- Serversuche und Verbindungsauswahl nach Rang (lokal vor direkt vor
  Vermittlung), mit Abgleich der Server-Kennung gegen veraltete
  plex.direct-Adressen
- PlexServer als einzige Stelle, an der die App Endpunkte kennt:
  Mediatheken, Hubs, seitenweises Blättern mit Filtern, Metadaten,
  Staffeln/Folgen, Suche

Die Oberfläche:
- Startseite mit Aufmacher und den Reihen vom Server
- Mediathek als Raster oder Liste, mit Filter- und Sortierblatt
- Detailseiten für Filme, Folgen, Serien und Staffeln inkl. Besetzung,
  Fassungsauswahl und aufklappbaren technischen Angaben
- Suche mit gemerkten Anfragen
- Vollbildplayer mit eigenem Chrome

Der Player:
- AVPlayerEngine und VLCPlayerEngine hinter einem gemeinsamen Protokoll
- VLCKit liegt in einem eigenen Package (FlixyVLC), damit `swift test`
  in FlixyKit nicht das 920-MB-Binärpaket mitzieht

Am echten plex.tv geprüft: der Anmeldecode kommt an. Dabei fiel auf,
dass `strong=true` einen dreißigstelligen Code liefert, der sich bei
plex.tv/link nicht eintippen lässt — jetzt der kurze.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 16:46:28 +02:00

66 lines
2.4 KiB
Swift

import SwiftUI
import FlixyDesign
import PlexKit
/// Die Einstellungen.
///
/// In Phase 1 bewusst schmal: Serverangaben und Abmelden. Akzentfarbe,
/// Qualitätsregler und Download-Einstellungen kommen mit den Phasen, in denen
/// es das Geregelte auch gibt.
struct SettingsView: View {
@Environment(FlixySession.self) private var session
@State private var showsSignOutConfirmation = false
var body: some View {
Form {
if let server = session.server {
Section("settings.server") {
LabeledContent("settings.serverName", value: server.name)
LabeledContent("settings.connection", value: connectionLabel(server.connection))
LabeledContent("settings.address", value: server.connection.uri)
.font(.flixyCaption)
.textSelection(.enabled)
}
Section("settings.libraries") {
ForEach(session.libraries) { library in
LabeledContent(library.title, value: library.type.capitalized)
}
}
}
Section("settings.app") {
LabeledContent("settings.version", value: Branding.version)
}
Section {
Button("action.signOut", role: .destructive) {
showsSignOutConfirmation = true
}
}
}
.scrollContentBackground(.hidden)
.background(Color.flixyCanvas)
.navigationTitle(Text("sidebar.settings"))
.navigationBarTitleDisplayMode(.inline)
.confirmationDialog(
Text("settings.signOutConfirm"),
isPresented: $showsSignOutConfirmation,
titleVisibility: .visible
) {
Button("action.signOut", role: .destructive) { session.signOut() }
Button("action.cancel", role: .cancel) {}
} message: {
Text("settings.signOutExplanation")
}
}
/// Zeigt, über welchen Weg die Verbindung läuft — beim Suchen nach
/// Ruckeln ist das die erste Frage.
private func connectionLabel(_ connection: PlexConnection) -> String {
if connection.local { return String(localized: "settings.connectionLocal") }
if connection.relay { return String(localized: "settings.connectionRelay") }
return String(localized: "settings.connectionRemote")
}
}