feat: select all books button in library
* Added "Select all books" button to the Library which selects all books in the current category
This commit is contained in:
parent
14cf04a8ce
commit
30ee74cfff
9 changed files with 54 additions and 10 deletions
|
|
@ -8,6 +8,7 @@ package ua.acclorite.book_story.presentation.library
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import ua.acclorite.book_story.domain.model.library.Category
|
||||
import ua.acclorite.book_story.presentation.library.model.SelectableBook
|
||||
|
||||
@Immutable
|
||||
sealed class LibraryEvent {
|
||||
|
|
@ -35,6 +36,10 @@ sealed class LibraryEvent {
|
|||
val select: Boolean? = null
|
||||
) : LibraryEvent()
|
||||
|
||||
data class OnSelectBooks(
|
||||
val books: List<SelectableBook>
|
||||
) : LibraryEvent()
|
||||
|
||||
data object OnShowMoveDialog : LibraryEvent()
|
||||
|
||||
data class OnActionMoveDialog(
|
||||
|
|
|
|||
|
|
@ -191,6 +191,25 @@ class LibraryModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
is LibraryEvent.OnSelectBooks -> {
|
||||
withContext(Dispatchers.Default) {
|
||||
val editedList = _state.value.books.map { book ->
|
||||
if (event.books.any { book.data.id == it.data.id }) book.copy(
|
||||
selected = if (event.books.size > 1) true else !book.selected
|
||||
)
|
||||
else book
|
||||
}
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
books = editedList,
|
||||
selectedItemsCount = editedList.filter { book -> book.selected }.size,
|
||||
hasSelectedItems = editedList.any { book -> book.selected }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is LibraryEvent.OnShowMoveDialog -> {
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ object LibraryScreen : Screen, Parcelable {
|
|||
state.value.books.any { book ->
|
||||
book.data.categories.none { category -> category in categoryIds }
|
||||
} || categories.isEmpty() || settings.libraryShowDefaultTab.lastValue
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +141,7 @@ object LibraryScreen : Screen, Parcelable {
|
|||
requestFocus = screenModel::onEvent,
|
||||
searchQueryChange = screenModel::onEvent,
|
||||
search = screenModel::onEvent,
|
||||
selectBooks = screenModel::onEvent,
|
||||
clearSelectedBooks = screenModel::onEvent,
|
||||
showMoveDialog = screenModel::onEvent,
|
||||
actionMoveDialog = screenModel::onEvent,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ fun LibraryContent(
|
|||
requestFocus: (LibraryEvent.OnRequestFocus) -> Unit,
|
||||
searchQueryChange: (LibraryEvent.OnSearchQueryChange) -> Unit,
|
||||
search: (LibraryEvent.OnSearch) -> Unit,
|
||||
selectBooks: (LibraryEvent.OnSelectBooks) -> Unit,
|
||||
clearSelectedBooks: (LibraryEvent.OnClearSelectedBooks) -> Unit,
|
||||
showMoveDialog: (LibraryEvent.OnShowMoveDialog) -> Unit,
|
||||
showDeleteDialog: (LibraryEvent.OnShowDeleteDialog) -> Unit,
|
||||
|
|
@ -126,6 +127,7 @@ fun LibraryContent(
|
|||
searchQueryChange = searchQueryChange,
|
||||
search = search,
|
||||
selectBook = selectBook,
|
||||
selectBooks = selectBooks,
|
||||
clearSelectedBooks = clearSelectedBooks,
|
||||
showMoveDialog = showMoveDialog,
|
||||
showDeleteDialog = showDeleteDialog,
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ fun LibraryScaffold(
|
|||
requestFocus: (LibraryEvent.OnRequestFocus) -> Unit,
|
||||
searchQueryChange: (LibraryEvent.OnSearchQueryChange) -> Unit,
|
||||
search: (LibraryEvent.OnSearch) -> Unit,
|
||||
selectBooks: (LibraryEvent.OnSelectBooks) -> Unit,
|
||||
clearSelectedBooks: (LibraryEvent.OnClearSelectedBooks) -> Unit,
|
||||
showMoveDialog: (LibraryEvent.OnShowMoveDialog) -> Unit,
|
||||
showDeleteDialog: (LibraryEvent.OnShowDeleteDialog) -> Unit,
|
||||
|
|
@ -90,6 +91,7 @@ fun LibraryScaffold(
|
|||
requestFocus = requestFocus,
|
||||
searchQueryChange = searchQueryChange,
|
||||
search = search,
|
||||
selectBooks = selectBooks,
|
||||
clearSelectedBooks = clearSelectedBooks,
|
||||
showMoveDialog = showMoveDialog,
|
||||
showDeleteDialog = showDeleteDialog,
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import ua.acclorite.book_story.domain.model.library.Category
|
||||
import ua.acclorite.book_story.presentation.library.model.SelectableBook
|
||||
import ua.acclorite.book_story.ui.common.components.common.StyledText
|
||||
|
||||
@Composable
|
||||
fun LibraryTabs(
|
||||
categoriesWithBookCount: List<Pair<Category, Int>>,
|
||||
categoriesWithBooks: List<Pair<Category, List<SelectableBook>>>,
|
||||
pagerState: PagerState,
|
||||
itemCountBackgroundColor: Color,
|
||||
showBookCount: Boolean
|
||||
|
|
@ -70,7 +71,7 @@ fun LibraryTabs(
|
|||
}
|
||||
}
|
||||
) {
|
||||
categoriesWithBookCount.forEachIndexed { index, tabItem ->
|
||||
categoriesWithBooks.forEachIndexed { index, tabItem ->
|
||||
Tab(
|
||||
selected = pagerState.currentPage == index,
|
||||
onClick = {
|
||||
|
|
@ -91,7 +92,7 @@ fun LibraryTabs(
|
|||
if (showBookCount) {
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
StyledText(
|
||||
text = tabItem.second.toString(),
|
||||
text = tabItem.second.size.toString(),
|
||||
modifier = Modifier
|
||||
.background(
|
||||
itemCountBackgroundColor,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.FilterList
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.icons.filled.SelectAll
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.MoveUp
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
|
|
@ -72,13 +73,14 @@ fun LibraryTopBar(
|
|||
requestFocus: (LibraryEvent.OnRequestFocus) -> Unit,
|
||||
searchQueryChange: (LibraryEvent.OnSearchQueryChange) -> Unit,
|
||||
search: (LibraryEvent.OnSearch) -> Unit,
|
||||
selectBooks: (LibraryEvent.OnSelectBooks) -> Unit,
|
||||
clearSelectedBooks: (LibraryEvent.OnClearSelectedBooks) -> Unit,
|
||||
showMoveDialog: (LibraryEvent.OnShowMoveDialog) -> Unit,
|
||||
showDeleteDialog: (LibraryEvent.OnShowDeleteDialog) -> Unit,
|
||||
showFilterBottomSheet: (LibraryEvent.OnShowFilterBottomSheet) -> Unit
|
||||
) {
|
||||
val defaultCategory = stringResource(id = R.string.default_tab)
|
||||
val categoriesWithBookCount = remember(
|
||||
val categoriesWithBooks = remember(
|
||||
books,
|
||||
categories,
|
||||
showDefaultCategory,
|
||||
|
|
@ -86,7 +88,7 @@ fun LibraryTopBar(
|
|||
) {
|
||||
derivedStateOf {
|
||||
categories.filterNot { it.id == -1 }.map { category ->
|
||||
category to books.count { it.data.categories.any { it == category.id } }
|
||||
category to books.filter { it.data.categories.any { it == category.id } }
|
||||
}.toMutableList().apply {
|
||||
if (showDefaultCategory) {
|
||||
val categoryIds = categories.map { it.id }.toSet()
|
||||
|
|
@ -95,7 +97,7 @@ fun LibraryTopBar(
|
|||
Category(
|
||||
id = -1,
|
||||
title = defaultCategory
|
||||
) to books.count { book ->
|
||||
) to books.filter { book ->
|
||||
book.data.categories.none { category -> category in categoryIds }
|
||||
}
|
||||
)
|
||||
|
|
@ -103,9 +105,9 @@ fun LibraryTopBar(
|
|||
}.toList()
|
||||
}
|
||||
}
|
||||
val currentCategory = remember(pagerState.currentPage, categoriesWithBookCount) {
|
||||
val currentCategory = remember(pagerState.currentPage, categoriesWithBooks) {
|
||||
derivedStateOf {
|
||||
categoriesWithBookCount.value[pagerState.currentPage]
|
||||
categoriesWithBooks.value[pagerState.currentPage]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +228,17 @@ fun LibraryTopBar(
|
|||
)
|
||||
},
|
||||
contentActions = {
|
||||
IconButton(
|
||||
icon = Icons.Default.SelectAll,
|
||||
contentDescription = R.string.select_all_books_content_desc,
|
||||
disableOnClick = false,
|
||||
) {
|
||||
selectBooks(
|
||||
LibraryEvent.OnSelectBooks(
|
||||
books = currentCategory.value.second
|
||||
)
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
icon = Icons.Outlined.MoveUp,
|
||||
contentDescription = R.string.move_books_content_desc,
|
||||
|
|
@ -252,7 +265,7 @@ fun LibraryTopBar(
|
|||
exit = shrinkVertically()
|
||||
) {
|
||||
LibraryTabs(
|
||||
categoriesWithBookCount = categoriesWithBookCount.value,
|
||||
categoriesWithBooks = categoriesWithBooks.value,
|
||||
pagerState = pagerState,
|
||||
itemCountBackgroundColor = animatedItemCountBackgroundColor.value,
|
||||
showBookCount = showBookCount
|
||||
|
|
|
|||
|
|
@ -475,6 +475,7 @@
|
|||
<string name="clear_selected_items_content_desc">Очистити обрані предмети</string>
|
||||
<string name="add_files_content_desc">Додати файли</string>
|
||||
<string name="select_all_files_content_desc">Вибрати всі файли</string>
|
||||
<string name="select_all_books_content_desc">Вибрати всі книги</string>
|
||||
<string name="exit_search_content_desc">Вийти з пошуку</string>
|
||||
<string name="delete_whole_history_content_desc">Видалити всю історію</string>
|
||||
<string name="move_books_content_desc">Перемістити обрані книги</string>
|
||||
|
|
|
|||
|
|
@ -611,6 +611,7 @@
|
|||
<string name="clear_selected_items_content_desc">Clear selected items</string>
|
||||
<string name="add_files_content_desc">Add files</string>
|
||||
<string name="select_all_files_content_desc">Select all files</string>
|
||||
<string name="select_all_books_content_desc">Select all books</string>
|
||||
<string name="exit_search_content_desc">Exit search</string>
|
||||
<string name="delete_whole_history_content_desc">Delete whole history</string>
|
||||
<string name="move_books_content_desc">Move selected books</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue