77 lines
2.4 KiB
Swift
77 lines
2.4 KiB
Swift
import Foundation
|
|
import Observation
|
|
import VelodyDomain
|
|
import VelodyPersistence
|
|
|
|
@MainActor
|
|
@Observable
|
|
final class MacLibraryViewModel {
|
|
var tracks: [LibraryTrack] = []
|
|
var selectedFolderPath = "No folder selected"
|
|
var scanStatus = "Choose a folder to begin local discovery."
|
|
var discoveredTrackCount = 0
|
|
var isScanning = false
|
|
|
|
private let folderAccessService: any VelodyPersistence.FolderAccessService
|
|
private let localMusicScanner: any LocalMusicScanner
|
|
private let store = InMemoryLocalLibraryStore()
|
|
private var hasLoaded = false
|
|
|
|
init() {
|
|
let folderAccessService = FolderAccessService()
|
|
let localMusicScanner = FileSystemLocalMusicScanner(
|
|
metadataReader: AVFoundationMetadataReader()
|
|
)
|
|
|
|
self.folderAccessService = folderAccessService
|
|
self.localMusicScanner = localMusicScanner
|
|
|
|
if let url = folderAccessService.storedFolderURL() {
|
|
selectedFolderPath = url.path
|
|
scanStatus = "Folder restored. Run a manual scan to discover MP3 files."
|
|
}
|
|
}
|
|
|
|
func loadIfNeeded() async {
|
|
guard !hasLoaded else { return }
|
|
hasLoaded = true
|
|
tracks = await store.loadTracks()
|
|
discoveredTrackCount = tracks.count
|
|
}
|
|
|
|
func chooseFolder() {
|
|
if let url = folderAccessService.chooseFolder() {
|
|
selectedFolderPath = url.path
|
|
scanStatus = "Folder selected. Run a manual scan to discover MP3 files."
|
|
tracks = []
|
|
discoveredTrackCount = 0
|
|
Task {
|
|
await store.replaceTracks([])
|
|
}
|
|
}
|
|
}
|
|
|
|
func scanMP3Files() async {
|
|
guard let folderURL = folderAccessService.storedFolderURL() else {
|
|
scanStatus = "Choose a folder before scanning."
|
|
return
|
|
}
|
|
|
|
isScanning = true
|
|
scanStatus = "Scanning MP3 files..."
|
|
defer {
|
|
isScanning = false
|
|
}
|
|
|
|
do {
|
|
let discoveredTracks = try await localMusicScanner.scanFolder(at: folderURL)
|
|
await store.replaceTracks(discoveredTracks)
|
|
tracks = await store.loadTracks()
|
|
discoveredTrackCount = tracks.count
|
|
scanStatus = "Scan finished. Found \(discoveredTrackCount) MP3 file(s)."
|
|
} catch {
|
|
scanStatus = "Scan failed: \(error.localizedDescription)"
|
|
}
|
|
}
|
|
}
|