Full player showed "Nothing playing." while the mini bar showed a
live track. Regression from v2026.05.13.2's load-then-swap
rewrite: _displayedMedia only got populated by the ref.listen
callback on mediaItem changes, but ref.listen doesn't fire on
initial subscription. initState now reads the current mediaItem
synchronously and seeds _displayedMedia (and _displayedDominant
from the color provider's cached value when available) before the
first build runs; a post-frame _scheduleSwap covers the cold-color
case. (2df35e6)
Features
External media controllers (Android Wear, Auto, Bluetooth dashes,
lock-screen widgets) now see a complete MediaSession surface.
Several handler methods were already implemented but never
advertised in PlaybackState.systemActions; Android 13+ silently
drops any callback for an action not in that set, which matched
user reports of "watch sometimes works but doesn't play nice with
Minstrel."
stop() override now actually halts the player + dismisses the
foreground notification (BaseAudioHandler default was a no-op
that just flipped processingState)
Native heart-rating wired through to LikesController. The
setRating action is the standard MediaSession protocol for
favorite-style buttons on Wear, lock-screen widgets, and Auto.
New LikeBridge adapter (toggleTrackLike + isTrackLiked closures)
passes through configure(); _toMediaItem populates MediaItem.
rating from likedIdsProvider so the right filled/outlined heart
shows on every track change; PlayerActions listens to
likedIdsProvider and calls refreshCurrentRating so toggles from
TrackRow / kebab / another device (SSE) also reflect on the watch
without waiting for the next track. (d1e2762, bfad4dd)
MediaItem.artUri populated on the first broadcast for warm-cache
tracks. New AlbumCoverCache.peekCached returns the file path
synchronously when the cover is already on disk; _toMediaItem
uses it to seed artUri so external controllers see the cover
immediately instead of waiting for the later async
_loadArtForCurrentItem path. Cold-cache tracks fall through to
that path unchanged. (d1e2762)
Operator notes
No schema changes.
In-app updater should upgrade cleanly (versionCode 3 → 4).
Patch batch on top of v2026.05.13.2.
## Fixes
- **Full player showed "Nothing playing." while the mini bar showed a
live track.** Regression from v2026.05.13.2's load-then-swap
rewrite: _displayedMedia only got populated by the ref.listen
callback on mediaItem changes, but ref.listen doesn't fire on
initial subscription. initState now reads the current mediaItem
synchronously and seeds _displayedMedia (and _displayedDominant
from the color provider's cached value when available) before the
first build runs; a post-frame _scheduleSwap covers the cold-color
case. (`2df35e6`)
## Features
- **External media controllers (Android Wear, Auto, Bluetooth dashes,
lock-screen widgets) now see a complete MediaSession surface.**
Several handler methods were already implemented but never
advertised in PlaybackState.systemActions; Android 13+ silently
drops any callback for an action not in that set, which matched
user reports of "watch sometimes works but doesn't play nice with
Minstrel."
- controls list adds MediaControl.stop
- systemActions adds stop, skipToQueueItem, setShuffleMode,
setRepeatMode, setRating
- stop() override now actually halts the player + dismisses the
foreground notification (BaseAudioHandler default was a no-op
that just flipped processingState)
- **Native heart-rating wired through to LikesController.** The
setRating action is the standard MediaSession protocol for
favorite-style buttons on Wear, lock-screen widgets, and Auto.
New LikeBridge adapter (toggleTrackLike + isTrackLiked closures)
passes through configure(); _toMediaItem populates MediaItem.
rating from likedIdsProvider so the right filled/outlined heart
shows on every track change; PlayerActions listens to
likedIdsProvider and calls refreshCurrentRating so toggles from
TrackRow / kebab / another device (SSE) also reflect on the watch
without waiting for the next track. (`d1e2762`, `bfad4dd`)
- **MediaItem.artUri populated on the first broadcast for warm-cache
tracks.** New AlbumCoverCache.peekCached returns the file path
synchronously when the cover is already on disk; _toMediaItem
uses it to seed artUri so external controllers see the cover
immediately instead of waiting for the later async
_loadArtForCurrentItem path. Cold-cache tracks fall through to
that path unchanged. (`d1e2762`)
## Operator notes
- No schema changes.
- In-app updater should upgrade cleanly (versionCode 3 → 4).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Patch batch on top of v2026.05.13.2.
Fixes
live track. Regression from v2026.05.13.2's load-then-swap
rewrite: _displayedMedia only got populated by the ref.listen
callback on mediaItem changes, but ref.listen doesn't fire on
initial subscription. initState now reads the current mediaItem
synchronously and seeds _displayedMedia (and _displayedDominant
from the color provider's cached value when available) before the
first build runs; a post-frame _scheduleSwap covers the cold-color
case. (
2df35e6)Features
External media controllers (Android Wear, Auto, Bluetooth dashes,
lock-screen widgets) now see a complete MediaSession surface.
Several handler methods were already implemented but never
advertised in PlaybackState.systemActions; Android 13+ silently
drops any callback for an action not in that set, which matched
user reports of "watch sometimes works but doesn't play nice with
Minstrel."
setRepeatMode, setRating
foreground notification (BaseAudioHandler default was a no-op
that just flipped processingState)
Native heart-rating wired through to LikesController. The
setRating action is the standard MediaSession protocol for
favorite-style buttons on Wear, lock-screen widgets, and Auto.
New LikeBridge adapter (toggleTrackLike + isTrackLiked closures)
passes through configure(); _toMediaItem populates MediaItem.
rating from likedIdsProvider so the right filled/outlined heart
shows on every track change; PlayerActions listens to
likedIdsProvider and calls refreshCurrentRating so toggles from
TrackRow / kebab / another device (SSE) also reflect on the watch
without waiting for the next track. (
d1e2762,bfad4dd)MediaItem.artUri populated on the first broadcast for warm-cache
tracks. New AlbumCoverCache.peekCached returns the file path
synchronously when the cover is already on disk; _toMediaItem
uses it to seed artUri so external controllers see the cover
immediately instead of waiting for the later async
_loadArtForCurrentItem path. Cold-cache tracks fall through to
that path unchanged. (
d1e2762)Operator notes