diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index 2cc01fe6..287f38a5 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -148,6 +148,8 @@ final class MPVBackend: PlayerBackend { } else { replaceItem(nil) } + + startClientUpdates() } func play() { diff --git a/Model/Player/PlayerControlsModel.swift b/Model/Player/PlayerControlsModel.swift index 626b2509..3d71c939 100644 --- a/Model/Player/PlayerControlsModel.swift +++ b/Model/Player/PlayerControlsModel.swift @@ -11,6 +11,8 @@ final class PlayerControlsModel: ObservableObject { @Published var timer: Timer? @Published var playingFullscreen = false + private var throttle = Throttle(interval: 1) + var player: PlayerModel! var playbackTime: String { @@ -52,7 +54,13 @@ final class PlayerControlsModel: ObservableObject { } func show() { - player.backend.updateControls() + guard !(player?.currentItem.isNil ?? true) else { + return + } + + guard !presentingControls else { + return + } withAnimation(PlayerControls.animation) { presentingControls = true @@ -60,16 +68,21 @@ final class PlayerControlsModel: ObservableObject { } func hide() { + player?.backend.stopControlsUpdates() + + guard !(player?.currentItem.isNil ?? true) else { + return + } + + guard presentingControls else { + return + } withAnimation(PlayerControls.animation) { presentingControls = false } } func toggle() { - if !presentingControls { - player.backend.updateControls() - } - withAnimation(PlayerControls.animation) { presentingControls.toggle() } @@ -118,4 +131,10 @@ final class PlayerControlsModel: ObservableObject { timer?.invalidate() timer = nil } + + func update() { + throttle.execute { [weak self] in + self?.player?.backend.updateControls() + } + } } diff --git a/Shared/Player/PlayerGestures.swift b/Shared/Player/PlayerGestures.swift index b29a5447..b6370a58 100644 --- a/Shared/Player/PlayerGestures.swift +++ b/Shared/Player/PlayerGestures.swift @@ -14,6 +14,9 @@ struct PlayerGestures: View { }, doubleTapAction: { player.backend.seek(relative: .secondsInDefaultTimescale(-10)) + }, + anyTapAction: { + model.update() } ) @@ -25,6 +28,9 @@ struct PlayerGestures: View { }, doubleTapAction: { player.backend.togglePlay() + }, + anyTapAction: { + model.update() } ) @@ -36,6 +42,9 @@ struct PlayerGestures: View { }, doubleTapAction: { player.backend.seek(relative: .secondsInDefaultTimescale(10)) + }, + anyTapAction: { + model.update() } ) } diff --git a/Shared/Player/TapRecognizerViewModifier.swift b/Shared/Player/TapRecognizerViewModifier.swift index 6e746498..ddfadbbc 100644 --- a/Shared/Player/TapRecognizerViewModifier.swift +++ b/Shared/Player/TapRecognizerViewModifier.swift @@ -6,11 +6,18 @@ struct TapRecognizerViewModifier: ViewModifier { var tapSensitivity: Double var singleTapAction: () -> Void var doubleTapAction: () -> Void + var anyTapAction: () -> Void - init(tapSensitivity: Double, singleTapAction: @escaping () -> Void, doubleTapAction: @escaping () -> Void) { + init( + tapSensitivity: Double, + singleTapAction: @escaping () -> Void, + doubleTapAction: @escaping () -> Void, + anyTapAction: @escaping () -> Void + ) { self.tapSensitivity = tapSensitivity self.singleTapAction = singleTapAction self.doubleTapAction = doubleTapAction + self.anyTapAction = anyTapAction } func body(content: Content) -> some View { @@ -19,6 +26,8 @@ struct TapRecognizerViewModifier: ViewModifier { private var singleTapGesture: some Gesture { TapGesture(count: 1).onEnded { + anyTapAction() + singleTapIsTaped = true DispatchQueue.main.asyncAfter(deadline: .now() + tapSensitivity) { @@ -42,7 +51,19 @@ struct TapRecognizerViewModifier: ViewModifier { } extension View { - func tapRecognizer(tapSensitivity: Double, singleTapAction: @escaping () -> Void, doubleTapAction: @escaping () -> Void) -> some View { - modifier(TapRecognizerViewModifier(tapSensitivity: tapSensitivity, singleTapAction: singleTapAction, doubleTapAction: doubleTapAction)) + func tapRecognizer( + tapSensitivity: Double, + singleTapAction: @escaping () -> Void, + doubleTapAction: @escaping () -> Void, + anyTapAction: @escaping () -> Void = {} + ) -> some View { + modifier( + TapRecognizerViewModifier( + tapSensitivity: tapSensitivity, + singleTapAction: singleTapAction, + doubleTapAction: doubleTapAction, + anyTapAction: anyTapAction + ) + ) } }