damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

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:
Mdamus/Views/Video/DamusVideoPlayer.swift | 28++++++++++++++++++++--------
Mdamus/damusApp.swift | 17+++++++++++++++++
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 + } +}