From ab8e498cee31549762a47781944d4fd551238968 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 29 Nov 2022 22:41:36 -0500 Subject: [PATCH] Refactor menu actions to allow presenting from menu bar items --- Tusker.xcodeproj/project.pbxproj | 8 ++-- Tusker/Preferences/StatusSwipeAction.swift | 2 +- .../AccountListViewController.swift | 2 +- .../ProfileDirectoryViewController.swift | 2 +- .../TrendingHashtagsViewController.swift | 2 +- .../Screens/Search/SearchViewController.swift | 2 +- ...tatusActionAccountListViewController.swift | 2 +- Tusker/Screens/Utilities/Previewing.swift | 26 ++++++------- Tusker/TuskerNavigationDelegate.swift | 39 ++++++++++++++++--- .../Account Cell/AccountTableViewCell.swift | 2 +- Tusker/Views/ContentTextView.swift | 6 +-- ...FollowNotificationGroupTableViewCell.swift | 2 +- .../PollFinishedTableViewCell.swift | 2 +- ...atusUpdatedNotificationTableViewCell.swift | 2 +- .../Profile Header/ProfileHeaderView.swift | 2 +- .../Status/BaseStatusTableViewCell.swift | 4 +- .../ConversationMainStatusTableViewCell.swift | 2 +- Tusker/Views/Status/StatusCardView.swift | 2 +- .../Status/StatusCollectionViewCell.swift | 4 +- .../TimelineStatusCollectionViewCell.swift | 2 +- .../Status/TimelineStatusTableViewCell.swift | 4 +- .../Views/Toast/ToastableViewController.swift | 10 +---- Tusker/{WeakArray.swift => Weak.swift} | 22 +++++------ 23 files changed, 85 insertions(+), 66 deletions(-) rename Tusker/{WeakArray.swift => Weak.swift} (69%) diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index eb7acc8a..4acf06ff 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -293,7 +293,7 @@ D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */; }; D6DF95C12533F5DE0027A9B6 /* RelationshipMO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DF95C02533F5DE0027A9B6 /* RelationshipMO.swift */; }; D6DFC69E242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69D242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift */; }; - D6DFC6A0242C4CCC00ACC392 /* WeakArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */; }; + D6DFC6A0242C4CCC00ACC392 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69F242C4CCC00ACC392 /* Weak.swift */; }; D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; }; D6E343AB265AAD6B00C4AA01 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6E343AA265AAD6B00C4AA01 /* Media.xcassets */; }; D6E343AD265AAD6B00C4AA01 /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E343AC265AAD6B00C4AA01 /* ActionViewController.swift */; }; @@ -668,7 +668,7 @@ D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Preferences+Notification.swift"; sourceTree = ""; }; D6DF95C02533F5DE0027A9B6 /* RelationshipMO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipMO.swift; sourceTree = ""; }; D6DFC69D242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackpadScrollGestureRecognizer.swift; sourceTree = ""; }; - D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakArray.swift; sourceTree = ""; }; + D6DFC69F242C4CCC00ACC392 /* Weak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; }; D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = ""; }; D6E343A8265AAD6B00C4AA01 /* OpenInTusker.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OpenInTusker.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D6E343AA265AAD6B00C4AA01 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; @@ -1421,7 +1421,7 @@ D6945C2E23AC47C3005C403C /* SavedDataManager.swift */, D6895DE828D962C2006341DA /* TimelineLikeController.swift */, D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */, - D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */, + D6DFC69F242C4CCC00ACC392 /* Weak.swift */, D63D8DF32850FE7A008D95E1 /* ViewTags.swift */, D6D4DDD6212518A200E1C4BB /* Assets.xcassets */, D6AEBB3F2321640F00E5038B /* Activities */, @@ -2010,7 +2010,7 @@ D6945C3223AC4D36005C403C /* HashtagTimelineViewController.swift in Sources */, D647D92824257BEB0005044F /* AttachmentPreviewViewController.swift in Sources */, D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */, - D6DFC6A0242C4CCC00ACC392 /* WeakArray.swift in Sources */, + D6DFC6A0242C4CCC00ACC392 /* Weak.swift in Sources */, D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */, D61ABEF828EFC3F900B29151 /* ProfileStatusesViewController.swift in Sources */, D6ADB6EA28E91C30009924AB /* TimelineStatusCollectionViewCell.swift in Sources */, diff --git a/Tusker/Preferences/StatusSwipeAction.swift b/Tusker/Preferences/StatusSwipeAction.swift index 00064d51..f6cccb8d 100644 --- a/Tusker/Preferences/StatusSwipeAction.swift +++ b/Tusker/Preferences/StatusSwipeAction.swift @@ -125,7 +125,7 @@ private func createReblogAction(status: StatusMO, container: StatusSwipeActionCo private func createShareAction(status: StatusMO, container: StatusSwipeActionContainer) -> UIContextualAction { let action = UIContextualAction(style: .normal, title: "Share") { [unowned container] _, _, completion in - container.navigationDelegate.showMoreOptions(forStatus: status.id, sourceView: container) + container.navigationDelegate.showMoreOptions(forStatus: status.id, source: .view(container)) completion(true) } // bold to more closesly match other action symbols diff --git a/Tusker/Screens/Account List/AccountListViewController.swift b/Tusker/Screens/Account List/AccountListViewController.swift index 053c7b0d..72f5dbcc 100644 --- a/Tusker/Screens/Account List/AccountListViewController.swift +++ b/Tusker/Screens/Account List/AccountListViewController.swift @@ -88,7 +88,7 @@ extension AccountListViewController: UICollectionViewDelegate { return UIContextMenuConfiguration { ProfileViewController(accountID: id, mastodonController: self.mastodonController) } actionProvider: { _ in - UIMenu(children: self.actionsForProfile(accountID: id, sourceView: cell)) + UIMenu(children: self.actionsForProfile(accountID: id, source: .view(cell))) } } diff --git a/Tusker/Screens/Explore/ProfileDirectoryViewController.swift b/Tusker/Screens/Explore/ProfileDirectoryViewController.swift index b4f16044..95dac999 100644 --- a/Tusker/Screens/Explore/ProfileDirectoryViewController.swift +++ b/Tusker/Screens/Explore/ProfileDirectoryViewController.swift @@ -174,7 +174,7 @@ extension ProfileDirectoryViewController: UICollectionViewDelegate { return UIContextMenuConfiguration(identifier: nil) { return ProfileViewController(accountID: account.id, mastodonController: self.mastodonController) } actionProvider: { (_) in - let actions = self.actionsForProfile(accountID: account.id, sourceView: self.collectionView.cellForItem(at: indexPath)) + let actions = self.actionsForProfile(accountID: account.id, source: .view(self.collectionView.cellForItem(at: indexPath))) return UIMenu(children: actions) } diff --git a/Tusker/Screens/Explore/TrendingHashtagsViewController.swift b/Tusker/Screens/Explore/TrendingHashtagsViewController.swift index 98393372..b0afbb30 100644 --- a/Tusker/Screens/Explore/TrendingHashtagsViewController.swift +++ b/Tusker/Screens/Explore/TrendingHashtagsViewController.swift @@ -98,7 +98,7 @@ extension TrendingHashtagsViewController: UICollectionViewDelegate { return UIContextMenuConfiguration(identifier: nil) { HashtagTimelineViewController(for: hashtag, mastodonController: self.mastodonController) } actionProvider: { (_) in - UIMenu(children: self.actionsForHashtag(hashtag, sourceView: self.collectionView.cellForItem(at: indexPath))) + UIMenu(children: self.actionsForHashtag(hashtag, source: .view(self.collectionView.cellForItem(at: indexPath)))) } } } diff --git a/Tusker/Screens/Search/SearchViewController.swift b/Tusker/Screens/Search/SearchViewController.swift index 7a548f39..e862ef80 100644 --- a/Tusker/Screens/Search/SearchViewController.swift +++ b/Tusker/Screens/Search/SearchViewController.swift @@ -270,7 +270,7 @@ extension SearchViewController: UICollectionViewDelegate { return UIContextMenuConfiguration(identifier: nil) { HashtagTimelineViewController(for: hashtag, mastodonController: self.mastodonController) } actionProvider: { (_) in - UIMenu(children: self.actionsForHashtag(hashtag, sourceView: self.collectionView.cellForItem(at: indexPath))) + UIMenu(children: self.actionsForHashtag(hashtag, source: .view(self.collectionView.cellForItem(at: indexPath)))) } case let .link(card): diff --git a/Tusker/Screens/Status Action Account List/StatusActionAccountListViewController.swift b/Tusker/Screens/Status Action Account List/StatusActionAccountListViewController.swift index 60e2d432..b6a098da 100644 --- a/Tusker/Screens/Status Action Account List/StatusActionAccountListViewController.swift +++ b/Tusker/Screens/Status Action Account List/StatusActionAccountListViewController.swift @@ -206,7 +206,7 @@ extension StatusActionAccountListViewController: UICollectionViewDelegate { return UIContextMenuConfiguration { ProfileViewController(accountID: id, mastodonController: self.mastodonController) } actionProvider: { _ in - UIMenu(children: self.actionsForProfile(accountID: id, sourceView: cell)) + UIMenu(children: self.actionsForProfile(accountID: id, source: .view(cell))) } } } diff --git a/Tusker/Screens/Utilities/Previewing.swift b/Tusker/Screens/Utilities/Previewing.swift index 6f70fbd6..2d310198 100644 --- a/Tusker/Screens/Utilities/Previewing.swift +++ b/Tusker/Screens/Utilities/Previewing.swift @@ -39,15 +39,15 @@ extension MenuActionProvider { private var mastodonController: MastodonController? { navigationDelegate?.apiController } - func actionsForProfile(accountID: String, sourceView: UIView?) -> [UIMenuElement] { + func actionsForProfile(accountID: String, source: PopoverSource) -> [UIMenuElement] { guard let mastodonController = mastodonController, let account = mastodonController.persistentContainer.account(for: accountID) else { return [] } var shareSection = [ openInSafariAction(url: account.url), - createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self, weak sourceView] (_) in + createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in guard let self = self else { return } - self.navigationDelegate?.showMoreOptions(forAccount: accountID, sourceView: sourceView) + self.navigationDelegate?.showMoreOptions(forAccount: accountID, source: source) }) ] @@ -95,17 +95,17 @@ extension MenuActionProvider { ] } - func actionsForURL(_ url: URL, sourceView: UIView?) -> [UIAction] { + func actionsForURL(_ url: URL, source: PopoverSource) -> [UIAction] { return [ openInSafariAction(url: url), - createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self, weak sourceView] (_) in + createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in guard let self = self else { return } - self.navigationDelegate?.showMoreOptions(forURL: url, sourceView: sourceView) + self.navigationDelegate?.showMoreOptions(forURL: url, source: source) }) ] } - func actionsForHashtag(_ hashtag: Hashtag, sourceView: UIView?) -> [UIMenuElement] { + func actionsForHashtag(_ hashtag: Hashtag, source: PopoverSource) -> [UIMenuElement] { let actionsSection: [UIMenuElement] if let mastodonController = mastodonController, mastodonController.loggedIn { @@ -127,7 +127,7 @@ extension MenuActionProvider { let shareSection: [UIMenuElement] if let url = URL(hashtag.url) { - shareSection = actionsForURL(url, sourceView: sourceView) + shareSection = actionsForURL(url, source: source) } else { shareSection = [] } @@ -138,16 +138,16 @@ extension MenuActionProvider { ] } - func actionsForStatus(_ status: StatusMO, sourceView: UIView?, includeStatusButtonActions: Bool = true) -> [UIMenuElement] { + func actionsForStatus(_ status: StatusMO, source: PopoverSource, includeStatusButtonActions: Bool = true) -> [UIMenuElement] { guard let mastodonController = mastodonController else { return [] } guard let accountID = mastodonController.accountInfo?.id else { // user is logged out return [ openInSafariAction(url: status.url!), - createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self, weak sourceView] (_) in + createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in guard let self = self else { return } - self.navigationDelegate?.showMoreOptions(forStatus: status.id, sourceView: sourceView) + self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source) }) ] } @@ -271,9 +271,9 @@ extension MenuActionProvider { } else { Logging.general.fault("Status missing URL: id=\(status.id, privacy: .public), reblog=\((status.reblog?.id).debugDescription, privacy: .public)") } - shareSection.append(createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self, weak sourceView] (_) in + shareSection.append(createAction(identifier: "share", title: "Share", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in guard let self = self else { return } - self.navigationDelegate?.showMoreOptions(forStatus: status.id, sourceView: sourceView) + self.navigationDelegate?.showMoreOptions(forStatus: status.id, source: source) })) addOpenInNewWindow(actions: &shareSection, activity: UserActivityManager.showConversationActivity(mainStatusID: status.id, accountID: accountID)) diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift index 2416c952..2fbe7dfe 100644 --- a/Tusker/TuskerNavigationDelegate.swift +++ b/Tusker/TuskerNavigationDelegate.swift @@ -159,21 +159,21 @@ extension TuskerNavigationDelegate { return UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: nil) } - func showMoreOptions(forStatus statusID: String, sourceView: UIView?) { + func showMoreOptions(forStatus statusID: String, source: PopoverSource) { let vc = moreOptions(forStatus: statusID) - vc.popoverPresentationController?.sourceView = sourceView + source.apply(to: vc) present(vc, animated: true) } - func showMoreOptions(forURL url: URL, sourceView: UIView?) { + func showMoreOptions(forURL url: URL, source: PopoverSource) { let vc = moreOptions(forURL: url) - vc.popoverPresentationController?.sourceView = sourceView + source.apply(to: vc) present(vc, animated: true) } - func showMoreOptions(forAccount accountID: String, sourceView: UIView?) { + func showMoreOptions(forAccount accountID: String, source: PopoverSource) { let vc = moreOptions(forAccount: accountID) - vc.popoverPresentationController?.sourceView = sourceView + source.apply(to: vc) present(vc, animated: true) } @@ -188,3 +188,30 @@ extension TuskerNavigationDelegate { } } + +enum PopoverSource { + case none + case view(WeakHolder) + case barButtonItem(WeakHolder) + + func apply(to viewController: UIViewController) { + if let popoverPresentationController = viewController.popoverPresentationController { + switch self { + case .none: + break + case .view(let view): + popoverPresentationController.sourceView = view.object + case .barButtonItem(let item): + popoverPresentationController.barButtonItem = item.object + } + } + } + + static func view(_ view: UIView?) -> Self { + .view(WeakHolder(view)) + } + + static func barButtonItem(_ item: UIBarButtonItem?) -> Self { + .barButtonItem(WeakHolder(item)) + } +} diff --git a/Tusker/Views/Account Cell/AccountTableViewCell.swift b/Tusker/Views/Account Cell/AccountTableViewCell.swift index 620ead07..6039fb5a 100644 --- a/Tusker/Views/Account Cell/AccountTableViewCell.swift +++ b/Tusker/Views/Account Cell/AccountTableViewCell.swift @@ -109,7 +109,7 @@ extension AccountTableViewCell: MenuPreviewProvider { guard let mastodonController = mastodonController else { return nil } return ( content: { ProfileViewController(accountID: self.accountID, mastodonController: mastodonController) }, - actions: { self.delegate?.actionsForProfile(accountID: self.accountID, sourceView: self.avatarImageView) ?? [] } + actions: { self.delegate?.actionsForProfile(accountID: self.accountID, source: .view(self.avatarImageView)) ?? [] } ) } } diff --git a/Tusker/Views/ContentTextView.swift b/Tusker/Views/ContentTextView.swift index 23c2b204..e8effca2 100644 --- a/Tusker/Views/ContentTextView.swift +++ b/Tusker/Views/ContentTextView.swift @@ -321,11 +321,11 @@ extension ContentTextView: UIContextMenuInteractionDelegate { let text = (self.text as NSString).substring(with: range) let actions: [UIMenuElement] if let mention = self.getMention(for: link, text: text) { - actions = self.actionsForProfile(accountID: mention.id, sourceView: self) + actions = self.actionsForProfile(accountID: mention.id, source: .view(self)) } else if let tag = self.getHashtag(for: link, text: text) { - actions = self.actionsForHashtag(tag, sourceView: self) + actions = self.actionsForHashtag(tag, source: .view(self)) } else { - actions = self.actionsForURL(link, sourceView: self) + actions = self.actionsForURL(link, source: .view(self)) } return UIMenu(title: "", image: nil, identifier: nil, options: [], children: actions) } diff --git a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift index 7afb7d7e..c7fc1f63 100644 --- a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift @@ -214,7 +214,7 @@ extension FollowNotificationGroupTableViewCell: MenuPreviewProvider { } }, actions: { if accountIDs.count == 1 { - return self.delegate?.actionsForProfile(accountID: accountIDs.first!, sourceView: self) ?? [] + return self.delegate?.actionsForProfile(accountID: accountIDs.first!, source: .view(self)) ?? [] } else { return [] } diff --git a/Tusker/Views/Notifications/PollFinishedTableViewCell.swift b/Tusker/Views/Notifications/PollFinishedTableViewCell.swift index 726220a1..e773549a 100644 --- a/Tusker/Views/Notifications/PollFinishedTableViewCell.swift +++ b/Tusker/Views/Notifications/PollFinishedTableViewCell.swift @@ -114,7 +114,7 @@ extension PollFinishedTableViewCell: MenuPreviewProvider { return (content: { delegate.conversation(mainStatusID: statusID, state: .unknown) }, actions: { - delegate.actionsForStatus(status, sourceView: self) + delegate.actionsForStatus(status, source: .view(self)) }) } } diff --git a/Tusker/Views/Notifications/StatusUpdatedNotificationTableViewCell.swift b/Tusker/Views/Notifications/StatusUpdatedNotificationTableViewCell.swift index 555894b2..32a70ec4 100644 --- a/Tusker/Views/Notifications/StatusUpdatedNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/StatusUpdatedNotificationTableViewCell.swift @@ -108,7 +108,7 @@ extension StatusUpdatedNotificationTableViewCell: MenuPreviewProvider { return (content: { delegate.conversation(mainStatusID: statusID, state: .unknown) }, actions: { - delegate.actionsForStatus(status, sourceView: self) + delegate.actionsForStatus(status, source: .view(self)) }) } } diff --git a/Tusker/Views/Profile Header/ProfileHeaderView.swift b/Tusker/Views/Profile Header/ProfileHeaderView.swift index 9f1e1097..2baf56d3 100644 --- a/Tusker/Views/Profile Header/ProfileHeaderView.swift +++ b/Tusker/Views/Profile Header/ProfileHeaderView.swift @@ -122,7 +122,7 @@ class ProfileHeaderView: UIView { updateImages(account: account) - moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForProfile(accountID: accountID, sourceView: moreButton) ?? []) + moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForProfile(accountID: accountID, source: .view(moreButton)) ?? []) noteTextView.navigationDelegate = delegate noteTextView.setTextFromHtml(account.note) diff --git a/Tusker/Views/Status/BaseStatusTableViewCell.swift b/Tusker/Views/Status/BaseStatusTableViewCell.swift index 1e4d135c..43b9d6a3 100644 --- a/Tusker/Views/Status/BaseStatusTableViewCell.swift +++ b/Tusker/Views/Status/BaseStatusTableViewCell.swift @@ -209,7 +209,7 @@ class BaseStatusTableViewCell: UITableViewCell { // keep menu in sync with changed states e.g. bookmarked, muted // do not include reply action here, because the cell already contains a button for it - moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForStatus(status, sourceView: moreButton, includeStatusButtonActions: false) ?? []) + moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForStatus(status, source: .view(moreButton), includeStatusButtonActions: false) ?? []) pollView.isHidden = status.poll == nil pollView.mastodonController = mastodonController @@ -408,7 +408,7 @@ class BaseStatusTableViewCell: UITableViewCell { } @IBAction func morePressed() { - delegate?.showMoreOptions(forStatus: statusID, sourceView: moreButton) + delegate?.showMoreOptions(forStatus: statusID, source: .view(moreButton)) } @objc func accountPressed() { diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 5cae0150..53e5634f 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -135,7 +135,7 @@ extension ConversationMainStatusTableViewCell: UIContextMenuInteractionDelegate return UIContextMenuConfiguration(identifier: nil) { ProfileViewController(accountID: self.accountID, mastodonController: self.mastodonController) } actionProvider: { (_) in - return UIMenu(title: "", image: nil, identifier: nil, options: [], children: self.delegate?.actionsForProfile(accountID: self.accountID, sourceView: self.avatarImageView) ?? []) + return UIMenu(title: "", image: nil, identifier: nil, options: [], children: self.delegate?.actionsForProfile(accountID: self.accountID, source: .view(self.avatarImageView)) ?? []) } } } diff --git a/Tusker/Views/Status/StatusCardView.swift b/Tusker/Views/Status/StatusCardView.swift index ef813c2e..5dcc84d9 100644 --- a/Tusker/Views/Status/StatusCardView.swift +++ b/Tusker/Views/Status/StatusCardView.swift @@ -230,7 +230,7 @@ extension StatusCardView: UIContextMenuInteractionDelegate { return UIContextMenuConfiguration(identifier: nil) { return SFSafariViewController(url: URL(card.url)!) } actionProvider: { (_) in - let actions = self.actionProvider?.actionsForURL(URL(card.url)!, sourceView: self) ?? [] + let actions = self.actionProvider?.actionsForURL(URL(card.url)!, source: .view(self)) ?? [] return UIMenu(title: "", image: nil, identifier: nil, options: [], children: actions) } } diff --git a/Tusker/Views/Status/StatusCollectionViewCell.swift b/Tusker/Views/Status/StatusCollectionViewCell.swift index 2bd63a25..eb0ace0a 100644 --- a/Tusker/Views/Status/StatusCollectionViewCell.swift +++ b/Tusker/Views/Status/StatusCollectionViewCell.swift @@ -195,7 +195,7 @@ extension StatusCollectionViewCell { // keep menu in sync with changed states e.g. bookmarked, muted // do not include reply action here, because the cell already contains a button for it - moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForStatus(status, sourceView: moreButton, includeStatusButtonActions: false) ?? []) + moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForStatus(status, source: .view(moreButton), includeStatusButtonActions: false) ?? []) contentContainer.pollView.isHidden = status.poll == nil contentContainer.pollView.mastodonController = mastodonController @@ -257,7 +257,7 @@ extension StatusCollectionViewCell { return UIContextMenuConfiguration() { ProfileViewController(accountID: self.accountID, mastodonController: self.mastodonController) } actionProvider: { _ in - return UIMenu(children: self.delegate?.actionsForProfile(accountID: self.accountID, sourceView: sourceView) ?? []) + return UIMenu(children: self.delegate?.actionsForProfile(accountID: self.accountID, source: .view(sourceView)) ?? []) } } } diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index 07c063c4..505fdfd3 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -653,7 +653,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti return UIContextMenuConfiguration { ConversationTableViewController(for: self.statusID, state: self.statusState.copy(), mastodonController: self.mastodonController) } actionProvider: { _ in - UIMenu(children: self.delegate!.actionsForStatus(status, sourceView: self)) + UIMenu(children: self.delegate!.actionsForStatus(status, source: .view(self))) } } diff --git a/Tusker/Views/Status/TimelineStatusTableViewCell.swift b/Tusker/Views/Status/TimelineStatusTableViewCell.swift index cdfe51f3..632f3442 100644 --- a/Tusker/Views/Status/TimelineStatusTableViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusTableViewCell.swift @@ -377,7 +377,7 @@ extension TimelineStatusTableViewCell: UIContextMenuInteractionDelegate { return UIContextMenuConfiguration(identifier: nil) { ProfileViewController(accountID: self.accountID, mastodonController: self.mastodonController) } actionProvider: { (_) in - return UIMenu(title: "", image: nil, identifier: nil, options: [], children: self.delegate?.actionsForProfile(accountID: self.accountID, sourceView: self.avatarImageView) ?? []) + return UIMenu(title: "", image: nil, identifier: nil, options: [], children: self.delegate?.actionsForProfile(accountID: self.accountID, source: .view(self.avatarImageView)) ?? []) } } @@ -405,7 +405,7 @@ extension TimelineStatusTableViewCell: MenuPreviewProvider { } return ( content: { ConversationTableViewController(for: self.statusID, state: self.statusState.copy(), mastodonController: mastodonController) }, - actions: { self.delegate?.actionsForStatus(status, sourceView: self) ?? [] } + actions: { self.delegate?.actionsForStatus(status, source: .view(self)) ?? [] } ) } } diff --git a/Tusker/Views/Toast/ToastableViewController.swift b/Tusker/Views/Toast/ToastableViewController.swift index ea25f570..8827691d 100644 --- a/Tusker/Views/Toast/ToastableViewController.swift +++ b/Tusker/Views/Toast/ToastableViewController.swift @@ -27,7 +27,7 @@ extension ToastableViewController { } set { if let newValue = newValue { - objc_setAssociatedObject(self, currentToastKey, WeakHolder(object: newValue), .OBJC_ASSOCIATION_RETAIN) + objc_setAssociatedObject(self, currentToastKey, WeakHolder(newValue), .OBJC_ASSOCIATION_RETAIN) } else { objc_setAssociatedObject(self, currentToastKey, nil, .OBJC_ASSOCIATION_RETAIN) } @@ -96,11 +96,3 @@ extension ToastableViewController { } } - -fileprivate class WeakHolder { - weak var object: T? - - init(object: T) { - self.object = object - } -} diff --git a/Tusker/WeakArray.swift b/Tusker/Weak.swift similarity index 69% rename from Tusker/WeakArray.swift rename to Tusker/Weak.swift index 6228bc80..f956a727 100644 --- a/Tusker/WeakArray.swift +++ b/Tusker/Weak.swift @@ -1,5 +1,5 @@ // -// WeakArray.swift +// Weak.swift // Tusker // // Created by Shadowfacts on 3/25/20. @@ -8,16 +8,16 @@ import Foundation -fileprivate class WeakWrapper { - weak var value: T? +class WeakHolder { + weak var object: T? - init(_ value: T?) { - self.value = value + init(_ object: T?) { + self.object = object } } struct WeakArray: MutableCollection, RangeReplaceableCollection { - private var array: [WeakWrapper] + private var array: [WeakHolder] var startIndex: Int { array.startIndex } var endIndex: Int { array.endIndex } @@ -27,19 +27,19 @@ struct WeakArray: MutableCollection, RangeReplaceableCollect } init(_ elements: [Element]) { - array = elements.map { WeakWrapper($0) } + array = elements.map { WeakHolder($0) } } init(_ elements: [Element?]) { - array = elements.map { WeakWrapper($0) } + array = elements.map { WeakHolder($0) } } subscript(position: Int) -> Element? { get { - array[position].value + array[position].object } set(newValue) { - array[position] = WeakWrapper(newValue) + array[position] = WeakHolder(newValue) } } @@ -48,6 +48,6 @@ struct WeakArray: MutableCollection, RangeReplaceableCollect } mutating func replaceSubrange(_ subrange: Range, with newElements: C) where C : Collection, Self.Element == C.Element { - array.replaceSubrange(subrange, with: newElements.map { WeakWrapper($0) }) + array.replaceSubrange(subrange, with: newElements.map { WeakHolder($0) }) } }