feat/music-streaming
parent
d61ccda111
commit
c5b468103a
@ -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…
Reference in new issue