feat(updates-selection): Enable whole-group selection & Fix range selection in Updates screen (#913)
* fix(updates-screen): Fix range selection in Updates screen * feat(updates-screen): select Updates whole-group * improve performance * simplify onUpdateSelected parameters using UpdateSelectionOptions
This commit is contained in:
parent
2f55a0bc16
commit
a3abccb34b
3 changed files with 78 additions and 16 deletions
|
|
@ -60,7 +60,7 @@ fun UpdateScreen(
|
|||
onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit,
|
||||
onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit,
|
||||
onMultiDeleteClicked: (List<UpdatesItem>) -> Unit,
|
||||
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onUpdateSelected: (UpdatesItem, /* KMK --> */ UpdatesScreenModel.UpdateSelectionOptions /* KMK <-- */) -> Unit,
|
||||
onOpenChapter: (UpdatesItem) -> Unit,
|
||||
// KMK -->
|
||||
collapseToggle: (key: String) -> Unit,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import eu.kanade.presentation.util.relativeTimeSpanString
|
|||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
||||
import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel.UpdateSelectionOptions
|
||||
import eu.kanade.tachiyomi.ui.updates.groupByDateAndManga
|
||||
import mihon.feature.upcoming.DateHeading
|
||||
import tachiyomi.domain.updates.model.UpdatesWithRelations
|
||||
|
|
@ -91,7 +92,7 @@ internal fun LazyListScope.updatesUiItems(
|
|||
// SY -->
|
||||
preserveReadingPosition: Boolean,
|
||||
// SY <--
|
||||
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onUpdateSelected: (UpdatesItem, /* KMK --> */ UpdateSelectionOptions /* KMK <-- */) -> Unit,
|
||||
onClickCover: (UpdatesItem) -> Unit,
|
||||
onClickUpdate: (UpdatesItem) -> Unit,
|
||||
onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit,
|
||||
|
|
@ -124,10 +125,10 @@ internal fun LazyListScope.updatesUiItems(
|
|||
}
|
||||
is UpdatesUiModel.Item -> {
|
||||
val updatesItem = item.item
|
||||
// KMK -->
|
||||
val isLeader = item is UpdatesUiModel.Leader
|
||||
val isExpanded = expandedState.contains(updatesItem.update.groupByDateAndManga())
|
||||
|
||||
// KMK -->
|
||||
AnimatedVisibility(
|
||||
visible = isLeader || isExpanded,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
|
|
@ -153,11 +154,33 @@ internal fun LazyListScope.updatesUiItems(
|
|||
)
|
||||
},
|
||||
onLongClick = {
|
||||
onUpdateSelected(updatesItem, !updatesItem.selected, true, true)
|
||||
onUpdateSelected(
|
||||
updatesItem,
|
||||
// KMK -->
|
||||
UpdateSelectionOptions(
|
||||
selected = !updatesItem.selected,
|
||||
userSelected = true,
|
||||
fromLongPress = true,
|
||||
isGroup = isLeader && item.isExpandable,
|
||||
isExpanded = isExpanded,
|
||||
),
|
||||
// KMK <--
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
when {
|
||||
selectionMode -> onUpdateSelected(updatesItem, !updatesItem.selected, true, false)
|
||||
selectionMode -> onUpdateSelected(
|
||||
updatesItem,
|
||||
// KMK -->
|
||||
UpdateSelectionOptions(
|
||||
selected = !updatesItem.selected,
|
||||
userSelected = true,
|
||||
fromLongPress = false,
|
||||
isGroup = isLeader && item.isExpandable,
|
||||
isExpanded = isExpanded,
|
||||
),
|
||||
// KMK <--
|
||||
)
|
||||
else -> onClickUpdate(updatesItem)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -94,10 +94,20 @@ class UpdatesScreenModel(
|
|||
_events.send(Event.InternalError)
|
||||
}
|
||||
.collectLatest { updates ->
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
mutableState.update { state ->
|
||||
state.copy(
|
||||
isLoading = false,
|
||||
items = updates.toUpdateItems(),
|
||||
items = updates.toUpdateItems()
|
||||
// KMK -->
|
||||
.groupBy { it.update.mangaId }
|
||||
.values
|
||||
.flatMap { mangaChapters ->
|
||||
val (unread, read) = mangaChapters.partition { !it.update.read }
|
||||
unread.sortedBy { it.update.dateFetch } +
|
||||
read.sortedByDescending { it.update.dateFetch }
|
||||
}
|
||||
.toPersistentList(),
|
||||
// KMK <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -282,12 +292,26 @@ class UpdatesScreenModel(
|
|||
setDialog(Dialog.DeleteConfirmation(updatesItem))
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
/** Bundles all of the boolean flags for update‐selection into one type */
|
||||
data class UpdateSelectionOptions(
|
||||
val selected: Boolean,
|
||||
val userSelected: Boolean = false,
|
||||
val fromLongPress: Boolean = false,
|
||||
val isGroup: Boolean = false,
|
||||
val isExpanded: Boolean = false,
|
||||
)
|
||||
// KMK <--
|
||||
|
||||
fun toggleSelection(
|
||||
item: UpdatesItem,
|
||||
selected: Boolean,
|
||||
userSelected: Boolean = false,
|
||||
fromLongPress: Boolean = false,
|
||||
// KMK -->
|
||||
selectionOptions: UpdateSelectionOptions,
|
||||
// KMK <--
|
||||
) {
|
||||
// KMK -->
|
||||
val (selected, userSelected, fromLongPress, isGroup, isExpanded) = selectionOptions
|
||||
// KMK <--
|
||||
mutableState.update { state ->
|
||||
val newItems = state.items.toMutableList().apply {
|
||||
val selectedIndex = indexOfFirst { it.update.chapterId == item.update.chapterId }
|
||||
|
|
@ -300,6 +324,25 @@ class UpdatesScreenModel(
|
|||
set(selectedIndex, selectedItem.copy(selected = selected))
|
||||
selectedChapterIds.addOrRemove(item.update.chapterId, selected)
|
||||
|
||||
// KMK -->
|
||||
if (isGroup && !isExpanded) {
|
||||
val selectedItemDate = selectedItem.update.dateFetch.toLocalDate()
|
||||
val zone = java.time.ZoneId.systemDefault()
|
||||
val dayStartMillis = selectedItemDate.atStartOfDay(zone).toInstant().toEpochMilli()
|
||||
val dayEndMillis = selectedItemDate.plusDays(1).atStartOfDay(zone).toInstant().toEpochMilli()
|
||||
|
||||
state.items.mapIndexed { index, item -> index to item }
|
||||
.filter {
|
||||
it.second.update.mangaId == selectedItem.update.mangaId &&
|
||||
it.second.update.dateFetch in dayStartMillis..<dayEndMillis
|
||||
}
|
||||
.forEach { (index, item) ->
|
||||
set(index, item.copy(selected = selected))
|
||||
selectedChapterIds.addOrRemove(item.update.chapterId, selected)
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
if (selected && userSelected && fromLongPress) {
|
||||
if (firstSelection) {
|
||||
selectedPositions[0] = selectedIndex
|
||||
|
|
@ -413,13 +456,9 @@ class UpdatesScreenModel(
|
|||
.groupBy { it.update.mangaId }
|
||||
.values
|
||||
.flatMap { mangaChapters ->
|
||||
val (unread, read) = mangaChapters.partition { !it.update.read }
|
||||
val sortedChapters = unread.sortedBy { it.update.dateFetch } +
|
||||
read.sortedByDescending { it.update.dateFetch }
|
||||
val isExpandable = mangaChapters.size > 1
|
||||
|
||||
var lastMangaId = -1L
|
||||
sortedChapters.map { chapter ->
|
||||
mangaChapters.map { chapter ->
|
||||
if (chapter.update.mangaId != lastMangaId) {
|
||||
lastMangaId = chapter.update.mangaId
|
||||
UpdatesUiModel.Leader(chapter, isExpandable)
|
||||
|
|
|
|||
Loading…
Reference in a new issue