You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.6 KiB
63 lines
1.6 KiB
import Foundation
|
|
import Observation
|
|
import GRDB
|
|
|
|
@Observable
|
|
final class LibraryViewModel {
|
|
var tracks: [Track] = []
|
|
var searchText = ""
|
|
var sortColumn = "title"
|
|
var sortAscending = true
|
|
var trackCount = 0
|
|
|
|
private let db: DatabaseService
|
|
private var cancellable: AnyDatabaseCancellable?
|
|
private var searchTask: Task<Void, Never>?
|
|
|
|
init(db: DatabaseService) {
|
|
self.db = db
|
|
updateQuery()
|
|
}
|
|
|
|
func search(_ text: String) {
|
|
searchText = text
|
|
searchTask?.cancel()
|
|
searchTask = Task { @MainActor [weak self] in
|
|
try? await Task.sleep(for: .milliseconds(150))
|
|
guard !Task.isCancelled else { return }
|
|
self?.updateQuery()
|
|
}
|
|
}
|
|
|
|
func sort(by column: String) {
|
|
if sortColumn == column {
|
|
sortAscending.toggle()
|
|
} else {
|
|
sortColumn = column
|
|
sortAscending = true
|
|
}
|
|
updateQuery()
|
|
}
|
|
|
|
private func updateQuery() {
|
|
cancellable?.cancel()
|
|
let search = searchText
|
|
let col = sortColumn
|
|
let asc = sortAscending
|
|
|
|
let observation = ValueObservation.tracking { [db] dbAccess in
|
|
try db.fetchTracks(db: dbAccess, search: search, sortColumn: col, ascending: asc)
|
|
}
|
|
|
|
cancellable = observation.start(
|
|
in: db.dbPool,
|
|
onError: { error in
|
|
print("Library observation error: \(error)")
|
|
},
|
|
onChange: { [weak self] tracks in
|
|
self?.tracks = tracks
|
|
self?.trackCount = tracks.count
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|