1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-13 22:00:31 +05:30
yattee/Model/Search/SearchModel.swift

141 lines
3.9 KiB
Swift
Raw Normal View History

2021-07-30 04:04:13 +05:30
import Defaults
import Siesta
import SwiftUI
2021-09-25 13:48:22 +05:30
final class SearchModel: ObservableObject {
@Published var store = Store<[ContentItem]>()
@Published var page: SearchPage?
2021-09-14 02:11:16 +05:30
2021-10-17 04:18:58 +05:30
var accounts = AccountsModel()
2021-09-25 13:48:22 +05:30
@Published var query = SearchQuery()
2021-09-19 18:12:47 +05:30
@Published var queryText = ""
2021-09-14 02:11:16 +05:30
@Published var querySuggestions = Store<[String]>()
2021-12-06 23:42:33 +05:30
@Published var suggestionsText = ""
2021-09-14 02:11:16 +05:30
2021-11-28 20:07:55 +05:30
@Published var fieldIsFocused = false
2021-07-30 04:04:13 +05:30
private var resource: Resource!
var isLoading: Bool {
2021-09-25 17:47:58 +05:30
resource?.isLoading ?? false
2021-09-14 02:11:16 +05:30
}
2021-07-30 04:04:13 +05:30
func changeQuery(_ changeHandler: @escaping (SearchQuery) -> Void = { _ in }) {
changeHandler(query)
let newResource = accounts.api.search(query, page: nil)
guard newResource != resource else {
2021-07-30 04:04:13 +05:30
return
}
page = nil
2021-07-30 04:04:13 +05:30
2021-09-19 16:36:54 +05:30
resource = newResource
resource.addObserver(store)
if !query.isEmpty {
loadResource()
}
2021-09-19 16:36:54 +05:30
}
func resetQuery(_ query: SearchQuery = SearchQuery()) {
2021-09-19 16:36:54 +05:30
self.query = query
let newResource = accounts.api.search(query, page: nil)
guard newResource != resource else {
2021-09-19 16:36:54 +05:30
return
}
page = nil
2021-09-19 16:36:54 +05:30
store.replace([])
2021-07-30 04:04:13 +05:30
resource = newResource
resource.addObserver(store)
if !query.isEmpty {
loadResource()
}
2021-07-30 04:04:13 +05:30
}
func loadResource() {
2021-07-30 04:04:13 +05:30
let currentResource = resource!
resource.load().onSuccess { response in
if let page: SearchPage = response.typedContent() {
self.page = page
self.replace(page.results, for: currentResource)
2021-07-30 04:04:13 +05:30
}
}
}
func replace(_ items: [ContentItem], for resource: Resource) {
2021-07-30 04:04:13 +05:30
if self.resource == resource {
store = Store<[ContentItem]>(items)
2021-07-30 04:04:13 +05:30
}
}
2021-09-25 17:47:58 +05:30
private var suggestionsDebounceTimer: Timer?
func loadSuggestions(_ query: String) {
2021-11-28 20:07:55 +05:30
guard !query.isEmpty else {
querySuggestions.replace([])
2021-11-28 20:07:55 +05:30
return
}
2021-09-25 17:47:58 +05:30
suggestionsDebounceTimer?.invalidate()
2021-12-06 23:42:33 +05:30
suggestionsDebounceTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
2021-10-21 03:51:50 +05:30
let resource = self.accounts.api.searchSuggestions(query: query)
2021-09-25 17:47:58 +05:30
resource.addObserver(self.querySuggestions)
resource.loadIfNeeded()
if let request = resource.loadIfNeeded() {
request.onSuccess { response in
if let suggestions: [String] = response.typedContent() {
self.querySuggestions = Store<[String]>(suggestions)
}
2021-12-06 23:42:33 +05:30
self.suggestionsText = query
2021-09-25 17:47:58 +05:30
}
} else {
self.querySuggestions = Store<[String]>(self.querySuggestions.collection)
2021-12-06 23:42:33 +05:30
self.suggestionsText = query
2021-09-25 17:47:58 +05:30
}
}
}
func loadNextPage() {
guard var pageToLoad = page, !pageToLoad.last else {
return
}
if pageToLoad.nextPage.isNil, accounts.app.searchUsesIndexedPages {
pageToLoad.nextPage = "2"
}
resource?.removeObservers(ownedBy: store)
resource = accounts.api.search(query, page: page?.nextPage)
resource.addObserver(store)
resource
.load()
.onSuccess { response in
if let page: SearchPage = response.typedContent() {
var nextPage: Int?
if self.accounts.app.searchUsesIndexedPages {
nextPage = Int(pageToLoad.nextPage ?? "0")
}
self.page = page
if self.accounts.app.searchUsesIndexedPages {
self.page?.nextPage = String((nextPage ?? 1) + 1)
}
self.replace(self.store.collection + page.results, for: self.resource)
}
}
}
2021-07-30 04:04:13 +05:30
}