diff --git a/app/src/main/java/eu/kanade/presentation/browse/MigrateMangaScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/MigrateMangaScreen.kt deleted file mode 100644 index 0564eca21..000000000 --- a/app/src/main/java/eu/kanade/presentation/browse/MigrateMangaScreen.kt +++ /dev/null @@ -1,84 +0,0 @@ -package eu.kanade.presentation.browse - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.items -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import eu.kanade.presentation.components.AppBar -import eu.kanade.presentation.manga.components.BaseMangaListItem -import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreenModel -import tachiyomi.domain.manga.model.Manga -import tachiyomi.i18n.MR -import tachiyomi.presentation.core.components.FastScrollLazyColumn -import tachiyomi.presentation.core.components.material.Scaffold -import tachiyomi.presentation.core.screens.EmptyScreen - -@Composable -fun MigrateMangaScreen( - navigateUp: () -> Unit, - title: String?, - state: MigrateMangaScreenModel.State, - onClickItem: (Manga) -> Unit, - onClickCover: (Manga) -> Unit, -) { - Scaffold( - topBar = { scrollBehavior -> - AppBar( - title = title, - navigateUp = navigateUp, - scrollBehavior = scrollBehavior, - ) - }, - ) { contentPadding -> - if (state.isEmpty) { - EmptyScreen( - stringRes = MR.strings.empty_screen, - modifier = Modifier.padding(contentPadding), - ) - return@Scaffold - } - - MigrateMangaContent( - contentPadding = contentPadding, - state = state, - onClickItem = onClickItem, - onClickCover = onClickCover, - ) - } -} - -@Composable -private fun MigrateMangaContent( - contentPadding: PaddingValues, - state: MigrateMangaScreenModel.State, - onClickItem: (Manga) -> Unit, - onClickCover: (Manga) -> Unit, -) { - FastScrollLazyColumn( - contentPadding = contentPadding, - ) { - items(state.titles) { manga -> - MigrateMangaItem( - manga = manga, - onClickItem = onClickItem, - onClickCover = onClickCover, - ) - } - } -} - -@Composable -private fun MigrateMangaItem( - manga: Manga, - onClickItem: (Manga) -> Unit, - onClickCover: (Manga) -> Unit, - modifier: Modifier = Modifier, -) { - BaseMangaListItem( - modifier = modifier, - manga = manga, - onClickItem = { onClickItem(manga) }, - onClickCover = { onClickCover(manga) }, - ) -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt index 6ef80871c..0a090032a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt @@ -1,21 +1,41 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.ArrowForward +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow -import eu.kanade.presentation.browse.MigrateMangaScreen +import eu.kanade.presentation.components.AppBar +import eu.kanade.presentation.manga.components.BaseMangaListItem import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.flow.collectLatest import mihon.feature.migration.config.MigrationConfigScreen +import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.MR +import tachiyomi.presentation.core.components.FastScrollLazyColumn +import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton +import tachiyomi.presentation.core.components.material.Scaffold +import tachiyomi.presentation.core.i18n.stringResource +import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.LoadingScreen +import tachiyomi.presentation.core.util.selectedBackground +import tachiyomi.presentation.core.util.shouldExpandFAB data class MigrateMangaScreen( private val sourceId: Long, @@ -34,13 +54,59 @@ data class MigrateMangaScreen( return } - MigrateMangaScreen( - navigateUp = navigator::pop, - title = state.source!!.name, - state = state, - onClickItem = { navigator.push(MigrationConfigScreen(it.id)) }, - onClickCover = { navigator.push(MangaScreen(it.id)) }, - ) + BackHandler(enabled = state.selectionMode) { + screenModel.clearSelection() + } + + val lazyListState = rememberLazyListState() + + Scaffold( + topBar = { scrollBehavior -> + AppBar( + title = state.source!!.name, + navigateUp = { + if (state.selectionMode) { + screenModel.clearSelection() + } else { + navigator.pop() + } + }, + scrollBehavior = scrollBehavior, + ) + }, + floatingActionButton = { + if (state.selectionMode) { + ExtendedFloatingActionButton( + text = { Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) }, + icon = { + Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) + }, + onClick = { + val selection = state.selection + screenModel.clearSelection() + navigator.push(MigrationConfigScreen(selection)) + }, + expanded = lazyListState.shouldExpandFAB(), + ) + } + }, + ) { contentPadding -> + if (state.isEmpty) { + EmptyScreen( + stringRes = MR.strings.empty_screen, + modifier = Modifier.padding(contentPadding), + ) + return@Scaffold + } + + MigrateMangaContent( + lazyListState = lazyListState, + contentPadding = contentPadding, + state = state, + onClickItem = screenModel::toggleSelection, + onClickCover = { navigator.push(MangaScreen(it.id)) }, + ) + } LaunchedEffect(Unit) { screenModel.events.collectLatest { event -> @@ -52,4 +118,43 @@ data class MigrateMangaScreen( } } } + + @Composable + private fun MigrateMangaContent( + lazyListState: LazyListState, + contentPadding: PaddingValues, + state: MigrateMangaScreenModel.State, + onClickItem: (Manga) -> Unit, + onClickCover: (Manga) -> Unit, + ) { + FastScrollLazyColumn( + state = lazyListState, + contentPadding = contentPadding, + ) { + items(state.titles) { manga -> + MigrateMangaItem( + manga = manga, + isSelected = manga.id in state.selection, + onClickItem = onClickItem, + onClickCover = onClickCover, + ) + } + } + } + + @Composable + private fun MigrateMangaItem( + manga: Manga, + isSelected: Boolean, + onClickItem: (Manga) -> Unit, + onClickCover: (Manga) -> Unit, + modifier: Modifier = Modifier, + ) { + BaseMangaListItem( + modifier = modifier.selectedBackground(isSelected), + manga = manga, + onClickItem = { onClickItem(manga) }, + onClickCover = { onClickCover(manga) }, + ) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreenModel.kt index 8faf1c320..f3f3de4dd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreenModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import logcat.LogPriority +import mihon.core.common.utils.mutate import tachiyomi.core.common.util.system.logcat import tachiyomi.domain.manga.interactor.GetFavorites import tachiyomi.domain.manga.model.Manga @@ -57,9 +58,23 @@ class MigrateMangaScreenModel( } } + fun toggleSelection(item: Manga) { + mutableState.update { state -> + val selection = state.selection.mutate { list -> + if (!list.remove(item.id)) list.add(item.id) + } + state.copy(selection = selection) + } + } + + fun clearSelection() { + mutableState.update { it.copy(selection = emptySet()) } + } + @Immutable data class State( val source: Source? = null, + val selection: Set = emptySet(), private val titleList: ImmutableList? = null, ) { @@ -71,6 +86,8 @@ class MigrateMangaScreenModel( val isEmpty: Boolean get() = titles.isEmpty() + + val selectionMode = selection.isNotEmpty() } }