Get rid of AppRouter

This commit is contained in:
Shadowfacts 2019-01-19 14:31:31 -05:00
parent b8430be00c
commit 55ed2f5d26
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
19 changed files with 105 additions and 241 deletions

View File

@ -64,7 +64,6 @@
D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */; }; D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */; };
D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; }; D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; };
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; }; 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 */; }; D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF75217E923E00CC0648 /* DraftsManager.swift */; };
D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627FF78217E950100CC0648 /* DraftsTableViewController.xib */; }; D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627FF78217E950100CC0648 /* DraftsTableViewController.xib */; };
D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */; }; 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 = "<group>"; }; D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyProfileTableViewController.swift; sourceTree = "<group>"; };
D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; }; D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; };
D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; }; D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; };
D627FF73217BBC9700CC0648 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = "<group>"; };
D627FF75217E923E00CC0648 /* DraftsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsManager.swift; sourceTree = "<group>"; }; D627FF75217E923E00CC0648 /* DraftsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsManager.swift; sourceTree = "<group>"; };
D627FF78217E950100CC0648 /* DraftsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraftsTableViewController.xib; sourceTree = "<group>"; }; D627FF78217E950100CC0648 /* DraftsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraftsTableViewController.xib; sourceTree = "<group>"; };
D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsTableViewController.swift; sourceTree = "<group>"; }; D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsTableViewController.swift; sourceTree = "<group>"; };
@ -971,10 +969,10 @@
D61099AC2144B0CC00432DC2 /* Pachyderm */, D61099AC2144B0CC00432DC2 /* Pachyderm */,
D61099B92144B0CC00432DC2 /* PachydermTests */, D61099B92144B0CC00432DC2 /* PachydermTests */,
04496BC9216252E5001F1B23 /* TTTAttributedLabel */, 04496BC9216252E5001F1B23 /* TTTAttributedLabel */,
D60A548C21ED515800F1F87C /* GMImagePicker */,
D6D4DDCE212518A000E1C4BB /* Tusker */, D6D4DDCE212518A000E1C4BB /* Tusker */,
D6D4DDE3212518A200E1C4BB /* TuskerTests */, D6D4DDE3212518A200E1C4BB /* TuskerTests */,
D6D4DDEE212518A200E1C4BB /* TuskerUITests */, D6D4DDEE212518A200E1C4BB /* TuskerUITests */,
D60A548C21ED515800F1F87C /* GMImagePicker */,
D6D4DDCD212518A000E1C4BB /* Products */, D6D4DDCD212518A000E1C4BB /* Products */,
D65A37F221472F300087646E /* Frameworks */, D65A37F221472F300087646E /* Frameworks */,
); );
@ -998,7 +996,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */, D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */,
D627FF73217BBC9700CC0648 /* AppRouter.swift */,
D64D0AAC2128D88B005A6F37 /* LocalData.swift */, D64D0AAC2128D88B005A6F37 /* LocalData.swift */,
D627FF75217E923E00CC0648 /* DraftsManager.swift */, D627FF75217E923E00CC0648 /* DraftsManager.swift */,
D6028B9A2150811100F223B9 /* MastodonCache.swift */, D6028B9A2150811100F223B9 /* MastodonCache.swift */,
@ -1489,7 +1486,6 @@
D6B8DB342182A59300424AF7 /* UIAlertController+Visibility.swift in Sources */, D6B8DB342182A59300424AF7 /* UIAlertController+Visibility.swift in Sources */,
D67C57AD21E265FC00C3118B /* LargeAccountDetailView.swift in Sources */, D67C57AD21E265FC00C3118B /* LargeAccountDetailView.swift in Sources */,
D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */, D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */,
D627FF74217BBC9700CC0648 /* AppRouter.swift in Sources */,
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */, D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */,
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */,
D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */, D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */,

View File

@ -12,7 +12,6 @@ import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate { class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
var router: AppRouter!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds) window = UIWindow(frame: UIScreen.main.bounds)
@ -70,7 +69,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let tabBarController = MainTabBarViewController() let tabBarController = MainTabBarViewController()
window!.rootViewController = tabBarController window!.rootViewController = tabBarController
router = tabBarController.router
} }
func showOnboardingUI() { func showOnboardingUI() {

View File

@ -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
}
}

View File

@ -15,8 +15,6 @@ import MobileCoreServices
class ComposeViewController: UIViewController { class ComposeViewController: UIViewController {
let router: AppRouter
var inReplyToID: String? var inReplyToID: String?
var accountsToMention: [String] var accountsToMention: [String]
var initialText: String? var initialText: String?
@ -66,9 +64,7 @@ class ComposeViewController: UIViewController {
@IBOutlet weak var postProgressView: SteppedProgressView! @IBOutlet weak var postProgressView: SteppedProgressView!
init(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil, router: AppRouter) { init(inReplyTo inReplyToID: String? = nil, mentioningAcct: String? = nil, text: String? = nil) {
self.router = router
self.inReplyToID = inReplyToID self.inReplyToID = inReplyToID
if let inReplyToID = inReplyToID, let inReplyTo = MastodonCache.status(for: inReplyToID) { if let inReplyToID = inReplyToID, let inReplyTo = MastodonCache.status(for: inReplyToID) {
accountsToMention = [inReplyTo.account.acct] + inReplyTo.mentions.map { $0.acct } accountsToMention = [inReplyTo.account.acct] + inReplyTo.mentions.map { $0.acct }
@ -323,7 +319,7 @@ class ComposeViewController: UIViewController {
self.close() self.close()
})) }))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
router.present(alert, animated: true) present(alert, animated: true)
} }
@objc func contentWarningButtonPressed() { @objc func contentWarningButtonPressed() {
@ -366,9 +362,9 @@ class ComposeViewController: UIViewController {
} }
@objc func draftsButtonPressed() { @objc func draftsButtonPressed() {
let draftsVC = router.drafts() let draftsVC = DraftsTableViewController()
draftsVC.delegate = self draftsVC.delegate = self
router.present(UINavigationController(rootViewController: draftsVC), animated: true) present(UINavigationController(rootViewController: draftsVC), animated: true)
} }
@IBAction func addAttachmentPressed(_ sender: Any) { @IBAction func addAttachmentPressed(_ sender: Any) {
@ -460,8 +456,8 @@ class ComposeViewController: UIViewController {
self.postProgressView.step() self.postProgressView.step()
self.dismiss(animated: true) self.dismiss(animated: true)
let conversationVC = self.router.conversation(for: status.id) let conversationVC = ConversationTableViewController(for: status.id)
self.router.push(conversationVC, animated: true) self.show(conversationVC, sender: self)
self.xcbSession?.complete(with: .success, additionalData: [ self.xcbSession?.complete(with: .success, additionalData: [
"statusURL": status.url?.absoluteString, "statusURL": status.url?.absoluteString,

View File

@ -7,12 +7,11 @@
// //
import UIKit import UIKit
import SafariServices
import Pachyderm import Pachyderm
class ConversationTableViewController: EnhancedTableViewController { class ConversationTableViewController: EnhancedTableViewController {
let router: AppRouter
var mainStatusID: String! var mainStatusID: String!
var statusIDs: [String] = [] { var statusIDs: [String] = [] {
didSet { didSet {
@ -22,9 +21,8 @@ class ConversationTableViewController: EnhancedTableViewController {
} }
} }
init(for mainStatusID: String, router: AppRouter) { init(for mainStatusID: String) {
self.mainStatusID = mainStatusID self.mainStatusID = mainStatusID
self.router = router
super.init(style: .plain) super.init(style: .plain)
} }
@ -77,8 +75,9 @@ class ConversationTableViewController: EnhancedTableViewController {
if let status = MastodonCache.status(for: mainStatusID), if let status = MastodonCache.status(for: mainStatusID),
let url = status.url { let url = status.url {
actions.append(UIPreviewAction(title: "Open in Safari", style: .default, handler: { (_, _) in 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) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true)
// TODO: kill this ^ with fire
})) }))
actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in
let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil) let vc = UIActivityViewController(activityItems: [url], applicationActivities: nil)

View File

@ -12,8 +12,6 @@ import Gifu
class LargeImageViewController: UIViewController, UIScrollViewDelegate { class LargeImageViewController: UIViewController, UIScrollViewDelegate {
let router: AppRouter
var originFrame: CGRect? var originFrame: CGRect?
var originCornerRadius: CGFloat? var originCornerRadius: CGFloat?
var dismissInteractionController: LargeImageInteractionController? var dismissInteractionController: LargeImageInteractionController?
@ -62,8 +60,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
return true return true
} }
init(image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, router: AppRouter) { init(image: UIImage, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat) {
self.router = router
self.image = image self.image = image
self.imageDescription = description self.imageDescription = description
self.originFrame = sourceFrame self.originFrame = sourceFrame

View File

@ -10,19 +10,17 @@ import UIKit
class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate { class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
lazy var router = AppRouter(root: self)
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.delegate = self self.delegate = self
viewControllers = [ viewControllers = [
embedInNavigationController(TimelineTableViewController(for: .home, router: router)), embedInNavigationController(TimelineTableViewController(for: .home)),
embedInNavigationController(NotificationsTableViewController(router: router)), embedInNavigationController(NotificationsTableViewController()),
ComposeViewController(router: router), ComposeViewController(),
embedInNavigationController(TimelineTableViewController(for: .public(local: false), router: router)), embedInNavigationController(TimelineTableViewController(for: .public(local: false))),
embedInNavigationController(MyProfileTableViewController(router: router)), embedInNavigationController(MyProfileTableViewController()),
] ]
} }
@ -36,7 +34,7 @@ class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController is ComposeViewController { if viewController is ComposeViewController {
let compose = embedInNavigationController(ComposeViewController(router: router)) let compose = embedInNavigationController(ComposeViewController())
tabBarController.present(compose, animated: true) tabBarController.present(compose, animated: true)
return false return false
} }

View File

@ -11,8 +11,6 @@ import Pachyderm
class NotificationsTableViewController: EnhancedTableViewController { class NotificationsTableViewController: EnhancedTableViewController {
let router: AppRouter
var notifications: [Pachyderm.Notification] = [] { var notifications: [Pachyderm.Notification] = [] {
didSet { didSet {
DispatchQueue.main.async { DispatchQueue.main.async {
@ -24,9 +22,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
var newer: RequestRange? var newer: RequestRange?
var older: RequestRange? var older: RequestRange?
init(router: AppRouter) { init() {
self.router = router
super.init(style: .plain) super.init(style: .plain)
self.title = "Notifications" self.title = "Notifications"

View File

@ -10,8 +10,8 @@ import UIKit
class MyProfileTableViewController: ProfileTableViewController { class MyProfileTableViewController: ProfileTableViewController {
init(router: AppRouter) { init() {
super.init(accountID: nil, router: router) super.init(accountID: nil)
title = "My Profile" title = "My Profile"
@ -41,7 +41,7 @@ class MyProfileTableViewController: ProfileTableViewController {
} }
@objc func preferencesPressed() { @objc func preferencesPressed() {
router.present(PreferencesTableViewController.create(), animated: true) present(PreferencesTableViewController.create(), animated: true)
} }
} }

View File

@ -12,8 +12,6 @@ import SafariServices
class ProfileTableViewController: EnhancedTableViewController, PreferencesAdaptive { class ProfileTableViewController: EnhancedTableViewController, PreferencesAdaptive {
let router: AppRouter
var accountID: String! { var accountID: String! {
didSet { didSet {
if shouldLoadOnAccountIDSet { if shouldLoadOnAccountIDSet {
@ -38,9 +36,8 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti
var shouldLoadOnAccountIDSet = false var shouldLoadOnAccountIDSet = false
var loadingVC: LoadingViewController? = nil var loadingVC: LoadingViewController? = nil
init(accountID: String?, router: AppRouter) { init(accountID: String?) {
self.accountID = accountID self.accountID = accountID
self.router = router
super.init(style: .plain) super.init(style: .plain)
@ -113,15 +110,16 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti
var actions = [UIPreviewActionItem]() var actions = [UIPreviewActionItem]()
if let account = MastodonCache.account(for: accountID) { if let account = MastodonCache.account(for: accountID) {
actions.append(UIPreviewAction(title: "Open in Safari", style: .default, handler: { (_, _) in 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) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true)
// TODO: kill this ^ with fire
})) }))
actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in actions.append(UIPreviewAction(title: "Share", style: .default, handler: { (_, _) in
let vc = UIActivityViewController(activityItems: [account.url], applicationActivities: nil) let vc = UIActivityViewController(activityItems: [account.url], applicationActivities: nil)
UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true)
})) }))
actions.append(UIPreviewAction(title: "Send Message", style: .default, handler: { (_, _) in 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) UIApplication.shared.delegate!.window!!.rootViewController!.present(vc, animated: true)
})) }))
} }
@ -154,7 +152,7 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti
func sendMessageMentioning() { func sendMessageMentioning() {
guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID!)") } 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) present(vc, animated: true)
} }

View File

@ -11,8 +11,6 @@ import Pachyderm
class TimelineTableViewController: EnhancedTableViewController { class TimelineTableViewController: EnhancedTableViewController {
let router: AppRouter
lazy var favoriteActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 137/131, height: 30)).image { _ in 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)) 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 newer: RequestRange?
var older: RequestRange? var older: RequestRange?
init(for timeline: Timeline, router: AppRouter) { init(for timeline: Timeline) {
self.timeline = timeline self.timeline = timeline
self.router = router
super.init(style: .plain) super.init(style: .plain)

View File

@ -12,9 +12,9 @@ import Pachyderm
class UserActivityManager { class UserActivityManager {
// MARK: - Utils // MARK: - Utils
private static var router: AppRouter = { private static func present(_ vc: UIViewController, animated: Bool = true) {
return (UIApplication.shared.delegate as! AppDelegate).router UIApplication.shared.delegate?.window??.rootViewController?.present(vc, animated: animated)
}() }
// MARK: - New Post // MARK: - New Post
static func newPostActivity(mentioning: Account? = nil) -> NSUserActivity { static func newPostActivity(mentioning: Account? = nil) -> NSUserActivity {
@ -35,7 +35,7 @@ class UserActivityManager {
static func handleNewPost(activity: NSUserActivity) { static func handleNewPost(activity: NSUserActivity) {
// TODO: check not currently showing compose screen // TODO: check not currently showing compose screen
let mentioning = activity.userInfo?["mentioning"] as? String let mentioning = activity.userInfo?["mentioning"] as? String
router.present(router.compose(mentioningAcct: mentioning), animated: true) present(ComposeViewController(mentioningAcct: mentioning))
} }
// MARK: - Check Notifications // MARK: - Check Notifications

View File

@ -12,8 +12,6 @@ import Pachyderm
protocol TuskerNavigationDelegate { protocol TuskerNavigationDelegate {
var router: AppRouter { get }
func selected(account accountID: String) func selected(account accountID: String)
func selected(mention: Mention) func selected(mention: Mention)
@ -50,19 +48,19 @@ extension TuskerNavigationDelegate where Self: UIViewController {
return return
} }
router.push(router.profile(for: accountID), animated: true) show(ProfileTableViewController(accountID: accountID), sender: self)
} }
func selected(mention: Mention) { func selected(mention: Mention) {
router.push(router.profile(for: mention), animated: true) show(ProfileTableViewController(accountID: mention.id), sender: self)
} }
func selected(tag: Hashtag) { 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) { func selected(url: URL) {
router.present(router.safariViewController(for: url), animated: true) present(SFSafariViewController(url: url), animated: true)
} }
func selected(status statusID: String) { func selected(status statusID: String) {
@ -72,17 +70,17 @@ extension TuskerNavigationDelegate where Self: UIViewController {
return return
} }
router.push(router.conversation(for: statusID), animated: true) show(ConversationTableViewController(for: statusID), sender: self)
} }
func compose() { func compose() {
let vc: UINavigationController = UINavigationController(rootViewController: router.compose()) let vc: UINavigationController = UINavigationController(rootViewController: ComposeViewController())
router.present(vc, animated: true) present(vc, animated: true)
} }
func reply(to statusID: String) { func reply(to statusID: String) {
let vc = UINavigationController(rootViewController: router.compose(inReplyTo: statusID)) let vc = UINavigationController(rootViewController: ComposeViewController(inReplyTo: statusID))
router.present(vc, animated: true) present(vc, animated: true)
} }
func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController { 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) sourceFrame = CGRect(x: x, y: y, width: width, height: height)
} }
let sourceCornerRadius = sourceView.layer.cornerRadius 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 { 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) sourceFrame = CGRect(x: x, y: y, width: width, height: height)
} }
let sourceCornerRadius = sourceView.layer.cornerRadius 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) { 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) { 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) { func showMoreOptions(forStatus statusID: String) {
router.present(router.moreOptions(forStatus: statusID), animated: true) present(moreOptions(forStatus: statusID), animated: true)
} }
func showMoreOptions(forURL url: URL) { func showMoreOptions(forURL url: URL) {
router.present(router.moreOptions(forURL: url), animated: true) present(moreOptions(forURL: url), animated: true)
} }
} }

View File

@ -7,6 +7,7 @@
// //
import UIKit import UIKit
import SafariServices
import TTTAttributedLabel import TTTAttributedLabel
import Pachyderm import Pachyderm
import SwiftSoup import SwiftSoup
@ -90,18 +91,17 @@ class ContentLabel: TTTAttributedLabel {
} }
func getViewController(forLinkAt point: CGPoint) -> UIViewController? { func getViewController(forLinkAt point: CGPoint) -> UIViewController? {
guard let navigationDelegate = navigationDelegate, guard let link = link(at: point),
let link = link(at: point),
let url = link.result.url else { let url = link.result.url else {
return nil return nil
} }
let text = (self.text as! NSString).substring(with: link.result.range) let text = (self.text as! NSString).substring(with: link.result.range)
if let mention = getMention(for: url, text: text) { 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) { } else if let tag = getHashtag(for: url, text: text) {
return navigationDelegate.router.timeline(tag: tag) return TimelineTableViewController(for: .tag(hashtag: tag.name))
} else { } else {
return navigationDelegate.router.safariViewController(for: url) return SFSafariViewController(url: url)
} }
} }

View File

@ -195,11 +195,11 @@ class ActionNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
extension ActionNotificationTableViewCell: PreviewViewControllerProvider { extension ActionNotificationTableViewCell: PreviewViewControllerProvider {
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
if avatarContainerView.frame.contains(location) { 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), } else if contentLabel.frame.contains(location),
let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) { let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) {
return vc return vc
} }
return delegate?.router.conversation(for: statusID) return ConversationTableViewController(for: statusID)
} }
} }

View File

@ -11,8 +11,6 @@ import Pachyderm
class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive { class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
var router: AppRouter!
var delegate: StatusTableViewCellDelegate? var delegate: StatusTableViewCellDelegate?
@IBOutlet weak var followLabel: UILabel! @IBOutlet weak var followLabel: UILabel!
@ -102,6 +100,6 @@ class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
extension FollowNotificationTableViewCell: PreviewViewControllerProvider { extension FollowNotificationTableViewCell: PreviewViewControllerProvider {
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
return router.profile(for: accountID) return ProfileTableViewController(accountID: accountID)
} }
} }

View File

@ -237,7 +237,7 @@ extension ConversationMainStatusTableViewCell: AttachmentViewDelegate {
extension ConversationMainStatusTableViewCell: PreviewViewControllerProvider { extension ConversationMainStatusTableViewCell: PreviewViewControllerProvider {
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
if avatarImageView.frame.contains(location) { if avatarImageView.frame.contains(location) {
return delegate?.router.profile(for: accountID) return ProfileTableViewController(accountID: accountID)
} else if attachmentsView.frame.contains(location) { } else if attachmentsView.frame.contains(location) {
let attachmentsViewLocation = attachmentsView.convert(location, from: self) let attachmentsViewLocation = attachmentsView.convert(location, from: self)
if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView { if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView {

View File

@ -364,7 +364,7 @@ extension StatusTableViewCell: AttachmentViewDelegate {
extension StatusTableViewCell: PreviewViewControllerProvider { extension StatusTableViewCell: PreviewViewControllerProvider {
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? { func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
if avatarImageView.frame.contains(location) { if avatarImageView.frame.contains(location) {
return delegate?.router.profile(for: accountID) return ProfileTableViewController(accountID: accountID)
} else if attachmentsView.frame.contains(location) { } else if attachmentsView.frame.contains(location) {
let attachmentsViewLocation = attachmentsView.convert(location, from: self) let attachmentsViewLocation = attachmentsView.convert(location, from: self)
if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView { 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)) { let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) {
return vc return vc
} }
return delegate?.router.conversation(for: statusID) return ConversationTableViewController(for: statusID)
} }
} }

View File

@ -13,9 +13,13 @@ import SwiftSoup
struct XCBActions { struct XCBActions {
// MARK: - Utils // MARK: - Utils
private static var router: AppRouter = { private static func show(_ vc: UIViewController) {
return (UIApplication.shared.delegate as! AppDelegate).router 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) { private static func getStatus(from request: XCBRequest, session: XCBSession, completion: @escaping (Status) -> Void) {
if let id = request.arguments["statusID"] { if let id = request.arguments["statusID"] {
@ -105,9 +109,9 @@ struct XCBActions {
// MARK: - Statuses // MARK: - Statuses
static func showStatus(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { static func showStatus(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) {
getStatus(from: request, session: session) { (status) in getStatus(from: request, session: session) { (status) in
let vc = router.conversation(for: status.id)
DispatchQueue.main.async { DispatchQueue.main.async {
router.push(vc, animated: true) let vc = ConversationTableViewController(for: status.id)
show(vc)
} }
} }
} }
@ -140,10 +144,10 @@ struct XCBActions {
} }
} }
} else { } else {
let compose = router.compose(mentioningAcct: mentioning, text: text) let compose = ComposeViewController(mentioningAcct: mentioning, text: text)
compose.xcbSession = session compose.xcbSession = session
let vc = UINavigationController(rootViewController: compose) let vc = UINavigationController(rootViewController: compose)
router.present(vc, animated: true) present(vc)
} }
} }
@ -207,9 +211,9 @@ struct XCBActions {
if silent ?? false { if silent ?? false {
performAction(status: status, completion: nil) performAction(status: status, completion: nil)
} else { } else {
let vc = router.conversation(for: status.id) let vc = ConversationTableViewController(for: status.id)
DispatchQueue.main.async { DispatchQueue.main.async {
router.push(vc, animated: true) show(vc)
} }
let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert) let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in
@ -223,7 +227,7 @@ struct XCBActions {
session.complete(with: .cancel) session.complete(with: .cancel)
})) }))
DispatchQueue.main.async { DispatchQueue.main.async {
router.present(alertController, animated: true) present(alertController)
} }
} }
} }
@ -234,9 +238,9 @@ struct XCBActions {
// MARK: - Accounts // MARK: - Accounts
static func showAccount(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { static func showAccount(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) {
getAccount(from: request, session: session) { (account) in getAccount(from: request, session: session) { (account) in
let vc = router.profile(for: account.id) let vc = ProfileTableViewController(accountID: account.id)
DispatchQueue.main.async { DispatchQueue.main.async {
router.push(vc, animated: true) show(vc)
} }
} }
} }
@ -291,9 +295,9 @@ struct XCBActions {
if silent ?? false { if silent ?? false {
performAction(account) performAction(account)
} else { } else {
let vc = router.profile(for: account.id) let vc = ProfileTableViewController(accountID: account.id)
DispatchQueue.main.async { DispatchQueue.main.async {
router.push(vc, animated: true) show(vc)
} }
let alertController = UIAlertController(title: "Follow \(account.realDisplayName)?", message: nil, preferredStyle: .alert) let alertController = UIAlertController(title: "Follow \(account.realDisplayName)?", message: nil, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) in
@ -303,7 +307,7 @@ struct XCBActions {
session.complete(with: .cancel) session.complete(with: .cancel)
})) }))
DispatchQueue.main.async { DispatchQueue.main.async {
router.present(alertController, animated: true) present(alertController)
} }
} }
} }