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.PaddingValues import androidx.compose.foundation.layout.Row 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 eu.kanade.domain.source.interactor.SetMigrateSorting import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.SourceIcon import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceState import eu.kanade.tachiyomi.util.system.copyToClipboard import tachiyomi.domain.source.model.Source import tachiyomi.presentation.core.components.Badge import tachiyomi.presentation.core.components.BadgeGroup import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.theme.header import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.secondaryItemAlpha @Composable fun MigrateSourceScreen( state: MigrateSourceState, contentPadding: PaddingValues, onClickItem: (Source) -> Unit, onToggleSortingDirection: () -> Unit, onToggleSortingMode: () -> Unit, ) { val context = LocalContext.current when { state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding)) state.isEmpty -> EmptyScreen( textResource = R.string.information_empty_library, modifier = Modifier.padding(contentPadding), ) else -> MigrateSourceList( list = state.items, contentPadding = contentPadding, onClickItem = onClickItem, onLongClickItem = { source -> val sourceId = source.id.toString() context.copyToClipboard(sourceId, sourceId) }, sortingMode = state.sortingMode, onToggleSortingMode = onToggleSortingMode, sortingDirection = state.sortingDirection, onToggleSortingDirection = onToggleSortingDirection, ) } } @Composable private fun MigrateSourceList( list: List>, contentPadding: PaddingValues, onClickItem: (Source) -> Unit, onLongClickItem: (Source) -> Unit, sortingMode: SetMigrateSorting.Mode, onToggleSortingMode: () -> Unit, sortingDirection: SetMigrateSorting.Direction, onToggleSortingDirection: () -> Unit, ) { ScrollbarLazyColumn( contentPadding = contentPadding + topSmallPaddingValues, ) { stickyHeader(key = STICKY_HEADER_KEY_PREFIX) { Row( modifier = Modifier .background(MaterialTheme.colorScheme.background) .padding(start = MaterialTheme.padding.medium), 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_count)) } } 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 = { _, sourceLangString -> Column( modifier = Modifier .padding(horizontal = MaterialTheme.padding.medium) .weight(1f), ) { Text( text = source.name.ifBlank { source.id.toString() }, maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.bodyMedium, ) Row( horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small), verticalAlignment = Alignment.CenterVertically, ) { if (sourceLangString != null) { Text( modifier = Modifier.secondaryItemAlpha(), text = sourceLangString, maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.bodySmall, ) } if (source.isStub) { Text( modifier = Modifier.secondaryItemAlpha(), text = stringResource(R.string.not_installed), maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.error, ) } } } }, ) }