Add search state object

This commit is contained in:
Arkadiusz Fal
2021-07-30 00:34:13 +02:00
parent 994903f8a7
commit 3a780b3d2c
5 changed files with 89 additions and 24 deletions

63
Model/SearchState.swift Normal file
View File

@@ -0,0 +1,63 @@
import Defaults
import Siesta
import SwiftUI
final class SearchState: ObservableObject {
@Published var query = SearchQuery()
@Default(.searchQuery) private var queryText
private var previousResource: Resource?
private var resource: Resource!
@Published var store = Store<[Video]>()
init() {
let newQuery = query
newQuery.query = queryText
query = newQuery
resource = InvidiousAPI.shared.search(newQuery)
}
var isLoading: Bool {
resource.isLoading
}
func changeQuery(_ changeHandler: @escaping (SearchQuery) -> Void = { _ in }) {
changeHandler(query)
let newResource = InvidiousAPI.shared.search(query)
guard newResource != previousResource else {
return
}
previousResource?.removeObservers(ownedBy: store)
previousResource = newResource
queryText = query.query
resource = newResource
resource.addObserver(store)
loadResourceIfNeededAndReplaceStore()
}
func loadResourceIfNeededAndReplaceStore() {
let currentResource = resource!
if let request = resource.loadIfNeeded() {
request.onSuccess { response in
if let videos: [Video] = response.typedContent() {
self.replace(videos, for: currentResource)
}
}
} else {
replace(store.collection, for: currentResource)
}
}
func replace(_ videos: [Video], for resource: Resource) {
if self.resource == resource {
store = Store<[Video]>(videos)
}
}
}

View File

@@ -7,6 +7,12 @@ final class Store<Data>: ResourceObserver, ObservableObject {
var collection: Data { all ?? ([] as! Data) }
var item: Data? { all }
init(_ data: Data? = nil) {
if data != nil {
replace(data!)
}
}
func resourceChanged(_ resource: Resource, event _: ResourceEvent) {
if let items: Data = resource.typedContent() {
replace(items)