videos: improve precision & sensitivity of auto-pause mechanism
Closes: https://github.com/damus-io/damus/pull/1308 Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
c5d8e4a4a1
commit
5caa4a6e97
@@ -7,10 +7,20 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// get coordinates in Global reference frame given a Local point & geometry
|
||||
func globalCoordinate(localX x: CGFloat, localY y: CGFloat,
|
||||
localGeometry geo: GeometryProxy) -> CGPoint {
|
||||
let localPoint = CGPoint(x: x, y: y)
|
||||
return geo.frame(in: .global).origin.applying(
|
||||
.init(translationX: localPoint.x, y: localPoint.y)
|
||||
)
|
||||
}
|
||||
|
||||
struct DamusVideoPlayer: View {
|
||||
var url: URL
|
||||
@ObservedObject var model: VideoPlayerModel
|
||||
@Binding var video_size: CGSize?
|
||||
@EnvironmentObject private var orientationTracker: OrientationTracker
|
||||
|
||||
var mute_icon: String {
|
||||
if model.has_audio == false || model.muted {
|
||||
@@ -45,10 +55,8 @@ struct DamusVideoPlayer: View {
|
||||
var body: some View {
|
||||
GeometryReader { geo in
|
||||
let localFrame = geo.frame(in: .local)
|
||||
let localCenter = CGPoint(x: localFrame.midX, y: localFrame.midY)
|
||||
let globalCenter = geo.frame(in: .global).origin.applying(.init(translationX: localCenter.x, y: localCenter.y))
|
||||
let centerY = globalCenter.y
|
||||
|
||||
let centerY = globalCoordinate(localX: 0, localY: localFrame.midY, localGeometry: geo).y
|
||||
let delta = localFrame.height / 2
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
VideoPlayer(url: url, model: model)
|
||||
if model.has_audio == true {
|
||||
@@ -66,10 +74,14 @@ struct DamusVideoPlayer: View {
|
||||
video_size = size
|
||||
}
|
||||
.onChange(of: centerY) { _ in
|
||||
let screenHeight = UIScreen.main.bounds.height
|
||||
let screenMidY = screenHeight / 2
|
||||
let tol = 0.20 * screenHeight /// tolerance - can vary to taste ie., % of screen height of a centered box in which video plays
|
||||
model.play = centerY > screenMidY - tol && centerY < screenMidY + tol /// video plays when inside tolerance box
|
||||
/// pause video when it is scrolled beyond visible range
|
||||
let isBelowTop = centerY + delta > 100, /// 100 =~ approx. bottom (y) of ContentView's TabView
|
||||
isAboveBottom = centerY - delta < orientationTracker.deviceMajorAxis
|
||||
if isBelowTop && isAboveBottom {
|
||||
model.start()
|
||||
} else {
|
||||
model.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@ struct damusApp: App {
|
||||
struct MainView: View {
|
||||
@State var needs_setup = false;
|
||||
@State var keypair: Keypair? = nil;
|
||||
@StateObject private var orientationTracker = OrientationTracker()
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if let kp = keypair, !needs_setup {
|
||||
ContentView(keypair: kp)
|
||||
.environmentObject(orientationTracker)
|
||||
} else {
|
||||
SetupView()
|
||||
.onReceive(handle_notify(.login)) { notif in
|
||||
@@ -38,7 +40,11 @@ struct MainView: View {
|
||||
try? clear_keypair()
|
||||
keypair = nil
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
|
||||
orientationTracker.setDeviceMajorAxis()
|
||||
}
|
||||
.onAppear {
|
||||
orientationTracker.setDeviceMajorAxis()
|
||||
keypair = get_saved_keypair()
|
||||
}
|
||||
}
|
||||
@@ -65,3 +71,14 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
|
||||
completionHandler()
|
||||
}
|
||||
}
|
||||
|
||||
class OrientationTracker: ObservableObject {
|
||||
var deviceMajorAxis: CGFloat = 0
|
||||
func setDeviceMajorAxis() {
|
||||
let bounds = UIScreen.main.bounds
|
||||
let height = max(bounds.height, bounds.width) /// device's longest dimension
|
||||
let width = min(bounds.height, bounds.width) /// device's shortest dimension
|
||||
let orientation = UIDevice.current.orientation
|
||||
deviceMajorAxis = (orientation == .portrait || orientation == .unknown) ? height : width
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user