Files
bearwave-mac/Sources/BearWaveCore/App/AppModel.swift
2026-06-25 09:21:42 +02:00

77 lines
2.7 KiB
Swift

import AppKit
import Foundation
import Observation
@Observable
@MainActor
public final class AppModel {
public let settings: SettingsStore
public let library: StationLibrary
public let playback: PlaybackController
let artwork: StationArtworkLoader
private let nowPlayingArtwork: NowPlayingArtworkResolver
public convenience init() {
self.init(settings: SettingsStore(), persistence: PersistenceStore())
}
init(
settings: SettingsStore = SettingsStore(),
persistence: PersistenceStore = PersistenceStore()
) {
self.settings = settings
let client = RadioBrowserClient(baseURL: settings.baseURL, cacheDirectory: persistence.apiCacheDirectory)
library = StationLibrary(client: client, persistence: persistence)
let artworkLoader = StationArtworkLoader(cacheDirectory: persistence.cacheDirectory)
artwork = artworkLoader
nowPlayingArtwork = NowPlayingArtworkResolver(cacheDirectory: persistence.cacheDirectory, faviconLoader: artworkLoader)
playback = PlaybackController(artworkProvider: { [weak nowPlayingArtwork] station, artist, title in
nowPlayingArtwork?.resolve(artist: artist, title: title, station: station) ?? BearWaveAssets.image(named: "bearwave") ?? NSImage()
})
nowPlayingArtwork.onArtworkLoaded = { [weak playback] in
playback?.refreshNowPlaying()
}
playback.onMetadataChanged = { [weak nowPlayingArtwork] artist, title, station in
nowPlayingArtwork?.fetchArtwork(artist: artist, title: title, station: station)
}
playback.volume = library.volume
library.updateBaseURL(settings.baseURL)
}
public func start() async {
await library.load(.top)
if settings.resumeOnLaunch, let station = library.resumeStation() {
play(station)
}
}
public func play(_ station: RadioStation) {
library.recordPlayback(station)
playback.play(station)
nowPlayingArtwork.fetchArtwork(
artist: playback.currentTrackArtist.isEmpty ? nil : playback.currentTrackArtist,
title: playback.currentTrackTitle.isEmpty ? nil : playback.currentTrackTitle,
station: station
)
}
public func resumeLastStation() {
guard let station = library.resumeStation() else { return }
play(station)
}
public func setVolume(_ value: Double) {
playback.volume = value
library.saveVolume(value)
}
public func applySettings() {
library.updateBaseURL(settings.baseURL)
}
public func quit() {
playback.stop()
nowPlayingArtwork.fetchArtwork(artist: nil, title: nil, station: nil)
}
}