// // AuxiliarySceneDelegate.swift // Tusker // // Created by Shadowfacts on 12/13/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import UIKit import Pachyderm 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: LocalData.UserAccountInfo if let activityAccount = UserActivityManager.getAccount(from: activity) { account = activityAccount } else if let mostRecent = LocalData.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 { // todo: list/hashtag controllers need whole objects which must be fetched asynchronously default: return TimelineViewController(for: timeline, mastodonController: mastodonController) } } @objc private func close() { closeWindow() } @objc private func themePrefChanged() { applyAppearancePreferences() } }