diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index cba3f768..7c9770c3 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */; }; D6C693CD2161257B007D6A6D /* SilentActionPermissionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6C693CC2161257B007D6A6D /* SilentActionPermissionCell.xib */; }; D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */; }; + D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; }; D6C94D852139DFD800CB5196 /* LargeImage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6C94D842139DFD800CB5196 /* LargeImage.storyboard */; }; D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D862139E62700CB5196 /* LargeImageViewController.swift */; }; D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D882139E6EC00CB5196 /* AttachmentView.swift */; }; @@ -267,6 +268,7 @@ D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionsTableViewController.swift; sourceTree = ""; }; D6C693CC2161257B007D6A6D /* SilentActionPermissionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SilentActionPermissionCell.xib; sourceTree = ""; }; D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionTableViewCell.swift; sourceTree = ""; }; + D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = ""; }; D6C94D842139DFD800CB5196 /* LargeImage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LargeImage.storyboard; sourceTree = ""; }; D6C94D862139E62700CB5196 /* LargeImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageViewController.swift; sourceTree = ""; }; D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = ""; }; @@ -661,6 +663,7 @@ D64D0AAC2128D88B005A6F37 /* LocalData.swift */, 04DACE8D212CC7CC009840C4 /* AvatarCache.swift */, D6028B9A2150811100F223B9 /* MastodonCache.swift */, + D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */, D6757A7A2157E00100721E32 /* XCallbackURL */, D663626021360A9600C9CBA2 /* Preferences */, D667E5F62135C2ED0057A976 /* Extensions */, @@ -988,6 +991,7 @@ D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */, D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */, + D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */, D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */, D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */, D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, diff --git a/Tusker/Extensions/UIViewController+Delegates.swift b/Tusker/Extensions/UIViewController+Delegates.swift index 0aace6a7..5f2b3ec7 100644 --- a/Tusker/Extensions/UIViewController+Delegates.swift +++ b/Tusker/Extensions/UIViewController+Delegates.swift @@ -10,93 +10,6 @@ import UIKit import Pachyderm import SafariServices -extension StatusTableViewCellDelegate 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 - } - - guard let navigationController = navigationController else { - fatalError("Can't show profile VC when not in navigation controller") - } - let vc = ProfileTableViewController.create(for: accountID) - navigationController.pushViewController(vc, animated: true) - } - - func selected(mention: Mention) { - - } - - func selected(tag: Hashtag) { - - } - - func selected(url: URL) { - let vc = SFSafariViewController(url: url) - present(vc, 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? ConversationViewController, - conversationController.mainStatusID == statusID { - return - } - - guard let navigationController = navigationController else { - fatalError("Can't show conversation VC when not in navigation controller") - } - let vc = ConversationViewController.create(for: statusID) - navigationController.pushViewController(vc, animated: true) - } - - func reply(to statusID: String) { - let vc = ComposeViewController.create(inReplyTo: statusID) - present(vc, animated: true) - } - - func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) { - guard let self = self as? UIViewController & LargeImageViewControllerDelegate else { return } - let vc = LargeImageViewController.create(image: image, description: description) - vc.delegate = self - var frame = originView.convert(originView.bounds, to: view) - if let scrollView = view as? UIScrollView { - let scale = scrollView.zoomScale - let width = frame.width * scale - let height = frame.height * scale - let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX - let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY - frame = CGRect(x: x, y: y, width: width, height: height) - } - vc.originFrame = frame - vc.originCornerRadius = originView.layer.cornerRadius - vc.transitioningDelegate = self - present(vc, animated: true) - } - - func showMoreOptions(status 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) - } - -} - extension LargeImageViewControllerDelegate where Self: UIViewController { func closeLargeImage() { dismiss(animated: true) diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index fdf23914..9e2a12b1 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -169,6 +169,7 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive { } +extension ProfileTableViewController: StatusTableViewCellDelegate {} extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate { func showMoreOptions() { @@ -216,5 +217,4 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate { } } - extension ProfileTableViewController: LargeImageViewControllerDelegate {} diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift new file mode 100644 index 00000000..181b5aef --- /dev/null +++ b/Tusker/TuskerNavigationDelegate.swift @@ -0,0 +1,116 @@ +// +// 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 reply(to statusID: String) + + func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) + + func showMoreOptions(forStatus statusID: String) +} + +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 + } + + guard let navigationController = navigationController else { + fatalError("Can't show profile VC when not in navigation controller") + } + let vc = ProfileTableViewController.create(for: accountID) + navigationController.pushViewController(vc, animated: true) + } + + func selected(mention: Mention) { + + } + + func selected(tag: Hashtag) { + + } + + func selected(url: URL) { + let vc = SFSafariViewController(url: url) + present(vc, 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? ConversationViewController, + conversationController.mainStatusID == statusID { + return + } + + guard let navigationController = navigationController else { + fatalError("Can't show conversation VC when not in navigation controller") + } + let vc = ConversationViewController.create(for: statusID) + navigationController.pushViewController(vc, animated: true) + } + + func reply(to statusID: String) { + let vc = ComposeViewController.create(inReplyTo: statusID) + present(vc, animated: true) + } + + func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) { + guard let self = self as? UIViewController & LargeImageViewControllerDelegate else { return } + let vc = LargeImageViewController.create(image: image, description: description) + vc.delegate = self + var frame = originView.convert(originView.bounds, to: view) + if let scrollView = view as? UIScrollView { + let scale = scrollView.zoomScale + let width = frame.width * scale + let height = frame.height * scale + let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX + let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY + frame = CGRect(x: x, y: y, width: width, height: height) + } + vc.originFrame = frame + vc.originCornerRadius = originView.layer.cornerRadius + vc.transitioningDelegate = self + 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) + } + +} diff --git a/Tusker/Views/Profile Header/ProfileHeaderTableViewCell.swift b/Tusker/Views/Profile Header/ProfileHeaderTableViewCell.swift index f76146ad..5356ad7a 100644 --- a/Tusker/Views/Profile Header/ProfileHeaderTableViewCell.swift +++ b/Tusker/Views/Profile Header/ProfileHeaderTableViewCell.swift @@ -9,10 +9,8 @@ import UIKit import Pachyderm -protocol ProfileHeaderTableViewCellDelegate: StatusTableViewCellDelegate { - +protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate { func showMoreOptions() - } class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive { diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 37bc9362..0c8e2292 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -213,7 +213,7 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive } @IBAction func morePressed(_ sender: Any) { - delegate?.showMoreOptions(status: statusID) + delegate?.showMoreOptions(forStatus: statusID) } } diff --git a/Tusker/Views/Status/StatusTableViewCell.swift b/Tusker/Views/Status/StatusTableViewCell.swift index a181dbd8..5d57d550 100644 --- a/Tusker/Views/Status/StatusTableViewCell.swift +++ b/Tusker/Views/Status/StatusTableViewCell.swift @@ -9,24 +9,7 @@ import UIKit import Pachyderm -protocol StatusTableViewCellDelegate { - - func selected(account accountID: String) - - func selected(mention: Mention) - - func selected(tag: Hashtag) - - func selected(url: URL) - - func selected(status statusID: String) - - func reply(to statusID: String) - - func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) - - func showMoreOptions(status statusID: String) - +protocol StatusTableViewCellDelegate: TuskerNavigationDelegate { } class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { @@ -264,7 +247,7 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { } @IBAction func morePressed(_ sender: Any) { - delegate?.showMoreOptions(status: statusID) + delegate?.showMoreOptions(forStatus: statusID) } } @@ -356,7 +339,7 @@ extension StatusTableViewCell: TableViewSwipeActionProvider { reply.backgroundColor = tintColor let more = UIContextualAction(style: .normal, title: "More") { (action, view, completion) in completion(true) - self.delegate?.showMoreOptions(status: self.statusID) + self.delegate?.showMoreOptions(forStatus: self.statusID) } more.image = StatusTableViewCell.moreActionImage more.backgroundColor = .gray