From 6f455b565f98de8a2154c62ef24d364b22f9d61c Mon Sep 17 00:00:00 2001 From: Honey Date: Sun, 16 Aug 2026 22:01:34 +0200 Subject: [PATCH] fix(android): smoother Erkunden swipe + top charts no longer vertically centered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pre-compose the neighbour page (beyondViewportPageCount = 1) so the first swipe doesn't hitch while the heavy LazyColumn builds. - Drive the TabRow indicator off pagerState.currentPage so it moves with the swipe (at the half-way point) instead of only on settle — the lag read as "not smooth". - Wrap each pager page in Box(fillMaxSize) so short content (the Top-Alben charts row) sits at the top again, not vertically centered. Co-Authored-By: Claude Opus 4.8 --- .../novasonic/app/ui/screen/ExploreScreen.kt | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ExploreScreen.kt b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ExploreScreen.kt index 4f98d15..9fb3fab 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ExploreScreen.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ExploreScreen.kt @@ -163,20 +163,22 @@ fun ExploreScreen( Column(Modifier.fillMaxSize()) { // ── Tabs ───────────────────────────────────────────────────────────── + // Drive the indicator off the pager's current page so it moves WITH the swipe (at the + // half-way point), not only once the swipe settles — that lag read as "not smooth". TabRow( - selectedTabIndex = state.tab.ordinal, + selectedTabIndex = pagerState.currentPage, containerColor = MaterialTheme.colorScheme.background, contentColor = NsAccent, ) { Tab( - selected = state.tab == ExploreTab.LIBRARY, + selected = pagerState.currentPage == ExploreTab.LIBRARY.ordinal, onClick = { vm.selectTab(ExploreTab.LIBRARY); vm.stopPreview() }, text = { Text("Bibliothek", maxLines = 1) }, selectedContentColor = NsAccent, unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant, ) Tab( - selected = state.tab == ExploreTab.GLOBAL, + selected = pagerState.currentPage == ExploreTab.GLOBAL.ordinal, onClick = { vm.selectTab(ExploreTab.GLOBAL); vm.stopPreview() }, text = { Text("Erkunden", maxLines = 1) }, selectedContentColor = NsAccent, @@ -246,27 +248,34 @@ fun ExploreScreen( // ── Content (swipeable) ──────────────────────────────────────────────── HorizontalPager( state = pagerState, + // Pre-compose the neighbour page so the swipe doesn't hitch while its (heavy) LazyColumn + // builds on first drag. + beyondViewportPageCount = 1, modifier = Modifier.weight(1f), ) { page -> - when (page) { - ExploreTab.LIBRARY.ordinal -> LibrarySearchContent( - query = state.query, - coverUrl = coverUrl, - playerState = playerState, - onSongPlay = onSongPlay, - onAlbumClick = onAlbumClick, - onArtistClick = onArtistClick, - onShowContextMenu = onShowContextMenu, - ) - else -> GlobalExploreContent( - state = state, - vm = vm, - coverUrl = coverUrl, - playerState = playerState, - onAlbumClick = onAlbumClick, - onSongPlay = onSongPlay, - onDownload = vm::showDownloadSheet, - ) + // fillMaxSize so short content (e.g. the Top-Alben charts row) sits at the top, not + // vertically centered in the page. + Box(Modifier.fillMaxSize()) { + when (page) { + ExploreTab.LIBRARY.ordinal -> LibrarySearchContent( + query = state.query, + coverUrl = coverUrl, + playerState = playerState, + onSongPlay = onSongPlay, + onAlbumClick = onAlbumClick, + onArtistClick = onArtistClick, + onShowContextMenu = onShowContextMenu, + ) + else -> GlobalExploreContent( + state = state, + vm = vm, + coverUrl = coverUrl, + playerState = playerState, + onAlbumClick = onAlbumClick, + onSongPlay = onSongPlay, + onDownload = vm::showDownloadSheet, + ) + } } } }