yattee/Model/SearchState.swift

96 lines
2.6 KiB
Swift
Raw Normal View History

2021-07-29 22:34:13 +00:00
import Defaults
import Siesta
import SwiftUI
final class SearchState: ObservableObject {
2021-09-13 20:41:16 +00:00
@Published var store = Store<[Video]>()
2021-07-29 22:34:13 +00:00
@Published var query = SearchQuery()
2021-09-13 20:41:16 +00:00
@Published var querySuggestions = Store<[String]>()
2021-07-29 22:34:13 +00:00
private var previousResource: Resource?
private var resource: Resource!
init() {
let newQuery = query
query = newQuery
resource = InvidiousAPI.shared.search(newQuery)
}
var isLoading: Bool {
resource.isLoading
}
2021-09-13 20:41:16 +00:00
func loadQuerySuggestions(_ query: String) {
let resource = InvidiousAPI.shared.searchSuggestions(query: query)
resource.addObserver(querySuggestions)
resource.loadIfNeeded()
if let request = resource.loadIfNeeded() {
request.onSuccess { response in
if let suggestions: [String] = response.typedContent() {
self.querySuggestions = Store<[String]>(suggestions)
}
}
} else {
querySuggestions = Store<[String]>(querySuggestions.collection)
}
}
2021-07-29 22:34:13 +00:00
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
2021-09-19 11:06:54 +00:00
resource = newResource
resource.addObserver(store)
loadResourceIfNeededAndReplaceStore()
}
func resetQuery(_ query: SearchQuery) {
self.query = query
let newResource = InvidiousAPI.shared.search(query)
guard newResource != previousResource else {
return
}
store.replace([])
previousResource?.removeObservers(ownedBy: store)
previousResource = newResource
2021-07-29 22:34:13 +00:00
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)
}
}
}