mirror of
https://github.com/cranci1/Sora.git
synced 2026-04-19 07:32:08 +00:00
131 lines
4.7 KiB
Swift
131 lines
4.7 KiB
Swift
//
|
|
// SoraApp.swift
|
|
// Sora
|
|
//
|
|
// Created by Francesco on 06/01/25.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
@main
|
|
struct SoraApp: App {
|
|
@StateObject private var settings = Settings()
|
|
@StateObject private var moduleManager = ModuleManager()
|
|
@StateObject private var libraryManager = LibraryManager()
|
|
@StateObject private var downloadManager = DownloadManager()
|
|
@StateObject private var jsController = JSController.shared
|
|
|
|
init() {
|
|
if let userAccentColor = UserDefaults.standard.color(forKey: "accentColor") {
|
|
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = userAccentColor
|
|
}
|
|
|
|
Task { @MainActor in
|
|
await Self.clearTmpFolder()
|
|
|
|
TraktToken.checkAuthenticationStatus { isAuthenticated in
|
|
if isAuthenticated {
|
|
Logger.shared.log("Trakt authentication is valid", type: "Debug")
|
|
} else {
|
|
Logger.shared.log("Trakt authentication required", type: "Debug")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
Group {
|
|
if !UserDefaults.standard.bool(forKey: "hideSplashScreen") {
|
|
SplashScreenView()
|
|
} else {
|
|
ContentView()
|
|
}
|
|
}
|
|
.environment(\.layoutDirection, .leftToRight)
|
|
.environmentObject(moduleManager)
|
|
.environmentObject(settings)
|
|
.environmentObject(libraryManager)
|
|
.environmentObject(downloadManager)
|
|
.environmentObject(jsController)
|
|
.accentColor(settings.accentColor)
|
|
.onAppear {
|
|
settings.updateAppearance()
|
|
Task {
|
|
if UserDefaults.standard.bool(forKey: "refreshModulesOnLaunch") {
|
|
await moduleManager.refreshModules()
|
|
}
|
|
}
|
|
}
|
|
.onOpenURL { url in
|
|
handleURL(url)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func handleURL(_ url: URL) {
|
|
guard url.scheme == "sora", let host = url.host else { return }
|
|
switch host {
|
|
case "default_page":
|
|
if let comps = URLComponents(url: url, resolvingAgainstBaseURL: true),
|
|
let libraryURL = comps.queryItems?.first(where: { $0.name == "url" })?.value {
|
|
|
|
UserDefaults.standard.set(libraryURL, forKey: "lastCommunityURL")
|
|
UserDefaults.standard.set(true, forKey: "didReceiveDefaultPageLink")
|
|
|
|
DropManager.shared.showDrop(
|
|
title: "Module Library Added",
|
|
subtitle: "You can browse the community library in settings.",
|
|
duration: 2,
|
|
icon: UIImage(systemName: "books.vertical.circle.fill")
|
|
)
|
|
}
|
|
|
|
case "module":
|
|
guard url.scheme == "sora",
|
|
url.host == "module",
|
|
let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
|
|
let moduleURL = components.queryItems?.first(where: { $0.name == "url" })?.value
|
|
else {
|
|
return
|
|
}
|
|
|
|
let addModuleView = ModuleAdditionSettingsView(moduleUrl: moduleURL).environmentObject(moduleManager)
|
|
let hostingController = UIHostingController(rootView: addModuleView)
|
|
|
|
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
|
let window = windowScene.windows.first {
|
|
window.rootViewController?.present(hostingController, animated: true)
|
|
} else {
|
|
Logger.shared.log(
|
|
"Failed to present module addition view: No window scene found",
|
|
type: "Error"
|
|
)
|
|
}
|
|
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
private static func clearTmpFolder() async {
|
|
let fileManager = FileManager.default
|
|
let tmpDirectory = NSTemporaryDirectory()
|
|
|
|
do {
|
|
let tmpURL = URL(fileURLWithPath: tmpDirectory)
|
|
let tmpContents = try fileManager.contentsOfDirectory(at: tmpURL, includingPropertiesForKeys: nil)
|
|
|
|
try await withThrowingTaskGroup(of: Void.self) { group in
|
|
for url in tmpContents {
|
|
group.addTask {
|
|
try FileManager.default.removeItem(at: url)
|
|
}
|
|
}
|
|
try await group.waitForAll()
|
|
}
|
|
} catch {
|
|
Logger.shared.log("Failed to clear tmp folder: \(error.localizedDescription)", type: "Error")
|
|
}
|
|
}
|
|
}
|