// // ComposeSceneDelegate.swift // Tusker // // Created by Shadowfacts on 12/12/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import UIKit import Combine import UserAccounts import ComposeUI class ComposeSceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate { var window: UIWindow? var rootViewController: TuskerRootViewController? { nil } private var cancellables = Set() func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } guard UserAccountsManager.shared.onboardingComplete else { UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil) return } let account: UserAccountInfo let controller: MastodonController let draft: Draft? if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity { if let activityAccount = UserActivityManager.getAccount(from: activity) { account = activityAccount } else { // todo: this potentially changes the account for the draft, should show the same warning to user as in the drafts selection screen account = UserAccountsManager.shared.getMostRecentAccount()! } controller = MastodonController.getForAccount(account) if let activityDraft = UserActivityManager.getDraft(from: activity) { draft = activityDraft } else if let mentioning = activity.userInfo?["mentioning"] as? String { draft = controller.createDraft(inReplyToID: nil, mentioningAcct: mentioning) } else { draft = nil } } else { account = UserAccountsManager.shared.getMostRecentAccount()! controller = MastodonController.getForAccount(account) draft = nil } session.mastodonController = controller controller.initialize() let composeVC = NewComposeHostingController(draft: draft, mastodonController: controller) composeVC.delegate = self let nav = EnhancedNavigationViewController(rootViewController: composeVC) window = UIWindow(windowScene: windowScene) window!.rootViewController = nav window!.makeKeyAndVisible() updateTitle(draft: composeVC.controller.draft) composeVC.controller.$draft .sink { [unowned self] in self.updateTitle(draft: $0) } .store(in: &cancellables) NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil) themePrefChanged() } func sceneWillResignActive(_ scene: UIScene) { OldDraftsManager.save() if let window = window, let nav = window.rootViewController as? UINavigationController, let compose = nav.topViewController as? ComposeHostingController { scene.userActivity = UserActivityManager.editDraftActivity(id: compose.draft.id, accountID: scene.session.mastodonController!.accountInfo!.id) } } func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? { return scene.userActivity } private func updateTitle(draft: Draft) { guard let scene = window?.windowScene, let mastodonController = scene.session.mastodonController else { return } if let inReplyToID = draft.inReplyToID, let inReplyTo = mastodonController.persistentContainer.status(for: inReplyToID) { scene.title = "Reply to @\(inReplyTo.account.acct)" } else { scene.title = "New Post" } } @objc private func themePrefChanged() { applyAppearancePreferences() } } extension ComposeSceneDelegate: NewComposeHostingControllerDelegate { func dismissCompose(mode: DismissMode) -> Bool { let animation: UIWindowScene.DismissalAnimation switch mode { case .cancel: animation = .decline case .post: animation = .commit } closeWindow(animation: animation) return true } }