9ab862a2e1
Replaces the ComingSoon stub with the actual Home matching the Flutter
client's `home_screen.dart` shape — vertical Column of named horizontal
sections, each row a labeled `HorizontalScrollRow`:
Playlists (placeholder header — Phase 7)
Recently added → AlbumCards
Rediscover → AlbumCards (and/or ArtistCards)
Most played → CompactTrackTile
Last played → ArtistCards
Wire path: `GET /api/home/index` → `HomeRepository.refreshIndex()`
upserts five sections into `cached_home_index`. Per-section Flows
observe that table and hydrate each ID against the existing
album/artist/track DAOs — rows that haven't been pulled into Room yet
are silently dropped from emission (the per-tile hydration queue from
Phase 7+ will fill those gaps).
New files:
- models/wire/HomeIndexWire.kt — @Serializable wire shape
- api/endpoints/HomeApi.kt — Retrofit `GET /api/home/index`
- home/data/HomeRepository.kt — observe/refresh + section constants
- home/ui/HomeScreen.kt — composable + HomeViewModel + HomeUiState
+ inline CompactTrackTile (proper CompactTrackCard lands in Phase 7
alongside player play-by-ID and per-track cover hydration)
- shared/widgets/HorizontalScrollRow.kt — labeled LazyRow wrapper
that takes a LazyListScope block (keeps row items lazy)
Modified:
- nav/MinstrelNavGraph.kt — startDestination = Home (was Library;
matches Flutter's `redirect '/' → '/home'`); Home composable now
renders the real `HomeScreen(navController)` inside `ShellScaffold`
CompactTrackTile uses a Lucide.Music placeholder for the cover because
TrackRef doesn't carry coverUrl — matching the Flutter tile-provider
hydration is a Phase-7 follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>