mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Seek settings
This commit is contained in:
parent
5d4983d6d2
commit
8631389b8f
@ -162,6 +162,7 @@ final class PlayerModel: ObservableObject {
|
||||
@Default(.closePiPOnOpeningPlayer) var closePiPOnOpeningPlayer
|
||||
@Default(.resetWatchedStatusOnPlaying) var resetWatchedStatusOnPlaying
|
||||
@Default(.playerRate) var playerRate
|
||||
@Default(.systemControlsSeekDuration) var systemControlsSeekDuration
|
||||
|
||||
#if !os(macOS)
|
||||
@Default(.closePiPAndOpenPlayerOnEnteringForeground) var closePiPAndOpenPlayerOnEnteringForeground
|
||||
@ -746,18 +747,19 @@ final class PlayerModel: ObservableObject {
|
||||
UIApplication.shared.beginReceivingRemoteControlEvents()
|
||||
#endif
|
||||
|
||||
let preferredIntervals = [NSNumber(10)]
|
||||
let interval = TimeInterval(systemControlsSeekDuration) ?? 10
|
||||
let preferredIntervals = [NSNumber(value: interval)]
|
||||
|
||||
skipForwardCommand.preferredIntervals = preferredIntervals
|
||||
skipBackwardCommand.preferredIntervals = preferredIntervals
|
||||
|
||||
skipForwardCommand.addTarget { [weak self] _ in
|
||||
self?.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
||||
self?.backend.seek(relative: .secondsInDefaultTimescale(interval), seekType: .userInteracted)
|
||||
return .success
|
||||
}
|
||||
|
||||
skipBackwardCommand.addTarget { [weak self] _ in
|
||||
self?.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
||||
self?.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||
return .success
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import Defaults
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
@ -51,4 +52,25 @@ struct Constants {
|
||||
return "list.and.film"
|
||||
}
|
||||
}
|
||||
|
||||
static func seekIcon(_ type: String, _ interval: TimeInterval) -> String {
|
||||
let interval = Int(interval)
|
||||
let allVersions = [10, 15, 30, 45, 60, 75, 90]
|
||||
let iOS15 = [5]
|
||||
let iconName = "go\(type).\(interval)"
|
||||
|
||||
if #available(iOS 15, macOS 12, *) {
|
||||
if iOS15.contains(interval) {
|
||||
return iconName
|
||||
}
|
||||
}
|
||||
|
||||
if allVersions.contains(interval) {
|
||||
return iconName
|
||||
}
|
||||
|
||||
let sign = type == "forward" ? "plus" : "minus"
|
||||
|
||||
return "go\(type).\(sign)"
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,12 @@ extension Defaults.Keys {
|
||||
static let playerActionsButtonLabelStyle = Key<ButtonLabelStyle>("playerActionsButtonLabelStyle", default: .iconAndText)
|
||||
|
||||
static let systemControlsCommands = Key<SystemControlsCommands>("systemControlsCommands", default: .restartAndAdvanceToNext)
|
||||
|
||||
static let buttonBackwardSeekDuration = Key<String>("buttonBackwardSeekDuration", default: "10")
|
||||
static let buttonForwardSeekDuration = Key<String>("buttonForwardSeekDuration", default: "10")
|
||||
static let gestureBackwardSeekDuration = Key<String>("gestureBackwardSeekDuration", default: "10")
|
||||
static let gestureForwardSeekDuration = Key<String>("gestureForwardSeekDuration", default: "10")
|
||||
static let systemControlsSeekDuration = Key<String>("systemControlsBackwardSeekDuration", default: "10")
|
||||
static let actionButtonShareEnabled = Key<Bool>("actionButtonShareEnabled", default: true)
|
||||
static let actionButtonAddToPlaylistEnabled = Key<Bool>("actionButtonAddToPlaylistEnabled", default: true)
|
||||
static let actionButtonSubscribeEnabled = Key<Bool>("actionButtonSubscribeEnabled", default: false)
|
||||
|
@ -29,6 +29,8 @@ struct PlayerControls: View {
|
||||
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
|
||||
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
|
||||
@Default(.openWatchNextOnClose) private var openWatchNextOnClose
|
||||
@Default(.buttonBackwardSeekDuration) private var buttonBackwardSeekDuration
|
||||
@Default(.buttonForwardSeekDuration) private var buttonForwardSeekDuration
|
||||
|
||||
private let controlsOverlayModel = ControlOverlaysModel.shared
|
||||
|
||||
@ -398,8 +400,14 @@ struct PlayerControls: View {
|
||||
size = playerControlsLayout.bigButtonSize
|
||||
#endif
|
||||
|
||||
return button("Seek Backward", systemImage: "gobackward.10", fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor) {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(buttonBackwardSeekDuration) ?? 10
|
||||
|
||||
return button(
|
||||
"Seek Backward",
|
||||
systemImage: Constants.seekIcon("backward", interval),
|
||||
fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor
|
||||
) {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||
}
|
||||
.disabled(player.liveStreamInAVPlayer)
|
||||
#if os(tvOS)
|
||||
@ -420,8 +428,14 @@ struct PlayerControls: View {
|
||||
size = playerControlsLayout.bigButtonSize
|
||||
#endif
|
||||
|
||||
return button("Seek Forward", systemImage: "goforward.10", fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor) {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(buttonForwardSeekDuration) ?? 10
|
||||
|
||||
return button(
|
||||
"Seek Forward",
|
||||
systemImage: Constants.seekIcon("forward", interval),
|
||||
fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor
|
||||
) {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(interval), seekType: .userInteracted)
|
||||
}
|
||||
.disabled(player.liveStreamInAVPlayer)
|
||||
#if os(tvOS)
|
||||
|
@ -1,9 +1,13 @@
|
||||
import Defaults
|
||||
import SwiftUI
|
||||
|
||||
struct PlayerGestures: View {
|
||||
private var player = PlayerModel.shared
|
||||
@ObservedObject private var model = PlayerControlsModel.shared
|
||||
|
||||
@Default(.gestureBackwardSeekDuration) private var gestureBackwardSeekDuration
|
||||
@Default(.gestureForwardSeekDuration) private var gestureForwardSeekDuration
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
gestureRectangle
|
||||
@ -11,7 +15,8 @@ struct PlayerGestures: View {
|
||||
tapSensitivity: 0.2,
|
||||
singleTapAction: { singleTapAction() },
|
||||
doubleTapAction: {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(gestureBackwardSeekDuration) ?? 10
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||
},
|
||||
anyTapAction: {
|
||||
model.update()
|
||||
@ -32,7 +37,8 @@ struct PlayerGestures: View {
|
||||
tapSensitivity: 0.2,
|
||||
singleTapAction: { singleTapAction() },
|
||||
doubleTapAction: {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(gestureForwardSeekDuration) ?? 10
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(interval), seekType: .userInteracted)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ struct VideoPlayerView: View {
|
||||
@Default(.seekGestureSpeed) var seekGestureSpeed
|
||||
@Default(.seekGestureSensitivity) var seekGestureSensitivity
|
||||
@Default(.playerSidebar) var playerSidebar
|
||||
@Default(.gestureBackwardSeekDuration) private var gestureBackwardSeekDuration
|
||||
@Default(.gestureForwardSeekDuration) private var gestureForwardSeekDuration
|
||||
|
||||
@ObservedObject internal var controlsOverlayModel = ControlOverlaysModel.shared
|
||||
|
||||
@ -371,10 +373,12 @@ struct VideoPlayerView: View {
|
||||
guard !player.controls.presentingControls else { return }
|
||||
|
||||
if direction == .left {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(gestureBackwardSeekDuration) ?? 10
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||
}
|
||||
if direction == .right {
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
||||
let interval = TimeInterval(gestureForwardSeekDuration) ?? 10
|
||||
player.backend.seek(relative: .secondsInDefaultTimescale(interval), seekType: .userInteracted)
|
||||
}
|
||||
}
|
||||
.onPlayPauseCommand {
|
||||
|
@ -33,6 +33,12 @@ struct PlayerSettings: View {
|
||||
@Default(.openWatchNextOnFinishedWatching) private var openWatchNextOnFinishedWatching
|
||||
@Default(.openWatchNextOnFinishedWatchingDelay) private var openWatchNextOnFinishedWatchingDelay
|
||||
|
||||
@Default(.buttonBackwardSeekDuration) private var buttonBackwardSeekDuration
|
||||
@Default(.buttonForwardSeekDuration) private var buttonForwardSeekDuration
|
||||
@Default(.gestureBackwardSeekDuration) private var gestureBackwardSeekDuration
|
||||
@Default(.gestureForwardSeekDuration) private var gestureForwardSeekDuration
|
||||
@Default(.systemControlsSeekDuration) private var systemControlsSeekDuration
|
||||
|
||||
@Default(.actionButtonShareEnabled) private var actionButtonShareEnabled
|
||||
@Default(.actionButtonSubscribeEnabled) private var actionButtonSubscribeEnabled
|
||||
@Default(.actionButtonNextEnabled) private var actionButtonNextEnabled
|
||||
@ -41,6 +47,7 @@ struct PlayerSettings: View {
|
||||
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
|
||||
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
|
||||
@Default(.actionButtonNextQueueCountEnabled) private var actionButtonNextQueueCountEnabled
|
||||
|
||||
@ObservedObject private var accounts = AccountsModel.shared
|
||||
private var player = PlayerModel.shared
|
||||
|
||||
@ -83,6 +90,10 @@ struct PlayerSettings: View {
|
||||
systemControlsCommandsPicker
|
||||
}
|
||||
|
||||
Section(header: SettingsHeader(text: "Seeking"), footer: seekingGestureSection) {
|
||||
seekingSection
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
Section(header: SettingsHeader(text: "Actions Buttons")) {
|
||||
actionButtonToggles
|
||||
@ -225,6 +236,43 @@ struct PlayerSettings: View {
|
||||
.multilineTextAlignment(.trailing)
|
||||
}
|
||||
|
||||
@ViewBuilder private var seekingSection: some View {
|
||||
seekingDurationSetting("System controls", $systemControlsSeekDuration)
|
||||
.foregroundColor(systemControlsCommands == .restartAndAdvanceToNext ? .secondary : .primary)
|
||||
.disabled(systemControlsCommands == .restartAndAdvanceToNext)
|
||||
seekingDurationSetting("Controls button: backwards", $buttonBackwardSeekDuration)
|
||||
seekingDurationSetting("Controls button: forwards", $buttonForwardSeekDuration)
|
||||
seekingDurationSetting("Gesture: backwards", $gestureBackwardSeekDuration)
|
||||
seekingDurationSetting("Gesture: fowards", $gestureForwardSeekDuration)
|
||||
}
|
||||
|
||||
private var seekingGestureSection: some View {
|
||||
#if os(iOS)
|
||||
Text("Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart.")
|
||||
#elseif os(macOS)
|
||||
Text("Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart.")
|
||||
#else
|
||||
Text("Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart.")
|
||||
#endif
|
||||
}
|
||||
|
||||
private func seekingDurationSetting(_ name: String, _ value: Binding<String>) -> some View {
|
||||
HStack {
|
||||
Text(name)
|
||||
.frame(minWidth: 140, alignment: .leading)
|
||||
Spacer()
|
||||
TextField("Duration", text: value)
|
||||
|
||||
.frame(maxWidth: 50, alignment: .trailing)
|
||||
.multilineTextAlignment(.trailing)
|
||||
|
||||
.labelsHidden()
|
||||
#if !os(macOS)
|
||||
.keyboardType(.numberPad)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private var actionButtonToggles: some View {
|
||||
actionButtonToggle("Share", $actionButtonShareEnabled)
|
||||
actionButtonToggle("Add to Playlist", $actionButtonAddToPlaylistEnabled)
|
||||
|
Loading…
Reference in New Issue
Block a user