import SwiftUI import FlixyDesign /// Die Einstellungen — als Übersicht, nicht als eine lange Liste. /// /// Vorher stand alles untereinander auf einem Bildschirm: Serverangaben, /// Qualität, Wiedergabe, drei Verweise, Downloads, Version, Abmelden. Das /// war beim Bauen bequem und beim Suchen anstrengend — je mehr Einstellungen /// dazukamen, desto weiter rutschte alles nach unten. /// /// Jetzt führt jede Zeile in einen Bildschirm, der zu **einer** Frage gehört. struct SettingsView: View { @Environment(FlixySession.self) private var session @Environment(\.flixyAccent) private var accent @State private var showsSignOutConfirmation = false var body: some View { Form { if session.backend != nil { Section { NavigationLink { ServerSettingsView() } label: { LabeledContent { Text(session.serverName) .foregroundStyle(Color.flixyTextSecondary) } label: { row( "settings.server", symbol: "externaldrive.connected.to.line.below", colour: SettingsPalette.server ) } } } } Section("settings.section.look") { link("appearance.title", symbol: "paintpalette", colour: SettingsPalette.appearance) { AppearanceView() } link("homeLayout.title", symbol: "rectangle.stack", colour: SettingsPalette.home) { HomeLayoutView() } } Section("settings.section.playing") { link("settings.playback", symbol: "play.rectangle", colour: SettingsPalette.playback) { PlaybackSettingsView() } link("languages.title", symbol: "captions.bubble", colour: SettingsPalette.languages) { LanguagesView() } link("sidebar.downloads", symbol: "arrow.down.circle", colour: SettingsPalette.downloads) { DownloadSettingsView() } } Section { link("diagnostics.title", symbol: "stethoscope", colour: SettingsPalette.diagnostics) { DiagnosticsView() } } Section("settings.app") { LabeledContent("settings.version", value: Branding.version) LabeledContent("settings.build", value: Branding.buildStamp) } Section { Button("action.signOut", role: .destructive) { showsSignOutConfirmation = true } } } // Ausdrücklich, nicht nur geerbt. // // Listen und Formulare zeichnen ihre Zeilen teilweise in einem // eigenen Darstellungskontext, in dem eigene Umgebungswerte verloren // gehen können — sichtbar an Picker-Werten, die in der Standardfarbe // leuchteten, während die Schalter daneben schon die gewählte trugen. .tint(accent) .flixyForm() .scrollContentBackground(.hidden) .background(Color.flixyCanvas) .navigationTitle(Text("sidebar.settings")) .flixyInlineTitle() .confirmationDialog( Text("settings.signOutConfirm"), isPresented: $showsSignOutConfirmation, titleVisibility: .visible ) { Button("action.signOut", role: .destructive) { session.signOut() } Button("action.cancel", role: .cancel) {} } message: { Text("settings.signOutExplanation") } } private func link( _ title: LocalizedStringKey, symbol: String, colour: Color, @ViewBuilder destination: @escaping () -> Destination ) -> some View { NavigationLink { destination() } label: { row(title, symbol: symbol, colour: colour) } } private func row(_ title: LocalizedStringKey, symbol: String, colour: Color) -> some View { HStack(spacing: FlixySpacing.regular) { SettingsIcon(symbol: symbol, colour: colour) Text(title) } } }