[Framework] Feed item filtering in the Feed List view (#11)

This PR contains the work done to implement the filtering of the items shown in the `FeedListViewController` view controller by star rating.

Reviewed-on: rock-n-code/app-reviews#11
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #11.
This commit is contained in:
2024-03-20 21:35:46 +00:00
committed by javier
parent c9f4b9a677
commit eac34c61c1
11 changed files with 517 additions and 94 deletions
@@ -7,6 +7,8 @@
//
import Combine
import Foundation
import ReviewsFoundationKit
import ReviewsUIKit
import SwiftUI
import UIKit
@@ -19,6 +21,36 @@ public class FeedListViewController: UITableViewController {
// MARK: Properties
private var cancellables: Set<AnyCancellable> = []
// MARK: Outlets
private lazy var filterButton = {
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: {
FilterOption.allCases.map { option -> UIAction in
.init(title: option.text,
image: .init(systemName: option.icon)
) { [weak self] _ in
self?.viewModel.filter(by: option)
}
}
}()
)
)
}()
// MARK: Initialisers
public init(configuration: Configuration = .init()) {
self.viewModel = .init(configuration: configuration)
@@ -30,6 +62,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 +97,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 +114,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 +131,26 @@ private extension FeedListViewController {
// MARK: Functions
func bindViewModel() {
viewModel.$loading
.sink { loading in
print("LOADING: \(loading)")
viewModel.$filter
.receive(on: RunLoop.main)
.sink { [weak self] option in
self?.updateFilterMenu(option)
self?.tableView.reloadData()
}
.store(in: &cancellables)
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 +166,24 @@ 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
)
}
func updateFilterMenu(_ option: FilterOption) {
filterButton
.menu?
.children
.compactMap { $0 as? UIAction }
.forEach { action in
action.state = action.title == option.text
? .on
: .off
}
}
}
@@ -151,11 +216,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, *)