mirror of
https://github.com/mihonapp/mihon.git
synced 2024-12-26 10:58:24 +01:00
MangaScreen: Save selection state (#7560)
This commit is contained in:
parent
473dc688f0
commit
00519e3b93
@ -38,8 +38,6 @@ import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
@ -106,6 +104,11 @@ fun MangaScreen(
|
||||
onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit,
|
||||
onMarkPreviousAsReadClicked: (Chapter) -> Unit,
|
||||
onMultiDeleteClicked: (List<Chapter>) -> Unit,
|
||||
|
||||
// Chapter selection
|
||||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
) {
|
||||
if (windowWidthSizeClass == WindowWidthSizeClass.Compact) {
|
||||
MangaScreenSmallImpl(
|
||||
@ -131,6 +134,9 @@ fun MangaScreen(
|
||||
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
|
||||
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
|
||||
onMultiDeleteClicked = onMultiDeleteClicked,
|
||||
onChapterSelected = onChapterSelected,
|
||||
onAllChapterSelected = onAllChapterSelected,
|
||||
onInvertSelection = onInvertSelection,
|
||||
)
|
||||
} else {
|
||||
MangaScreenLargeImpl(
|
||||
@ -157,6 +163,9 @@ fun MangaScreen(
|
||||
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
|
||||
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
|
||||
onMultiDeleteClicked = onMultiDeleteClicked,
|
||||
onChapterSelected = onChapterSelected,
|
||||
onAllChapterSelected = onAllChapterSelected,
|
||||
onInvertSelection = onInvertSelection,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -191,18 +200,21 @@ private fun MangaScreenSmallImpl(
|
||||
onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit,
|
||||
onMarkPreviousAsReadClicked: (Chapter) -> Unit,
|
||||
onMultiDeleteClicked: (List<Chapter>) -> Unit,
|
||||
|
||||
// Chapter selection
|
||||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
) {
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
val chapterListState = rememberLazyListState()
|
||||
|
||||
val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues()
|
||||
val chapters = remember(state) { state.processedChapters.toList() }
|
||||
val selected = remember(chapters) { emptyList<ChapterItem>().toMutableStateList() }
|
||||
val selectedPositions = remember(chapters) { arrayOf(-1, -1) } // first and last selected index in list
|
||||
|
||||
val internalOnBackPressed = {
|
||||
if (selected.isNotEmpty()) {
|
||||
selected.clear()
|
||||
if (chapters.any { it.selected }) {
|
||||
onAllChapterSelected(false)
|
||||
} else {
|
||||
onBackClicked()
|
||||
}
|
||||
@ -236,21 +248,14 @@ private fun MangaScreenSmallImpl(
|
||||
onDownloadClicked = onDownloadActionClicked,
|
||||
onEditCategoryClicked = onEditCategoryClicked,
|
||||
onMigrateClicked = onMigrateClicked,
|
||||
actionModeCounter = selected.size,
|
||||
onSelectAll = {
|
||||
selected.clear()
|
||||
selected.addAll(chapters)
|
||||
},
|
||||
onInvertSelection = {
|
||||
val toSelect = chapters - selected
|
||||
selected.clear()
|
||||
selected.addAll(toSelect)
|
||||
},
|
||||
actionModeCounter = chapters.count { it.selected },
|
||||
onSelectAll = { onAllChapterSelected(true) },
|
||||
onInvertSelection = { onInvertSelection() },
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
SharedMangaBottomActionMenu(
|
||||
selected = selected,
|
||||
selected = chapters.filter { it.selected },
|
||||
onMultiBookmarkClicked = onMultiBookmarkClicked,
|
||||
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
|
||||
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
|
||||
@ -262,7 +267,7 @@ private fun MangaScreenSmallImpl(
|
||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
floatingActionButton = {
|
||||
AnimatedVisibility(
|
||||
visible = chapters.any { !it.chapter.read } && selected.isEmpty(),
|
||||
visible = chapters.any { !it.chapter.read } && chapters.none { it.selected },
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
@ -370,10 +375,9 @@ private fun MangaScreenSmallImpl(
|
||||
|
||||
sharedChapterItems(
|
||||
chapters = chapters,
|
||||
selected = selected,
|
||||
selectedPositions = selectedPositions,
|
||||
onChapterClicked = onChapterClicked,
|
||||
onDownloadChapter = onDownloadChapter,
|
||||
onChapterSelected = onChapterSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -412,6 +416,11 @@ fun MangaScreenLargeImpl(
|
||||
onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit,
|
||||
onMarkPreviousAsReadClicked: (Chapter) -> Unit,
|
||||
onMultiDeleteClicked: (List<Chapter>) -> Unit,
|
||||
|
||||
// Chapter selection
|
||||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
) {
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
val density = LocalDensity.current
|
||||
@ -436,12 +445,10 @@ fun MangaScreenLargeImpl(
|
||||
) {
|
||||
val chapterListState = rememberLazyListState()
|
||||
val chapters = remember(state) { state.processedChapters.toList() }
|
||||
val selected = remember(chapters) { emptyList<ChapterItem>().toMutableStateList() }
|
||||
val selectedPositions = remember(chapters) { arrayOf(-1, -1) } // first and last selected index in list
|
||||
|
||||
val internalOnBackPressed = {
|
||||
if (selected.isNotEmpty()) {
|
||||
selected.clear()
|
||||
if (chapters.any { it.selected }) {
|
||||
onAllChapterSelected(false)
|
||||
} else {
|
||||
onBackClicked()
|
||||
}
|
||||
@ -454,7 +461,7 @@ fun MangaScreenLargeImpl(
|
||||
MangaSmallAppBar(
|
||||
modifier = Modifier.onSizeChanged { onTopBarHeightChanged(it.height) },
|
||||
title = state.manga.title,
|
||||
titleAlphaProvider = { if (selected.isEmpty()) 0f else 1f },
|
||||
titleAlphaProvider = { if (chapters.any { it.selected }) 1f else 0f },
|
||||
backgroundAlphaProvider = { 1f },
|
||||
incognitoMode = state.isIncognitoMode,
|
||||
downloadedOnlyMode = state.isDownloadedOnlyMode,
|
||||
@ -463,16 +470,9 @@ fun MangaScreenLargeImpl(
|
||||
onDownloadClicked = onDownloadActionClicked,
|
||||
onEditCategoryClicked = onEditCategoryClicked,
|
||||
onMigrateClicked = onMigrateClicked,
|
||||
actionModeCounter = selected.size,
|
||||
onSelectAll = {
|
||||
selected.clear()
|
||||
selected.addAll(chapters)
|
||||
},
|
||||
onInvertSelection = {
|
||||
val toSelect = chapters - selected
|
||||
selected.clear()
|
||||
selected.addAll(toSelect)
|
||||
},
|
||||
actionModeCounter = chapters.count { it.selected },
|
||||
onSelectAll = { onAllChapterSelected(true) },
|
||||
onInvertSelection = { onInvertSelection() },
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
@ -481,7 +481,7 @@ fun MangaScreenLargeImpl(
|
||||
contentAlignment = Alignment.BottomEnd,
|
||||
) {
|
||||
SharedMangaBottomActionMenu(
|
||||
selected = selected,
|
||||
selected = chapters.filter { it.selected },
|
||||
onMultiBookmarkClicked = onMultiBookmarkClicked,
|
||||
onMultiMarkAsReadClicked = onMultiMarkAsReadClicked,
|
||||
onMarkPreviousAsReadClicked = onMarkPreviousAsReadClicked,
|
||||
@ -494,7 +494,7 @@ fun MangaScreenLargeImpl(
|
||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
floatingActionButton = {
|
||||
AnimatedVisibility(
|
||||
visible = chapters.any { !it.chapter.read } && selected.isEmpty(),
|
||||
visible = chapters.any { !it.chapter.read } && chapters.none { it.selected },
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
@ -578,10 +578,9 @@ fun MangaScreenLargeImpl(
|
||||
|
||||
sharedChapterItems(
|
||||
chapters = chapters,
|
||||
selected = selected,
|
||||
selectedPositions = selectedPositions,
|
||||
onChapterClicked = onChapterClicked,
|
||||
onDownloadChapter = onDownloadChapter,
|
||||
onChapterSelected = onChapterSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -592,7 +591,7 @@ fun MangaScreenLargeImpl(
|
||||
|
||||
@Composable
|
||||
private fun SharedMangaBottomActionMenu(
|
||||
selected: SnapshotStateList<ChapterItem>,
|
||||
selected: List<ChapterItem>,
|
||||
onMultiBookmarkClicked: (List<Chapter>, bookmarked: Boolean) -> Unit,
|
||||
onMultiMarkAsReadClicked: (List<Chapter>, markAsRead: Boolean) -> Unit,
|
||||
onMarkPreviousAsReadClicked: (Chapter) -> Unit,
|
||||
@ -605,33 +604,26 @@ private fun SharedMangaBottomActionMenu(
|
||||
modifier = Modifier.fillMaxWidth(fillFraction),
|
||||
onBookmarkClicked = {
|
||||
onMultiBookmarkClicked.invoke(selected.map { it.chapter }, true)
|
||||
selected.clear()
|
||||
}.takeIf { selected.any { !it.chapter.bookmark } },
|
||||
onRemoveBookmarkClicked = {
|
||||
onMultiBookmarkClicked.invoke(selected.map { it.chapter }, false)
|
||||
selected.clear()
|
||||
}.takeIf { selected.all { it.chapter.bookmark } },
|
||||
onMarkAsReadClicked = {
|
||||
onMultiMarkAsReadClicked(selected.map { it.chapter }, true)
|
||||
selected.clear()
|
||||
}.takeIf { selected.any { !it.chapter.read } },
|
||||
onMarkAsUnreadClicked = {
|
||||
onMultiMarkAsReadClicked(selected.map { it.chapter }, false)
|
||||
selected.clear()
|
||||
}.takeIf { selected.any { it.chapter.read } },
|
||||
onMarkPreviousAsReadClicked = {
|
||||
onMarkPreviousAsReadClicked(selected[0].chapter)
|
||||
selected.clear()
|
||||
}.takeIf { selected.size == 1 },
|
||||
onDownloadClicked = {
|
||||
onDownloadChapter!!(selected.toList(), ChapterDownloadAction.START)
|
||||
selected.clear()
|
||||
}.takeIf {
|
||||
onDownloadChapter != null && selected.any { it.downloadState != Download.State.DOWNLOADED }
|
||||
},
|
||||
onDeleteClicked = {
|
||||
onMultiDeleteClicked(selected.map { it.chapter })
|
||||
selected.clear()
|
||||
}.takeIf {
|
||||
onDownloadChapter != null && selected.any { it.downloadState == Download.State.DOWNLOADED }
|
||||
},
|
||||
@ -640,10 +632,9 @@ private fun SharedMangaBottomActionMenu(
|
||||
|
||||
private fun LazyListScope.sharedChapterItems(
|
||||
chapters: List<ChapterItem>,
|
||||
selected: SnapshotStateList<ChapterItem>,
|
||||
selectedPositions: Array<Int>,
|
||||
onChapterClicked: (Chapter) -> Unit,
|
||||
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
|
||||
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
) {
|
||||
items(
|
||||
items = chapters,
|
||||
@ -658,24 +649,18 @@ private fun LazyListScope.sharedChapterItems(
|
||||
scanlator = chapterItem.chapter.scanlator.takeIf { !it.isNullOrBlank() },
|
||||
read = chapterItem.chapter.read,
|
||||
bookmark = chapterItem.chapter.bookmark,
|
||||
selected = selected.contains(chapterItem),
|
||||
selected = chapterItem.selected,
|
||||
downloadStateProvider = { chapterItem.downloadState },
|
||||
downloadProgressProvider = { chapterItem.downloadProgress },
|
||||
onLongClick = {
|
||||
val dispatched = onChapterItemLongClick(
|
||||
chapterItem = chapterItem,
|
||||
selected = selected,
|
||||
chapters = chapters,
|
||||
selectedPositions = selectedPositions,
|
||||
)
|
||||
if (dispatched) haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onChapterSelected(chapterItem, !chapterItem.selected, true, true)
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
},
|
||||
onClick = {
|
||||
onChapterItemClick(
|
||||
chapterItem = chapterItem,
|
||||
selected = selected,
|
||||
chapters = chapters,
|
||||
selectedPositions = selectedPositions,
|
||||
onToggleSelection = { onChapterSelected(chapterItem, !chapterItem.selected, true, false) },
|
||||
onChapterClicked = onChapterClicked,
|
||||
)
|
||||
},
|
||||
@ -686,72 +671,15 @@ private fun LazyListScope.sharedChapterItems(
|
||||
}
|
||||
}
|
||||
|
||||
private fun onChapterItemLongClick(
|
||||
chapterItem: ChapterItem,
|
||||
selected: MutableList<ChapterItem>,
|
||||
chapters: List<ChapterItem>,
|
||||
selectedPositions: Array<Int>,
|
||||
): Boolean {
|
||||
if (!selected.contains(chapterItem)) {
|
||||
val selectedIndex = chapters.indexOf(chapterItem)
|
||||
if (selected.isEmpty()) {
|
||||
selected.add(chapterItem)
|
||||
selectedPositions[0] = selectedIndex
|
||||
selectedPositions[1] = selectedIndex
|
||||
return true
|
||||
}
|
||||
|
||||
// Try to select the items in-between when possible
|
||||
val range: IntRange
|
||||
if (selectedIndex < selectedPositions[0]) {
|
||||
range = selectedIndex until selectedPositions[0]
|
||||
selectedPositions[0] = selectedIndex
|
||||
} else if (selectedIndex > selectedPositions[1]) {
|
||||
range = (selectedPositions[1] + 1)..selectedIndex
|
||||
selectedPositions[1] = selectedIndex
|
||||
} else {
|
||||
// Just select itself
|
||||
range = selectedIndex..selectedIndex
|
||||
}
|
||||
|
||||
range.forEach {
|
||||
val toAdd = chapters[it]
|
||||
if (!selected.contains(toAdd)) {
|
||||
selected.add(toAdd)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun onChapterItemClick(
|
||||
chapterItem: ChapterItem,
|
||||
selected: MutableList<ChapterItem>,
|
||||
chapters: List<ChapterItem>,
|
||||
selectedPositions: Array<Int>,
|
||||
onToggleSelection: (Boolean) -> Unit,
|
||||
onChapterClicked: (Chapter) -> Unit,
|
||||
) {
|
||||
val selectedIndex = chapters.indexOf(chapterItem)
|
||||
when {
|
||||
selected.contains(chapterItem) -> {
|
||||
val removedIndex = chapters.indexOf(chapterItem)
|
||||
selected.remove(chapterItem)
|
||||
|
||||
if (removedIndex == selectedPositions[0]) {
|
||||
selectedPositions[0] = chapters.indexOfFirst { selected.contains(it) }
|
||||
} else if (removedIndex == selectedPositions[1]) {
|
||||
selectedPositions[1] = chapters.indexOfLast { selected.contains(it) }
|
||||
}
|
||||
}
|
||||
selected.isNotEmpty() -> {
|
||||
if (selectedIndex < selectedPositions[0]) {
|
||||
selectedPositions[0] = selectedIndex
|
||||
} else if (selectedIndex > selectedPositions[1]) {
|
||||
selectedPositions[1] = selectedIndex
|
||||
}
|
||||
selected.add(chapterItem)
|
||||
}
|
||||
chapterItem.selected -> onToggleSelection(false)
|
||||
chapters.any { it.selected } -> onToggleSelection(true)
|
||||
else -> onChapterClicked(chapterItem.chapter)
|
||||
}
|
||||
}
|
||||
|
@ -142,6 +142,9 @@ class MangaController :
|
||||
onMultiMarkAsReadClicked = presenter::markChaptersRead,
|
||||
onMarkPreviousAsReadClicked = presenter::markPreviousChapterRead,
|
||||
onMultiDeleteClicked = this::deleteChaptersWithConfirmation,
|
||||
onChapterSelected = presenter::toggleSelection,
|
||||
onAllChapterSelected = presenter::toggleAllSelection,
|
||||
onInvertSelection = presenter::invertSelection,
|
||||
)
|
||||
} else {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
|
@ -140,6 +140,8 @@ class MangaPresenter(
|
||||
val processedChapters: Sequence<ChapterItem>?
|
||||
get() = successState?.processedChapters
|
||||
|
||||
private val selectedPositions: Array<Int> = arrayOf(-1, -1) // first and last selected index in list
|
||||
|
||||
/**
|
||||
* Helper function to update the UI state only if it's currently in success state
|
||||
*/
|
||||
@ -583,6 +585,7 @@ class MangaPresenter(
|
||||
values = chapters.toTypedArray(),
|
||||
)
|
||||
}
|
||||
toggleAllSelection(false)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -592,6 +595,7 @@ class MangaPresenter(
|
||||
fun downloadChapters(chapters: List<DomainChapter>) {
|
||||
val manga = successState?.manga ?: return
|
||||
downloadManager.downloadChapters(manga, chapters.map { it.toDbChapter() })
|
||||
toggleAllSelection(false)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -605,6 +609,7 @@ class MangaPresenter(
|
||||
.map { ChapterUpdate(id = it.id, bookmark = bookmarked) }
|
||||
.let { updateChapter.awaitAll(it) }
|
||||
}
|
||||
toggleAllSelection(false)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -627,12 +632,16 @@ class MangaPresenter(
|
||||
deletedChapters.forEach {
|
||||
val index = indexOf(it)
|
||||
val toAdd = removeAt(index)
|
||||
.copy(downloadState = Download.State.NOT_DOWNLOADED, downloadProgress = 0)
|
||||
.copy(
|
||||
downloadState = Download.State.NOT_DOWNLOADED,
|
||||
downloadProgress = 0,
|
||||
)
|
||||
add(index, toAdd)
|
||||
}
|
||||
}
|
||||
successState.copy(chapters = newChapters)
|
||||
}
|
||||
toggleAllSelection(false)
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
@ -725,6 +734,89 @@ class MangaPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleSelection(
|
||||
item: ChapterItem,
|
||||
selected: Boolean,
|
||||
userSelected: Boolean = false,
|
||||
fromLongPress: Boolean = false,
|
||||
) {
|
||||
updateSuccessState { successState ->
|
||||
val modifiedIndex = successState.chapters.indexOfFirst { it.chapter.id == item.chapter.id }
|
||||
if (modifiedIndex < 0) return@updateSuccessState successState
|
||||
|
||||
val oldItem = successState.chapters[modifiedIndex]
|
||||
if ((oldItem.selected && selected) || (!oldItem.selected && !selected)) return@updateSuccessState successState
|
||||
|
||||
val newChapters = successState.chapters.toMutableList().apply {
|
||||
val firstSelection = none { it.selected }
|
||||
var newItem = removeAt(modifiedIndex)
|
||||
add(modifiedIndex, newItem.copy(selected = selected))
|
||||
|
||||
if (selected && userSelected && fromLongPress) {
|
||||
if (firstSelection) {
|
||||
selectedPositions[0] = modifiedIndex
|
||||
selectedPositions[1] = modifiedIndex
|
||||
} else {
|
||||
// Try to select the items in-between when possible
|
||||
val range: IntRange
|
||||
if (modifiedIndex < selectedPositions[0]) {
|
||||
range = modifiedIndex + 1 until selectedPositions[0]
|
||||
selectedPositions[0] = modifiedIndex
|
||||
} else if (modifiedIndex > selectedPositions[1]) {
|
||||
range = (selectedPositions[1] + 1) until modifiedIndex
|
||||
selectedPositions[1] = modifiedIndex
|
||||
} else {
|
||||
// Just select itself
|
||||
range = IntRange.EMPTY
|
||||
}
|
||||
|
||||
range.forEach {
|
||||
newItem = removeAt(it)
|
||||
add(it, newItem.copy(selected = true))
|
||||
}
|
||||
}
|
||||
} else if (userSelected && !fromLongPress) {
|
||||
if (!selected) {
|
||||
if (modifiedIndex == selectedPositions[0]) {
|
||||
selectedPositions[0] = indexOfFirst { it.selected }
|
||||
} else if (modifiedIndex == selectedPositions[1]) {
|
||||
selectedPositions[1] = indexOfLast { it.selected }
|
||||
}
|
||||
} else {
|
||||
if (modifiedIndex < selectedPositions[0]) {
|
||||
selectedPositions[0] = modifiedIndex
|
||||
} else if (modifiedIndex > selectedPositions[1]) {
|
||||
selectedPositions[1] = modifiedIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
successState.copy(chapters = newChapters)
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleAllSelection(selected: Boolean) {
|
||||
updateSuccessState { successState ->
|
||||
val newChapters = successState.chapters.map {
|
||||
it.copy(selected = selected)
|
||||
}
|
||||
selectedPositions[0] = -1
|
||||
selectedPositions[1] = -1
|
||||
successState.copy(chapters = newChapters)
|
||||
}
|
||||
}
|
||||
|
||||
fun invertSelection() {
|
||||
updateSuccessState { successState ->
|
||||
val newChapters = successState.chapters.map {
|
||||
it.copy(selected = !it.selected)
|
||||
}
|
||||
selectedPositions[0] = -1
|
||||
selectedPositions[1] = -1
|
||||
successState.copy(chapters = newChapters)
|
||||
}
|
||||
}
|
||||
|
||||
// Chapters list - end
|
||||
|
||||
// Track sheet - start
|
||||
@ -962,6 +1054,8 @@ data class ChapterItem(
|
||||
val chapterTitleString: String,
|
||||
val dateUploadString: String?,
|
||||
val readProgressString: String?,
|
||||
|
||||
val selected: Boolean = false,
|
||||
) {
|
||||
val isDownloaded = downloadState == Download.State.DOWNLOADED
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user