[Framework] Show top words for filtered items in the Feed List (#12)
This PR contains the work done to show the top 3 words belonging to the filtered reviews in the `FeedListViewController` view controller. Reviewed-on: rock-n-code/app-reviews#12 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 #12.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TopWord+DTOs.swift
|
||||
// ReviewsFeed
|
||||
//
|
||||
// Created by Javier Cicchelli on 21/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ReviewsFilterKit
|
||||
|
||||
extension TopWord {
|
||||
|
||||
// MARK: Initialisers
|
||||
init(_ dto: WordCount) {
|
||||
self = .init(
|
||||
id: UUID().uuidString,
|
||||
term: dto.word.term,
|
||||
count: dto.count
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TopWord.swift
|
||||
// ReviewsFeed
|
||||
//
|
||||
// Created by Javier Cicchelli on 21/03/2024.
|
||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
struct TopWord: Identifiable {
|
||||
|
||||
// MARK: Constants
|
||||
let id: String
|
||||
let term: String
|
||||
let count: Int
|
||||
|
||||
}
|
||||
@@ -18,6 +18,9 @@ extension FeedListViewController {
|
||||
|
||||
// MARK: Constants
|
||||
private let configuration: Configuration
|
||||
|
||||
private let filterWords: FilterWordsUseCase = .init()
|
||||
private let topWords: TopWordsUseCase = .init()
|
||||
|
||||
// MARK: Properties
|
||||
@Published var filter: FilterOption = .all
|
||||
@@ -26,9 +29,11 @@ extension FeedListViewController {
|
||||
@Published var isLoading: Bool = false
|
||||
|
||||
var items: [Review] = []
|
||||
var words: [TopWord] = []
|
||||
|
||||
private var reviewsAll: [Review] = []
|
||||
private var reviewsFiltered: FilteredReviews = [:]
|
||||
private var reviewsTopWords: TopWordsReviews = [:]
|
||||
|
||||
lazy private var iTunesService: iTunesService = {
|
||||
.init(configuration: .init(session: configuration.session))
|
||||
@@ -38,6 +43,18 @@ extension FeedListViewController {
|
||||
init(configuration: Configuration = .init()) {
|
||||
self.configuration = configuration
|
||||
}
|
||||
|
||||
// MARK: Computed
|
||||
var itemsCount: Int {
|
||||
isWordsShowing
|
||||
? items.count
|
||||
: items.count + 1
|
||||
}
|
||||
|
||||
var isWordsShowing: Bool {
|
||||
filter != .all
|
||||
&& !words.isEmpty
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
func fetch() {
|
||||
@@ -56,6 +73,14 @@ extension FeedListViewController {
|
||||
.reduce(into: FilteredReviews()) { partialResult, option in
|
||||
partialResult[option] = reviewsAll.filter { $0.rating.stars == option.rawValue }
|
||||
}
|
||||
reviewsTopWords = reviewsFiltered
|
||||
.mapValues { reviews in
|
||||
reviews.map(\.comment)
|
||||
.compactMap { try? filterWords($0) }
|
||||
}
|
||||
.mapValues {
|
||||
topWords($0).map(TopWord.init)
|
||||
}
|
||||
|
||||
items = reviewsAll
|
||||
isFilterEnabled = !items.isEmpty
|
||||
@@ -74,9 +99,18 @@ extension FeedListViewController {
|
||||
items = option == .all
|
||||
? reviewsAll
|
||||
: reviewsFiltered[option] ?? []
|
||||
|
||||
words = reviewsTopWords[option] ?? []
|
||||
|
||||
filter = option
|
||||
}
|
||||
|
||||
func item(for index: Int) -> Review? {
|
||||
guard index < items.count else { return nil }
|
||||
|
||||
return isWordsShowing
|
||||
? items[index - 1]
|
||||
: items[index]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -86,5 +120,6 @@ private extension FeedListViewController.ViewModel {
|
||||
|
||||
// MARK: Type aliases
|
||||
typealias FilteredReviews = [FilterOption: [Review]]
|
||||
typealias TopWordsReviews = [FilterOption: [TopWord]]
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user