commit 5caa4a6e975bb05141cdefcb761fa3ea282db85f
parent c5d8e4a4a14e71113002e04f60f7ceb1a0550945
Author: gladiusKatana <garthsnyder@protonmail.com>
Date: Wed, 21 Jun 2023 03:11:50 -0400
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>
Diffstat:
2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/damus/Views/Video/DamusVideoPlayer.swift b/damus/Views/Video/DamusVideoPlayer.swift
@@ -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()
+ }
}
}
}
diff --git a/damus/damusApp.swift b/damus/damusApp.swift
@@ -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
+ }
+}