feat: add LibraryViewModel with reactive queries, debounced search, and column sorting

feat/music-streaming
Laurent 1 month ago
parent d61ccda111
commit c5b468103a
  1. 63
      Music/ViewModels/LibraryViewModel.swift

@ -0,0 +1,63 @@
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
}
)
}
}
Loading…
Cancel
Save