yattee/iOS/OrientationModel.swift
2023-09-23 17:14:21 +02:00

96 lines
3.5 KiB
Swift

import Defaults
import Foundation
import Repeat
import SwiftUI
final class OrientationModel {
static var shared = OrientationModel()
var orientation = UIInterfaceOrientation.portrait
var lastOrientation: UIInterfaceOrientation?
var orientationDebouncer = Debouncer(.milliseconds(300))
var orientationObserver: Any?
private var player = PlayerModel.shared
func configureOrientationUpdatesBasedOnAccelerometer() {
let currentOrientation = OrientationTracker.shared.currentInterfaceOrientation
if currentOrientation.isLandscape,
Defaults[.enterFullscreenInLandscape],
!Defaults[.honorSystemOrientationLock],
!player.playingFullScreen,
!player.currentItem.isNil,
player.lockedOrientation.isNil || player.lockedOrientation!.contains(.landscape),
!player.playingInPictureInPicture,
player.presentingPlayer
{
DispatchQueue.main.async {
self.player.controls.presentingControls = false
self.player.enterFullScreen(showControls: false)
}
player.onPresentPlayer.append {
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: currentOrientation)
}
}
orientationObserver = NotificationCenter.default.addObserver(
forName: OrientationTracker.deviceOrientationChangedNotification,
object: nil,
queue: .main
) { _ in
guard !Defaults[.honorSystemOrientationLock],
self.player.presentingPlayer,
!self.player.playingInPictureInPicture,
self.player.lockedOrientation.isNil
else {
return
}
let orientation = OrientationTracker.shared.currentInterfaceOrientation
guard self.lastOrientation != orientation else {
return
}
self.lastOrientation = orientation
DispatchQueue.main.async {
guard Defaults[.enterFullscreenInLandscape],
self.player.presentingPlayer
else {
return
}
self.orientationDebouncer.callback = {
DispatchQueue.main.async {
if orientation.isLandscape {
self.player.controls.presentingControls = false
self.player.enterFullScreen(showControls: false)
Orientation.lockOrientation(OrientationTracker.shared.currentInterfaceOrientationMask, andRotateTo: orientation)
} else {
self.player.exitFullScreen(showControls: false)
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: .portrait)
}
}
}
self.orientationDebouncer.call()
}
}
}
func stopOrientationUpdates() {
guard let observer = orientationObserver else { return }
NotificationCenter.default.removeObserver(observer)
}
func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation? = nil) {
if let rotateOrientation {
self.orientation = rotateOrientation
lastOrientation = rotateOrientation
}
Orientation.lockOrientation(orientation, andRotateTo: rotateOrientation)
}
}