mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 09:49:46 +00:00
112 lines
3.5 KiB
Swift
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
|