// // 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 selected(account accountID: String) func selected(mention: Mention) func selected(tag: Hashtag) func selected(url: URL) func selected(status statusID: String) func compose() func reply(to statusID: String) func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController func largeImage(gifData: Data, description: String?, sourceView: UIView) -> LargeImageViewController func showLargeImage(_ image: UIImage, description: String?, animatingFrom sourceView: UIView) func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView) func showMoreOptions(forStatus statusID: String) func showMoreOptions(forURL url: URL) } extension TuskerNavigationDelegate where Self: UIViewController { 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 } show(ProfileTableViewController(accountID: accountID), sender: self) } func selected(mention: Mention) { show(ProfileTableViewController(accountID: mention.id), sender: self) } func selected(tag: Hashtag) { show(TimelineTableViewController(for: .tag(hashtag: tag.name)), sender: self) } func selected(url: URL) { present(SFSafariViewController(url: url), animated: true) } func selected(status statusID: String) { // don't open if the conversation is the same as the current one if let conversationController = self as? ConversationTableViewController, conversationController.mainStatusID == statusID { return } show(ConversationTableViewController(for: statusID), sender: self) } func compose() { let vc: UINavigationController = UINavigationController(rootViewController: ComposeViewController()) present(vc, animated: true) } func reply(to statusID: String) { let vc = UINavigationController(rootViewController: ComposeViewController(inReplyTo: statusID)) present(vc, animated: true) } func largeImage(_ image: UIImage, description: String?, sourceView: UIView) -> LargeImageViewController { var sourceFrame = sourceView.convert(sourceView.bounds, to: view) if let scrollView = view as? UIScrollView { let scale = scrollView.zoomScale let width = sourceFrame.width * scale let height = sourceFrame.height * scale let x = sourceFrame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX let y = sourceFrame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY sourceFrame = CGRect(x: x, y: y, width: width, height: height) } let sourceCornerRadius = sourceView.layer.cornerRadius 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 { var sourceFrame = sourceView.convert(sourceView.bounds, to: view) if let scrollView = view as? UIScrollView { let scale = scrollView.zoomScale let width = sourceFrame.width * scale let height = sourceFrame.height * scale let x = sourceFrame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX let y = sourceFrame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY sourceFrame = CGRect(x: x, y: y, width: width, height: height) } let sourceCornerRadius = sourceView.layer.cornerRadius 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) { present(largeImage(image, description: description, sourceView: sourceView), animated: true) } func showLargeImage(gifData: Data, description: String?, animatingFrom sourceView: UIView) { 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.title = url.absoluteString 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) { present(moreOptions(forStatus: statusID), animated: true) } func showMoreOptions(forURL url: URL) { present(moreOptions(forURL: url), animated: true) } }