102 lines
3.6 KiB
Kotlin
Raw Normal View History

2022-08-31 14:43:58 -04:00
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.Tab
import androidx.compose.material3.TabRow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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 eu.kanade.tachiyomi.widget.TachiyomiBottomNavigationView
import kotlinx.coroutines.launch
@Composable
2022-08-31 14:43:58 -04:00
fun TabbedScreen(
@StringRes titleRes: Int,
tabs: List<TabContent>,
startIndex: Int? = null,
searchQuery: String? = null,
onChangeSearchQuery: (String?) -> Unit = {},
incognitoMode: Boolean,
downloadedOnlyMode: Boolean,
) {
val scope = rememberCoroutineScope()
val state = rememberPagerState()
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) },
)
},
) { 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,
)
}
}
AppStateBanners(downloadedOnlyMode, incognitoMode)
HorizontalPager(
count = tabs.size,
modifier = Modifier.fillMaxSize(),
state = state,
verticalAlignment = Alignment.Top,
) { page ->
tabs[page].content(
TachiyomiBottomNavigationView.withBottomNavPadding(
PaddingValues(bottom = contentPadding.calculateBottomPadding()),
),
)
}
}
}
}
2022-08-31 14:43:58 -04:00
data class TabContent(
@StringRes val titleRes: Int,
val badgeNumber: Int? = null,
val searchEnabled: Boolean = false,
val actions: List<AppBar.Action> = emptyList(),
val content: @Composable (contentPadding: PaddingValues) -> Unit,
)