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