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

UiEvents.kt

Each line, with the release that last changed it.

0.5.01package dev.stave.ui.events
2
3import kotlinx.coroutines.channels.BufferOverflow
4import kotlinx.coroutines.flow.MutableSharedFlow
5import kotlinx.coroutines.flow.SharedFlow
6import kotlinx.coroutines.flow.asSharedFlow
7
8/**
9 * App-wide bus for transient user-facing notifications. Emitters post strings;
10 * [dev.stave.desktop.ui.ToastHost] in StaveApp collects them into a small stack of
11 * Material Snackbar-style banners.
12 *
13 * **Design.** MutableSharedFlow with replay=0 (a toast that arrives before a
14 * collector is ready is dropped — we don't want last week's error flashing up on
15 * today's launch) and extraBufferCapacity=4 so a brief burst (e.g. three playlist
16 * loads failing in quick succession) queues rather than dropping.
17 *
18 * **What goes here.** Non-blocking informational messages that the user can safely
19 * ignore. Examples: "Lyrics unavailable for this track", "Couldn't reach LRCLIB",
20 * "Playlist saved to library", "Tag reader timed out". **Not** here: fatal errors
21 * that should prevent a user action from completing (those deserve a dialog), or
22 * status that's not time-bounded (those belong in the relevant screen's persistent
23 * UI).
24 */
25class UiEvents {
26 private val _messages = MutableSharedFlow<String>(
27 replay = 0,
28 extraBufferCapacity = 4,
29 onBufferOverflow = BufferOverflow.DROP_OLDEST,
30 )
31
32 /** Observe toast messages. Collectors are fire-and-forget; missed emissions
33 * while no collector is attached stay missed, which is what we want. */
34 val messages: SharedFlow<String> = _messages.asSharedFlow()
35
36 /** Post a toast. Non-suspending for convenience in non-coroutine call sites
37 * (IO error handlers, VLCJ callbacks). Drops on overflow — at which point the
38 * user probably has bigger problems than one dropped toast. */
39 fun post(message: String) {
40 _messages.tryEmit(message)
41 }
42}