194 lines
7.5 KiB
Swift
194 lines
7.5 KiB
Swift
//
|
|
// SceneDelegate.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 1/6/20.
|
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Pachyderm
|
|
import CrashReporter
|
|
import MessageUI
|
|
|
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|
|
|
var window: UIWindow?
|
|
|
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
|
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
|
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
|
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
|
guard let windowScene = scene as? UIWindowScene else { return }
|
|
|
|
window = UIWindow(windowScene: windowScene)
|
|
|
|
if let report = AppDelegate.pendingCrashReport {
|
|
AppDelegate.pendingCrashReport = nil
|
|
handlePendingCrashReport(report, session: session)
|
|
} else {
|
|
showAppOrOnboardingUI(session: session)
|
|
}
|
|
|
|
window!.makeKeyAndVisible()
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil)
|
|
themePrefChanged()
|
|
|
|
if let shortcutItem = connectionOptions.shortcutItem {
|
|
_ = AppShortcutItem.handle(shortcutItem)
|
|
}
|
|
}
|
|
|
|
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
|
|
if URLContexts.count > 1 {
|
|
fatalError("Cannot open more than 1 URL")
|
|
}
|
|
|
|
let url = URLContexts.first!.url
|
|
|
|
if url.host == "x-callback-url" {
|
|
_ = XCBManager.handle(url: url)
|
|
} else if var components = URLComponents(url: url, resolvingAgainstBaseURL: false),
|
|
let tabBarController = window!.rootViewController as? MainTabBarViewController,
|
|
let exploreNavController = tabBarController.getTabController(tab: .explore) as? UINavigationController,
|
|
let exploreController = exploreNavController.viewControllers.first as? ExploreViewController {
|
|
|
|
tabBarController.select(tab: .explore)
|
|
exploreNavController.popToRootViewController(animated: false)
|
|
|
|
exploreController.loadViewIfNeeded()
|
|
exploreController.searchController.isActive = true
|
|
|
|
components.scheme = "https"
|
|
let query = url.absoluteString
|
|
exploreController.searchController.searchBar.text = query
|
|
exploreController.resultsController.performSearch(query: query)
|
|
}
|
|
}
|
|
|
|
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
|
_ = userActivity.handleResume()
|
|
}
|
|
|
|
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
|
completionHandler(AppShortcutItem.handle(shortcutItem))
|
|
}
|
|
|
|
func sceneDidDisconnect(_ scene: UIScene) {
|
|
// Called as the scene is being released by the system.
|
|
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
|
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
|
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
|
|
|
|
Preferences.save()
|
|
DraftsManager.save()
|
|
}
|
|
|
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
|
// Called when the scene has moved from an inactive state to an active state.
|
|
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
|
}
|
|
|
|
func sceneWillResignActive(_ scene: UIScene) {
|
|
// Called when the scene will move from an active state to an inactive state.
|
|
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
|
|
|
Preferences.save()
|
|
DraftsManager.save()
|
|
}
|
|
|
|
func sceneWillEnterForeground(_ scene: UIScene) {
|
|
// Called as the scene transitions from the background to the foreground.
|
|
// Use this method to undo the changes made on entering the background.
|
|
}
|
|
|
|
func sceneDidEnterBackground(_ scene: UIScene) {
|
|
// Called as the scene transitions from the foreground to the background.
|
|
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
|
// to restore the scene back to its current state.
|
|
|
|
try! scene.session.mastodonController?.persistentContainer.viewContext.save()
|
|
}
|
|
|
|
private func handlePendingCrashReport(_ report: PLCrashReport, session: UISceneSession) {
|
|
#if !DEBUG
|
|
guard MFMailComposeViewController.canSendMail() else {
|
|
print("Cannot send email")
|
|
showAppOrOnboardingUI(session: session)
|
|
return
|
|
}
|
|
|
|
window!.rootViewController = CrashReporterViewController.create(report: report)
|
|
#endif
|
|
}
|
|
|
|
func showAppOrOnboardingUI(session: UISceneSession? = nil) {
|
|
let session = session ?? window!.windowScene!.session
|
|
if LocalData.shared.onboardingComplete {
|
|
if session.mastodonController == nil {
|
|
let account = LocalData.shared.getMostRecentAccount()!
|
|
session.mastodonController = MastodonController.getForAccount(account)
|
|
}
|
|
|
|
showAppUI()
|
|
} else {
|
|
showOnboardingUI()
|
|
}
|
|
}
|
|
|
|
func activateAccount(_ account: LocalData.UserAccountInfo) {
|
|
LocalData.shared.setMostRecentAccount(account)
|
|
window!.windowScene!.session.mastodonController = MastodonController.getForAccount(account)
|
|
showAppUI()
|
|
}
|
|
|
|
func logoutCurrent() {
|
|
LocalData.shared.removeAccount(LocalData.shared.getMostRecentAccount()!)
|
|
if LocalData.shared.onboardingComplete {
|
|
activateAccount(LocalData.shared.accounts.first!)
|
|
} else {
|
|
showOnboardingUI()
|
|
}
|
|
}
|
|
|
|
func showAppUI() {
|
|
let mastodonController = window!.windowScene!.session.mastodonController!
|
|
mastodonController.getOwnAccount()
|
|
mastodonController.getOwnInstance()
|
|
|
|
let rootController: UIViewController
|
|
if #available(iOS 14.0, *) {
|
|
rootController = MainSplitViewController(mastodonController: mastodonController)
|
|
} else {
|
|
rootController = MainTabBarViewController(mastodonController: mastodonController)
|
|
}
|
|
window!.rootViewController = rootController
|
|
}
|
|
|
|
func showOnboardingUI() {
|
|
let onboarding = OnboardingViewController()
|
|
onboarding.onboardingDelegate = self
|
|
window!.rootViewController = onboarding
|
|
}
|
|
|
|
@objc func themePrefChanged() {
|
|
window?.overrideUserInterfaceStyle = Preferences.shared.theme
|
|
}
|
|
|
|
}
|
|
|
|
extension SceneDelegate: OnboardingViewControllerDelegate {
|
|
func didFinishOnboarding(account: LocalData.UserAccountInfo) {
|
|
activateAccount(account)
|
|
}
|
|
}
|
|
|
|
extension SceneDelegate: MFMailComposeViewControllerDelegate {
|
|
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
|
|
controller.dismiss(animated: true) {
|
|
self.showAppOrOnboardingUI()
|
|
}
|
|
}
|
|
}
|