Improve Update view's UI & order (always show latest unread chapter first) (#743)

* adjust Updates view item height & caret animation

* reorder Updates view to always show unread chapter first

* revert to Book cover

* reorder read chapter showng latest chapter first

* adjust carret position
This commit is contained in:
Cuong-Tran 2025-03-03 13:02:05 +07:00
parent 84f3826fe8
commit 249c4bb0c3
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
2 changed files with 39 additions and 20 deletions

View file

@ -1,5 +1,8 @@
package eu.kanade.presentation.updates package eu.kanade.presentation.updates
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -15,8 +18,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmark import androidx.compose.material.icons.filled.Bookmark
import androidx.compose.material.icons.filled.Circle import androidx.compose.material.icons.filled.Circle
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
@ -46,6 +47,7 @@ import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.manga.components.RatioSwitchToPanorama import eu.kanade.presentation.manga.components.RatioSwitchToPanorama
import eu.kanade.presentation.util.animateItemFastScroll import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.relativeTimeSpanString import eu.kanade.presentation.util.relativeTimeSpanString
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.updates.UpdatesItem import eu.kanade.tachiyomi.ui.updates.UpdatesItem
import eu.kanade.tachiyomi.ui.updates.groupByDateAndManga import eu.kanade.tachiyomi.ui.updates.groupByDateAndManga
@ -200,7 +202,7 @@ private fun UpdatesUiItem(
) )
.padding( .padding(
// KMK --> // KMK -->
vertical = MaterialTheme.padding.extraSmall, vertical = if (isLeader) MaterialTheme.padding.extraSmall else 0.dp,
// KMK <-- // KMK <--
horizontal = MaterialTheme.padding.medium, horizontal = MaterialTheme.padding.medium,
), ),
@ -262,6 +264,9 @@ private fun UpdatesUiItem(
.padding(horizontal = MaterialTheme.padding.medium) .padding(horizontal = MaterialTheme.padding.medium)
.weight(1f), .weight(1f),
) { ) {
// KMK -->
if (isLeader) {
// KMK <--
Text( Text(
text = update.mangaTitle, text = update.mangaTitle,
maxLines = 1, maxLines = 1,
@ -269,6 +274,7 @@ private fun UpdatesUiItem(
color = LocalContentColor.current.copy(alpha = textAlpha), color = LocalContentColor.current.copy(alpha = textAlpha),
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
}
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
var textHeight by remember { mutableIntStateOf(0) } var textHeight by remember { mutableIntStateOf(0) }
@ -342,12 +348,16 @@ fun CollapseButton(
) { ) {
Box( Box(
modifier = modifier modifier = modifier
.size(IndicatorSize), .size(IndicatorSize + MaterialTheme.padding.extraSmall),
contentAlignment = Alignment.Center, contentAlignment = Alignment.TopCenter,
) { ) {
IconButton(onClick = { collapseToggle() }) { IconButton(
onClick = { collapseToggle() },
modifier = Modifier.size(IndicatorSize),
) {
val image = AnimatedImageVector.animatedVectorResource(R.drawable.anim_caret_down)
Icon( Icon(
imageVector = if (expanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, painter = rememberAnimatedVectorPainter(image, !expanded),
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) )
@ -355,7 +365,8 @@ fun CollapseButton(
} }
} }
private val IndicatorSize = 18.dp private val IndicatorSize = MaterialTheme.padding.large
private val UpdateItemPanoramaWidth = 126.dp
private val UpdateItemPanoramaWidth = 126.dp // Book cover
private val UpdateItemWidth = 56.dp private val UpdateItemWidth = 56.dp
// KMK <-- // KMK <--

View file

@ -408,15 +408,22 @@ class UpdatesScreenModel(
// KMK --> // KMK -->
var lastMangaId = -1L var lastMangaId = -1L
// KMK <-- // KMK <--
return items.groupBy { it.update.dateFetch.toLocalDate() } return items
// KMK -->
.groupBy { it.update.dateFetch.toLocalDate() }
.flatMap { groupDate -> .flatMap { groupDate ->
groupDate.value.groupBy { it.update.mangaId } groupDate.value.groupBy { it.update.mangaId }
.flatMap { groupManga -> .flatMap { mangaChapters ->
val list = groupManga.value val list = mangaChapters.value
list.sortedBy { it.update.dateFetch } val (read, unread) = list.partition { it.update.read }
(
unread.sortedBy { it.update.dateFetch } +
read.sortedByDescending { it.update.dateFetch }
)
.map { UpdatesUiModel.Item(it, list.size > 1) } .map { UpdatesUiModel.Item(it, list.size > 1) }
} }
} }
// KMK <--
.insertSeparators { before, after -> .insertSeparators { before, after ->
val beforeDate = before?.item?.update?.dateFetch?.toLocalDate() val beforeDate = before?.item?.update?.dateFetch?.toLocalDate()
val afterDate = after?.item?.update?.dateFetch?.toLocalDate() val afterDate = after?.item?.update?.dateFetch?.toLocalDate()
@ -469,5 +476,6 @@ data class UpdatesItem(
} }
// KMK --> // KMK -->
/** String to identify which manga's update on which day it is collapsing */
fun UpdatesWithRelations.groupByDateAndManga() = "${dateFetch.toLocalDate().toEpochDay()}-$mangaId" fun UpdatesWithRelations.groupByDateAndManga() = "${dateFetch.toLocalDate().toEpochDay()}-$mangaId"
// KMK <-- // KMK <--