2022-08-31 14:43:58 -04:00
|
|
|
package eu.kanade.presentation.components
|
2022-08-29 17:18:06 -04:00
|
|
|
|
|
|
|
import androidx.annotation.StringRes
|
|
|
|
import androidx.compose.foundation.layout.Column
|
2022-10-10 02:52:56 +07:00
|
|
|
import androidx.compose.foundation.layout.PaddingValues
|
2022-10-09 00:28:09 +07:00
|
|
|
import androidx.compose.foundation.layout.calculateEndPadding
|
|
|
|
import androidx.compose.foundation.layout.calculateStartPadding
|
2022-08-29 17:18:06 -04:00
|
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
import androidx.compose.foundation.layout.padding
|
2023-05-13 23:06:00 +07:00
|
|
|
import androidx.compose.foundation.pager.rememberPagerState
|
2022-10-30 23:04:46 +07:00
|
|
|
import androidx.compose.material3.MaterialTheme
|
2022-11-24 10:28:25 +07:00
|
|
|
import androidx.compose.material3.SnackbarHost
|
|
|
|
import androidx.compose.material3.SnackbarHostState
|
2022-08-29 17:18:06 -04:00
|
|
|
import androidx.compose.material3.Tab
|
|
|
|
import androidx.compose.material3.TabRow
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
2022-11-24 10:28:25 +07:00
|
|
|
import androidx.compose.runtime.remember
|
2022-08-29 17:18:06 -04:00
|
|
|
import androidx.compose.runtime.rememberCoroutineScope
|
|
|
|
import androidx.compose.ui.Alignment
|
|
|
|
import androidx.compose.ui.Modifier
|
2022-10-09 00:28:09 +07:00
|
|
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
2022-08-29 17:18:06 -04:00
|
|
|
import androidx.compose.ui.res.stringResource
|
|
|
|
import kotlinx.coroutines.launch
|
2023-02-18 17:04:32 -05:00
|
|
|
import tachiyomi.presentation.core.components.HorizontalPager
|
2023-02-18 15:52:52 -05:00
|
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
2023-02-18 16:33:03 -05:00
|
|
|
import tachiyomi.presentation.core.components.material.TabIndicator
|
|
|
|
import tachiyomi.presentation.core.components.material.TabText
|
2022-08-29 17:18:06 -04:00
|
|
|
|
|
|
|
@Composable
|
2022-08-31 14:43:58 -04:00
|
|
|
fun TabbedScreen(
|
|
|
|
@StringRes titleRes: Int,
|
|
|
|
tabs: List<TabContent>,
|
2022-08-29 17:18:06 -04:00
|
|
|
startIndex: Int? = null,
|
2022-09-03 10:47:48 -04:00
|
|
|
searchQuery: String? = null,
|
|
|
|
onChangeSearchQuery: (String?) -> Unit = {},
|
2022-08-29 17:18:06 -04:00
|
|
|
) {
|
|
|
|
val scope = rememberCoroutineScope()
|
2023-05-21 11:11:33 -04:00
|
|
|
val state = rememberPagerState { tabs.size }
|
2022-11-24 10:28:25 +07:00
|
|
|
val snackbarHostState = remember { SnackbarHostState() }
|
2022-08-29 17:18:06 -04:00
|
|
|
|
|
|
|
LaunchedEffect(startIndex) {
|
|
|
|
if (startIndex != null) {
|
|
|
|
state.scrollToPage(startIndex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Scaffold(
|
|
|
|
topBar = {
|
2022-10-31 01:34:47 +08:00
|
|
|
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) },
|
|
|
|
)
|
2022-08-29 17:18:06 -04:00
|
|
|
},
|
2022-11-24 10:28:25 +07:00
|
|
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
2022-10-09 00:28:09 +07:00
|
|
|
) { contentPadding ->
|
|
|
|
Column(
|
|
|
|
modifier = Modifier.padding(
|
|
|
|
top = contentPadding.calculateTopPadding(),
|
|
|
|
start = contentPadding.calculateStartPadding(LocalLayoutDirection.current),
|
|
|
|
end = contentPadding.calculateEndPadding(LocalLayoutDirection.current),
|
|
|
|
),
|
|
|
|
) {
|
2022-08-29 17:18:06 -04:00
|
|
|
TabRow(
|
|
|
|
selectedTabIndex = state.currentPage,
|
2023-03-17 09:20:25 +07:00
|
|
|
indicator = { TabIndicator(it[state.currentPage], state.currentPageOffsetFraction) },
|
2022-08-29 17:18:06 -04:00
|
|
|
) {
|
|
|
|
tabs.forEachIndexed { index, tab ->
|
|
|
|
Tab(
|
|
|
|
selected = state.currentPage == index,
|
|
|
|
onClick = { scope.launch { state.animateScrollToPage(index) } },
|
2022-10-30 23:04:46 +07:00
|
|
|
text = { TabText(text = stringResource(tab.titleRes), badgeCount = tab.badgeNumber) },
|
|
|
|
unselectedContentColor = MaterialTheme.colorScheme.onSurface,
|
2022-08-29 17:18:06 -04:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HorizontalPager(
|
|
|
|
modifier = Modifier.fillMaxSize(),
|
|
|
|
state = state,
|
|
|
|
verticalAlignment = Alignment.Top,
|
|
|
|
) { page ->
|
2022-10-10 02:52:56 +07:00
|
|
|
tabs[page].content(
|
2022-12-03 10:35:30 +07:00
|
|
|
PaddingValues(bottom = contentPadding.calculateBottomPadding()),
|
2022-11-24 10:28:25 +07:00
|
|
|
snackbarHostState,
|
2022-10-10 02:52:56 +07:00
|
|
|
)
|
2022-08-29 17:18:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-31 14:43:58 -04:00
|
|
|
data class TabContent(
|
2022-08-29 17:18:06 -04:00
|
|
|
@StringRes val titleRes: Int,
|
|
|
|
val badgeNumber: Int? = null,
|
2022-10-31 01:34:47 +08:00
|
|
|
val searchEnabled: Boolean = false,
|
2022-08-29 17:18:06 -04:00
|
|
|
val actions: List<AppBar.Action> = emptyList(),
|
2022-11-24 10:28:25 +07:00
|
|
|
val content: @Composable (contentPadding: PaddingValues, snackbarHostState: SnackbarHostState) -> Unit,
|
2022-08-29 17:18:06 -04:00
|
|
|
)
|