fix: search result always append to last issue
This commit is contained in:
parent
d8af11a9bc
commit
2c041e70b2
|
@ -37,7 +37,8 @@ extension SearchResultViewModel.State {
|
||||||
let logger = Logger(subsystem: "SearchResultViewModel.State.Loading", category: "Logic")
|
let logger = Logger(subsystem: "SearchResultViewModel.State.Loading", category: "Logic")
|
||||||
|
|
||||||
var previousSearchText = ""
|
var previousSearchText = ""
|
||||||
var offset = 0
|
var offset: Int? = nil
|
||||||
|
var latestLoadingToken = UUID()
|
||||||
|
|
||||||
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
|
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
|
||||||
guard let viewModel = self.viewModel else { return false }
|
guard let viewModel = self.viewModel else { return false }
|
||||||
|
@ -77,15 +78,15 @@ extension SearchResultViewModel.State {
|
||||||
|
|
||||||
if searchText != previousSearchText {
|
if searchText != previousSearchText {
|
||||||
previousSearchText = searchText
|
previousSearchText = searchText
|
||||||
|
offset = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// not set offset for all case
|
// not set offset for all case
|
||||||
// and assert other cases the items are all the same type elements
|
// and assert other cases the items are all the same type elements
|
||||||
let offset: Int? = {
|
let _offset: Int? = {
|
||||||
switch searchType {
|
switch searchType {
|
||||||
case .default: return nil
|
case .default: return nil
|
||||||
default:
|
default: return offset
|
||||||
return viewModel.items.value.isEmpty ? nil : viewModel.items.value.count
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -98,10 +99,13 @@ extension SearchResultViewModel.State {
|
||||||
excludeUnreviewed: nil,
|
excludeUnreviewed: nil,
|
||||||
resolve: nil,
|
resolve: nil,
|
||||||
limit: nil,
|
limit: nil,
|
||||||
offset: offset,
|
offset: _offset,
|
||||||
following: nil
|
following: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let id = UUID()
|
||||||
|
latestLoadingToken = id
|
||||||
|
|
||||||
viewModel.context.apiService.search(
|
viewModel.context.apiService.search(
|
||||||
domain: domain,
|
domain: domain,
|
||||||
query: query,
|
query: query,
|
||||||
|
@ -121,9 +125,12 @@ extension SearchResultViewModel.State {
|
||||||
|
|
||||||
// discard result when search text is outdated
|
// discard result when search text is outdated
|
||||||
guard searchText == self.previousSearchText else { return }
|
guard searchText == self.previousSearchText else { return }
|
||||||
|
// discard result when request not the latest one
|
||||||
|
guard id == self.latestLoadingToken else { return }
|
||||||
|
// discard result when state is not Loading
|
||||||
guard stateMachine.currentState is Loading else { return }
|
guard stateMachine.currentState is Loading else { return }
|
||||||
|
|
||||||
let oldItems = offset == nil ? [] : viewModel.items.value
|
let oldItems = _offset == nil ? [] : viewModel.items.value
|
||||||
var newItems: [SearchResultItem] = []
|
var newItems: [SearchResultItem] = []
|
||||||
|
|
||||||
for account in response.value.accounts {
|
for account in response.value.accounts {
|
||||||
|
@ -136,17 +143,18 @@ extension SearchResultViewModel.State {
|
||||||
guard !oldItems.contains(item) else { continue }
|
guard !oldItems.contains(item) else { continue }
|
||||||
newItems.append(item)
|
newItems.append(item)
|
||||||
}
|
}
|
||||||
if searchType == .default {
|
|
||||||
newItems.sort(by: { ($0.sortKey ?? "") < ($1.sortKey ?? "")})
|
|
||||||
}
|
|
||||||
|
|
||||||
var newStatusIDs = offset == nil ? [] : viewModel.statusFetchedResultsController.statusIDs.value
|
var newStatusIDs = _offset == nil ? [] : viewModel.statusFetchedResultsController.statusIDs.value
|
||||||
for status in response.value.statuses {
|
for status in response.value.statuses {
|
||||||
guard !newStatusIDs.contains(status.id) else { continue }
|
guard !newStatusIDs.contains(status.id) else { continue }
|
||||||
newStatusIDs.append(status.id)
|
newStatusIDs.append(status.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateMachine.enter(Idle.self)
|
if viewModel.searchScope == .all {
|
||||||
|
stateMachine.enter(NoMore.self)
|
||||||
|
} else {
|
||||||
|
stateMachine.enter(Idle.self)
|
||||||
|
}
|
||||||
viewModel.items.value = oldItems + newItems
|
viewModel.items.value = oldItems + newItems
|
||||||
viewModel.statusFetchedResultsController.statusIDs.value = newStatusIDs
|
viewModel.statusFetchedResultsController.statusIDs.value = newStatusIDs
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,12 @@ final class SearchResultViewModel {
|
||||||
snapshot.appendSections([.main])
|
snapshot.appendSections([.main])
|
||||||
|
|
||||||
// append account & hashtag items
|
// append account & hashtag items
|
||||||
|
|
||||||
|
var items = items
|
||||||
|
if self.searchScope == .all {
|
||||||
|
// all search scope not paging. it's safe sort on whole dataset
|
||||||
|
items.sort(by: { ($0.sortKey ?? "") < ($1.sortKey ?? "")})
|
||||||
|
}
|
||||||
snapshot.appendItems(items, toSection: .main)
|
snapshot.appendItems(items, toSection: .main)
|
||||||
|
|
||||||
var oldSnapshotAttributeDict: [NSManagedObjectID : Item.StatusAttribute] = [:]
|
var oldSnapshotAttributeDict: [NSManagedObjectID : Item.StatusAttribute] = [:]
|
||||||
|
|
Loading…
Reference in New Issue