From bf27b8fd4752d46464eb9441036bce28d69524e6 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 22 Jan 2024 17:21:53 -0500 Subject: [PATCH] Fix issues when changing scope after searching --- .../Search/SearchResultsViewController.swift | 80 +++++++++++-------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/Tusker/Screens/Search/SearchResultsViewController.swift b/Tusker/Screens/Search/SearchResultsViewController.swift index d587b006..fb5c0975 100644 --- a/Tusker/Screens/Search/SearchResultsViewController.swift +++ b/Tusker/Screens/Search/SearchResultsViewController.swift @@ -46,6 +46,7 @@ class SearchResultsViewController: UIViewController, CollectionViewController { private let searchSubject = PassthroughSubject() 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)