From 799007621249a9545fd1cc84e2b9998e3822fa36 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Wed, 20 Mar 2024 21:24:02 +0100 Subject: [PATCH] Implemented the filter navigation button with its respective filter menu for the FeedListViewController view controller in the Feed framework. --- .../FeedListViewController.swift | 90 +++++++++++++++++-- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedListViewController.swift b/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedListViewController.swift index 09ee7bd..fb60287 100644 --- a/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedListViewController.swift +++ b/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedListViewController.swift @@ -7,6 +7,8 @@ // import Combine +import Foundation +import ReviewsFoundationKit import ReviewsUIKit import SwiftUI import UIKit @@ -19,6 +21,50 @@ public class FeedListViewController: UITableViewController { // MARK: Properties private var cancellables: Set = [] + // MARK: Outlets + private lazy var filterButton = { + let allStars = UIAction( + title: FilterOption.all.text, + image: .init(systemName: FilterOption.all.icon) + ) { [weak self] _ in + self?.viewModel.filter = .all + } + + return UIBarButtonItem( + title: NSLocalizedString( + .Key.Navigation.Button.filter, + bundle: .module, + comment: .empty + ), + image: .Icon.filter, + primaryAction: nil, + menu: .init( + title: NSLocalizedString( + .Key.Menu.filter, + bundle: .module, + comment: .empty + ), + image: UIImage.Icon.star, + children: [allStars, filterStarMenu] + ) + ) + }() + + private lazy var filterStarMenu = { + UIMenu( + options: .displayInline, + children: { + FilterOption.allCases.map { option -> UIAction in + .init(title: option.text, + image: .init(systemName: option.icon) + ) { [weak self] _ in + self?.viewModel.filter = option + } + } + }() + ) + }() + // MARK: Initialisers public init(configuration: Configuration = .init()) { self.viewModel = .init(configuration: configuration) @@ -30,6 +76,11 @@ public class FeedListViewController: UITableViewController { fatalError("init(coder:) has not been implemented") } + // MARK: Computed + var items: [Review] { + viewModel.items + } + // MARK: UIViewController public override func viewDidLoad() { super.viewDidLoad() @@ -60,11 +111,11 @@ public class FeedListViewController: UITableViewController { cell.contentConfiguration = { if #available(iOS 16.0, *) { UIHostingConfiguration { - FeedItemCell(viewModel.items[indexPath.row]) + FeedItemCell(items[indexPath.row]) } } else { HostingConfiguration { - FeedItemCell(viewModel.items[indexPath.row]) + FeedItemCell(items[indexPath.row]) } } }() @@ -77,7 +128,7 @@ public class FeedListViewController: UITableViewController { _ tableView: UITableView, didSelectRowAt indexPath: IndexPath ) { - let details = FeedItemViewController(viewModel.items[indexPath.row]) + let details = FeedItemViewController(items[indexPath.row]) tableView.deselectRow( at: indexPath, @@ -94,15 +145,18 @@ private extension FeedListViewController { // MARK: Functions func bindViewModel() { - viewModel.$loading - .sink { loading in - print("LOADING: \(loading)") + viewModel.$isFilterEnabled + .removeDuplicates() + .receive(on: RunLoop.main) + .sink { [weak self] enabled in + self?.filterButton.isEnabled = enabled } .store(in: &cancellables) - viewModel.$loading + viewModel.$isLoading .dropFirst() .filter { $0 == false } + .removeDuplicates() .receive(on: RunLoop.main) .sink { [weak self] _ in self?.tableView.reloadData() @@ -118,7 +172,12 @@ private extension FeedListViewController { navigationController?.navigationBar.prefersLargeTitles = true navigationController?.navigationBar.isTranslucent = true - navigationItem.title = "Latest reviews" + navigationItem.rightBarButtonItem = filterButton + navigationItem.title = NSLocalizedString( + .Key.Navigation.title, + bundle: .module, + comment: .empty + ) } } @@ -151,11 +210,24 @@ private extension String { enum Cell { static let feedItem = "FeedItemCell" } + + enum Key { + enum Menu { + static let filter = "common.filter.menu.title.text" + } + + enum Navigation { + static let title = "view.feed-list.navigation-bar.title.text" + + enum Button { + static let filter = "view.feed-list.navigation-bar.button.filter-list.text" + } + } + } } // MARK: - Previews #if DEBUG -import ReviewsFoundationKit import ReviewsiTunesKit @available(iOS 17.0, *)