From 55ed2f5d26becc021f58b08060ba9f6208766da2 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 19 Jan 2019 14:31:31 -0500 Subject: [PATCH] Get rid of AppRouter --- Tusker.xcodeproj/project.pbxproj | 6 +- Tusker/AppDelegate.swift | 2 - Tusker/AppRouter.swift | 139 ------------------ .../Compose/ComposeViewController.swift | 16 +- .../ConversationTableViewController.swift | 9 +- .../LargeImageViewController.swift | 5 +- .../Main/MainTabBarViewController.swift | 14 +- .../NotificationsTableViewController.swift | 6 +- .../MyProfileTableViewController.swift | 6 +- .../Profile/ProfileTableViewController.swift | 12 +- .../TimelineTableViewController.swift | 5 +- Tusker/Shortcuts/UserActivityManager.swift | 8 +- Tusker/TuskerNavigationDelegate.swift | 60 +++++--- Tusker/Views/ContentLabel.swift | 10 +- .../ActionNotificationTableViewCell.swift | 4 +- .../FollowNotificationTableViewCell.swift | 4 +- .../ConversationMainStatusTableViewCell.swift | 2 +- Tusker/Views/Status/StatusTableViewCell.swift | 4 +- Tusker/XCallbackURL/XCBActions.swift | 34 +++-- 19 files changed, 105 insertions(+), 241 deletions(-) delete mode 100644 Tusker/AppRouter.swift diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index befce5b86e..d73a489d0c 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -64,7 +64,6 @@ D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */; }; D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; }; D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; }; - D627FF74217BBC9700CC0648 /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF73217BBC9700CC0648 /* AppRouter.swift */; }; D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF75217E923E00CC0648 /* DraftsManager.swift */; }; D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627FF78217E950100CC0648 /* DraftsTableViewController.xib */; }; D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */; }; @@ -306,7 +305,6 @@ D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyProfileTableViewController.swift; sourceTree = ""; }; D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = ""; }; D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = ""; }; - D627FF73217BBC9700CC0648 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = ""; }; D627FF75217E923E00CC0648 /* DraftsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsManager.swift; sourceTree = ""; }; D627FF78217E950100CC0648 /* DraftsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraftsTableViewController.xib; sourceTree = ""; }; D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsTableViewController.swift; sourceTree = ""; }; @@ -971,10 +969,10 @@ D61099AC2144B0CC00432DC2 /* Pachyderm */, D61099B92144B0CC00432DC2 /* PachydermTests */, 04496BC9216252E5001F1B23 /* TTTAttributedLabel */, + D60A548C21ED515800F1F87C /* GMImagePicker */, D6D4DDCE212518A000E1C4BB /* Tusker */, D6D4DDE3212518A200E1C4BB /* TuskerTests */, D6D4DDEE212518A200E1C4BB /* TuskerUITests */, - D60A548C21ED515800F1F87C /* GMImagePicker */, D6D4DDCD212518A000E1C4BB /* Products */, D65A37F221472F300087646E /* Frameworks */, ); @@ -998,7 +996,6 @@ isa = PBXGroup; children = ( D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */, - D627FF73217BBC9700CC0648 /* AppRouter.swift */, D64D0AAC2128D88B005A6F37 /* LocalData.swift */, D627FF75217E923E00CC0648 /* DraftsManager.swift */, D6028B9A2150811100F223B9 /* MastodonCache.swift */, @@ -1489,7 +1486,6 @@ D6B8DB342182A59300424AF7 /* UIAlertController+Visibility.swift in Sources */, D67C57AD21E265FC00C3118B /* LargeAccountDetailView.swift in Sources */, D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */, - D627FF74217BBC9700CC0648 /* AppRouter.swift in Sources */, D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */, diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index a24e263740..730fce2ed2 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -12,7 +12,6 @@ import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - var router: AppRouter! func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) @@ -70,7 +69,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let tabBarController = MainTabBarViewController() window!.rootViewController = tabBarController - router = tabBarController.router } func showOnboardingUI() { diff --git a/Tusker/AppRouter.swift b/Tusker/AppRouter.swift deleted file mode 100644 index 1f89c8808a..0000000000 --- a/Tusker/AppRouter.swift +++ /dev/null @@ -1,139 +0,0 @@ -// -// AppRouter.swift -// Tusker -// -// Created by Shadowfacts on 10/20/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit -import Pachyderm -import SafariServices - -class AppRouter { - - let rootViewController: UIViewController - - init(root: UIViewController) { - self.rootViewController = root - } - - private func getTopViewController(parent vc: UIViewController) -> UIViewController { - if let vc = vc as? UINavigationController, - let top = vc.topViewController { - return getTopViewController(parent: top) - } else if let vc = vc as? UITabBarController, - let selected = vc.selectedViewController { - return getTopViewController(parent: selected) - } else if let presented = vc.presentedViewController { - return getTopViewController(parent: presented) - } else { - return vc - } - } - - private func getNavController(parent vc: UIViewController) -> UINavigationController { - if let vc = vc as? UINavigationController { - return vc - } else if let vc = vc as? UITabBarController, - let selected = vc.selectedViewController { - return getNavController(parent: selected) - } else { - fatalError() - } - } - - func present(_ vc: UIViewController, animated: Bool) { - let top = getTopViewController(parent: rootViewController) - top.present(vc, animated: animated) - } - - func push(_ vc: UIViewController, animated: Bool) { - let nav = getNavController(parent: rootViewController) - nav.pushViewController(vc, animated: true) - } - - func profile(for accountID: String) -> ProfileTableViewController { - return ProfileTableViewController(accountID: accountID, router: self) - } - - func profile(for mention: Mention) -> ProfileTableViewController { - return ProfileTableViewController(accountID: mention.id, router: self) - } - - func timeline(for timeline: Timeline) -> TimelineTableViewController { - return TimelineTableViewController(for: timeline, router: self) - } - - func timeline(tag: Hashtag) -> TimelineTableViewController { - return timeline(for: .tag(hashtag: tag.name)) - } - - func safariViewController(for url: URL) -> SFSafariViewController { - return SFSafariViewController(url: url) - } - - func conversation(for statusID: String) -> ConversationTableViewController { - return ConversationTableViewController(for: statusID, router: self) - } - - func compose(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil) -> ComposeViewController { - return ComposeViewController(inReplyTo: inReplyToID, mentioningAcct: mentioningAcct, text: text, router: self) - } - - func drafts() -> DraftsTableViewController { - return DraftsTableViewController() - } - - func largeImage(_ image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, transitioningDelegate: UIViewControllerTransitioningDelegate?) -> LargeImageViewController { - let vc = LargeImageViewController(image: image, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, router: self) - vc.transitioningDelegate = transitioningDelegate - return vc - } - - func largeImage(gifData: Data, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, transitioningDelegate: UIViewControllerTransitioningDelegate?) -> LargeImageViewController { - let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, router: self) - vc.gifData = gifData - vc.transitioningDelegate = transitioningDelegate - return vc - } - - func moreOptions(forStatus statusID: String) -> UIAlertController { - guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") } - - let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - if let url = status.url { - alert.addAction(UIAlertAction(title: "Open in Safari", style: .default, handler: { (_) in - let vc = SFSafariViewController(url: url) - self.present(vc, animated: true) - })) - alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (_) in - UIPasteboard.general.url = url - })) - alert.addAction(UIAlertAction(title: "Share...", style: .default, handler: { (_) in - let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil) - self.present(vc, animated: true) - })) - } - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - return alert - } - - func moreOptions(forURL url: URL) -> UIAlertController { - let alert = UIAlertController(title: nil, message: url.absoluteString, preferredStyle: .actionSheet) - alert.addAction(UIAlertAction(title: "Open in Safari", style: .default, handler: { (_) in - let vc = SFSafariViewController(url: url) - self.present(vc, animated: true) - })) - alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (_) in - UIPasteboard.general.url = url - })) - alert.addAction(UIAlertAction(title: "Share...", style: .default, handler: { (_) in - let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil) - self.present(vc, animated: true) - })) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - return alert - } - -} diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index 8040def251..aae8a2505f 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -15,8 +15,6 @@ import MobileCoreServices class ComposeViewController: UIViewController { - let router: AppRouter - var inReplyToID: String? var accountsToMention: [String] var initialText: String? @@ -66,9 +64,7 @@ class ComposeViewController: UIViewController { @IBOutlet weak var postProgressView: SteppedProgressView! - init(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil, router: AppRouter) { - self.router = router - + init(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil) { self.inReplyToID = inReplyToID if let inReplyToID = inReplyToID, let inReplyTo = MastodonCache.status(for: inReplyToID) { accountsToMention = [inReplyTo.account.acct] + inReplyTo.mentions.map { $0.acct } @@ -323,7 +319,7 @@ class ComposeViewController: UIViewController { self.close() })) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - router.present(alert, animated: true) + present(alert, animated: true) } @objc func contentWarningButtonPressed() { @@ -366,9 +362,9 @@ class ComposeViewController: UIViewController { } @objc func draftsButtonPressed() { - let draftsVC = router.drafts() + let draftsVC = DraftsTableViewController() draftsVC.delegate = self - router.present(UINavigationController(rootViewController: draftsVC), animated: true) + present(UINavigationController(rootViewController: draftsVC), animated: true) } @IBAction func addAttachmentPressed(_ sender: Any) { @@ -460,8 +456,8 @@ class ComposeViewController: UIViewController { self.postProgressView.step() self.dismiss(animated: true) - let conversationVC = self.router.conversation(for: status.id) - self.router.push(conversationVC, animated: true) + let conversationVC = ConversationTableViewController(for: status.id) + self.show(conversationVC, sender: self) self.xcbSession?.complete(with: .success, additionalData: [ "statusURL": status.url?.absoluteString, diff --git a/Tusker/Screens/Conversation/ConversationTableViewController.swift b/Tusker/Screens/Conversation/ConversationTableViewController.swift index 5bf8686ff5..83b13669dd 100644 --- a/Tusker/Screens/Conversation/ConversationTableViewController.swift +++ b/Tusker/Screens/Conversation/ConversationTableViewController.swift @@ -7,12 +7,11 @@ // import UIKit +import SafariServices import Pachyderm class ConversationTableViewController: EnhancedTableViewController { - let router: AppRouter - var mainStatusID: String! var statusIDs: [String] = [] { didSet { @@ -22,9 +21,8 @@ class ConversationTableViewController: EnhancedTableViewController { } } - init(for mainStatusID: String, router: AppRouter) { + init(for mainStatusID: String) { self.mainStatusID = mainStatusID - self.router = router super.init(style: .plain) } @@ -77,8 +75,9 @@ class ConversationTableViewController: EnhancedTableViewController { if let status = MastodonCache.status(for: mainStatusID), let url = status.url { actions.append(UIPreviewAction(title: "Open in Safari", style: .default, handler: { (_, _) in - let vc = self.router.safariViewController(for: url) + let vc = SFSafariViewController(url: url) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true) + // TODO: kill this ^ with fire })) actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil) diff --git a/Tusker/Screens/Large Image/LargeImageViewController.swift b/Tusker/Screens/Large Image/LargeImageViewController.swift index fb2a4494e7..8cdb2e7391 100644 --- a/Tusker/Screens/Large Image/LargeImageViewController.swift +++ b/Tusker/Screens/Large Image/LargeImageViewController.swift @@ -12,8 +12,6 @@ import Gifu class LargeImageViewController: UIViewController, UIScrollViewDelegate { - let router: AppRouter - var originFrame: CGRect? var originCornerRadius: CGFloat? var dismissInteractionController: LargeImageInteractionController? @@ -62,8 +60,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate { return true } - init(image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, router: AppRouter) { - self.router = router + init(image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat) { self.image = image self.imageDescription = description self.originFrame = sourceFrame diff --git a/Tusker/Screens/Main/MainTabBarViewController.swift b/Tusker/Screens/Main/MainTabBarViewController.swift index b89065c28a..547df8d3e6 100644 --- a/Tusker/Screens/Main/MainTabBarViewController.swift +++ b/Tusker/Screens/Main/MainTabBarViewController.swift @@ -10,19 +10,17 @@ import UIKit class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate { - lazy var router = AppRouter(root: self) - override func viewDidLoad() { super.viewDidLoad() self.delegate = self viewControllers = [ - embedInNavigationController(TimelineTableViewController(for: .home, router: router)), - embedInNavigationController(NotificationsTableViewController(router: router)), - ComposeViewController(router: router), - embedInNavigationController(TimelineTableViewController(for: .public(local: false), router: router)), - embedInNavigationController(MyProfileTableViewController(router: router)), + embedInNavigationController(TimelineTableViewController(for: .home)), + embedInNavigationController(NotificationsTableViewController()), + ComposeViewController(), + embedInNavigationController(TimelineTableViewController(for: .public(local: false))), + embedInNavigationController(MyProfileTableViewController()), ] } @@ -36,7 +34,7 @@ class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { if viewController is ComposeViewController { - let compose = embedInNavigationController(ComposeViewController(router: router)) + let compose = embedInNavigationController(ComposeViewController()) tabBarController.present(compose, animated: true) return false } diff --git a/Tusker/Screens/Notifications/NotificationsTableViewController.swift b/Tusker/Screens/Notifications/NotificationsTableViewController.swift index 2c4afefb76..1c06586dff 100644 --- a/Tusker/Screens/Notifications/NotificationsTableViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsTableViewController.swift @@ -11,8 +11,6 @@ import Pachyderm class NotificationsTableViewController: EnhancedTableViewController { - let router: AppRouter - var notifications: [Pachyderm.Notification] = [] { didSet { DispatchQueue.main.async { @@ -24,9 +22,7 @@ class NotificationsTableViewController: EnhancedTableViewController { var newer: RequestRange? var older: RequestRange? - init(router: AppRouter) { - self.router = router - + init() { super.init(style: .plain) self.title = "Notifications" diff --git a/Tusker/Screens/Profile/MyProfileTableViewController.swift b/Tusker/Screens/Profile/MyProfileTableViewController.swift index e9a5cb47fd..8df3a28def 100644 --- a/Tusker/Screens/Profile/MyProfileTableViewController.swift +++ b/Tusker/Screens/Profile/MyProfileTableViewController.swift @@ -10,8 +10,8 @@ import UIKit class MyProfileTableViewController: ProfileTableViewController { - init(router: AppRouter) { - super.init(accountID: nil, router: router) + init() { + super.init(accountID: nil) title = "My Profile" @@ -41,7 +41,7 @@ class MyProfileTableViewController: ProfileTableViewController { } @objc func preferencesPressed() { - router.present(PreferencesTableViewController.create(), animated: true) + present(PreferencesTableViewController.create(), animated: true) } } diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index fc46272a19..09ec03cccf 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -12,8 +12,6 @@ import SafariServices class ProfileTableViewController: EnhancedTableViewController, PreferencesAdaptive { - let router: AppRouter - var accountID: String! { didSet { if shouldLoadOnAccountIDSet { @@ -38,9 +36,8 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti var shouldLoadOnAccountIDSet = false var loadingVC: LoadingViewController? = nil - init(accountID: String?, router: AppRouter) { + init(accountID: String?) { self.accountID = accountID - self.router = router super.init(style: .plain) @@ -113,15 +110,16 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti var actions = [UIPreviewActionItem]() if let account = MastodonCache.account(for: accountID) { actions.append(UIPreviewAction(title: "Open in Safari", style: .default, handler: { (_, _) in - let vc = self.router.safariViewController(for: account.url) + let vc = SFSafariViewController(url: account.url) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true) + // TODO: kill this ^ with fire })) actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in let vc = UIActivityViewController(activityItems: [account.url], applicationActivities: nil) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true) })) actions.append(UIPreviewAction(title: "Send Message", style: .default, handler: { (_, _) in - let vc = UINavigationController(rootViewController: ComposeViewController(mentioningAcct: account.acct, router: self.router)) + let vc = UINavigationController(rootViewController: ComposeViewController(mentioningAcct: account.acct)) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true) })) } @@ -154,7 +152,7 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti func sendMessageMentioning() { guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID!)") } - let vc = UINavigationController(rootViewController: ComposeViewController(mentioningAcct: account.acct, router: router)) + let vc = UINavigationController(rootViewController: ComposeViewController(mentioningAcct: account.acct)) present(vc, animated: true) } diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index c0947714f1..6313ffdc0f 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -11,8 +11,6 @@ import Pachyderm class TimelineTableViewController: EnhancedTableViewController { - let router: AppRouter - lazy var favoriteActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 137/131, height: 30)).image { _ in UIImage(named: "Favorite")!.draw(in: CGRect(x: 0, y: 0, width: 30 * 137/131, height: 30)) } @@ -39,9 +37,8 @@ class TimelineTableViewController: EnhancedTableViewController { var newer: RequestRange? var older: RequestRange? - init(for timeline: Timeline, router: AppRouter) { + init(for timeline: Timeline) { self.timeline = timeline - self.router = router super.init(style: .plain) diff --git a/Tusker/Shortcuts/UserActivityManager.swift b/Tusker/Shortcuts/UserActivityManager.swift index c30e1542ad..ee41dc59a4 100644 --- a/Tusker/Shortcuts/UserActivityManager.swift +++ b/Tusker/Shortcuts/UserActivityManager.swift @@ -12,9 +12,9 @@ import Pachyderm class UserActivityManager { // MARK: - Utils - private static var router: AppRouter = { - return (UIApplication.shared.delegate as! AppDelegate).router - }() + private static func present(_ vc: UIViewController, animated: Bool = true) { + UIApplication.shared.delegate?.window??.rootViewController?.present(vc, animated: animated) + } // MARK: - New Post static func newPostActivity(mentioning: Account? = nil) -> NSUserActivity { @@ -35,7 +35,7 @@ class UserActivityManager { static func handleNewPost(activity: NSUserActivity) { // TODO: check not currently showing compose screen let mentioning = activity.userInfo?["mentioning"] as? String - router.present(router.compose(mentioningAcct: mentioning), animated: true) + present(ComposeViewController(mentioningAcct: mentioning)) } // MARK: - Check Notifications diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift index 9365d1f6be..53f1553661 100644 --- a/Tusker/TuskerNavigationDelegate.swift +++ b/Tusker/TuskerNavigationDelegate.swift @@ -12,8 +12,6 @@ import Pachyderm protocol TuskerNavigationDelegate { - var router: AppRouter { get } - func selected(account accountID: String) func selected(mention: Mention) @@ -50,19 +48,19 @@ extension TuskerNavigationDelegate where Self: UIViewController { return } - router.push(router.profile(for: accountID), animated: true) + show(ProfileTableViewController(accountID: accountID), sender: self) } func selected(mention: Mention) { - router.push(router.profile(for: mention), animated: true) + show(ProfileTableViewController(accountID: mention.id), sender: self) } func selected(tag: Hashtag) { - router.push(router.timeline(tag: tag), animated: true) + show(TimelineTableViewController(for: .tag(hashtag: tag.name)), sender: self) } func selected(url: URL) { - router.present(router.safariViewController(for: url), animated: true) + present(SFSafariViewController(url: url), animated: true) } func selected(status statusID: String) { @@ -72,17 +70,17 @@ extension TuskerNavigationDelegate where Self: UIViewController { return } - router.push(router.conversation(for: statusID), animated: true) + show(ConversationTableViewController(for: statusID), sender: self) } func compose() { - let vc: UINavigationController = UINavigationController(rootViewController: router.compose()) - router.present(vc, animated: true) + let vc: UINavigationController = UINavigationController(rootViewController: ComposeViewController()) + present(vc, animated: true) } func reply(to statusID: String) { - let vc = UINavigationController(rootViewController: router.compose(inReplyTo: statusID)) - router.present(vc, animated: true) + let vc = UINavigationController(rootViewController: ComposeViewController(inReplyTo: statusID)) + present(vc, animated: true) } func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController { @@ -96,7 +94,9 @@ extension TuskerNavigationDelegate where Self: UIViewController { sourceFrame = CGRect(x: x, y: y, width: width, height: height) } let sourceCornerRadius = sourceView.layer.cornerRadius - return router.largeImage(image, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, transitioningDelegate: self) + let vc = LargeImageViewController(image: image, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius) + vc.transitioningDelegate = self + return vc } func largeImage(gifData: Data, description: String?, sourceView: UIView) -> LargeImageViewController { @@ -110,23 +110,49 @@ extension TuskerNavigationDelegate where Self: UIViewController { sourceFrame = CGRect(x: x, y: y, width: width, height: height) } let sourceCornerRadius = sourceView.layer.cornerRadius - return router.largeImage(gifData: gifData, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius, transitioningDelegate: self) + let vc = LargeImageViewController(image: UIImage(data: gifData)!, description: description, sourceFrame: sourceFrame, sourceCornerRadius: sourceCornerRadius) + vc.transitioningDelegate = self + vc.gifData = gifData + return vc } func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIView) { - router.present(largeImage(image, description: description, sourceView: sourceView), animated: true) + present(largeImage(image, description: description, sourceView: sourceView), animated: true) } func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView) { - router.present(largeImage(gifData: gifData, description: description, sourceView: sourceView), animated: true) + present(largeImage(gifData: gifData, description: description, sourceView: sourceView), animated: true) + } + + private func moreOptions(forURL url: URL) -> UIAlertController { + let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + alert.addAction(UIAlertAction(title: "Open in Safari", style: .default, handler: { (_) in + let vc = SFSafariViewController(url: url) + self.present(vc, animated: true) + })) + alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (_) in + UIPasteboard.general.url = url + })) + alert.addAction(UIAlertAction(title: "Share...", style: .default, handler: { (_) in + let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil) + self.present(vc, animated: true) + })) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + return alert + } + + private func moreOptions(forStatus statusID: String) -> UIAlertController { + guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") } + guard let url = status.url else { fatalError("Missing url for status \(statusID)") } + return moreOptions(forURL: url) } func showMoreOptions(forStatus statusID: String) { - router.present(router.moreOptions(forStatus: statusID), animated: true) + present(moreOptions(forStatus: statusID), animated: true) } func showMoreOptions(forURL url: URL) { - router.present(router.moreOptions(forURL: url), animated: true) + present(moreOptions(forURL: url), animated: true) } } diff --git a/Tusker/Views/ContentLabel.swift b/Tusker/Views/ContentLabel.swift index 62e4f6654c..acf1ec5e60 100644 --- a/Tusker/Views/ContentLabel.swift +++ b/Tusker/Views/ContentLabel.swift @@ -7,6 +7,7 @@ // import UIKit +import SafariServices import TTTAttributedLabel import Pachyderm import SwiftSoup @@ -90,18 +91,17 @@ class ContentLabel: TTTAttributedLabel { } func getViewController(forLinkAt point: CGPoint) -> UIViewController? { - guard let navigationDelegate = navigationDelegate, - let link = link(at: point), + guard let link = link(at: point), let url = link.result.url else { return nil } let text = (self.text as! NSString).substring(with: link.result.range) if let mention = getMention(for: url, text: text) { - return navigationDelegate.router.profile(for: mention) + return ProfileTableViewController(accountID: mention.id) } else if let tag = getHashtag(for: url, text: text) { - return navigationDelegate.router.timeline(tag: tag) + return TimelineTableViewController(for: .tag(hashtag: tag.name)) } else { - return navigationDelegate.router.safariViewController(for: url) + return SFSafariViewController(url: url) } } diff --git a/Tusker/Views/Notifications/ActionNotificationTableViewCell.swift b/Tusker/Views/Notifications/ActionNotificationTableViewCell.swift index 67591c1beb..0e8b811233 100644 --- a/Tusker/Views/Notifications/ActionNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/ActionNotificationTableViewCell.swift @@ -195,11 +195,11 @@ class ActionNotificationTableViewCell: UITableViewCell, PreferencesAdaptive { extension ActionNotificationTableViewCell: PreviewViewControllerProvider { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { if avatarContainerView.frame.contains(location) { - return delegate?.router.profile(for: notification.account.id) + return ProfileTableViewController(accountID: notification.account.id) } else if contentLabel.frame.contains(location), let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) { return vc } - return delegate?.router.conversation(for: statusID) + return ConversationTableViewController(for: statusID) } } diff --git a/Tusker/Views/Notifications/FollowNotificationTableViewCell.swift b/Tusker/Views/Notifications/FollowNotificationTableViewCell.swift index 7ca3e29091..f5899f9542 100644 --- a/Tusker/Views/Notifications/FollowNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowNotificationTableViewCell.swift @@ -11,8 +11,6 @@ import Pachyderm class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive { - var router: AppRouter! - var delegate: StatusTableViewCellDelegate? @IBOutlet weak var followLabel: UILabel! @@ -102,6 +100,6 @@ class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive { extension FollowNotificationTableViewCell: PreviewViewControllerProvider { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { - return router.profile(for: accountID) + return ProfileTableViewController(accountID: accountID) } } diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index e9fce9bb3a..dee029be07 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -237,7 +237,7 @@ extension ConversationMainStatusTableViewCell: AttachmentViewDelegate { extension ConversationMainStatusTableViewCell: PreviewViewControllerProvider { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { if avatarImageView.frame.contains(location) { - return delegate?.router.profile(for: accountID) + return ProfileTableViewController(accountID: accountID) } else if attachmentsView.frame.contains(location) { let attachmentsViewLocation = attachmentsView.convert(location, from: self) if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView { diff --git a/Tusker/Views/Status/StatusTableViewCell.swift b/Tusker/Views/Status/StatusTableViewCell.swift index a1355d5674..ce809c6469 100644 --- a/Tusker/Views/Status/StatusTableViewCell.swift +++ b/Tusker/Views/Status/StatusTableViewCell.swift @@ -364,7 +364,7 @@ extension StatusTableViewCell: AttachmentViewDelegate { extension StatusTableViewCell: PreviewViewControllerProvider { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { if avatarImageView.frame.contains(location) { - return delegate?.router.profile(for: accountID) + return ProfileTableViewController(accountID: accountID) } else if attachmentsView.frame.contains(location) { let attachmentsViewLocation = attachmentsView.convert(location, from: self) if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView { @@ -376,6 +376,6 @@ extension StatusTableViewCell: PreviewViewControllerProvider { let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) { return vc } - return delegate?.router.conversation(for: statusID) + return ConversationTableViewController(for: statusID) } } diff --git a/Tusker/XCallbackURL/XCBActions.swift b/Tusker/XCallbackURL/XCBActions.swift index 8741d52006..b9d77d91ad 100644 --- a/Tusker/XCallbackURL/XCBActions.swift +++ b/Tusker/XCallbackURL/XCBActions.swift @@ -13,9 +13,13 @@ import SwiftSoup struct XCBActions { // MARK: - Utils - private static var router: AppRouter = { - return (UIApplication.shared.delegate as! AppDelegate).router - }() + private static func show(_ vc: UIViewController) { + UIApplication.shared.delegate!.window!!.rootViewController!.show(vc, sender: nil) + } + + private static func present(_ vc: UIViewController, animated: Bool = true) { + UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: animated) + } private static func getStatus(from request: XCBRequest, session: XCBSession, completion: @escaping (Status) -> Void) { if let id = request.arguments["statusID"] { @@ -105,9 +109,9 @@ struct XCBActions { // MARK: - Statuses static func showStatus(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { getStatus(from: request, session: session) { (status) in - let vc = router.conversation(for: status.id) DispatchQueue.main.async { - router.push(vc, animated: true) + let vc = ConversationTableViewController(for: status.id) + show(vc) } } } @@ -140,10 +144,10 @@ struct XCBActions { } } } else { - let compose = router.compose(mentioningAcct: mentioning, text: text) + let compose = ComposeViewController(mentioningAcct: mentioning, text: text) compose.xcbSession = session let vc = UINavigationController(rootViewController: compose) - router.present(vc, animated: true) + present(vc) } } @@ -207,9 +211,9 @@ struct XCBActions { if silent ?? false { performAction(status: status, completion: nil) } else { - let vc = router.conversation(for: status.id) + let vc = ConversationTableViewController(for: status.id) DispatchQueue.main.async { - router.push(vc, animated: true) + show(vc) } let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in @@ -223,7 +227,7 @@ struct XCBActions { session.complete(with: .cancel) })) DispatchQueue.main.async { - router.present(alertController, animated: true) + present(alertController) } } } @@ -234,9 +238,9 @@ struct XCBActions { // MARK: - Accounts static func showAccount(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { getAccount(from: request, session: session) { (account) in - let vc = router.profile(for: account.id) + let vc = ProfileTableViewController(accountID: account.id) DispatchQueue.main.async { - router.push(vc, animated: true) + show(vc) } } } @@ -291,9 +295,9 @@ struct XCBActions { if silent ?? false { performAction(account) } else { - let vc = router.profile(for: account.id) + let vc = ProfileTableViewController(accountID: account.id) DispatchQueue.main.async { - router.push(vc, animated: true) + show(vc) } let alertController = UIAlertController(title: "Follow \(account.realDisplayName)?", message: nil, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in @@ -303,7 +307,7 @@ struct XCBActions { session.complete(with: .cancel) })) DispatchQueue.main.async { - router.present(alertController, animated: true) + present(alertController) } } }