2022-08-28 17:18:49 +00:00
|
|
|
import Defaults
|
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
extension VideoPlayerView {
|
|
|
|
var playerDragGesture: some Gesture {
|
2024-05-16 16:59:54 +00:00
|
|
|
DragGesture(minimumDistance: 30, coordinateSpace: .global)
|
|
|
|
#if os(iOS)
|
2022-08-28 17:18:49 +00:00
|
|
|
.updating($dragGestureOffset) { value, state, _ in
|
|
|
|
guard isVerticalDrag else { return }
|
|
|
|
var translation = value.translation
|
|
|
|
translation.height = max(0, translation.height)
|
|
|
|
state = translation
|
|
|
|
}
|
2024-05-16 16:59:54 +00:00
|
|
|
#endif
|
2022-08-28 17:18:49 +00:00
|
|
|
.updating($dragGestureState) { _, state, _ in
|
|
|
|
state = true
|
|
|
|
}
|
|
|
|
.onChanged { value in
|
2024-05-16 16:59:54 +00:00
|
|
|
guard player.presentingPlayer,
|
|
|
|
!controlsOverlayModel.presenting,
|
|
|
|
dragGestureState else { return }
|
2022-08-28 17:18:49 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
if player.controls.presentingControls, !player.musicMode {
|
|
|
|
player.controls.presentingControls = false
|
|
|
|
}
|
2022-08-28 17:18:49 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
if player.musicMode {
|
|
|
|
player.backend.stopControlsUpdates()
|
|
|
|
}
|
2022-08-29 11:55:23 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
let verticalDrag = value.translation.height
|
|
|
|
let horizontalDrag = value.translation.width
|
2022-08-28 17:18:49 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
#if os(iOS)
|
2024-08-20 14:14:57 +00:00
|
|
|
// Detect if the gesture starts within the top 5% of the screen and the player is in fullscreen mode
|
|
|
|
if value.startLocation.y <= UIScreen.main.bounds.height * 0.05, PlayerModel.shared.playingFullScreen {
|
|
|
|
// If it's a downward swipe, do nothing (return early)
|
|
|
|
if verticalDrag > 0, abs(verticalDrag) > abs(horizontalDrag) {
|
|
|
|
return
|
|
|
|
}
|
2024-05-16 16:59:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
2022-08-28 17:18:49 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
if !isVerticalDrag,
|
|
|
|
horizontalPlayerGestureEnabled,
|
|
|
|
abs(horizontalDrag) > seekGestureSensitivity,
|
|
|
|
!isHorizontalDrag,
|
|
|
|
player.activeBackend == .mpv || !avPlayerUsesSystemControls
|
|
|
|
{
|
|
|
|
isHorizontalDrag = true
|
|
|
|
player.seek.onSeekGestureStart()
|
|
|
|
viewDragOffset = 0
|
|
|
|
}
|
2024-05-01 16:37:42 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
if horizontalPlayerGestureEnabled, isHorizontalDrag {
|
|
|
|
player.seek.updateCurrentTime {
|
|
|
|
let time = player.backend.playerItemDuration?.seconds ?? 0
|
|
|
|
if player.seek.gestureStart.isNil {
|
|
|
|
player.seek.gestureStart = time
|
|
|
|
}
|
|
|
|
let timeSeek = (time / player.playerSize.width) * horizontalDrag * seekGestureSpeed
|
2024-05-01 16:37:42 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
player.seek.gestureSeek = timeSeek
|
|
|
|
}
|
|
|
|
return
|
2024-05-01 16:37:42 +00:00
|
|
|
}
|
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
guard verticalDrag > 0 else { return }
|
|
|
|
viewDragOffset = verticalDrag
|
2024-05-01 16:37:42 +00:00
|
|
|
|
2024-05-16 16:59:54 +00:00
|
|
|
if verticalDrag > 60,
|
|
|
|
player.playingFullScreen
|
|
|
|
{
|
|
|
|
player.exitFullScreen(showControls: false)
|
|
|
|
#if os(iOS)
|
|
|
|
if Constants.isIPhone {
|
|
|
|
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: .portrait)
|
|
|
|
}
|
|
|
|
#endif
|
2024-05-01 16:37:42 +00:00
|
|
|
}
|
2024-05-16 16:59:54 +00:00
|
|
|
}
|
|
|
|
.onEnded { _ in
|
|
|
|
onPlayerDragGestureEnded()
|
|
|
|
}
|
2022-08-28 17:18:49 +00:00
|
|
|
}
|
|
|
|
|
2022-08-29 15:58:40 +00:00
|
|
|
func onPlayerDragGestureEnded() {
|
2022-08-28 17:18:49 +00:00
|
|
|
if horizontalPlayerGestureEnabled, isHorizontalDrag {
|
|
|
|
isHorizontalDrag = false
|
2022-08-29 11:55:23 +00:00
|
|
|
player.seek.onSeekGestureEnd()
|
2022-08-28 17:18:49 +00:00
|
|
|
}
|
|
|
|
|
2023-05-20 20:49:10 +00:00
|
|
|
if viewDragOffset > 60,
|
|
|
|
player.playingFullScreen
|
|
|
|
{
|
|
|
|
#if os(iOS)
|
|
|
|
player.lockedOrientation = nil
|
|
|
|
#endif
|
|
|
|
player.exitFullScreen(showControls: false)
|
|
|
|
viewDragOffset = 0
|
|
|
|
return
|
|
|
|
}
|
2022-08-28 17:18:49 +00:00
|
|
|
isVerticalDrag = false
|
|
|
|
|
|
|
|
guard player.presentingPlayer,
|
2022-09-01 23:05:31 +00:00
|
|
|
!controlsOverlayModel.presenting else { return }
|
2022-08-28 17:18:49 +00:00
|
|
|
|
|
|
|
if viewDragOffset > 100 {
|
|
|
|
withAnimation(Constants.overlayAnimation) {
|
|
|
|
viewDragOffset = Self.hiddenOffset
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
withAnimation(Constants.overlayAnimation) {
|
|
|
|
viewDragOffset = 0
|
|
|
|
}
|
|
|
|
player.backend.setNeedsDrawing(true)
|
|
|
|
player.show()
|
|
|
|
|
|
|
|
if player.musicMode {
|
|
|
|
player.backend.startControlsUpdates()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|