Commit Graph

4 Commits

Author SHA1 Message Date
bvandeusen f65650fb6d fix(flutter): player bar layout, system playlist tap, banner height
Player bar: drop the volume slider — phone hardware controls volume.
Right cluster collapses to a single row of shuffle/repeat/queue.

Playlist card: GestureDetector defers to children by default, so taps
over the cover image area didn't always register. Add HitTestBehavior.opaque
so the whole card surface is tappable.

Update banner: was 3-4× the height of its text — IconButton's default
48dp tap target plus generous vertical padding dominated. Tighten
padding (8→4), shrink dismiss button to 32×32 with iconSize 16, slim
the action button to 28dp height with shrinkWrap tap target.

Home screen: ClampingScrollPhysics + 140dp bottom padding (already
applied in working tree) so scroll stops just above the mini-player.
2026-05-11 07:27:14 -04:00
bvandeusen 19061cd10c feat(flutter): full parity for player bar — shuffle/repeat/volume + Like + kebab + 3-column layout (#356)
Mirrors web's compact PlayerBar both visually (3-column top + full-
width seek bottom) and functionally — closes parity gaps that had
been hidden because the prior mini-bar surfaced none of these
controls.

### audio_handler.dart

- Override `setShuffleMode` → delegates to just_audio's
  `setShuffleModeEnabled`.
- Override `setRepeatMode` → maps audio_service modes (none/one/all/
  group) to just_audio's LoopMode (off/one/all).
- New `setVolume(double)` + `volumeStream` getter (audio_service's
  PlaybackState doesn't carry volume — surface it separately).
- `_broadcastState` now populates PlaybackState's shuffleMode +
  repeatMode fields, and re-fires on shuffle/repeat/loop stream
  changes so UI subscribers stay in sync.

### player_provider.dart

- New `volumeProvider` (StreamProvider<double>).
- `PlayerActions` gains `toggleShuffle()`, `cycleRepeat()` (none →
  all → one → none), and `setVolume(double)`.

### player_bar.dart

Complete rebuild matching the operator-designed layout:

  ┌──────────┬───────────┬──────────────────┐
  │ art      │ ♥   ⋮     │ 🔀 🔁 ☰           │  ← short row
  │ title    │           │                  │
  │ artist   │ ⏮  ⏯  ⏭   │ volume slider    │  ← play row, full size
  ├──────────┴───────────┴──────────────────┤
  │ 0:42 ━━━━━●━━━━━━━━━━━━━━━━━━━━━ 3:21  │
  └─────────────────────────────────────────┘

- Column 1 (35%): cover + title + artist. Tap → /now-playing.
- Column 2 (intrinsic): like + kebab on top, play controls (40/48/40)
  on bottom.
- Column 3 (30%): shuffle/repeat/queue on top, volume slider on bottom.
- Bottom: full-width seek slider with mm:ss labels.

`TrackActionsButton` reused for the kebab; reconstructs a minimal
TrackRef from MediaItem extras (same pattern NowPlayingScreen
already uses).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 23:59:53 -04:00
bvandeusen 147d6e280e feat(flutter): bump deps to latest + Search screen slice
Major version bumps (riverpod 2->3, go_router 14->17, just_audio 0.9->0.10,
flutter_secure_storage 9->10, google_fonts 6->8, flutter_lints 4->6).
package_info_plus held at 8.x due to win32 conflict with secure_storage 10.x.

Riverpod 3 breaks: AsyncValue.valueOrNull -> .value, StateProvider replaced
with Notifier subclass. just_audio 0.10: ConcatenatingAudioSource -> setAudioSources.

Search slice:
- models/page.dart (generic Page<T> envelope)
- models/search_response.dart (3-facet wrapper)
- api/endpoints/search.dart
- search/search_provider.dart (debounced 250ms)
- search/search_screen.dart (TextField + 3 horizontal/vertical sections)
- Wired /search route + search button on home AppBar
2026-05-08 14:30:01 -04:00
bvandeusen bbfeb5d3ff feat(flutter/player): mini PlayerBar in shell + tap-to-play wiring
PlayerBar reads playbackState + mediaItem streams; hidden when no
queue. Home track-row tap, album play button, album track tap, artist
play button (shuffle) all route to playerActions.playTracks. Token +
baseUrl forwarded to the audio handler before each new queue.
2026-05-02 17:39:09 -04:00