feat(updates-screen): Swipe actions for chapter updates (#915)

* feat(updates-screen): Swipe actions for chapter updates

* Smaller cover size & add option to hide cover images (debug menu)

* Correctly apply passed-in modifier

* Memoize `getSwipeAction(...)`` invocations with Compose’s `remember` (keyed on the action and state) to avoid recreating those objects on every recomposition
This commit is contained in:
Cuong-Tran 2025-05-16 14:05:49 +07:00 committed by GitHub
parent a3abccb34b
commit c52de8c472
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 336 additions and 179 deletions

View file

@ -27,10 +27,12 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.manga.components.MangaCoverHide
import eu.kanade.presentation.manga.components.RatioSwitchToPanorama
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.util.lang.toTimestampString
import exh.debug.DebugToggles
import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
@ -63,37 +65,46 @@ fun HistoryItem(
val coverIsWide = coverRatio.floatValue <= RatioSwitchToPanorama
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second
if (usePanoramaCover && coverIsWide) {
MangaCover.Panorama(
if (DebugToggles.HIDE_COVER_IMAGE_ONLY_SHOW_COLOR.enabled) {
MangaCoverHide.Book(
modifier = Modifier.fillMaxHeight(),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
// KMK <--
)
} else {
// KMK <--
MangaCover.Book(
modifier = Modifier.fillMaxHeight(),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
if (usePanoramaCover && coverIsWide) {
MangaCover.Panorama(
modifier = Modifier.fillMaxHeight(),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
// KMK <--
)
} else {
// KMK <--
)
MangaCover.Book(
modifier = Modifier.fillMaxHeight(),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
// KMK <--
)
}
}
Column(
modifier = Modifier

View file

@ -268,7 +268,7 @@ private fun Modifier.commonClickable(
),
)
private val IndicatorSize = 26.dp
internal val IndicatorSize = 26.dp
private val IndicatorPadding = 2.dp
// To match composable parameter name when used later

View file

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmark
@ -68,27 +69,36 @@ fun MangaChapterListItem(
onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
modifier: Modifier = Modifier,
) {
val start = getSwipeAction(
action = chapterSwipeStartAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = MaterialTheme.colorScheme.primaryContainer,
onSwipe = { onChapterSwipe(chapterSwipeStartAction) },
)
val end = getSwipeAction(
action = chapterSwipeEndAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = MaterialTheme.colorScheme.primaryContainer,
onSwipe = { onChapterSwipe(chapterSwipeEndAction) },
)
// KMK -->
val swipeBackground = MaterialTheme.colorScheme.primaryContainer
val swipeStart = remember(chapterSwipeStartAction, read, bookmark, downloadStateProvider()) {
// KMK <--
getSwipeAction(
action = chapterSwipeStartAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = swipeBackground,
onSwipe = { onChapterSwipe(chapterSwipeStartAction) },
)
}
// KMK -->
val swipeEnd = remember(chapterSwipeEndAction, read, bookmark, downloadStateProvider()) {
// KMK <--
getSwipeAction(
action = chapterSwipeEndAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = swipeBackground,
onSwipe = { onChapterSwipe(chapterSwipeEndAction) },
)
}
SwipeableActionsBox(
modifier = Modifier.clipToBounds(),
startActions = listOfNotNull(start),
endActions = listOfNotNull(end),
startActions = listOfNotNull(swipeStart),
endActions = listOfNotNull(swipeEnd),
swipeThreshold = swipeActionThreshold,
backgroundUntilSwipeThreshold = MaterialTheme.colorScheme.surfaceContainerLowest,
) {
@ -200,7 +210,7 @@ fun MangaChapterListItem(
}
}
private fun getSwipeAction(
internal fun getSwipeAction(
action: LibraryPreferences.ChapterSwipeAction,
read: Boolean,
bookmark: Boolean,
@ -243,7 +253,9 @@ private fun swipeAction(
return me.saket.swipe.SwipeAction(
icon = {
Icon(
modifier = Modifier.padding(16.dp),
modifier = Modifier
.padding(horizontal = 16.dp)
.size(IndicatorSize),
imageVector = icon,
tint = contentColorFor(background),
contentDescription = null,
@ -255,4 +267,4 @@ private fun swipeAction(
)
}
private val swipeActionThreshold = 56.dp
internal val swipeActionThreshold = 56.dp

View file

@ -30,6 +30,10 @@ import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImagePainter
import coil3.compose.SubcomposeAsyncImage
import eu.kanade.presentation.manga.components.MangaCover.Companion.COVER_TEMPLATE_SIZE_BIG
import eu.kanade.presentation.manga.components.MangaCover.Companion.COVER_TEMPLATE_SIZE_MEDIUM
import eu.kanade.presentation.manga.components.MangaCover.Companion.COVER_TEMPLATE_SIZE_NORMAL
import eu.kanade.presentation.manga.components.MangaCover.Size
import eu.kanade.tachiyomi.R
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.asMangaCover
@ -175,6 +179,7 @@ enum class MangaCoverHide(private val ratio: Float) {
bgColor: Color? = CoverPlaceholderColor,
/** onBackground color, which used for loading/error indicator */
@ColorInt tint: Int? = null,
size: Size = Size.Normal,
) {
val modifierColored = modifier
.aspectRatio(ratio)
@ -198,7 +203,13 @@ enum class MangaCoverHide(private val ratio: Float) {
imageVector = ImageVector.vectorResource(R.drawable.ic_baseline_menu_book_24),
contentDescription = contentDescription,
modifier = Modifier
.size(32.dp)
.size(
when (size) {
Size.Big -> COVER_TEMPLATE_SIZE_BIG
Size.Medium -> COVER_TEMPLATE_SIZE_MEDIUM
else -> COVER_TEMPLATE_SIZE_NORMAL
},
)
.align(Alignment.Center),
colorFilter = ColorFilter.tint(
tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor,

View file

@ -32,6 +32,7 @@ import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.i18n.kmk.KMR
import tachiyomi.presentation.core.components.FastScrollLazyColumn
@ -60,6 +61,11 @@ fun UpdateScreen(
onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit,
onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit,
onMultiDeleteClicked: (List<UpdatesItem>) -> Unit,
// KMK -->
updateSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
updateSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onUpdateSwipe: (UpdatesItem, LibraryPreferences.ChapterSwipeAction) -> Unit,
// KMK <--
onUpdateSelected: (UpdatesItem, /* KMK --> */ UpdatesScreenModel.UpdateSelectionOptions /* KMK <-- */) -> Unit,
onOpenChapter: (UpdatesItem) -> Unit,
// KMK -->
@ -143,6 +149,11 @@ fun UpdateScreen(
onClickCover = onClickCover,
onClickUpdate = onOpenChapter,
onDownloadChapter = onDownloadChapter,
// KMK -->
updateSwipeStartAction = updateSwipeStartAction,
updateSwipeEndAction = updateSwipeEndAction,
onUpdateSwipe = onUpdateSwipe,
// KMK <--
)
}
}

View file

@ -37,6 +37,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalDensity
@ -48,7 +49,10 @@ import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.presentation.manga.components.ChapterDownloadIndicator
import eu.kanade.presentation.manga.components.DotSeparatorText
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.manga.components.MangaCoverHide
import eu.kanade.presentation.manga.components.RatioSwitchToPanorama
import eu.kanade.presentation.manga.components.getSwipeAction
import eu.kanade.presentation.manga.components.swipeActionThreshold
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.relativeTimeSpanString
import eu.kanade.tachiyomi.R
@ -56,7 +60,10 @@ 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 exh.debug.DebugToggles
import me.saket.swipe.SwipeableActionsBox
import mihon.feature.upcoming.DateHeading
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
@ -96,6 +103,11 @@ internal fun LazyListScope.updatesUiItems(
onClickCover: (UpdatesItem) -> Unit,
onClickUpdate: (UpdatesItem) -> Unit,
onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit,
// KMK -->
updateSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
updateSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onUpdateSwipe: (UpdatesItem, LibraryPreferences.ChapterSwipeAction) -> Unit,
// KMK <--
) {
items(
items = uiModels,
@ -191,6 +203,11 @@ internal fun LazyListScope.updatesUiItems(
downloadStateProvider = updatesItem.downloadStateProvider,
downloadProgressProvider = updatesItem.downloadProgressProvider,
// KMK -->
updateSwipeStartAction = updateSwipeStartAction,
updateSwipeEndAction = updateSwipeEndAction,
onUpdateSwipe = {
onUpdateSwipe(updatesItem, it)
},
isLeader = isLeader,
isExpandable = item.isExpandable,
expanded = isExpanded,
@ -217,6 +234,9 @@ private fun UpdatesUiItem(
downloadStateProvider: () -> Download.State,
downloadProgressProvider: () -> Int,
// KMK -->
updateSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
updateSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onUpdateSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
isLeader: Boolean,
isExpandable: Boolean,
expanded: Boolean,
@ -231,152 +251,193 @@ private fun UpdatesUiItem(
val haptic = LocalHapticFeedback.current
val textAlpha = if (update.read) DISABLED_ALPHA else 1f
Row(
modifier = modifier
.selectedBackground(selected)
.combinedClickable(
onClick = onClick,
onLongClick = {
onLongClick()
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
},
)
.padding(
// KMK -->
vertical = if (isLeader) MaterialTheme.padding.extraSmall else 0.dp,
// KMK <--
horizontal = MaterialTheme.padding.medium,
),
verticalAlignment = Alignment.CenterVertically,
) {
// KMK -->
val mangaCover = update.coverData
val coverIsWide = coverRatio.floatValue <= RatioSwitchToPanorama
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second
if (isLeader) {
if (usePanoramaCover && coverIsWide) {
MangaCover.Panorama(
modifier = Modifier
.padding(top = MaterialTheme.padding.small)
.width(UpdateItemPanoramaWidth),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
// KMK <--
)
} else {
// KMK <--
MangaCover.Book(
modifier = Modifier
// KMK -->
.padding(top = MaterialTheme.padding.small)
.width(UpdateItemWidth),
// KMK <--
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
)
}
} else {
Box(
modifier = Modifier
.width(if (usePanoramaCover && coverIsWide) UpdateItemPanoramaWidth else UpdateItemWidth),
)
// KMK <--
}
// KMK -->
val swipeBackground = MaterialTheme.colorScheme.primaryContainer
val swipeStart = remember(updateSwipeStartAction, update.read, update.bookmark, downloadStateProvider()) {
getSwipeAction(
action = updateSwipeStartAction,
read = update.read,
bookmark = update.bookmark,
downloadState = downloadStateProvider(),
background = swipeBackground,
onSwipe = { onUpdateSwipe(updateSwipeStartAction) },
)
}
val swipeEnd = remember(updateSwipeEndAction, update.read, update.bookmark, downloadStateProvider()) {
getSwipeAction(
action = updateSwipeEndAction,
read = update.read,
bookmark = update.bookmark,
downloadState = downloadStateProvider(),
background = swipeBackground,
onSwipe = { onUpdateSwipe(updateSwipeEndAction) },
)
}
Column(
SwipeableActionsBox(
modifier = modifier.clipToBounds(),
startActions = listOfNotNull(swipeStart),
endActions = listOfNotNull(swipeEnd),
swipeThreshold = swipeActionThreshold,
backgroundUntilSwipeThreshold = MaterialTheme.colorScheme.surfaceContainerLowest,
) {
// KMK <--
Row(
modifier = Modifier
.padding(horizontal = MaterialTheme.padding.medium)
.weight(1f),
.selectedBackground(selected)
.combinedClickable(
onClick = onClick,
onLongClick = {
onLongClick()
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
},
)
.padding(top = if (isLeader) MaterialTheme.padding.small else 0.dp)
.padding(
// KMK -->
vertical = if (isLeader) MaterialTheme.padding.extraSmall else 0.dp,
// KMK <--
horizontal = MaterialTheme.padding.medium,
),
verticalAlignment = Alignment.CenterVertically,
) {
// KMK -->
val mangaCover = update.coverData
val coverIsWide = coverRatio.floatValue <= RatioSwitchToPanorama
val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) }
val onBgColor = mangaCover.dominantCoverColors?.second
if (isLeader) {
// KMK <--
Text(
text = update.mangaTitle,
maxLines = 1,
style = MaterialTheme.typography.bodyMedium,
color = LocalContentColor.current.copy(alpha = textAlpha),
overflow = TextOverflow.Ellipsis,
if (DebugToggles.HIDE_COVER_IMAGE_ONLY_SHOW_COLOR.enabled) {
MangaCoverHide.Book(
modifier = Modifier
.width(UpdateItemWidth),
bgColor = bgColor ?: (MaterialTheme.colorScheme.surface.takeIf { selected }),
tint = onBgColor,
size = MangaCover.Size.Medium,
)
} else {
if (usePanoramaCover && coverIsWide) {
MangaCover.Panorama(
modifier = Modifier
.width(UpdateItemPanoramaWidth),
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
// KMK <--
)
} else {
// KMK <--
MangaCover.Book(
modifier = Modifier
// KMK -->
.width(UpdateItemWidth),
// KMK <--
data = mangaCover,
onClick = onClickCover,
// KMK -->
bgColor = bgColor,
tint = onBgColor,
size = MangaCover.Size.Medium,
onCoverLoaded = { _, result ->
val image = result.result.image
coverRatio.floatValue = image.height.toFloat() / image.width
},
)
}
}
} else {
Box(
modifier = Modifier
.width(if (usePanoramaCover && coverIsWide) UpdateItemPanoramaWidth else UpdateItemWidth),
)
// KMK <--
}
Row(verticalAlignment = Alignment.CenterVertically) {
var textHeight by remember { mutableIntStateOf(0) }
if (!update.read) {
Icon(
imageVector = Icons.Filled.Circle,
contentDescription = stringResource(MR.strings.unread),
modifier = Modifier
.height(8.dp)
.padding(end = 4.dp),
tint = MaterialTheme.colorScheme.primary,
)
}
if (update.bookmark) {
Icon(
imageVector = Icons.Filled.Bookmark,
contentDescription = stringResource(MR.strings.action_filter_bookmarked),
modifier = Modifier
.sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }),
tint = MaterialTheme.colorScheme.primary,
)
Spacer(modifier = Modifier.width(2.dp))
}
Text(
text = update.chapterName,
maxLines = 1,
style = MaterialTheme.typography.bodySmall,
color = LocalContentColor.current.copy(alpha = textAlpha),
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
modifier = Modifier
.weight(weight = 1f, fill = false),
)
if (readProgress != null) {
DotSeparatorText()
Column(
modifier = Modifier
.padding(horizontal = MaterialTheme.padding.medium)
.weight(1f),
) {
// KMK -->
if (isLeader) {
// KMK <--
Text(
text = readProgress,
text = update.mangaTitle,
maxLines = 1,
color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
style = MaterialTheme.typography.bodyMedium,
color = LocalContentColor.current.copy(alpha = textAlpha),
overflow = TextOverflow.Ellipsis,
)
}
}
}
// KMK -->
if (isLeader && isExpandable) {
CollapseButton(
expanded = expanded,
collapseToggle = { collapseToggle(update.groupByDateAndManga()) },
Row(verticalAlignment = Alignment.CenterVertically) {
var textHeight by remember { mutableIntStateOf(0) }
if (!update.read) {
Icon(
imageVector = Icons.Filled.Circle,
contentDescription = stringResource(MR.strings.unread),
modifier = Modifier
.height(8.dp)
.padding(end = 4.dp),
tint = MaterialTheme.colorScheme.primary,
)
}
if (update.bookmark) {
Icon(
imageVector = Icons.Filled.Bookmark,
contentDescription = stringResource(MR.strings.action_filter_bookmarked),
modifier = Modifier
.sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }),
tint = MaterialTheme.colorScheme.primary,
)
Spacer(modifier = Modifier.width(2.dp))
}
Text(
text = update.chapterName,
maxLines = 1,
style = MaterialTheme.typography.bodySmall,
color = LocalContentColor.current.copy(alpha = textAlpha),
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
modifier = Modifier
.weight(weight = 1f, fill = false),
)
if (readProgress != null) {
DotSeparatorText()
Text(
text = readProgress,
maxLines = 1,
color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
overflow = TextOverflow.Ellipsis,
)
}
}
}
// KMK -->
if (isLeader && isExpandable) {
CollapseButton(
expanded = expanded,
collapseToggle = { collapseToggle(update.groupByDateAndManga()) },
)
}
// KMK <--
ChapterDownloadIndicator(
enabled = onDownloadChapter != null,
modifier = Modifier.padding(start = 4.dp),
downloadStateProvider = downloadStateProvider,
downloadProgressProvider = downloadProgressProvider,
onClick = { onDownloadChapter?.invoke(it) },
)
}
// KMK <--
ChapterDownloadIndicator(
enabled = onDownloadChapter != null,
modifier = Modifier.padding(start = 4.dp),
downloadStateProvider = downloadStateProvider,
downloadProgressProvider = downloadProgressProvider,
onClick = { onDownloadChapter?.invoke(it) },
)
}
}
@ -412,6 +473,6 @@ fun CollapseButton(
private val IndicatorSize = MaterialTheme.padding.large
private val UpdateItemPanoramaWidth = 126.dp // Book cover
private val UpdateItemWidth = 56.dp
private val UpdateItemPanoramaWidth = 108.dp // Book cover
private val UpdateItemWidth = 48.dp
// KMK <--

View file

@ -432,6 +432,52 @@ class UpdatesScreenModel(
)
}
}
val chapterSwipeStartAction by libraryPreferences.swipeToEndAction().asState(screenModelScope)
val chapterSwipeEndAction by libraryPreferences.swipeToStartAction().asState(screenModelScope)
/**
* @throws IllegalStateException if the swipe action is [LibraryPreferences.ChapterSwipeAction.Disabled]
*/
fun updateSwipe(updateItem: UpdatesItem, swipeAction: LibraryPreferences.ChapterSwipeAction) {
screenModelScope.launch {
executeUpdateSwipeAction(updateItem, swipeAction)
}
}
/**
* @throws IllegalStateException if the swipe action is [LibraryPreferences.ChapterSwipeAction.Disabled]
*/
private fun executeUpdateSwipeAction(
updateItem: UpdatesItem,
swipeAction: LibraryPreferences.ChapterSwipeAction,
) {
val update = updateItem.update
when (swipeAction) {
LibraryPreferences.ChapterSwipeAction.ToggleRead -> {
markUpdatesRead(listOf(updateItem), !update.read)
}
LibraryPreferences.ChapterSwipeAction.ToggleBookmark -> {
bookmarkUpdates(listOf(updateItem), !update.bookmark)
}
LibraryPreferences.ChapterSwipeAction.Download -> {
val downloadAction = when (updateItem.downloadStateProvider()) {
Download.State.ERROR,
Download.State.NOT_DOWNLOADED,
-> ChapterDownloadAction.START_NOW
Download.State.QUEUE,
Download.State.DOWNLOADING,
-> ChapterDownloadAction.CANCEL
Download.State.DOWNLOADED -> ChapterDownloadAction.DELETE
}
downloadChapters(
items = listOf(updateItem),
action = downloadAction,
)
}
LibraryPreferences.ChapterSwipeAction.Disabled -> throw IllegalStateException()
}
}
// KMK <--
@Immutable

View file

@ -88,6 +88,11 @@ data object UpdatesTab : Tab {
onMultiBookmarkClicked = screenModel::bookmarkUpdates,
onMultiMarkAsReadClicked = screenModel::markUpdatesRead,
onMultiDeleteClicked = screenModel::showConfirmDeleteChapters,
// KMK -->
updateSwipeStartAction = screenModel.chapterSwipeStartAction,
updateSwipeEndAction = screenModel.chapterSwipeEndAction,
onUpdateSwipe = screenModel::updateSwipe,
// KMK <--
onUpdateSelected = screenModel::toggleSelection,
onOpenChapter = {
val intent = ReaderActivity.newIntent(context, it.update.mangaId, it.update.chapterId)