Fix issues when changing scope after searching

This commit is contained in:
Shadowfacts 2024-01-22 17:21:53 -05:00
parent 32b8d27949
commit bf27b8fd47
1 changed files with 46 additions and 34 deletions

View File

@ -46,6 +46,7 @@ class SearchResultsViewController: UIViewController, CollectionViewController {
private let searchSubject = PassthroughSubject<String?, Never>()
private var searchCancellable: AnyCancellable?
private var currentQuery: String?
private var currentSearchResults: SearchResults?
init(mastodonController: MastodonController, scope: Scope = .all) {
self.mastodonController = mastodonController
@ -260,7 +261,14 @@ class SearchResultsViewController: UIViewController, CollectionViewController {
switch response {
case let .success(results, _):
guard self.currentQuery == query else { return }
self.showSearchResults(results)
self.mastodonController.persistentContainer.performBatchUpdates { (context, addAccounts, addStatuses) in
addAccounts(results.accounts)
addStatuses(results.statuses)
} completion: {
DispatchQueue.main.async {
self.showSearchResults(results)
}
}
case let .failure(error):
DispatchQueue.main.async {
self.showSearchError(error)
@ -269,31 +277,29 @@ class SearchResultsViewController: UIViewController, CollectionViewController {
}
}
@MainActor
private func showSearchResults(_ results: SearchResults) {
self.currentSearchResults = results
var snapshot = dataSource.snapshot()
snapshot.deleteSections([.loadingIndicator])
removeResults(from: &snapshot)
self.mastodonController.persistentContainer.performBatchUpdates({ (context, addAccounts, addStatuses) in
let resultTypes = self.scope.resultTypes
if !results.accounts.isEmpty && resultTypes.contains(.accounts) {
snapshot.appendSections([.accounts])
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
addAccounts(results.accounts)
}
if !results.hashtags.isEmpty && resultTypes.contains(.hashtags) {
snapshot.appendSections([.hashtags])
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
}
if !results.statuses.isEmpty && resultTypes.contains(.statuses) {
snapshot.appendSections([.statuses])
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
addStatuses(results.statuses)
}
}, completion: {
DispatchQueue.main.async {
self.dataSource.apply(snapshot)
}
})
let resultTypes = self.scope.resultTypes
if !results.accounts.isEmpty && resultTypes.contains(.accounts) {
snapshot.appendSections([.accounts])
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
}
if !results.hashtags.isEmpty && resultTypes.contains(.hashtags) {
snapshot.appendSections([.hashtags])
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
}
if !results.statuses.isEmpty && resultTypes.contains(.statuses) {
snapshot.appendSections([.statuses])
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
}
dataSource.apply(snapshot)
}
private func showSearchError(_ error: Client.Error) {
@ -563,19 +569,25 @@ extension SearchResultsViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
let newQuery = searchBar.searchQueryWithOperators
let newScope = Scope.allCases[selectedScope]
if self.scope == .all && currentQuery == newQuery {
self.scope = newScope
var snapshot = dataSource.snapshot()
if snapshot.sectionIdentifiers.contains(.accounts) && scope != .people {
snapshot.deleteSections([.accounts])
if currentQuery == newQuery,
let currentSearchResults {
if self.scope == .all {
self.scope = newScope
var snapshot = dataSource.snapshot()
if snapshot.sectionIdentifiers.contains(.accounts) && scope != .people {
snapshot.deleteSections([.accounts])
}
if snapshot.sectionIdentifiers.contains(.hashtags) && scope != .hashtags {
snapshot.deleteSections([.hashtags])
}
if snapshot.sectionIdentifiers.contains(.statuses) && scope != .posts {
snapshot.deleteSections([.statuses])
}
dataSource.apply(snapshot)
} else {
self.scope = newScope
showSearchResults(currentSearchResults)
}
if snapshot.sectionIdentifiers.contains(.hashtags) && scope != .hashtags {
snapshot.deleteSections([.hashtags])
}
if snapshot.sectionIdentifiers.contains(.statuses) && scope != .posts {
snapshot.deleteSections([.statuses])
}
dataSource.apply(snapshot)
} else {
self.scope = newScope
performSearch(query: newQuery)