feat: add badge to UpdateScreen header (#798)

* feat: add badge to UpdateScreen header

* optimize code
This commit is contained in:
Cuong-Tran 2025-03-27 00:43:43 +07:00 committed by GitHub
parent e477f22426
commit ee5b3d0d92
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 47 deletions

View file

@ -259,7 +259,7 @@ private fun UpdatesBottomBar(
}
sealed interface UpdatesUiModel {
data class Header(val date: LocalDate) : UpdatesUiModel
data class Header(val date: LocalDate, val mangaCount: Int) : UpdatesUiModel
open class Item(open val item: UpdatesItem, open val isExpandable: Boolean = false) : UpdatesUiModel
// KMK -->
/** The first [Item] in a group of chapters from same manga */

View file

@ -39,7 +39,6 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.relativeDateText
import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.presentation.manga.components.ChapterDownloadIndicator
import eu.kanade.presentation.manga.components.DotSeparatorText
@ -51,9 +50,9 @@ 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.groupByDateAndManga
import mihon.feature.upcoming.DateHeading
import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ListGroupHeader
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@ -109,13 +108,14 @@ internal fun LazyListScope.updatesUiItems(
) { item ->
when (item) {
is UpdatesUiModel.Header -> {
ListGroupHeader(
// KMK -->
DateHeading(
modifier = Modifier.animateItemFastScroll()
// KMK -->
.padding(top = MaterialTheme.padding.extraSmall),
// KMK <--
text = relativeDateText(item.date),
date = item.date,
mangaCount = item.mangaCount,
)
// KMK <--
}
is UpdatesUiModel.Item -> {
val updatesItem = item.item
@ -183,9 +183,11 @@ private fun UpdatesUiItem(
expanded: Boolean,
collapseToggle: (key: String) -> Unit,
usePanoramaCover: Boolean,
coverRatio: MutableFloatState = remember { mutableFloatStateOf(1f) },
// KMK <--
modifier: Modifier = Modifier,
// KMK -->
coverRatio: MutableFloatState = remember { mutableFloatStateOf(1f) },
// KMK <--
) {
val haptic = LocalHapticFeedback.current
val textAlpha = if (update.read) DISABLED_ALPHA else 1f

View file

@ -8,7 +8,6 @@ import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import eu.kanade.core.preference.asState
import eu.kanade.core.util.addOrRemove
import eu.kanade.core.util.insertSeparators
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.presentation.updates.UpdatesUiModel
@ -406,46 +405,30 @@ class UpdatesScreenModel(
fun getUiModel(): List<UpdatesUiModel> {
// KMK -->
var lastMangaId = -1L
// KMK <--
return items
// KMK -->
.groupBy { it.update.dateFetch.toLocalDate() }
.flatMap { groupDate ->
groupDate.value.groupBy { it.update.mangaId }
.flatMap { (date, mangas) ->
val header = UpdatesUiModel.Header(date, mangas.size)
val mangaItems = mangas
.groupBy { it.update.mangaId }
.values
.flatMap { mangaChapters ->
val list = mangaChapters.value
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) }
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 ->
if (chapter.update.mangaId != lastMangaId) {
lastMangaId = chapter.update.mangaId
UpdatesUiModel.Leader(chapter, isExpandable)
} else {
UpdatesUiModel.Item(chapter, isExpandable)
}
}
}
}
// KMK <--
.insertSeparators { before, after ->
val beforeDate = before?.item?.update?.dateFetch?.toLocalDate()
val afterDate = after?.item?.update?.dateFetch?.toLocalDate()
when {
beforeDate != afterDate && afterDate != null -> UpdatesUiModel.Header(afterDate)
// Return null to avoid adding a separator between two items.
else -> null
}
}
// KMK -->
.map {
if (it is UpdatesUiModel.Header) {
lastMangaId = -1L
it
} else {
if ((it as UpdatesUiModel.Item).item.update.mangaId != lastMangaId) {
lastMangaId = it.item.update.mangaId
UpdatesUiModel.Leader(it.item, it.isExpandable)
} else {
it
}
}
listOf(header) + mangaItems
}
// KMK <--
}

View file

@ -176,13 +176,16 @@ private fun UpcomingToolbar(
}
@Composable
private fun DateHeading(
internal fun DateHeading(
date: LocalDate,
mangaCount: Int,
// KMK -->
modifier: Modifier = Modifier,
// KMK <--
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth(),
modifier = modifier.fillMaxWidth(),
) {
Text(
text = relativeDateText(date),