1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-15 14:50:32 +05:30
yattee/Shared/YatteeApp.swift

298 lines
11 KiB
Swift
Raw Normal View History

2021-09-25 13:48:22 +05:30
import Defaults
import MediaPlayer
import PINCache
import SDWebImage
import SDWebImageWebPCoder
import Siesta
2021-06-10 02:21:23 +05:30
import SwiftUI
@main
2021-11-07 19:02:01 +05:30
struct YatteeApp: App {
2022-01-06 20:32:53 +05:30
static var version: String {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
}
static var build: String {
Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "unknown"
}
static var isForPreviews: Bool {
ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
}
2022-07-07 03:38:38 +05:30
static var logsDirectory: URL {
2024-02-02 04:24:16 +05:30
temporaryDirectory
}
static var settingsExportDirectory: URL {
temporaryDirectory
}
private static var temporaryDirectory: URL {
2022-07-07 03:38:38 +05:30
URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
}
2021-10-24 14:46:04 +05:30
#if os(macOS)
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#elseif os(iOS)
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
2023-07-24 23:08:32 +05:30
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
2021-10-24 14:46:04 +05:30
#endif
@State private var configured = false
2023-04-23 01:43:59 +05:30
@StateObject private var accounts = AccountsModel.shared
@StateObject private var comments = CommentsModel.shared
@StateObject private var instances = InstancesModel.shared
@StateObject private var menu = MenuModel.shared
2023-04-23 01:43:59 +05:30
@StateObject private var navigation = NavigationModel.shared
@StateObject private var networkState = NetworkStateModel.shared
@StateObject private var player = PlayerModel.shared
@StateObject private var playlists = PlaylistsModel.shared
@StateObject private var recents = RecentsModel.shared
@StateObject private var settings = SettingsModel.shared
2022-12-11 20:45:42 +05:30
@StateObject private var subscriptions = SubscribedChannelsModel.shared
@StateObject private var thumbnails = ThumbnailsModel.shared
2021-11-09 04:44:28 +05:30
let persistenceController = PersistenceController.shared
2023-05-25 17:58:29 +05:30
var favorites: FavoritesModel { .shared }
2022-09-01 23:31:01 +05:30
var playerControls: PlayerControlsModel { .shared }
2021-06-10 02:21:23 +05:30
var body: some Scene {
WindowGroup {
ContentView()
.onAppear(perform: configure)
.environment(\.managedObjectContext, persistenceController.container.viewContext)
2023-07-24 23:08:32 +05:30
.environment(\.navigationStyle, navigationStyle)
2022-01-06 21:05:45 +05:30
#if os(macOS)
.background(
HostingWindowFinder { window in
Windows.mainWindow = window
}
)
#else
2023-05-08 01:15:18 +05:30
.onReceive(
2022-01-06 21:05:45 +05:30
NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)
) { _ in
player.handleEnterForeground()
}
2022-06-05 22:42:00 +05:30
.onReceive(
NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)
) { _ in
player.handleEnterBackground()
}
#endif
2021-12-25 00:50:05 +05:30
#if os(iOS)
.handlesExternalEvents(preferring: Set(["*"]), allowing: Set(["*"]))
#endif
2023-07-24 23:08:32 +05:30
#if !os(tvOS)
.onOpenURL { url in
URLBookmarkModel.shared.saveBookmark(url)
OpenURLHandler(navigationStyle: navigationStyle).handle(url)
}
#endif
2021-06-10 02:21:23 +05:30
}
2021-12-25 00:50:05 +05:30
#if os(iOS)
.handlesExternalEvents(matching: Set(["*"]))
#endif
2021-07-28 04:10:04 +05:30
#if !os(tvOS)
2021-11-08 21:59:35 +05:30
.commands {
SidebarCommands()
2021-12-08 04:39:49 +05:30
CommandGroup(replacing: .newItem) {}
2021-12-08 04:39:49 +05:30
MenuCommands(model: Binding<MenuModel>(get: { MenuModel.shared }, set: { _ in }))
2021-11-08 21:59:35 +05:30
}
2021-07-28 04:10:04 +05:30
#endif
2021-09-25 13:48:22 +05:30
#if os(macOS)
WindowGroup(player.windowTitle) {
VideoPlayerView()
.onAppear(perform: configure)
2022-01-06 21:05:45 +05:30
.background(
HostingWindowFinder { window in
Windows.playerWindow = window
2022-04-03 17:53:42 +05:30
2023-06-17 17:39:51 +05:30
NotificationCenter.default.addObserver( // swiftlint:disable:this discarded_notification_center_observer
2022-04-03 17:53:42 +05:30
forName: NSWindow.willExitFullScreenNotification,
object: window,
queue: OperationQueue.main
) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.player.playingFullScreen = false
2022-04-03 17:53:42 +05:30
}
}
2022-01-06 21:05:45 +05:30
}
)
.onAppear { player.presentingPlayer = true }
.onDisappear { player.presentingPlayer = false }
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environment(\.navigationStyle, .sidebar)
2021-12-25 00:50:05 +05:30
.handlesExternalEvents(preferring: Set(["player", "*"]), allowing: Set(["player", "*"]))
2023-07-24 23:08:32 +05:30
.onOpenURL { url in
URLBookmarkModel.shared.saveBookmark(url)
OpenURLHandler(navigationStyle: navigationStyle).handle(url)
}
}
2021-12-25 00:50:05 +05:30
.handlesExternalEvents(matching: Set(["player", "*"]))
2021-09-25 13:48:22 +05:30
Settings {
SettingsView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
2021-09-25 13:48:22 +05:30
}
#endif
}
func configure() {
guard !Self.isForPreviews, !configured else {
return
}
configured = true
DispatchQueue.main.async {
#if DEBUG
SiestaLog.Category.enabled = .common
#endif
#if os(tvOS)
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
#else
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
#endif
2024-05-23 15:14:58 +05:30
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
if !Defaults[.lastAccountIsPublic] {
AccountsModel.shared.configureAccount()
}
if let countryOfPublicInstances = Defaults[.countryOfPublicInstances] {
InstancesManifest.shared.setPublicAccount(countryOfPublicInstances, asCurrent: AccountsModel.shared.current.isNil)
}
if !AccountsModel.shared.current.isNil {
player.restoreQueue()
}
DispatchQueue.global(qos: .userInitiated).async {
if !Defaults[.saveRecents] {
recents.clear()
}
}
let startupSection = Defaults[.startupSection]
var section: TabSelection? = startupSection.tabSelection
#if os(macOS)
if section == .playlists {
section = .search
}
#endif
NavigationModel.shared.tabSelection = section ?? .search
2022-08-15 18:19:12 +05:30
DispatchQueue.main.async {
playlists.load()
}
#if !os(macOS)
player.updateRemoteCommandCenter()
#endif
2022-08-08 23:32:46 +05:30
if player.presentingPlayer {
player.presentingPlayer = false
}
#if os(iOS)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if Defaults[.lockPortraitWhenBrowsing] {
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
} else {
let rotationOrientation =
OrientationTracker.shared.currentDeviceOrientation.rawValue == 4 ? UIInterfaceOrientation.landscapeRight :
(OrientationTracker.shared.currentDeviceOrientation.rawValue == 3 ? UIInterfaceOrientation.landscapeLeft : UIInterfaceOrientation.portrait)
Orientation.lockOrientation(.all, andRotateTo: rotationOrientation)
}
}
#endif
// Initialize UserAgentManager
_ = UserAgentManager.shared
DispatchQueue.global(qos: .userInitiated).async {
URLBookmarkModel.shared.refreshAll()
}
2022-11-15 03:43:29 +05:30
DispatchQueue.global(qos: .userInitiated).async {
self.migrateHomeHistoryItems()
}
2023-05-25 17:58:29 +05:30
DispatchQueue.global(qos: .userInitiated).async {
self.migrateQualityProfiles()
}
#if os(iOS)
DispatchQueue.global(qos: .userInitiated).async {
self.migrateRotateToLandscapeOnEnterFullScreen()
}
DispatchQueue.global(qos: .userInitiated).async {
self.migrateLockPortraitWhenBrowsing()
}
#endif
}
2023-05-25 17:58:29 +05:30
}
func migrateHomeHistoryItems() {
guard Defaults[.homeHistoryItems] > 0 else { return }
if favorites.addableItems().contains(where: { $0.section == .history }) {
let historyItem = FavoriteItem(section: .history)
favorites.add(historyItem)
favorites.setListingStyle(.list, historyItem)
favorites.setLimit(Defaults[.homeHistoryItems], historyItem)
print("migrated home history items: \(favorites.limit(historyItem))")
}
Defaults[.homeHistoryItems] = -1
}
2023-07-24 23:08:32 +05:30
@Default(.qualityProfiles) private var qualityProfilesData
func migrateQualityProfiles() {
for profile in qualityProfilesData where profile.order.isEmpty {
var updatedProfile = profile
updatedProfile.order = Array(QualityProfile.Format.allCases.indices)
QualityProfilesModel.shared.update(profile, updatedProfile)
}
}
#if os(iOS)
func migrateRotateToLandscapeOnEnterFullScreen() {
if Defaults[.rotateToLandscapeOnEnterFullScreen] != .landscapeRight || Defaults[.rotateToLandscapeOnEnterFullScreen] != .landscapeLeft {
Defaults[.rotateToLandscapeOnEnterFullScreen] = .landscapeRight
}
}
func migrateLockPortraitWhenBrowsing() {
if Constants.isIPhone {
Defaults[.lockPortraitWhenBrowsing] = true
} else if Constants.isIPad, Defaults[.lockPortraitWhenBrowsing] {
Defaults[.enterFullscreenInLandscape] = true
}
}
#endif
2023-07-24 23:08:32 +05:30
var navigationStyle: NavigationStyle {
#if os(iOS)
return horizontalSizeClass == .compact ? .tab : .sidebar
#elseif os(tvOS)
return .tab
#else
return .sidebar
#endif
}
2021-06-10 02:21:23 +05:30
}