Tusker/Tusker/Scenes/AuxiliarySceneDelegate.swift

133 lines
5.5 KiB
Swift

//
// AuxiliarySceneDelegate.swift
// Tusker
//
// Created by Shadowfacts on 12/13/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
import UserAccounts
class AuxiliarySceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate {
var window: UIWindow?
var rootViewController: TuskerRootViewController? {
window?.rootViewController as? TuskerRootViewController
}
private var launchActivity: NSUserActivity?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
return
}
guard let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity else {
// without an account, we don't know what type of auxiliary scene this is and can't do anything
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
return
}
launchActivity = activity
let account: UserAccountInfo
if let activityAccount = UserActivityManager.getAccount(from: activity) {
account = activityAccount
} else if let mostRecent = UserAccountsManager.shared.getMostRecentAccount() {
account = mostRecent
} else {
// without an account, we can't do anything so we just destroy the scene
// todo: this isn't really true for instance public timelines, how much do we care about that?
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
return
}
let controller = MastodonController.getForAccount(account)
session.mastodonController = controller
controller.initialize()
guard let rootVC = viewController(for: activity, mastodonController: controller) else {
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
return
}
rootVC.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(close))
let nav = EnhancedNavigationViewController(rootViewController: rootVC)
window = UIWindow(windowScene: windowScene)
window!.rootViewController = nav
window!.makeKeyAndVisible()
NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil)
themePrefChanged()
}
func sceneWillResignActive(_ scene: UIScene) {
scene.userActivity = launchActivity
}
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
return scene.userActivity
}
private func viewController(for activity: NSUserActivity, mastodonController: MastodonController) -> UIViewController? {
switch UserActivityType(rawValue: activity.activityType) {
case .showTimeline:
guard let (timeline, _) = UserActivityManager.getTimeline(from: activity) else { return nil }
return timelineViewController(for: timeline, mastodonController: mastodonController)
case .showConversation:
guard let id = UserActivityManager.getConversationStatus(from: activity) else { return nil }
return ConversationViewController(for: id, state: .unknown, mastodonController: mastodonController)
case .checkNotifications:
guard let mode = UserActivityManager.getNotificationsMode(from: activity) else { return nil }
return NotificationsPageViewController(initialMode: mode, mastodonController: mastodonController)
case .search:
return InlineTrendsViewController(mastodonController: mastodonController)
case .bookmarks:
return BookmarksViewController(mastodonController: mastodonController)
case .myProfile:
return MyProfileViewController(mastodonController: mastodonController)
case .showProfile:
guard let id = UserActivityManager.getProfile(from: activity) else { return nil }
return ProfileViewController(accountID: id, mastodonController: mastodonController)
default:
fatalError("invalid activity type for auxiliary scene: \(activity.activityType)")
}
}
private func timelineViewController(for timeline: Timeline, mastodonController: MastodonController) -> UIViewController {
switch timeline {
case .tag(hashtag: let name):
return HashtagTimelineViewController(forNamed: name, mastodonController: mastodonController)
case .list(id: let id):
let req = ListMO.fetchRequest(id: id)
if let list = try? mastodonController.persistentContainer.viewContext.fetch(req).first {
return ListTimelineViewController(for: list.apiList, mastodonController: mastodonController)
} else {
return TimelineViewController(for: timeline, mastodonController: mastodonController)
}
default:
return TimelineViewController(for: timeline, mastodonController: mastodonController)
}
}
@objc private func close() {
closeWindow()
}
@objc private func themePrefChanged() {
applyAppearancePreferences()
}
}