Files
Flaro/Flixy/Views/Settings/SettingsView.swift
T
ScarriffleandClaude Opus 5 81e22c4f97 Hinter der Insel läuft jetzt das Wasser durch
Der schwarze Streifen über der Navigation war kein gezeichneter Balken,
sondern fehlender Inhalt: der gesamte Baum saß innerhalb des
Sicherheitsrands. Deshalb erreichte kein noch so gut gesetzter Rand
weiter unten die Fläche darüber — Inhalt kam dort nie hin.

Jetzt reißt der HStack den Rand oben auf und gibt den Platz kontrolliert
zurück: Seitenleiste und Insel bekommen ihren Abstand zur Statusleiste
explizit, der Inhalt bekommt ihn als Sicherheitsrand. Der Aufmacher
nimmt ihn sich wieder — um genau diese Strecke höher und um genau diese
Strecke größer, sodass unten alles bleibt, wo es war. Dazu ein knapper
Verlauf oben, damit Uhrzeit und Batterie auch über einem hellen Bild
lesbar bleiben.

Und die Leiste oben fährt beim Scrollen weg. Nur sie: der
Sicherheitsrand darunter bleibt stehen, sonst ruckte die Seite bei jedem
Ein- und Ausblenden unter dem Finger weg.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 22:52:07 +02:00

121 lines
4.4 KiB
Swift

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)
.flixyRevealsTopChrome()
.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<Destination: View>(
_ 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)
}
}
}