bulk-selection: reverse selection

This commit is contained in:
Cuong-Tran 2024-10-12 01:16:15 +07:00
parent a40385554c
commit b99389d2d0
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
12 changed files with 86 additions and 42 deletions

View file

@ -59,15 +59,20 @@ fun GlobalSearchScreen(
when (result) {
is SearchItemResult.Success -> {
result.result.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
}
else -> {}
}
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(
state.filteredItems.values
.filterIsInstance<SearchItemResult.Success>()
.flatMap { it.result },
)
},
)
} else {
// KMK <--

View file

@ -49,15 +49,20 @@ fun MigrateSearchScreen(
when (result) {
is SearchItemResult.Success -> {
result.result.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
}
else -> {}
}
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(
state.filteredItems.values
.filterIsInstance<SearchItemResult.Success>()
.flatMap { it.result },
)
},
)
} else {
// KMK <--

View file

@ -126,12 +126,16 @@ fun SourceFeedScreen(
onSelectAll = {
items.forEach {
it.results?.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(
items.mapNotNull { it.results }
.flatten(),
)
},
)
} else {
// KMK <--

View file

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BookmarkAdd
import androidx.compose.material.icons.filled.SelectAll
import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -23,6 +24,7 @@ fun BulkSelectionToolbar(
onClickClearSelection: () -> Unit,
onChangeCategoryClick: () -> Unit,
onSelectAll: (() -> Unit)? = null,
onReverseSelection: (() -> Unit)? = null,
) {
AppBar(
titleContent = { Text(text = "$selectedCount") },
@ -36,9 +38,16 @@ fun BulkSelectionToolbar(
AppBar.Action(
title = stringResource(MR.strings.action_select_all),
icon = Icons.Filled.SelectAll,
onClick = {
onSelectAll()
},
onClick = onSelectAll,
),
)
}
if (onReverseSelection != null) {
add(
AppBar.Action(
title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack,
onClick = onReverseSelection,
),
)
}

View file

@ -74,12 +74,16 @@ fun TabbedScreen(
onSelectAll = {
feedState.items?.forEach {
it.results?.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
}
},
onReverseSelection = {
feedState.items
?.mapNotNull { it.results }
?.flatten()
?.let { bulkFavoriteScreenModel.reverseSelection(it) }
},
)
} else {
// KMK <--

View file

@ -34,6 +34,7 @@ import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.mutate
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
@ -89,10 +90,6 @@ class BulkFavoriteScreenModel(
toggleSelection(manga, toSelectedState = true)
}
fun unselect(manga: Manga) {
toggleSelection(manga, toSelectedState = false)
}
/**
* @param toSelectedState set to true to only Select, set to false to only Unselect
*/
@ -105,11 +102,22 @@ class BulkFavoriteScreenModel(
list.add(manga)
}
}
state.copy(selection = newSelection)
}.also {
if (state.value.selection.isEmpty()) {
toggleSelectionMode()
}
state.copy(
selection = newSelection,
selectionMode = newSelection.isNotEmpty(),
)
}
}
fun reverseSelection(mangas: List<Manga>) {
mutableState.update { state ->
val newSelection = mangas.filterNot { manga ->
state.selection.contains(manga)
}.toPersistentList()
state.copy(
selection = newSelection,
selectionMode = newSelection.isNotEmpty(),
)
}
}

View file

@ -83,11 +83,12 @@ data class SourceSearchScreen(
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.mangaDisplayingList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList())
},
)
} else {
// KMK <--

View file

@ -183,11 +183,12 @@ data class BrowseSourceScreen(
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.mangaDisplayingList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList())
},
)
} else {
// KMK <--

View file

@ -57,12 +57,16 @@ fun RelatedMangasScreen(
successState.relatedMangasSorted?.forEach {
val relatedManga = it as RelatedManga.Success
relatedManga.mangaList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
}
},
onReverseSelection = {
successState.relatedMangasSorted
?.map { it as RelatedManga.Success }
?.flatMap { it.mangaList }
?.let { bulkFavoriteScreenModel.reverseSelection(it) }
},
)
} else {
BrowseSourceSimpleToolbar(

View file

@ -76,11 +76,12 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.mangaDisplayingList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList())
},
)
} else {
// KMK <--

View file

@ -72,11 +72,12 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() {
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.mangaDisplayingList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList())
},
)
} else {
// KMK <--

View file

@ -71,11 +71,12 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite,
onSelectAll = {
state.mangaDisplayingList.forEach { manga ->
if (!bulkFavoriteState.selection.contains(manga)) {
bulkFavoriteScreenModel.select(manga)
}
bulkFavoriteScreenModel.select(manga)
}
},
onReverseSelection = {
bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList())
},
)
} else {
// KMK <--