EARHORNMUSIC UPnP · Android TV · Phones · Android Auto · GNU/Linux
Release 0.5.0

SharedModule.kt

Each line, with the release that last changed it.

0.5.01package dev.stave.di
2
3import dev.stave.data.SessionStore
4import dev.stave.data.SettingsStore
5import dev.stave.lyrics.LyricsRepository
6import dev.stave.lyrics.LyricsViewModel
7import dev.stave.playlist.M3uPlaylistStore
8import dev.stave.playlist.M3uPlaylistWriter
9import dev.stave.ui.browse.BrowseViewModel
10import dev.stave.ui.events.UiEvents
11import dev.stave.ui.nowplaying.NowPlayingViewModel
12import dev.stave.ui.servers.ServersViewModel
13import dev.stave.upnp.AudioMetadataReader
14import dev.stave.upnp.ContentDirectoryClient
15import dev.stave.upnp.DidlParser
16import dev.stave.upnp.MediaCollector
17import org.koin.core.module.dsl.singleOf
18import org.koin.dsl.module
19
20/**
21 * Shared Koin module — binds the UPnP layer, the playlist writer, and the ViewModels.
22 * Platforms bind the UpnpServiceHolder and Renderer concretes themselves (see
23 * desktopModule / androidModule).
24 *
25 * Design note: the VMs are bound as plain singletons rather than Koin-ViewModels because
26 * Koin 4.0's multiplatform `viewModelOf` DSL has a type-constraint mismatch with the
27 * JB `lifecycle-viewmodel` KMP artifact in this configuration. App-scoped singletons are
28 * fine for a desktop app that shows one of each screen at a time — the VM survives
29 * navigation, which is actually useful here (caching the browse state).
30 *
31 * Resolution in composables: `koinInject<BrowseViewModel>()` (not `koinViewModel()`).
32 */
33val sharedModule = module {
34 singleOf(::DidlParser)
35 single { ContentDirectoryClient(holder = get(), parser = get(), settings = get()) }
36 singleOf(::MediaCollector)
37 singleOf(::M3uPlaylistWriter)
38 single { M3uPlaylistStore() }
39 singleOf(::AudioMetadataReader)
40 single {
41 val settings: SettingsStore = get()
42 dev.stave.upnp.AlbumInfoLoader(
43 reader = get(),
44 allowExternalCalls = { settings.allowExternalCalls.value },
45 )
46 }
47 single { dev.stave.ui.albuminfo.AlbumInfoViewModel(loader = get()) }
48 single { LyricsRepository(get()) }
49 single { SettingsStore() }
50 single { SessionStore() }
51 single { dev.stave.data.SearchHistoryStore() }
52 single { UiEvents() }
53 single { dev.stave.playback.LocalPlaybackGate(rawCast = get(), uiEvents = get()) }
54
55 single {
56 BrowseViewModel(
57 cd = get(),
58 renderer = get(),
59 collector = get(),
60 playGate = get(),
61 uiEvents = get(),
62 holder = get(),
63 )
64 }
65 // Explicit get() forms for NowPlayingViewModel + LyricsViewModel: their
66 // constructor arg counts (7 and 2 respectively) push against Koin 4's
67 // reflective singleOf reliability. The typed get() calls resolve at module
68 // build time, so any missing binding surfaces there rather than at first use.
69 single {
70 NowPlayingViewModel(
71 renderer = get(),
72 rawCast = get(),
73 cd = get(),
74 collector = get(),
75 playlistWriter = get(),
76 playlistStore = get(),
77 sessionStore = get(),
78 settings = get(),
79 uiEvents = get(),
80 playGate = get(),
81 )
82 }
83 single { dev.stave.upnp.MinimServerControl(holder = get()) }
84 single { ServersViewModel(holder = get(), cd = get(), minim = get()) }
85 single { LyricsViewModel(repository = get(), renderer = get(), rawCast = get(), settings = get()) }
86}