diff --git a/WordPress/Classes/ViewRelated/Pages/PageListCell.swift b/WordPress/Classes/ViewRelated/Pages/PageListCell.swift index bbbaa178c985..a0b989a52704 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageListCell.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageListCell.swift @@ -47,7 +47,7 @@ final class PageListCell: UITableViewCell, PostSearchResultCell, Reusable { func configure(with viewModel: PageListItemViewModel, indentation: Int = 0, isFirstSubdirectory: Bool = false, delegate: InteractivePostViewDelegate? = nil) { if let delegate { - configureEllipsisButton(with: viewModel.page, viewModel: viewModel.pageMenuViewModel, delegate: delegate) + configureEllipsisButton(with: viewModel.page, delegate: delegate) } titleLabel.attributedText = viewModel.title @@ -75,10 +75,9 @@ final class PageListCell: UITableViewCell, PostSearchResultCell, Reusable { indentationIconView.alpha = isFirstSubdirectory ? 1 : 0 // Still contribute to layout } - private func configureEllipsisButton(with page: Page, viewModel: PageMenuViewModel, delegate: InteractivePostViewDelegate) { - let menuHelper = AbstractPostMenuHelper(page, viewModel: viewModel) + private func configureEllipsisButton(with page: Page, delegate: InteractivePostViewDelegate) { ellipsisButton.showsMenuAsPrimaryAction = true - ellipsisButton.menu = menuHelper.makeMenu(presentingView: ellipsisButton, delegate: delegate) + ellipsisButton.menu = AbstractPostMenuHelper(page).makeMenu(presentingView: ellipsisButton, delegate: delegate) } // MARK: - Setup diff --git a/WordPress/Classes/ViewRelated/Pages/PageListItemViewModel.swift b/WordPress/Classes/ViewRelated/Pages/PageListItemViewModel.swift index 76c15e795c4c..2f58e0e70836 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageListItemViewModel.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageListItemViewModel.swift @@ -7,7 +7,6 @@ final class PageListItemViewModel { let badges: NSAttributedString let imageURL: URL? let accessibilityIdentifier: String? - let pageMenuViewModel: PageMenuViewModel init(page: Page) { self.page = page @@ -16,7 +15,6 @@ final class PageListItemViewModel { self.badges = makeBadgesString(for: page) self.imageURL = page.featuredImageURL self.accessibilityIdentifier = page.slugForDisplay() - self.pageMenuViewModel = PageMenuViewModel(page: page) } } diff --git a/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift b/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift index d768f52760aa..041dcffd16f8 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift @@ -319,13 +319,12 @@ class PageListViewController: AbstractPostListViewController, UIViewControllerRe } func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { - UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in + guard indexPath.section == Section.pages.rawValue else { return nil } + return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in guard let self else { return nil } let page = self.pages[indexPath.row] - let viewModel = PageMenuViewModel(page: page) - let helper = AbstractPostMenuHelper(page, viewModel: viewModel) let cell = self.tableView.cellForRow(at: indexPath) - return helper.makeMenu(presentingView: cell?.contentView ?? UIView(), delegate: self) + return AbstractPostMenuHelper(page).makeMenu(presentingView: cell ?? UIView(), delegate: self) } } diff --git a/WordPress/Classes/ViewRelated/Post/AbstractPostHelper+Actions.swift b/WordPress/Classes/ViewRelated/Post/AbstractPostHelper+Actions.swift index 046bed200c0f..2ac100700f64 100644 --- a/WordPress/Classes/ViewRelated/Post/AbstractPostHelper+Actions.swift +++ b/WordPress/Classes/ViewRelated/Post/AbstractPostHelper+Actions.swift @@ -1,6 +1,8 @@ import UIKit extension AbstractPostHelper { + // MARK: - Swipe Actions + static func makeLeadingContextualActions(for post: AbstractPost, delegate: InteractivePostViewDelegate) -> [UIContextualAction] { var actions: [UIContextualAction] = [] diff --git a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift index 805106330e44..e3638cb180c2 100644 --- a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift +++ b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift @@ -2,13 +2,10 @@ import Foundation import UIKit struct AbstractPostMenuHelper { - let post: AbstractPost - let viewModel: AbstractPostMenuViewModel - init(_ post: AbstractPost, viewModel: AbstractPostMenuViewModel) { + init(_ post: AbstractPost) { self.post = post - self.viewModel = viewModel } /// Creates a menu for post actions @@ -25,13 +22,25 @@ struct AbstractPostMenuHelper { ]) } + private func makeSections() -> [AbstractPostButtonSection] { + switch post { + case let post as Post: + return PostCardStatusViewModel(post: post).buttonSections + case let page as Page: + return PageMenuViewModel(page: page).buttonSections + default: + assertionFailure("Unsupported entity: \(post)") + return [] + } + } + /// Creates post actions grouped into sections /// /// - parameters: /// - presentingView: The view presenting the menu /// - delegate: The delegate that performs post actions private func makeSections(presentingView: UIView, delegate: InteractivePostViewDelegate) -> [UIMenu] { - return viewModel.buttonSections + return makeSections() .filter { !$0.buttons.isEmpty } .map { section in let actions = makeActions(for: section.buttons, presentingView: presentingView, delegate: delegate) diff --git a/WordPress/Classes/ViewRelated/Post/PostListHeaderView.swift b/WordPress/Classes/ViewRelated/Post/PostListHeaderView.swift index 0167d0a9e919..329e969c205d 100644 --- a/WordPress/Classes/ViewRelated/Post/PostListHeaderView.swift +++ b/WordPress/Classes/ViewRelated/Post/PostListHeaderView.swift @@ -27,13 +27,13 @@ final class PostListHeaderView: UIView { func configure(with viewModel: PostListItemViewModel, delegate: InteractivePostViewDelegate? = nil) { if let delegate { - configureEllipsisButton(with: viewModel.post, viewModel: viewModel.statusViewModel, delegate: delegate) + configureEllipsisButton(with: viewModel.post, delegate: delegate) } textLabel.attributedText = viewModel.badges } - private func configureEllipsisButton(with post: Post, viewModel: PostCardStatusViewModel, delegate: InteractivePostViewDelegate) { - let menuHelper = AbstractPostMenuHelper(post, viewModel: viewModel) + private func configureEllipsisButton(with post: Post, delegate: InteractivePostViewDelegate) { + let menuHelper = AbstractPostMenuHelper(post) ellipsisButton.showsMenuAsPrimaryAction = true ellipsisButton.menu = menuHelper.makeMenu(presentingView: ellipsisButton, delegate: delegate) } diff --git a/WordPress/Classes/ViewRelated/Post/PostListItemViewModel.swift b/WordPress/Classes/ViewRelated/Post/PostListItemViewModel.swift index ad447ceaacf4..55806220b126 100644 --- a/WordPress/Classes/ViewRelated/Post/PostListItemViewModel.swift +++ b/WordPress/Classes/ViewRelated/Post/PostListItemViewModel.swift @@ -6,7 +6,7 @@ final class PostListItemViewModel { let imageURL: URL? let badges: NSAttributedString let isEnabled: Bool - let statusViewModel: PostCardStatusViewModel + private let statusViewModel: PostCardStatusViewModel var status: String { statusViewModel.statusAndBadges(separatedBy: " ยท ")} var statusColor: UIColor { statusViewModel.statusColor } diff --git a/WordPress/Classes/ViewRelated/Post/PostListViewController.swift b/WordPress/Classes/ViewRelated/Post/PostListViewController.swift index ef9d78e67873..aeaa64cc83a5 100644 --- a/WordPress/Classes/ViewRelated/Post/PostListViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/PostListViewController.swift @@ -258,10 +258,8 @@ class PostListViewController: AbstractPostListViewController, UIViewControllerRe UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in guard let self else { return nil } let post = self.postAtIndexPath(indexPath) - let viewModel = PostListItemViewModel(post: post).statusViewModel - let helper = AbstractPostMenuHelper(post, viewModel: viewModel) let cell = self.tableView.cellForRow(at: indexPath) - return helper.makeMenu(presentingView: cell?.contentView ?? UIView(), delegate: self) + return AbstractPostMenuHelper(post).makeMenu(presentingView: cell ?? UIView(), delegate: self) } } diff --git a/WordPress/Classes/ViewRelated/Post/Search/PostSearchViewController.swift b/WordPress/Classes/ViewRelated/Post/Search/PostSearchViewController.swift index 6116e1542718..1e4b1aa8b95c 100644 --- a/WordPress/Classes/ViewRelated/Post/Search/PostSearchViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/Search/PostSearchViewController.swift @@ -172,7 +172,6 @@ final class PostSearchViewController: UIViewController, UITableViewDelegate, UIS default: fatalError("Unsupported post") } - break // TODO: Show post } } @@ -182,6 +181,16 @@ final class PostSearchViewController: UIViewController, UITableViewDelegate, UIS } } + func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { + guard indexPath.section == SectionID.posts.rawValue else { return nil } + return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in + guard let self, let delegate = self.delegate else { return nil } + let post = self.viewModel.posts[indexPath.row] + let cell = self.tableView.cellForRow(at: indexPath) + return AbstractPostMenuHelper(post).makeMenu(presentingView: cell ?? UIView(), delegate: delegate) + } + } + func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { guard let delegate, indexPath.section == SectionID.posts.rawValue else { return nil } let actions = AbstractPostHelper.makeLeadingContextualActions(for: viewModel.posts[indexPath.row], delegate: delegate)