Fix/aa images and flickering #1

Open
gronod wants to merge 19 commits from fix/aa-images-and-flickering into master
19 Commits
Author SHA1 Message Date
ChrisandClaude Opus 4.6 40a2e2f43a Fix AA shuffle/repeat buttons and artist images
Build Android APK / Build APK (pull_request) Failing after 23m4s
Shuffle/repeat buttons showed disabled after starting playback because
_refreshQueueAfterDelay only updated queue items without syncing the
shuffle/repeat state. Now syncs both flags and refreshes playback state.

Artist images failed in AA because _autoBuildArtistList used the basic
getImageUrl which returns null for artists without MA metadata images.
Now uses getArtistImageUrlWithFallback which tries external sources.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:27:14 +00:00
ChrisandClaude Opus 4.6 e15cfb545e Smooth scroll-to-hide for library filter bar and search bar
Replace boolean toggle with continuous ValueNotifier<double> so bars
slide 1:1 with finger movement instead of snapping. Use
ValueListenableBuilder to avoid full-screen rebuilds on every scroll
frame, and Align(heightFactor) for uniform top-clip instead of
SizedBox squishing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 06:47:18 +00:00
ChrisandClaude Opus 4.6 76d0f0b80e Sync shuffle/repeat state from queue when AA connects
The local _shuffleOn and _repeatMode flags were initialized to off,
so AA buttons always showed disabled on connect even when shuffle/repeat
were actually enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 06:14:36 +00:00
ChrisandClaude Opus 4.6 a3eb3db8a2 Fix 4 regressions: BT/AA pause, AA buttons, artist cache, AA disconnect
- Make onPlay/onPause callbacks non-toggle (resumePlayer/pausePlayer
  instead of playPauseSelectedPlayer) so AA buttons work correctly
- Fix interruption guard to treat builtin-active as "was playing" for
  PCM/Sendspin mode where playbackState can be stale
- Keep media session alive during transient idle when PCM is playing
- Only cache non-empty artist album results to prevent stale 0 counts
- Only pause builtin player on AA disconnect (not remote speakers)
- Auto-select builtin player on AA connect broadcast

Fixes #25

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 07:54:47 +00:00
ChrisandClaude Opus 4.6 1877205034 Add Start Radio button to artist albums page in Android Auto
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:12:08 +00:00
ChrisandClaude Opus 4.6 bb46a2dee1 Remove noisy periodic logging that filled the 1000-entry bug report buffer
Position tracker, queue persistence, notification timer, and message
receipt logs fired every few seconds, pushing out meaningful events
(AA lifecycle, playback state changes) within minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:51:03 +00:00
ChrisandClaude Opus 4.6 2c07134404 Fix volume slider grab area by adding opaque hit test behavior
Without HitTestBehavior.opaque, the GestureDetector only registered
hits on the 20px painted track area instead of the full 48px touch target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:12:03 +00:00
ChrisandClaude Opus 4.6 ea99b2bb11 Fix AA cold-start: async list builders and cache invalidation
List builders for artists, albums, and playlists now await
SyncService.loadFromCache() when data is empty (matching the existing
audiobook pattern). getArtistAlbumsWithCache also falls back to
SyncService when _albums is empty. After library loads (both from cache
and background sync), AA browse children are invalidated so stale
empty results get replaced.

Fixes #25

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 07:50:11 +00:00
ChrisandClaude Opus 4.6 9cd27553c1 Fix AA cold-start caching empty artist albums
Don't cache empty artist album results when the library hasn't loaded
yet. On cold start, SyncService may not have finished populating the
album list, causing getArtistAlbumsWithCache to return and cache 0
results permanently until the cache expires.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 06:54:43 +00:00
ChrisandClaude Opus 4.6 0db9bb3df7 Fix AA detection: trigger from any getChildren/playFromMediaId, not just root
AA caches the browse tree after first session, so getChildren for the
browsable root is never called on subsequent connects. This meant
_isAndroidAutoConnected was never set, breaking both disconnect detection
(display listener ignored) and playback button refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:54:56 +00:00
ChrisandClaude Opus 4.6 0a88d147ed Fix AA disconnect: detect via display removal, prevent auto-resume
Android Auto on projection-mode devices (com.google.android.projection.gearhead)
doesn't trigger ACTION_EXIT_CAR_MODE, so the disconnect was never detected.

- Add DisplayManager.DisplayListener to detect AA disconnect when virtual
  displays are removed (projection mode)
- Add bidirectional method channel so Dart notifies native of AA connection
- Add onAADisconnected callback that force-pauses (not toggles) the player
- Suppress Sendspin stream/start for 2s after disconnect to handle the race
  where the server sends audio before processing our pause command
- Guard interruption begin handler to only pause/toggle when actually playing,
  preventing the interrupted-while-paused -> accidental resume bug

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:56:13 +00:00
ChrisandClaude Opus 4.6 c3f6710dd1 Hide switch player in AA, fix resume on disconnect, rename Smart Shuffle
- Detect Android Auto via car mode broadcasts and getChildren; hide
  switch player button from controls while AA is connected
- Suppress audio auto-resume after becoming noisy / AA disconnect to
  prevent music playing from phone speaker when car turns off
- Rename "Smart Shuffle" to "Start Radio" with radio icon

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 19:03:16 +00:00
ChrisandClaude Opus 4.6 68e3b74d5d Add Smart Shuffle to Android Auto and radio fallback to shuffled playback
Radio calls now fall back gracefully when the provider doesn't support radio:
playRadio falls back to playing the single track, playArtistRadio falls back
to shuffled artist tracks via search. Direct API calls in context menu and
library screen routed through provider to pick up the fallback. Android Auto
gets a "Smart Shuffle" item at the top of track lists (albums, playlists,
favorites) with a custom sparkle-shuffle icon that attempts radio then falls
back to shuffled playback. Also fixes builtin player selection to avoid
premature fallback before Sendspin registration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 06:18:08 +00:00
ChrisandClaude Opus 4.6 b3aa55a021 Fix podcast/audiobook metadata in notifications and AA, position tracking
- Add _trackDisplayArtist() helper to show podcast name, audiobook author,
  or radio station instead of "Unknown Artist" in all notification/AA contexts
- Auto-restore audiobook context from cached data when URI matches
- Set podcast name context when playing episodes from AA browse tree
- Encode podcast ID in episode media IDs for context lookup
- Fix Sendspin pause position using server-synced position tracker instead
  of PCM elapsed time (which resets to 0 each stream)
- Fix Sendspin resume position to use position tracker instead of Duration.zero
- Add 10s seek-back on audiobook resume to compensate for Sendspin buffering
- Populate AA queue for podcast and radio playback via _refreshQueueAfterDelay
- Show podcast name as artist in AA episode browse list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:53:07 +00:00
ChrisandClaude Opus 4.6 823b95ec1a Fix builtin player notification conflicts and player selection fallback
Use updateLocalModeNotification instead of setRemotePlaybackState for
Sendspin/builtin players to avoid conflicting mediaItem.add() calls that
cause artwork flickering. Add fallback to builtin player when last
selected player is unavailable. Extract shared _controls getter, use
MediaControl.custom for switch player, and only claim audio focus on
play transitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 06:45:06 +00:00
ChrisandClaude Opus 4.6 59d48deaf7 Android Auto audit: artwork ContentProvider, queue, search, polish
- Add ArtworkContentProvider to serve artwork via content:// URIs
  (fixes broken images on many AA head units that reject HTTP URLs)
- Wrap all artUri sites in handler and provider with content:// URIs
- Populate AA play queue after playTracks for queue view support
- Wire updateQueueIndex from provider's _updatePlayerState
- Add error state communication to AA on playback failures
- Rewrite search() to return grouped results (artists, albums, tracks)
- Add playFromSearch() for voice command support ("Play X on Ensemble")
- Add search race condition guard
- Declare SEARCH_SUPPORTED in browsable root extras for search button
- Add invalidateAutoChildren for library add/delete events
- Add cache size limit (50 entries) with LRU eviction for track cache
- Clean up track cache and children subjects in dispose()
- Add audiobook completion status extras (progress bars in AA)
- Add subtitle link extras on track items (tappable artist)
- Reset idle timer on AA browse activity
- Fix PCM player auto-recovery triggering on user-initiated pause

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:16:21 +00:00
ChrisandClaude Opus 4.6 753f5161fb Fix AA reconnect race condition and audio focus handling
Make checkAndReconnect idempotent: concurrent callers now join the
existing reconnect attempt instead of each creating a new WebSocket
connection. This prevents the cascading "API disposed" errors seen
when Android Auto browses multiple categories simultaneously.

Activate audio session when Sendspin/remote playback starts so Android
delivers audio focus interruption events. Ensemble now pauses when
another app (Spotify, YouTube, etc.) takes audio focus, and resumes
when focus returns.

Remove switch-player button from Android Auto controls (not useful
in car context).

Fixes #25

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:07:17 +00:00
ChrisandClaude Opus 4.6 e4cdb40fde Fix home screen gradient obscuring third row text
Only show the bottom fade gradient when 4+ rows are enabled, since
with ≤3 rows the content doesn't scroll behind the mini player. Reduce
gradient height to mini player height only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:11:22 +00:00
ChrisandClaude Opus 4.6 ad5ecf59b0 Fix Android Auto images and player background flickering
Fix imageproxy URLs using wrong port: Dart's Uri.hasPort returns false
for default ports (80/443) even when explicitly specified, causing
fallback to port 8095. Use raw string check instead.

Fix player background flash: use theme surface color as fallback instead
of hardcoded black, and add race guard to color extraction to prevent
stale results on rapid track changes.

Fixes #25, fixes #73

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:05:31 +00:00