123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package eu.kanade.presentation.browse
- import androidx.compose.foundation.background
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.WindowInsets
- import androidx.compose.foundation.layout.asPaddingValues
- import androidx.compose.foundation.layout.navigationBars
- import androidx.compose.foundation.layout.padding
- import androidx.compose.foundation.lazy.items
- import androidx.compose.material.icons.Icons
- import androidx.compose.material.icons.outlined.ArrowDownward
- import androidx.compose.material.icons.outlined.ArrowUpward
- import androidx.compose.material.icons.outlined.Numbers
- import androidx.compose.material.icons.outlined.SortByAlpha
- import androidx.compose.material3.Icon
- import androidx.compose.material3.IconButton
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.platform.LocalContext
- import androidx.compose.ui.res.stringResource
- import androidx.compose.ui.text.style.TextOverflow
- import androidx.compose.ui.unit.dp
- import eu.kanade.domain.source.interactor.SetMigrateSorting
- import eu.kanade.domain.source.model.Source
- import eu.kanade.presentation.browse.components.BaseSourceItem
- import eu.kanade.presentation.browse.components.SourceIcon
- import eu.kanade.presentation.components.Badge
- import eu.kanade.presentation.components.BadgeGroup
- import eu.kanade.presentation.components.EmptyScreen
- import eu.kanade.presentation.components.LoadingScreen
- import eu.kanade.presentation.components.ScrollbarLazyColumn
- import eu.kanade.presentation.theme.header
- import eu.kanade.presentation.util.bottomNavPaddingValues
- import eu.kanade.presentation.util.horizontalPadding
- import eu.kanade.presentation.util.plus
- import eu.kanade.presentation.util.topPaddingValues
- import eu.kanade.tachiyomi.R
- import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrationSourcesPresenter
- import eu.kanade.tachiyomi.util.system.LocaleHelper
- import eu.kanade.tachiyomi.util.system.copyToClipboard
- @Composable
- fun MigrateSourceScreen(
- presenter: MigrationSourcesPresenter,
- onClickItem: (Source) -> Unit,
- ) {
- val context = LocalContext.current
- when {
- presenter.isLoading -> LoadingScreen()
- presenter.isEmpty -> EmptyScreen(textResource = R.string.information_empty_library)
- else ->
- MigrateSourceList(
- list = presenter.items,
- onClickItem = onClickItem,
- onLongClickItem = { source ->
- val sourceId = source.id.toString()
- context.copyToClipboard(sourceId, sourceId)
- },
- sortingMode = presenter.sortingMode,
- onToggleSortingMode = { presenter.toggleSortingMode() },
- sortingDirection = presenter.sortingDirection,
- onToggleSortingDirection = { presenter.toggleSortingDirection() },
- )
- }
- }
- @Composable
- private fun MigrateSourceList(
- list: List<Pair<Source, Long>>,
- onClickItem: (Source) -> Unit,
- onLongClickItem: (Source) -> Unit,
- sortingMode: SetMigrateSorting.Mode,
- onToggleSortingMode: () -> Unit,
- sortingDirection: SetMigrateSorting.Direction,
- onToggleSortingDirection: () -> Unit,
- ) {
- ScrollbarLazyColumn(
- contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
- ) {
- stickyHeader(key = "header") {
- Row(
- modifier = Modifier
- .background(MaterialTheme.colorScheme.background)
- .padding(start = horizontalPadding),
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Text(
- text = stringResource(R.string.migration_selection_prompt),
- modifier = Modifier.weight(1f),
- style = MaterialTheme.typography.header,
- )
- IconButton(onClick = onToggleSortingMode) {
- when (sortingMode) {
- SetMigrateSorting.Mode.ALPHABETICAL -> Icon(Icons.Outlined.SortByAlpha, contentDescription = stringResource(R.string.action_sort_alpha))
- SetMigrateSorting.Mode.TOTAL -> Icon(Icons.Outlined.Numbers, contentDescription = stringResource(R.string.action_sort_total))
- }
- }
- IconButton(onClick = onToggleSortingDirection) {
- when (sortingDirection) {
- SetMigrateSorting.Direction.ASCENDING -> Icon(Icons.Outlined.ArrowUpward, contentDescription = stringResource(R.string.action_asc))
- SetMigrateSorting.Direction.DESCENDING -> Icon(Icons.Outlined.ArrowDownward, contentDescription = stringResource(R.string.action_desc))
- }
- }
- }
- }
- items(
- items = list,
- key = { (source, _) -> "migrate-${source.id}" },
- ) { (source, count) ->
- MigrateSourceItem(
- modifier = Modifier.animateItemPlacement(),
- source = source,
- count = count,
- onClickItem = { onClickItem(source) },
- onLongClickItem = { onLongClickItem(source) },
- )
- }
- }
- }
- @Composable
- private fun MigrateSourceItem(
- modifier: Modifier = Modifier,
- source: Source,
- count: Long,
- onClickItem: () -> Unit,
- onLongClickItem: () -> Unit,
- ) {
- BaseSourceItem(
- modifier = modifier,
- source = source,
- showLanguageInContent = source.lang != "",
- onClickItem = onClickItem,
- onLongClickItem = onLongClickItem,
- icon = { SourceIcon(source = source) },
- action = {
- BadgeGroup {
- Badge(text = "$count")
- }
- },
- content = { source, showLanguageInContent ->
- Column(
- modifier = Modifier
- .padding(horizontal = horizontalPadding)
- .weight(1f),
- ) {
- Text(
- text = source.name.ifBlank { source.id.toString() },
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- style = MaterialTheme.typography.bodyMedium,
- )
- Row(
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- verticalAlignment = Alignment.CenterVertically,
- ) {
- if (showLanguageInContent) {
- Text(
- text = LocaleHelper.getDisplayName(source.lang),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- style = MaterialTheme.typography.bodySmall,
- )
- }
- if (source.isStub) {
- Text(
- text = stringResource(R.string.not_installed),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- style = MaterialTheme.typography.bodySmall,
- color = MaterialTheme.colorScheme.error,
- )
- }
- }
- }
- },
- )
- }
|