import SwiftUI import FlixyDesign import FlixyPlayback /// Alles, was die Wiedergabe betrifft. /// /// Vorher stand das verstreut in der langen Liste der Einstellungen, zwischen /// Serverangaben und Downloads. Zusammen ergibt es einen Bildschirm, den man /// einmal durchgeht und dann in Ruhe lässt. struct PlaybackSettingsView: View { @Environment(PlaybackSettings.self) private var settings @Environment(\.flixyAccent) private var accent var body: some View { @Bindable var settings = settings Form { Section { Picker("settings.qualityWifi", selection: $settings.wifiQuality) { ForEach(PlaybackSettings.Quality.allCases) { quality in Text(quality.label).tag(quality) } } Picker("settings.qualityCellular", selection: $settings.cellularQuality) { ForEach(PlaybackSettings.Quality.allCases) { quality in Text(quality.label).tag(quality) } } } header: { Text("settings.quality") } footer: { Text("settings.qualityExplanation") } Section { Toggle("settings.rememberQuality", isOn: $settings.remembersQuality) Toggle("settings.showBitrate", isOn: $settings.showsBitrate) } footer: { Text("settings.rememberQualityExplanation") } Section { Picker("settings.rewind", selection: $settings.rewindSeconds) { ForEach(PlaybackSettings.skipChoices, id: \.self) { seconds in Text("settings.seconds \(seconds)").tag(seconds) } } Picker("settings.forward", selection: $settings.forwardSeconds) { ForEach(PlaybackSettings.skipChoices, id: \.self) { seconds in Text("settings.seconds \(seconds)").tag(seconds) } } Picker("settings.defaultRate", selection: $settings.defaultRate) { ForEach(PlaybackSettings.rateChoices, id: \.self) { rate in Text(rateLabel(rate)).tag(rate) } } } header: { Text("settings.controls") } footer: { // Zurück und vor getrennt, weil sie verschiedene Zwecke haben: // zurück, weil man etwas nicht verstanden hat; vor, weil man // etwas überspringen will. Text("settings.controlsExplanation") } Section { Toggle("settings.lockLandscape", isOn: $settings.locksLandscape) } footer: { Text("settings.lockLandscapeExplanation") } Section { Toggle("settings.autoSkipIntro", isOn: $settings.autoSkipIntro) Toggle("settings.autoSkipCredits", isOn: $settings.autoSkipCredits) Toggle("settings.autoPlayNext", isOn: $settings.autoPlayNext) } header: { Text("settings.episodes") } } .tint(accent) .scrollContentBackground(.hidden) .background(Color.flixyCanvas) .navigationTitle(Text("settings.playback")) .navigationBarTitleDisplayMode(.inline) } private func rateLabel(_ rate: Double) -> String { rate == 1 ? String(localized: "settings.rateNormal") : rate.formatted(.number.precision(.fractionLength(0...2))) + "×" } } extension PlaybackSettings.Quality { var label: LocalizedStringKey { switch self { case .original: "quality.original" case .high: "quality.high" case .medium: "quality.medium" case .low: "quality.low" case .minimal: "quality.minimal" } } }