Android v1 polish + Web UI flavor pass #65
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
13 commits since the last main merge. All CI green on the tip (
682d7a5e, run 148).Android (7 commits)
User-reported issues from device testing, all fixed:
PlayerController.uiState+AuthStore.cacheSettingsand pre-downloads the next-N tracks (default 5) into the sharedSimpleCachevia Media3'sCacheWriter. Forward skips on a slow network now play from disk instead of stalling on a fresh HTTP connection.CacheSettings.prefetchWindowwas shipped at default=5 since M8 but the prefetcher itself was deferred — this closes that gap.Column.verticalScrollwon every drag delta before the outerdetectVerticalDragGesturessaw it. Replaced with aNestedScrollConnection.onPostScrollthat accumulates downward over-scroll at the top of the column toward a 200 px threshold. Same primitive Material'sModalBottomSheetuses.Crossfadewas keyed on the state INSTANCE, and because each section's flow emission creates a newUiState.Success(data), every per-section hydration tick re-ran the 300 ms fade. Keyed onstate::classinstead; Loading/Success/Empty/Error class transitions still animate, Success→Success recompositions update the LazyColumn normally.Box-based fill. No scrubber thumb on the mini bar. Tapping still expands to NowPlaying where scrubbing lives.SliderDefaults.Thumb.thumbSize. Spacers above/below shrunk to 4 dp.rememberSmoothPositionMshelper.produceStatekeyed on(positionMs, isPlaying, durationMs)resets to the canonical value on each polling tick and runs awithFrameMillisloop advancing at 1 ms/ms in between. Both MiniPlayer and NowPlaying consume the smoothed value — no more 500 ms steps.Web UI flavor pass (6 commits, 10 items)
Per operator screenshot review — wall of identical tiles → designed page with rhythm:
CardActionCluster).after:bg-accent/60).color-mix(fs-iron 60%, transparent)).from-accent/15 → surfacegradient. Anchors the page.w-56→ Recently addedw-48→ Rediscoverw-40. Freshest content gets the biggest tiles.shadow-sm→shadow-lg+ring-accent/40on:group-hoverfor all album tiles.APK channel
android.ymlwas simplified to testing-only earlier this session; the signed-release build moved intorelease.yml'sandroid-releasejob, chained toimage-releasevianeeds:. Main pushes still skipandroid-releaseby design, so this merge to main builds a fresh:latestimage but the bundled APK stays at whatever the last tag-build attached. Force-movingv2026.06.01after device-testing this PR will rebuild the APK and bundle it.Previously Recently Added chunked into rows of 25 and rendered each chunk as its own LazyRow, so chunks scrolled independently. Same pattern Most Played uses (one LazyHorizontalGrid where all rows scroll as a single panel) now applies to Recently Added. - New RECENTLY_ADDED_GRID_ROWS = 2 + RECENTLY_ADDED_GRID_HEIGHT_DP = 440 (matches a 200dp tile × 2 rows + the 8dp inter-row gap). - New RecentlyAddedGrid composable owns the section header + the LazyHorizontalGrid. Column-major re-flattening matches Web's row-major reading order on screen (top row first, then bottom). - recentlyAddedSection collapses from itemsIndexed-over-chunks to a single item { RecentlyAddedGrid(...) } in the outer LazyColumn. - AlbumsRow stays untouched (still used by Rediscover, etc.). The other multi-section helpers (Rediscover, Last Played, Playlists) are single-row by design and don't need this treatment.The new hero card on Home renders the For-You playlist twice — once at the top in the featured row and once in the Playlists carousel. The two existing assertions that did screen.getByText('For You') now match both and fail. Wrap each in within(playlistsSection) so the test targets the carousel render specifically.