diff --git a/android/app/src/main/java/com/fabledsword/minstrel/library/ui/LibraryScreen.kt b/android/app/src/main/java/com/fabledsword/minstrel/library/ui/LibraryScreen.kt index d01236eb..c0971a5b 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/library/ui/LibraryScreen.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/library/ui/LibraryScreen.kt @@ -4,7 +4,6 @@ package com.fabledsword.minstrel.library.ui import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize @@ -12,6 +11,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -22,11 +23,10 @@ import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController @@ -69,8 +69,12 @@ fun LibraryScreen( navController: NavHostController, viewModel: LibraryViewModel = hiltViewModel(), ) { - var selectedTab by remember { mutableIntStateOf(0) } val tabs = LIBRARY_TABS + // HorizontalPager owns the active-tab state — the TabRow reads + // pagerState.currentPage and animateScrollToPage drives it on tap, + // so swipe and tap stay in sync. + val pagerState = rememberPagerState(pageCount = { tabs.size }) + val scope = rememberCoroutineScope() Scaffold( modifier = Modifier.fillMaxSize(), @@ -91,13 +95,13 @@ fun LibraryScreen( }, ) PrimaryScrollableTabRow( - selectedTabIndex = selectedTab, + selectedTabIndex = pagerState.currentPage, edgePadding = 16.dp, ) { tabs.forEachIndexed { index, label -> Tab( - selected = selectedTab == index, - onClick = { selectedTab = index }, + selected = pagerState.currentPage == index, + onClick = { scope.launch { pagerState.animateScrollToPage(index) } }, text = { Text(label) }, ) } @@ -105,8 +109,11 @@ fun LibraryScreen( } }, ) { inner -> - Box(modifier = Modifier.fillMaxSize().padding(inner)) { - when (selectedTab) { + HorizontalPager( + state = pagerState, + modifier = Modifier.fillMaxSize().padding(inner), + ) { page -> + when (page) { TAB_ARTISTS -> ArtistsTab(viewModel = viewModel, navController = navController) TAB_ALBUMS -> AlbumsTab(viewModel = viewModel, navController = navController) TAB_HISTORY -> HistoryTab(