From 30e944ffc4668d6a461aa885f786c87e767d40bf Mon Sep 17 00:00:00 2001 From: Ethan Pippin Date: Thu, 8 Aug 2024 22:25:32 -0600 Subject: [PATCH] Fix iOS 15 Rotation (#1174) * fix and clean * fix --- .../PreferencesView/PreferenceKeys.swift | 4 +- .../UIPreferencesHostingController.swift | 26 ++++++++++ .../LiveVideoPlayerCoordinator.swift | 35 ++++++++++--- .../Coordinators/VideoPlayerCoordinator.swift | 45 ++++++++++++----- Shared/Services/SwiftfinNotifications.swift | 2 + Swiftfin/App/SwiftfinApp.swift | 50 +++++++++++++------ 6 files changed, 126 insertions(+), 36 deletions(-) diff --git a/PreferencesView/Sources/PreferencesView/PreferenceKeys.swift b/PreferencesView/Sources/PreferencesView/PreferenceKeys.swift index 75a1404f..d1819d8b 100644 --- a/PreferencesView/Sources/PreferencesView/PreferenceKeys.swift +++ b/PreferencesView/Sources/PreferencesView/PreferenceKeys.swift @@ -38,6 +38,8 @@ struct SupportedOrientationsPreferenceKey: PreferenceKey { static var defaultValue: UIInterfaceOrientationMask = .allButUpsideDown - static func reduce(value: inout UIInterfaceOrientationMask, nextValue: () -> UIInterfaceOrientationMask) {} + static func reduce(value: inout UIInterfaceOrientationMask, nextValue: () -> UIInterfaceOrientationMask) { + value = nextValue() + } } #endif diff --git a/PreferencesView/Sources/PreferencesView/UIPreferencesHostingController.swift b/PreferencesView/Sources/PreferencesView/UIPreferencesHostingController.swift index 4fc79d1c..328335dc 100644 --- a/PreferencesView/Sources/PreferencesView/UIPreferencesHostingController.swift +++ b/PreferencesView/Sources/PreferencesView/UIPreferencesHostingController.swift @@ -81,6 +81,8 @@ public class UIPreferencesHostingController: UIHostingController { didSet { if #available(iOS 16, *) { setNeedsUpdateOfSupportedInterfaceOrientations() + } else { + AppRotationUtility.lockOrientation(_orientations) } } } @@ -111,3 +113,27 @@ public class UIPreferencesHostingController: UIHostingController { #endif } + +// TODO: remove after iOS 15 support removed + +#if os(iOS) +enum AppRotationUtility { + + static func lockOrientation(_ orientationLock: UIInterfaceOrientationMask) { + + guard UIDevice.current.userInterfaceIdiom == .phone else { return } + + let rotateOrientation: UIInterfaceOrientation + + switch orientationLock { + case .landscape: + rotateOrientation = .landscapeRight + default: + rotateOrientation = .portrait + } + + UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation") + UINavigationController.attemptRotationToDeviceOrientation() + } +} +#endif diff --git a/Shared/Coordinators/LiveVideoPlayerCoordinator.swift b/Shared/Coordinators/LiveVideoPlayerCoordinator.swift index 0c2e1263..16c449ec 100644 --- a/Shared/Coordinators/LiveVideoPlayerCoordinator.swift +++ b/Shared/Coordinators/LiveVideoPlayerCoordinator.swift @@ -26,11 +26,22 @@ final class LiveVideoPlayerCoordinator: NavigationCoordinatable { self.videoPlayerManager = manager } + #if os(iOS) @ViewBuilder - func makeStart() -> some View { - #if os(iOS) - - PreferencesView { + private var versionedView: some View { + if #available(iOS 16, *) { + PreferencesView { + Group { + if Defaults[.VideoPlayer.videoPlayerType] == .swiftfin { + LiveVideoPlayer(manager: self.videoPlayerManager) + } else { + LiveNativeVideoPlayer(manager: self.videoPlayerManager) + } + } + .preferredColorScheme(.dark) + .supportedOrientations(UIDevice.isPhone ? .landscape : .allButUpsideDown) + } + } else { Group { if Defaults[.VideoPlayer.videoPlayerType] == .swiftfin { LiveVideoPlayer(manager: self.videoPlayerManager) @@ -40,10 +51,20 @@ final class LiveVideoPlayerCoordinator: NavigationCoordinatable { } .preferredColorScheme(.dark) .supportedOrientations(UIDevice.isPhone ? .landscape : .allButUpsideDown) + .preferredColorScheme(.dark) + .supportedOrientations(UIDevice.isPhone ? .landscape : .allButUpsideDown) } - .ignoresSafeArea() - .backport - .persistentSystemOverlays(.hidden) + } + #endif + + @ViewBuilder + func makeStart() -> some View { + #if os(iOS) + + versionedView + .ignoresSafeArea() + .backport + .persistentSystemOverlays(.hidden) #else diff --git a/Shared/Coordinators/VideoPlayerCoordinator.swift b/Shared/Coordinators/VideoPlayerCoordinator.swift index d56b2abd..55a89e0d 100644 --- a/Shared/Coordinators/VideoPlayerCoordinator.swift +++ b/Shared/Coordinators/VideoPlayerCoordinator.swift @@ -26,16 +26,24 @@ final class VideoPlayerCoordinator: NavigationCoordinatable { self.videoPlayerManager = manager } - @ViewBuilder - func makeStart() -> some View { - #if os(iOS) + // TODO: removed after iOS 15 support removed - // Some settings have to apply to the root PreferencesView and this - // one - separately. - // It is assumed that because Stinsen adds a lot of views that the - // PreferencesView isn't in the right place in the VC chain so that - // it can apply the settings, even SwiftUI settings. - PreferencesView { + #if os(iOS) + @ViewBuilder + private var versionedView: some View { + if #available(iOS 16, *) { + PreferencesView { + Group { + if Defaults[.VideoPlayer.videoPlayerType] == .swiftfin { + VideoPlayer(manager: self.videoPlayerManager) + } else { + NativeVideoPlayer(manager: self.videoPlayerManager) + } + } + .preferredColorScheme(.dark) + .supportedOrientations(UIDevice.isPhone ? .landscape : .allButUpsideDown) + } + } else { Group { if Defaults[.VideoPlayer.videoPlayerType] == .swiftfin { VideoPlayer(manager: self.videoPlayerManager) @@ -46,9 +54,22 @@ final class VideoPlayerCoordinator: NavigationCoordinatable { .preferredColorScheme(.dark) .supportedOrientations(UIDevice.isPhone ? .landscape : .allButUpsideDown) } - .ignoresSafeArea() - .backport - .persistentSystemOverlays(.hidden) + } + #endif + + @ViewBuilder + func makeStart() -> some View { + #if os(iOS) + + // Some settings have to apply to the root PreferencesView and this + // one - separately. + // It is assumed that because Stinsen adds a lot of views that the + // PreferencesView isn't in the right place in the VC chain so that + // it can apply the settings, even SwiftUI settings. + versionedView + .ignoresSafeArea() + .backport + .persistentSystemOverlays(.hidden) #else if Defaults[.VideoPlayer.videoPlayerType] == .swiftfin { diff --git a/Shared/Services/SwiftfinNotifications.swift b/Shared/Services/SwiftfinNotifications.swift index 396b73d5..08bfd64a 100644 --- a/Shared/Services/SwiftfinNotifications.swift +++ b/Shared/Services/SwiftfinNotifications.swift @@ -86,4 +86,6 @@ extension Notifications.Key { static let didDeleteServer = NotificationKey("didDeleteServer") static let didChangeUserProfileImage = NotificationKey("didChangeUserProfileImage") + + static let didStartPlayback = NotificationKey("didStartPlayback") } diff --git a/Swiftfin/App/SwiftfinApp.swift b/Swiftfin/App/SwiftfinApp.swift index 1e200a5d..c37087ac 100644 --- a/Swiftfin/App/SwiftfinApp.swift +++ b/Swiftfin/App/SwiftfinApp.swift @@ -71,31 +71,49 @@ struct SwiftfinApp: App { } } - var body: some Scene { - WindowGroup { + // TODO: removed after iOS 15 support removed + + @ViewBuilder + private var versionedView: some View { + if #available(iOS 16, *) { PreferencesView { MainCoordinator() .view() .supportedOrientations(UIDevice.isPad ? .allButUpsideDown : .portrait) } - .ignoresSafeArea() - .onNotification(UIApplication.didEnterBackgroundNotification) { _ in - Defaults[.backgroundTimeStamp] = Date.now - } - .onNotification(UIApplication.willEnterForegroundNotification) { _ in - - // TODO: needs to check if any background playback is happening - // - atow, background video playback isn't officially supported - let backgroundedInterval = Date.now.timeIntervalSince(Defaults[.backgroundTimeStamp]) - - if backgroundedInterval > Defaults[.backgroundSignOutInterval] { - Defaults[.lastSignedInUserID] = nil - Container.shared.currentUserSession.reset() - Notifications[.didSignOut].post() + } else { + PreferencesView { + PreferencesView { + MainCoordinator() + .view() + .supportedOrientations(UIDevice.isPad ? .allButUpsideDown : .portrait) } + .ignoresSafeArea() } } } + + var body: some Scene { + WindowGroup { + versionedView + .ignoresSafeArea() + .onNotification(UIApplication.didEnterBackgroundNotification) { _ in + Defaults[.backgroundTimeStamp] = Date.now + } + .onNotification(UIApplication.willEnterForegroundNotification) { _ in + + // TODO: needs to check if any background playback is happening + // - atow, background video playback isn't officially supported + let backgroundedInterval = Date.now.timeIntervalSince(Defaults[.backgroundTimeStamp]) + + if backgroundedInterval > Defaults[.backgroundSignOutInterval] { + Defaults[.lastSignedInUserID] = nil + Container.shared.currentUserSession.reset() + Notifications[.didSignOut].post() + } + } + } + } } extension UINavigationController {