// // TuskerNavigationDelegate.swift // Tusker // // Created by Shadowfacts on 9/30/18. // Copyright © 2018 Shadowfacts. All rights reserved. // import UIKit import SafariServices import Pachyderm protocol TuskerNavigationDelegate { func viewController(forAccount accountID: String) -> UIViewController func selected(account accountID: String) func viewController(forMention mention: Mention) -> UIViewController func selected(mention: Mention) func viewController(forTag tag: Hashtag) -> UIViewController func selected(tag: Hashtag) func viewController(forURL url: URL) -> UIViewController func selected(url: URL) func viewController(forStatus statusID: String) -> UIViewController func selected(status statusID: String) func reply(to statusID: String) func viewController(forImage image: UIImage, description: String?, animatingFrom originView: UIView) -> UIViewController func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) func showMoreOptions(forStatus statusID: String) } extension TuskerNavigationDelegate where Self: UIViewController { func viewController(forAccount accountID: String) -> UIViewController { return ProfileTableViewController.create(for: accountID) } func selected(account accountID: String) { // don't open if the account is the same as the current one if let profileController = self as? ProfileTableViewController, profileController.accountID == accountID { return } guard let navigationController = navigationController else { fatalError("Can't show profile VC when not in navigation controller") } let vc = viewController(forAccount: accountID) navigationController.pushViewController(vc, animated: true) } func viewController(forMention mention: Mention) -> UIViewController { return ProfileTableViewController.create(for: mention.id) } func selected(mention: Mention) { guard let navigationController = navigationController else { fatalError("Can't show profile VC from mention when not in navigation controller") } let vc = viewController(forMention: mention) navigationController.pushViewController(vc, animated: true) } func viewController(forTag tag: Hashtag) -> UIViewController { let timeline = Timeline.tag(hashtag: tag.name) return TimelineTableViewController.create(for: timeline) } func selected(tag: Hashtag) { guard let navigationController = navigationController else { fatalError("Can't show hashtag timeline when not in navigation controller") } let vc = viewController(forTag: tag) navigationController.pushViewController(vc, animated: true) } func viewController(forURL url: URL) -> UIViewController { return SFSafariViewController(url: url) } func selected(url: URL) { let vc = viewController(forURL: url) present(vc, animated: true) } func viewController(forStatus statusID: String) -> UIViewController { return ConversationViewController.create(for: statusID) } func selected(status statusID: String) { // don't open if the conversation is the same as the current one if let conversationController = self as? ConversationViewController, conversationController.mainStatusID == statusID { return } guard let navigationController = navigationController else { fatalError("Can't show conversation VC when not in navigation controller") } let vc = viewController(forStatus: statusID) navigationController.pushViewController(vc, animated: true) } func reply(to statusID: String) { let vc = ComposeViewController.create(inReplyTo: statusID) present(vc, animated: true) } func viewController(forImage image: UIImage, description: String?, animatingFrom originView: UIView) -> UIViewController { guard let self = self as? UIViewController & LargeImageViewControllerDelegate else { fatalError("Can't create large image view controller unless self is LargeImageViewControllerDelegate") } let vc = LargeImageViewController.create(image: image, description: description, sourceView: originView, sourceViewController: self) vc.delegate = self return vc } func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) { let vc = viewController(forImage: image, description: description, animatingFrom: originView) present(vc, animated: true) } func showMoreOptions(forStatus statusID: String) { 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: "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)) present(alert, animated: true) } }