Files
yattee/Yattee/Views/Settings/PlayerControls/Gestures/SeekGestureSettingsView.swift
2026-02-08 18:33:56 +01:00

112 lines
3.5 KiB
Swift

//
// SeekGestureSettingsView.swift
// Yattee
//
// Settings view for configuring horizontal seek gesture.
//
#if os(iOS)
import SwiftUI
/// Settings view for configuring horizontal seek gesture on the player.
struct SeekGestureSettingsView: View {
@Bindable var viewModel: PlayerControlsSettingsViewModel
// Local state for immediate UI updates
@State private var isEnabled: Bool = false
@State private var sensitivity: SeekGestureSensitivity = .medium
var body: some View {
List {
enableSection
if isEnabled {
sensitivitySection
}
}
.navigationTitle(String(localized: "gestures.seek.title", defaultValue: "Seek Gesture"))
.navigationBarTitleDisplayMode(.inline)
.onAppear {
syncFromViewModel()
}
.onChange(of: viewModel.activePreset?.id) { _, _ in
syncFromViewModel()
}
}
// MARK: - Sections
private var enableSection: some View {
Section {
Toggle(
String(localized: "gestures.seek.enable", defaultValue: "Enable Seek Gesture"),
isOn: $isEnabled
)
.onChange(of: isEnabled) { _, newValue in
viewModel.updateSeekGestureSettingsSync { $0.isEnabled = newValue }
}
.disabled(!viewModel.canEditActivePreset)
} footer: {
Text(String(localized: "gestures.seek.enableFooter", defaultValue: "Drag left or right to seek backward or forward when controls are hidden."))
}
}
private var sensitivitySection: some View {
Section {
Picker(
String(localized: "gestures.seek.sensitivity", defaultValue: "Sensitivity"),
selection: $sensitivity
) {
ForEach(SeekGestureSensitivity.allCases, id: \.self) { level in
VStack(alignment: .leading) {
Text(level.displayName)
}
.tag(level)
}
}
.pickerStyle(.inline)
.labelsHidden()
.onChange(of: sensitivity) { _, newValue in
viewModel.updateSeekGestureSettingsSync { $0.sensitivity = newValue }
}
.disabled(!viewModel.canEditActivePreset)
} header: {
Text(String(localized: "gestures.seek.sensitivity", defaultValue: "Sensitivity"))
} footer: {
Text(sensitivityFooterText)
}
}
// MARK: - Helpers
private var sensitivityFooterText: String {
switch sensitivity {
case .low:
String(localized: "gestures.seek.sensitivity.low.footer", defaultValue: "Precise control for short videos or fine-tuning.")
case .medium:
String(localized: "gestures.seek.sensitivity.medium.footer", defaultValue: "Balanced for most video lengths.")
case .high:
String(localized: "gestures.seek.sensitivity.high.footer", defaultValue: "Fast navigation for long videos or podcasts.")
}
}
private func syncFromViewModel() {
let settings = viewModel.seekGestureSettings
isEnabled = settings.isEnabled
sensitivity = settings.sensitivity
}
}
// MARK: - Preview
#Preview {
NavigationStack {
SeekGestureSettingsView(
viewModel: PlayerControlsSettingsViewModel(
layoutService: PlayerControlsLayoutService(),
settingsManager: SettingsManager()
)
)
}
}
#endif