Files
minstrel/android/app
bvandeusen d96f835b5b feat(android): Phase 13 — Search screen + /api/search wiring
Replaces the Search-route ComingSoon stub with the real
three-facet search. Mirrors `flutter_client/lib/search/search_screen.dart`.

New:
  - models/wire/SearchWire.kt — three concrete PagedXxxWire types
    (Artists / Albums / Tracks) wrapping the server's Page[T] envelope,
    plus SearchResponseWire. Going non-generic on the paged wrapper is
    fine — three call sites and the explicit types read clearer than
    a generic with manual type-arg gymnastics at decode time.
  - models/SearchResponseRef.kt — domain envelope with `isEmpty` for
    the screen's "no matches" branch.
  - api/endpoints/SearchApi.kt — Retrofit GET /api/search with q +
    limit + offset.
  - search/data/SearchRepository.kt — trivial wire→domain mapper;
    debouncing intentionally lives in the VM.
  - search/ui/SearchViewModel.kt — 250ms debounce on the query Flow
    via debounce() + distinctUntilChanged(). Empty query collapses
    to Idle without firing a request. `playTrack(track)` queues a
    single track via PlayerController for the same single-row-play
    pattern as HistoryTab.
  - search/ui/SearchScreen.kt — auto-focus the field on entry (the
    user typed Search to start typing), inline X button to clear.
    Results render as three sections (Artists / Albums / Tracks),
    each section omitted when its list is empty. Artist taps →
    ArtistDetail, album taps → AlbumDetail, track taps → play.

Modified:
  - nav/MinstrelNavGraph.kt — Search route renders the real screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 18:23:09 -04:00
..