package eu.kanade.presentation.components import androidx.annotation.StringRes import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import kotlinx.coroutines.launch import tachiyomi.presentation.core.components.HorizontalPager import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.TabIndicator import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.components.rememberPagerState @Composable fun TabbedScreen( @StringRes titleRes: Int, tabs: List, startIndex: Int? = null, searchQuery: String? = null, onChangeSearchQuery: (String?) -> Unit = {}, ) { val scope = rememberCoroutineScope() val state = rememberPagerState() val snackbarHostState = remember { SnackbarHostState() } LaunchedEffect(startIndex) { if (startIndex != null) { state.scrollToPage(startIndex) } } Scaffold( topBar = { val tab = tabs[state.currentPage] val searchEnabled = tab.searchEnabled SearchToolbar( titleContent = { AppBarTitle(stringResource(titleRes)) }, searchEnabled = searchEnabled, searchQuery = if (searchEnabled) searchQuery else null, onChangeSearchQuery = onChangeSearchQuery, actions = { AppBarActions(tab.actions) }, ) }, snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, ) { contentPadding -> Column( modifier = Modifier.padding( top = contentPadding.calculateTopPadding(), start = contentPadding.calculateStartPadding(LocalLayoutDirection.current), end = contentPadding.calculateEndPadding(LocalLayoutDirection.current), ), ) { TabRow( selectedTabIndex = state.currentPage, indicator = { TabIndicator(it[state.currentPage]) }, ) { tabs.forEachIndexed { index, tab -> Tab( selected = state.currentPage == index, onClick = { scope.launch { state.animateScrollToPage(index) } }, text = { TabText(text = stringResource(tab.titleRes), badgeCount = tab.badgeNumber) }, unselectedContentColor = MaterialTheme.colorScheme.onSurface, ) } } HorizontalPager( count = tabs.size, modifier = Modifier.fillMaxSize(), state = state, verticalAlignment = Alignment.Top, ) { page -> tabs[page].content( PaddingValues(bottom = contentPadding.calculateBottomPadding()), snackbarHostState, ) } } } } data class TabContent( @StringRes val titleRes: Int, val badgeNumber: Int? = null, val searchEnabled: Boolean = false, val actions: List = emptyList(), val content: @Composable (contentPadding: PaddingValues, snackbarHostState: SnackbarHostState) -> Unit, )