From 2185718d506359aca7d44754386bf94b6942ea1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Fri, 6 Sep 2024 15:11:31 +0200 Subject: [PATCH 1/3] orientation fullscreen code cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toni Förster --- Model/Player/PlayerModel.swift | 25 ++++++++++++++++++------- iOS/Orientation.swift | 1 - iOS/OrientationModel.swift | 11 +++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index a7ba1c11..5c939104 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -137,6 +137,7 @@ final class PlayerModel: ObservableObject { } @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen + @Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing #endif @Published var currentChapterIndex: Int? @@ -209,7 +210,7 @@ final class PlayerModel: ObservableObject { #if os(iOS) isOrientationLocked = Defaults[.isOrientationLocked] - if isOrientationLocked, Defaults[.lockPortraitWhenBrowsing] { + if isOrientationLocked, lockPortraitWhenBrowsing { lockedOrientation = UIInterfaceOrientationMask.portrait Orientation.lockOrientation(.portrait, andRotateTo: .portrait) } else if isOrientationLocked { @@ -564,7 +565,7 @@ final class PlayerModel: ObservableObject { if !presentingPlayer { #if os(iOS) - if Defaults[.lockPortraitWhenBrowsing] { + if lockPortraitWhenBrowsing { Orientation.lockOrientation(.portrait, andRotateTo: .portrait) } else { Orientation.lockOrientation(.allButUpsideDown) @@ -1155,10 +1156,20 @@ final class PlayerModel: ObservableObject { let lockOrientation = rotateToLandscapeOnEnterFullScreen.interfaceOrientation if currentVideoIsLandscape { if initiatedByButton { - Orientation.lockOrientation(self.isOrientationLocked ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) : .landscape) + Orientation.lockOrientation(isOrientationLocked + ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) + : .landscape) } - let orientation = OrientationTracker.shared.currentDeviceOrientation.isLandscape ? OrientationTracker.shared.currentInterfaceOrientation : self.rotateToLandscapeOnEnterFullScreen.interfaceOrientation - Orientation.lockOrientation(self.isOrientationLocked ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) : .landscape, andRotateTo: orientation) + let orientation = OrientationTracker.shared.currentDeviceOrientation.isLandscape + ? OrientationTracker.shared.currentInterfaceOrientation + : rotateToLandscapeOnEnterFullScreen.interfaceOrientation + + Orientation.lockOrientation( + isOrientationLocked + ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) + : .landscape, + andRotateTo: orientation + ) } } else { if activeBackend == .appleAVPlayer, avPlayerUsesSystemControls { @@ -1169,8 +1180,8 @@ final class PlayerModel: ObservableObject { if Defaults[.lockPortraitWhenBrowsing] { lockedOrientation = UIInterfaceOrientationMask.portrait } - let rotationOrientation = Defaults[.lockPortraitWhenBrowsing] ? UIInterfaceOrientation.portrait : nil - Orientation.lockOrientation(Defaults[.lockPortraitWhenBrowsing] ? .portrait : .allButUpsideDown, andRotateTo: rotationOrientation) + let rotationOrientation = lockPortraitWhenBrowsing ? UIInterfaceOrientation.portrait : nil + Orientation.lockOrientation(lockPortraitWhenBrowsing ? .portrait : .allButUpsideDown, andRotateTo: rotationOrientation) } #endif } diff --git a/iOS/Orientation.swift b/iOS/Orientation.swift index 2b93b18e..8371c012 100644 --- a/iOS/Orientation.swift +++ b/iOS/Orientation.swift @@ -1,5 +1,4 @@ import CoreMotion -import Defaults import Logging import UIKit diff --git a/iOS/OrientationModel.swift b/iOS/OrientationModel.swift index e4beb232..a3d1c2c7 100644 --- a/iOS/OrientationModel.swift +++ b/iOS/OrientationModel.swift @@ -13,6 +13,9 @@ final class OrientationModel { var orientationDebouncer = Debouncer(.milliseconds(300)) var orientationObserver: Any? + @Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing + @Default(.enterFullscreenInLandscape) private var enterFullscreenInLandscape + private var player = PlayerModel.shared func startOrientationUpdates() { @@ -25,7 +28,7 @@ final class OrientationModel { self.logger.info("Notification received: Device orientation changed.") // We only allow .portrait and are not showing the player - guard (!self.player.presentingPlayer && !Defaults[.lockPortraitWhenBrowsing]) || self.player.presentingPlayer + guard (!self.player.presentingPlayer && !self.lockPortraitWhenBrowsing) || self.player.presentingPlayer else { return } @@ -42,7 +45,7 @@ final class OrientationModel { } // Only take action if the player is active and presenting - guard (!self.player.isOrientationLocked && !self.player.playingInPictureInPicture) || (!Defaults[.lockPortraitWhenBrowsing] && !self.player.presentingPlayer) || (!Defaults[.lockPortraitWhenBrowsing] && self.player.presentingPlayer && !self.player.isOrientationLocked) + guard (!self.player.isOrientationLocked && !self.player.playingInPictureInPicture) || (!self.lockPortraitWhenBrowsing && !self.player.presentingPlayer) || (!self.lockPortraitWhenBrowsing && self.player.presentingPlayer && !self.player.isOrientationLocked) else { self.logger.info("Only updating orientation without actions.") return @@ -52,7 +55,7 @@ final class OrientationModel { self.orientationDebouncer.callback = { DispatchQueue.main.async { if orientation.isLandscape { - if Defaults[.enterFullscreenInLandscape], self.player.presentingPlayer { + if self.enterFullscreenInLandscape, self.player.presentingPlayer { self.logger.info("Entering fullscreen because orientation is landscape.") self.player.controls.presentingControls = false self.player.enterFullScreen(showControls: false) @@ -63,7 +66,7 @@ final class OrientationModel { if self.player.playingFullScreen { self.player.exitFullScreen(showControls: false) } - if Defaults[.lockPortraitWhenBrowsing] { + if self.lockPortraitWhenBrowsing { Orientation.lockOrientation(.portrait, andRotateTo: .portrait) } else { Orientation.lockOrientation(OrientationTracker.shared.currentInterfaceOrientationMask, andRotateTo: orientation) From 4e4add3c4238f4be1d9928452f1fbbfbeb02012c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Fri, 6 Sep 2024 16:47:03 +0200 Subject: [PATCH 2/3] fix double rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toni Förster --- Model/Player/PlayerModel.swift | 8 ++++---- Shared/Player/AppleAVPlayerView.swift | 6 +++--- Shared/Settings/BrowsingSettings.swift | 2 +- Shared/YatteeApp.swift | 2 +- Yattee.xcodeproj/project.pbxproj | 6 ++---- iOS/AppDelegate.swift | 2 +- iOS/Orientation.swift | 2 +- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 5c939104..f00ab36a 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -568,7 +568,7 @@ final class PlayerModel: ObservableObject { if lockPortraitWhenBrowsing { Orientation.lockOrientation(.portrait, andRotateTo: .portrait) } else { - Orientation.lockOrientation(.allButUpsideDown) + Orientation.lockOrientation(.all) } #endif } @@ -822,7 +822,7 @@ final class PlayerModel: ObservableObject { } else { isOrientationLocked = false lockedOrientation = nil - Orientation.lockOrientation(.allButUpsideDown) + Orientation.lockOrientation(.all) } } #endif @@ -1167,7 +1167,7 @@ final class PlayerModel: ObservableObject { Orientation.lockOrientation( isOrientationLocked ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) - : .landscape, + : .all, andRotateTo: orientation ) } @@ -1181,7 +1181,7 @@ final class PlayerModel: ObservableObject { lockedOrientation = UIInterfaceOrientationMask.portrait } let rotationOrientation = lockPortraitWhenBrowsing ? UIInterfaceOrientation.portrait : nil - Orientation.lockOrientation(lockPortraitWhenBrowsing ? .portrait : .allButUpsideDown, andRotateTo: rotationOrientation) + Orientation.lockOrientation(lockPortraitWhenBrowsing ? .portrait : .all, andRotateTo: rotationOrientation) } #endif } diff --git a/Shared/Player/AppleAVPlayerView.swift b/Shared/Player/AppleAVPlayerView.swift index a0b78a8e..98d784fa 100644 --- a/Shared/Player/AppleAVPlayerView.swift +++ b/Shared/Player/AppleAVPlayerView.swift @@ -22,8 +22,8 @@ import SwiftUI // not sure why but first rotation call is ignore so doing rotate to same orientation first Delay.by(delay) { let orientation = OrientationTracker.shared.currentDeviceOrientation.isLandscape ? OrientationTracker.shared.currentInterfaceOrientation : self.rotateToLandscapeOnEnterFullScreen.interfaceOrientation - Orientation.lockOrientation(.allButUpsideDown, andRotateTo: OrientationTracker.shared.currentInterfaceOrientation) - Orientation.lockOrientation(.allButUpsideDown, andRotateTo: orientation) + Orientation.lockOrientation(.all, andRotateTo: OrientationTracker.shared.currentInterfaceOrientation) + Orientation.lockOrientation(.all, andRotateTo: orientation) } } } @@ -37,7 +37,7 @@ import SwiftUI if !context.isCancelled { #if os(iOS) if Constants.isIPhone { - Orientation.lockOrientation(.allButUpsideDown, andRotateTo: .portrait) + Orientation.lockOrientation(.all, andRotateTo: .portrait) } if wasPlaying { diff --git a/Shared/Settings/BrowsingSettings.swift b/Shared/Settings/BrowsingSettings.swift index 632834aa..1f7a8d3e 100644 --- a/Shared/Settings/BrowsingSettings.swift +++ b/Shared/Settings/BrowsingSettings.swift @@ -170,7 +170,7 @@ struct BrowsingSettings: View { Orientation.lockOrientation(.portrait, andRotateTo: .portrait) } else { enterFullscreenInLandscape = false - Orientation.lockOrientation(.allButUpsideDown) + Orientation.lockOrientation(.all) } } } diff --git a/Shared/YatteeApp.swift b/Shared/YatteeApp.swift index 8ed8cf94..a072d909 100644 --- a/Shared/YatteeApp.swift +++ b/Shared/YatteeApp.swift @@ -211,7 +211,7 @@ struct YatteeApp: App { let rotationOrientation = OrientationTracker.shared.currentDeviceOrientation.rawValue == 4 ? UIInterfaceOrientation.landscapeRight : (OrientationTracker.shared.currentDeviceOrientation.rawValue == 3 ? UIInterfaceOrientation.landscapeLeft : UIInterfaceOrientation.portrait) - Orientation.lockOrientation(.allButUpsideDown, andRotateTo: rotationOrientation) + Orientation.lockOrientation(.all, andRotateTo: rotationOrientation) } } #endif diff --git a/Yattee.xcodeproj/project.pbxproj b/Yattee.xcodeproj/project.pbxproj index fc1539e0..9a1fa90e 100644 --- a/Yattee.xcodeproj/project.pbxproj +++ b/Yattee.xcodeproj/project.pbxproj @@ -4367,8 +4367,7 @@ INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UIStatusBarStyle = ""; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -4418,8 +4417,7 @@ INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UIStatusBarStyle = ""; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index e6ee8a08..94f2e46e 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -5,7 +5,7 @@ import Logging import UIKit final class AppDelegate: UIResponder, UIApplicationDelegate { - var orientationLock = UIInterfaceOrientationMask.allButUpsideDown + var orientationLock = UIInterfaceOrientationMask.all private var logger = Logger(label: "stream.yattee.app.delegate") private(set) static var instance: AppDelegate! diff --git a/iOS/Orientation.swift b/iOS/Orientation.swift index 8371c012..23798e7f 100644 --- a/iOS/Orientation.swift +++ b/iOS/Orientation.swift @@ -34,7 +34,7 @@ enum Orientation { let rotateOrientationMask = rotateOrientation == .portrait ? UIInterfaceOrientationMask.portrait : rotateOrientation == .landscapeLeft ? .landscapeLeft : rotateOrientation == .landscapeRight ? .landscapeRight : - .allButUpsideDown + .all windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: rotateOrientationMask)) { error in print("denied rotation \(error)") From b2421da95d5b64e461ac23f60ee78b1d07cdd864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Fri, 6 Sep 2024 17:05:20 +0200 Subject: [PATCH 3/3] apply new fullscreen logic to AppleAVPlayerView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toni Förster --- Model/Player/PlayerModel.swift | 8 ++++--- Shared/Player/AppleAVPlayerView.swift | 34 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index f00ab36a..f4b7f3a6 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -136,8 +136,9 @@ final class PlayerModel: ObservableObject { } } - @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen - @Default(.lockPortraitWhenBrowsing) private var lockPortraitWhenBrowsing + @Default(.rotateToLandscapeOnEnterFullScreen) var rotateToLandscapeOnEnterFullScreen + @Default(.lockPortraitWhenBrowsing) var lockPortraitWhenBrowsing + var fullscreenInitiatedByButton = false #endif @Published var currentChapterIndex: Int? @@ -1150,6 +1151,7 @@ final class PlayerModel: ObservableObject { #if os(iOS) if playingFullScreen { if activeBackend == .appleAVPlayer, avPlayerUsesSystemControls { + fullscreenInitiatedByButton = initiatedByButton avPlayerBackend.controller.enterFullScreen(animated: true) return } @@ -1177,7 +1179,7 @@ final class PlayerModel: ObservableObject { avPlayerBackend.controller.dismiss(animated: true) return } - if Defaults[.lockPortraitWhenBrowsing] { + if lockPortraitWhenBrowsing { lockedOrientation = UIInterfaceOrientationMask.portrait } let rotationOrientation = lockPortraitWhenBrowsing ? UIInterfaceOrientation.portrait : nil diff --git a/Shared/Player/AppleAVPlayerView.swift b/Shared/Player/AppleAVPlayerView.swift index 98d784fa..ac5d524d 100644 --- a/Shared/Player/AppleAVPlayerView.swift +++ b/Shared/Player/AppleAVPlayerView.swift @@ -4,11 +4,6 @@ import SwiftUI #if !os(macOS) final class AppleAVPlayerViewControllerDelegate: NSObject, AVPlayerViewControllerDelegate { - #if os(iOS) - @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen - @Default(.avPlayerUsesSystemControls) private var avPlayerUsesSystemControls - #endif - var player: PlayerModel { .shared } func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_: AVPlayerViewController) -> Bool { @@ -17,14 +12,23 @@ import SwiftUI #if os(iOS) func playerViewController(_: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator _: UIViewControllerTransitionCoordinator) { - if PlayerModel.shared.currentVideoIsLandscape { - let delay = PlayerModel.shared.activeBackend == .appleAVPlayer && avPlayerUsesSystemControls ? 0.8 : 0 - // not sure why but first rotation call is ignore so doing rotate to same orientation first - Delay.by(delay) { - let orientation = OrientationTracker.shared.currentDeviceOrientation.isLandscape ? OrientationTracker.shared.currentInterfaceOrientation : self.rotateToLandscapeOnEnterFullScreen.interfaceOrientation - Orientation.lockOrientation(.all, andRotateTo: OrientationTracker.shared.currentInterfaceOrientation) - Orientation.lockOrientation(.all, andRotateTo: orientation) + let lockOrientation = player.rotateToLandscapeOnEnterFullScreen.interfaceOrientation + if player.currentVideoIsLandscape { + if player.fullscreenInitiatedByButton { + Orientation.lockOrientation(player.isOrientationLocked + ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) + : .landscape) } + let orientation = OrientationTracker.shared.currentDeviceOrientation.isLandscape + ? OrientationTracker.shared.currentInterfaceOrientation + : player.rotateToLandscapeOnEnterFullScreen.interfaceOrientation + + Orientation.lockOrientation( + player.isOrientationLocked + ? (lockOrientation == .landscapeRight ? .landscapeRight : .landscapeLeft) + : .all, + andRotateTo: orientation + ) } } @@ -36,9 +40,11 @@ import SwiftUI } if !context.isCancelled { #if os(iOS) - if Constants.isIPhone { - Orientation.lockOrientation(.all, andRotateTo: .portrait) + if self.player.lockPortraitWhenBrowsing { + self.player.lockedOrientation = UIInterfaceOrientationMask.portrait } + let rotationOrientation = self.player.lockPortraitWhenBrowsing ? UIInterfaceOrientation.portrait : nil + Orientation.lockOrientation(self.player.lockPortraitWhenBrowsing ? .portrait : .all, andRotateTo: rotationOrientation) if wasPlaying { self.player.play()