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(.closePiPOnOpeningPlayer) var closePiPOnOpeningPlayer
|
||||||
@Default(.resetWatchedStatusOnPlaying) var resetWatchedStatusOnPlaying
|
@Default(.resetWatchedStatusOnPlaying) var resetWatchedStatusOnPlaying
|
||||||
@Default(.playerRate) var playerRate
|
@Default(.playerRate) var playerRate
|
||||||
|
@Default(.systemControlsSeekDuration) var systemControlsSeekDuration
|
||||||
|
|
||||||
#if !os(macOS)
|
#if !os(macOS)
|
||||||
@Default(.closePiPAndOpenPlayerOnEnteringForeground) var closePiPAndOpenPlayerOnEnteringForeground
|
@Default(.closePiPAndOpenPlayerOnEnteringForeground) var closePiPAndOpenPlayerOnEnteringForeground
|
||||||
@ -746,18 +747,19 @@ final class PlayerModel: ObservableObject {
|
|||||||
UIApplication.shared.beginReceivingRemoteControlEvents()
|
UIApplication.shared.beginReceivingRemoteControlEvents()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
let preferredIntervals = [NSNumber(10)]
|
let interval = TimeInterval(systemControlsSeekDuration) ?? 10
|
||||||
|
let preferredIntervals = [NSNumber(value: interval)]
|
||||||
|
|
||||||
skipForwardCommand.preferredIntervals = preferredIntervals
|
skipForwardCommand.preferredIntervals = preferredIntervals
|
||||||
skipBackwardCommand.preferredIntervals = preferredIntervals
|
skipBackwardCommand.preferredIntervals = preferredIntervals
|
||||||
|
|
||||||
skipForwardCommand.addTarget { [weak self] _ in
|
skipForwardCommand.addTarget { [weak self] _ in
|
||||||
self?.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
self?.backend.seek(relative: .secondsInDefaultTimescale(interval), seekType: .userInteracted)
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
skipBackwardCommand.addTarget { [weak self] _ in
|
skipBackwardCommand.addTarget { [weak self] _ in
|
||||||
self?.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
self?.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Defaults
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@ -51,4 +52,25 @@ struct Constants {
|
|||||||
return "list.and.film"
|
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 playerActionsButtonLabelStyle = Key<ButtonLabelStyle>("playerActionsButtonLabelStyle", default: .iconAndText)
|
||||||
|
|
||||||
static let systemControlsCommands = Key<SystemControlsCommands>("systemControlsCommands", default: .restartAndAdvanceToNext)
|
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 actionButtonShareEnabled = Key<Bool>("actionButtonShareEnabled", default: true)
|
||||||
static let actionButtonAddToPlaylistEnabled = Key<Bool>("actionButtonAddToPlaylistEnabled", default: true)
|
static let actionButtonAddToPlaylistEnabled = Key<Bool>("actionButtonAddToPlaylistEnabled", default: true)
|
||||||
static let actionButtonSubscribeEnabled = Key<Bool>("actionButtonSubscribeEnabled", default: false)
|
static let actionButtonSubscribeEnabled = Key<Bool>("actionButtonSubscribeEnabled", default: false)
|
||||||
|
@ -29,6 +29,8 @@ struct PlayerControls: View {
|
|||||||
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
|
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
|
||||||
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
|
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
|
||||||
@Default(.openWatchNextOnClose) private var openWatchNextOnClose
|
@Default(.openWatchNextOnClose) private var openWatchNextOnClose
|
||||||
|
@Default(.buttonBackwardSeekDuration) private var buttonBackwardSeekDuration
|
||||||
|
@Default(.buttonForwardSeekDuration) private var buttonForwardSeekDuration
|
||||||
|
|
||||||
private let controlsOverlayModel = ControlOverlaysModel.shared
|
private let controlsOverlayModel = ControlOverlaysModel.shared
|
||||||
|
|
||||||
@ -398,8 +400,14 @@ struct PlayerControls: View {
|
|||||||
size = playerControlsLayout.bigButtonSize
|
size = playerControlsLayout.bigButtonSize
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return button("Seek Backward", systemImage: "gobackward.10", fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor) {
|
let interval = TimeInterval(buttonBackwardSeekDuration) ?? 10
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
|
||||||
|
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)
|
.disabled(player.liveStreamInAVPlayer)
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
@ -420,8 +428,14 @@ struct PlayerControls: View {
|
|||||||
size = playerControlsLayout.bigButtonSize
|
size = playerControlsLayout.bigButtonSize
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return button("Seek Forward", systemImage: "goforward.10", fontSize: fontSize, size: size, cornerRadius: 5, background: false, foregroundColor: foregroundColor) {
|
let interval = TimeInterval(buttonForwardSeekDuration) ?? 10
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(10), seekType: .userInteracted)
|
|
||||||
|
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)
|
.disabled(player.liveStreamInAVPlayer)
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
import Defaults
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PlayerGestures: View {
|
struct PlayerGestures: View {
|
||||||
private var player = PlayerModel.shared
|
private var player = PlayerModel.shared
|
||||||
@ObservedObject private var model = PlayerControlsModel.shared
|
@ObservedObject private var model = PlayerControlsModel.shared
|
||||||
|
|
||||||
|
@Default(.gestureBackwardSeekDuration) private var gestureBackwardSeekDuration
|
||||||
|
@Default(.gestureForwardSeekDuration) private var gestureForwardSeekDuration
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
gestureRectangle
|
gestureRectangle
|
||||||
@ -11,7 +15,8 @@ struct PlayerGestures: View {
|
|||||||
tapSensitivity: 0.2,
|
tapSensitivity: 0.2,
|
||||||
singleTapAction: { singleTapAction() },
|
singleTapAction: { singleTapAction() },
|
||||||
doubleTapAction: {
|
doubleTapAction: {
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10), seekType: .userInteracted)
|
let interval = TimeInterval(gestureBackwardSeekDuration) ?? 10
|
||||||
|
player.backend.seek(relative: .secondsInDefaultTimescale(-interval), seekType: .userInteracted)
|
||||||
},
|
},
|
||||||
anyTapAction: {
|
anyTapAction: {
|
||||||
model.update()
|
model.update()
|
||||||
@ -32,7 +37,8 @@ struct PlayerGestures: View {
|
|||||||
tapSensitivity: 0.2,
|
tapSensitivity: 0.2,
|
||||||
singleTapAction: { singleTapAction() },
|
singleTapAction: { singleTapAction() },
|
||||||
doubleTapAction: {
|
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(.seekGestureSpeed) var seekGestureSpeed
|
||||||
@Default(.seekGestureSensitivity) var seekGestureSensitivity
|
@Default(.seekGestureSensitivity) var seekGestureSensitivity
|
||||||
@Default(.playerSidebar) var playerSidebar
|
@Default(.playerSidebar) var playerSidebar
|
||||||
|
@Default(.gestureBackwardSeekDuration) private var gestureBackwardSeekDuration
|
||||||
|
@Default(.gestureForwardSeekDuration) private var gestureForwardSeekDuration
|
||||||
|
|
||||||
@ObservedObject internal var controlsOverlayModel = ControlOverlaysModel.shared
|
@ObservedObject internal var controlsOverlayModel = ControlOverlaysModel.shared
|
||||||
|
|
||||||
@ -371,10 +373,12 @@ struct VideoPlayerView: View {
|
|||||||
guard !player.controls.presentingControls else { return }
|
guard !player.controls.presentingControls else { return }
|
||||||
|
|
||||||
if direction == .left {
|
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 {
|
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 {
|
.onPlayPauseCommand {
|
||||||
|
@ -33,6 +33,12 @@ struct PlayerSettings: View {
|
|||||||
@Default(.openWatchNextOnFinishedWatching) private var openWatchNextOnFinishedWatching
|
@Default(.openWatchNextOnFinishedWatching) private var openWatchNextOnFinishedWatching
|
||||||
@Default(.openWatchNextOnFinishedWatchingDelay) private var openWatchNextOnFinishedWatchingDelay
|
@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(.actionButtonShareEnabled) private var actionButtonShareEnabled
|
||||||
@Default(.actionButtonSubscribeEnabled) private var actionButtonSubscribeEnabled
|
@Default(.actionButtonSubscribeEnabled) private var actionButtonSubscribeEnabled
|
||||||
@Default(.actionButtonNextEnabled) private var actionButtonNextEnabled
|
@Default(.actionButtonNextEnabled) private var actionButtonNextEnabled
|
||||||
@ -41,6 +47,7 @@ struct PlayerSettings: View {
|
|||||||
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
|
@Default(.actionButtonSettingsEnabled) private var actionButtonSettingsEnabled
|
||||||
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
|
@Default(.actionButtonHideEnabled) private var actionButtonHideEnabled
|
||||||
@Default(.actionButtonNextQueueCountEnabled) private var actionButtonNextQueueCountEnabled
|
@Default(.actionButtonNextQueueCountEnabled) private var actionButtonNextQueueCountEnabled
|
||||||
|
|
||||||
@ObservedObject private var accounts = AccountsModel.shared
|
@ObservedObject private var accounts = AccountsModel.shared
|
||||||
private var player = PlayerModel.shared
|
private var player = PlayerModel.shared
|
||||||
|
|
||||||
@ -83,6 +90,10 @@ struct PlayerSettings: View {
|
|||||||
systemControlsCommandsPicker
|
systemControlsCommandsPicker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Section(header: SettingsHeader(text: "Seeking"), footer: seekingGestureSection) {
|
||||||
|
seekingSection
|
||||||
|
}
|
||||||
|
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
Section(header: SettingsHeader(text: "Actions Buttons")) {
|
Section(header: SettingsHeader(text: "Actions Buttons")) {
|
||||||
actionButtonToggles
|
actionButtonToggles
|
||||||
@ -225,6 +236,43 @@ struct PlayerSettings: View {
|
|||||||
.multilineTextAlignment(.trailing)
|
.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 {
|
@ViewBuilder private var actionButtonToggles: some View {
|
||||||
actionButtonToggle("Share", $actionButtonShareEnabled)
|
actionButtonToggle("Share", $actionButtonShareEnabled)
|
||||||
actionButtonToggle("Add to Playlist", $actionButtonAddToPlaylistEnabled)
|
actionButtonToggle("Add to Playlist", $actionButtonAddToPlaylistEnabled)
|
||||||
|
Loading…
Reference in New Issue
Block a user