Add bulk-selection & improve display mode in RecommendsScreen

This commit is contained in:
Cuong-Tran 2025-01-24 02:38:23 +07:00
parent 7b30a2a10f
commit c643d8a55b
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
10 changed files with 92 additions and 56 deletions

View file

@ -57,13 +57,10 @@ fun GlobalSearchScreen(
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.filteredItems.forEach { (_, result) ->
when (result) {
is SearchItemResult.Success -> {
result.result.forEach { manga ->
bulkFavoriteScreenModel.select(manga)
}
if (result is SearchItemResult.Success) {
result.result.forEach { manga ->
bulkFavoriteScreenModel.select(manga)
}
else -> {}
}
}
},

View file

@ -25,7 +25,7 @@ import tachiyomi.presentation.core.i18n.stringResource
fun BrowseSourceSimpleToolbar(
navigateUp: () -> Unit,
title: String,
displayMode: LibraryDisplayMode,
displayMode: LibraryDisplayMode?,
onDisplayModeChange: (LibraryDisplayMode) -> Unit,
scrollBehavior: TopAppBarScrollBehavior,
// KMK -->
@ -38,25 +38,30 @@ fun BrowseSourceSimpleToolbar(
title = title,
actions = {
var selectingDisplayMode by remember { mutableStateOf(false) }
// KMK -->
AppBarActions(
// SY -->
actions = persistentListOf(
AppBar.Action(
title = stringResource(MR.strings.action_display_mode),
// KMK -->
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.AutoMirrored.Filled.ViewList
} else {
Icons.Filled.ViewModule
},
// KMK <--
onClick = { selectingDisplayMode = true },
),
// KMK -->
bulkSelectionButton(isRunning, toggleSelectionMode),
// KMK <--
),
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
displayMode?.let {
add(
AppBar.Action(
title = stringResource(MR.strings.action_display_mode),
icon = if (displayMode == LibraryDisplayMode.List) {
Icons.AutoMirrored.Filled.ViewList
} else {
Icons.Filled.ViewModule
},
onClick = { selectingDisplayMode = true },
),
)
add(
bulkSelectionButton(isRunning, toggleSelectionMode),
)
}
}
.build(),
)
// KMK <--
DropdownMenu(
expanded = selectingDisplayMode,
onDismissRequest = { selectingDisplayMode = false },

View file

@ -35,7 +35,7 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
BackHandler(enabled = bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteScreenModel.backHandler()
}
// KMK <--

View file

@ -75,7 +75,7 @@ data class SourceSearchScreen(
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
BackHandler(enabled = bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteScreenModel.backHandler()
}
val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems()

View file

@ -50,7 +50,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import tachiyomi.core.common.preference.CheckboxState

View file

@ -87,8 +87,6 @@ import exh.pagepreview.PagePreviewScreen
import exh.recs.RecommendsScreen
import exh.source.MERGED_SOURCE_ID
import exh.source.getMainSource
import exh.source.isMdBasedSource
import exh.ui.ifSourcesLoaded
import exh.ui.metadata.MetadataViewScreen
import exh.ui.smartsearch.SmartSearchScreen
import kotlinx.coroutines.CancellationException
@ -160,7 +158,7 @@ class MangaScreen(
BackHandler(enabled = bulkFavoriteState.selectionMode || showingRelatedMangasScreen.value) {
when {
bulkFavoriteState.selectionMode -> bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteState.selectionMode -> bulkFavoriteScreenModel.backHandler()
showingRelatedMangasScreen.value -> showingRelatedMangasScreen.value = false
}
}

View file

@ -59,7 +59,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
BackHandler(enabled = bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteScreenModel.backHandler()
}
// KMK <--

View file

@ -28,7 +28,6 @@ import eu.kanade.tachiyomi.ui.browse.RemoveMangaDialog
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import exh.ui.ifSourcesLoaded
import mihon.presentation.core.util.collectAsLazyPagingItems
import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.manga.model.Manga
@ -65,7 +64,7 @@ class BrowseRecommendsScreen(
val haptic = LocalHapticFeedback.current
BackHandler(enabled = bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteScreenModel.backHandler()
}
// KMK <--

View file

@ -1,25 +1,16 @@
package exh.recs
import androidx.activity.compose.BackHandler
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.AddDuplicateMangaDialog
import eu.kanade.tachiyomi.ui.browse.AllowDuplicateDialog
@ -28,14 +19,11 @@ import eu.kanade.tachiyomi.ui.browse.ChangeMangaCategoryDialog
import eu.kanade.tachiyomi.ui.browse.ChangeMangasCategoryDialog
import eu.kanade.tachiyomi.ui.browse.RemoveMangaDialog
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
import mihon.presentation.core.util.collectAsLazyPagingItems
import tachiyomi.core.common.util.lang.launchIO
import eu.kanade.tachiyomi.ui.manga.MangaScreen
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import exh.recs.components.RecommendsScreen
import exh.ui.ifSourcesLoaded
import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.manga.model.Manga
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.screens.LoadingScreen
class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
@ -63,7 +51,7 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
val haptic = LocalHapticFeedback.current
BackHandler(enabled = bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
bulkFavoriteScreenModel.backHandler()
}
// KMK <--
@ -125,8 +113,6 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
},
// KMK -->
bulkFavoriteScreenModel = bulkFavoriteScreenModel,
displayMode = screenModel.displayMode,
onDisplayModeChange = { screenModel.displayMode = it },
// KMK <--
)

View file

@ -4,13 +4,18 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.util.formattedMessage
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
import exh.recs.RecommendationItemResult
import exh.recs.RecommendsScreenModel
import exh.recs.sources.RecommendationPagingSource
@ -30,14 +35,52 @@ fun RecommendsScreen(
onClickSource: (RecommendationPagingSource) -> Unit,
onClickItem: (Manga) -> Unit,
onLongClickItem: (Manga) -> Unit,
// KMK -->
bulkFavoriteScreenModel: BulkFavoriteScreenModel,
// KMK <--
) {
// KMK -->
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
// KMK <--
Scaffold(
topBar = { scrollBehavior ->
AppBar(
title = stringResource(SYMR.strings.similar, manga.title),
scrollBehavior = scrollBehavior,
navigateUp = navigateUp,
)
// KMK -->
if (bulkFavoriteState.selectionMode) {
BulkSelectionToolbar(
selectedCount = bulkFavoriteState.selection.size,
isRunning = bulkFavoriteState.isRunning,
onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode,
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.filteredItems.forEach { (_, result) ->
if (result is RecommendationItemResult.Success) {
result.result.forEach { manga ->
bulkFavoriteScreenModel.select(manga)
}
}
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(
state.filteredItems.values
.filterIsInstance<SearchItemResult.Success>()
.flatMap { it.result },
)
},
)
} else {
BrowseSourceSimpleToolbar(
displayMode = null,
onDisplayModeChange = {},
toggleSelectionMode = bulkFavoriteScreenModel::toggleSelectionMode,
isRunning = bulkFavoriteState.isRunning,
// KMK <--
title = stringResource(SYMR.strings.similar, manga.title),
scrollBehavior = scrollBehavior,
navigateUp = navigateUp,
)
}
},
) { paddingValues ->
RecommendsContent(
@ -47,6 +90,9 @@ fun RecommendsScreen(
onClickSource = onClickSource,
onClickItem = onClickItem,
onLongClickItem = onLongClickItem,
// KMK -->
selection = bulkFavoriteState.selection,
// KMK <--
)
}
}
@ -59,6 +105,9 @@ internal fun RecommendsContent(
onClickSource: (RecommendationPagingSource) -> Unit,
onClickItem: (Manga) -> Unit,
onLongClickItem: (Manga) -> Unit,
// KMK -->
selection: List<Manga>,
// KMK <--
) {
LazyColumn(
contentPadding = contentPadding,
@ -80,6 +129,9 @@ internal fun RecommendsContent(
getManga = getManga,
onClick = onClickItem,
onLongClick = onLongClickItem,
// KMK -->
selection = selection,
// KMK <--
)
}
is RecommendationItemResult.Error -> {