From b46608ac156775a6e67fe9513007b8edf5269ab6 Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Mon, 30 Dec 2024 17:13:16 +0700 Subject: [PATCH 1/3] collapsible grouping Updates --- .../presentation/updates/UpdatesScreen.kt | 23 +++++++- .../presentation/updates/UpdatesUiItem.kt | 53 +++++++++++++++++++ .../ui/updates/UpdatesScreenModel.kt | 38 +++++++++++++ .../kanade/tachiyomi/ui/updates/UpdatesTab.kt | 3 ++ 4 files changed, 115 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt index d966437a14..8d4e9213f1 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt @@ -27,6 +27,7 @@ import eu.kanade.presentation.manga.components.MangaBottomActionMenu import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.ui.updates.UpdatesItem import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel +import eu.kanade.tachiyomi.ui.updates.groupByDateAndManga import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -59,6 +60,9 @@ fun UpdateScreen( onMultiDeleteClicked: (List) -> Unit, onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit, onOpenChapter: (UpdatesItem) -> Unit, + // KMK --> + collapseToggle: (key: String) -> Unit, + // KMK <-- ) { BackHandler(enabled = state.selectionMode, onBack = { onSelectAll(false) }) @@ -116,7 +120,18 @@ fun UpdateScreen( updatesLastUpdatedItem(lastUpdated) updatesUiItems( - uiModels = state.getUiModel(), + uiModels = state.getUiModel() + // KMK --> + .filter { + when (it) { + is UpdatesUiModel.Header, is UpdatesUiModel.Leader -> true + is UpdatesUiModel.Item -> + state.expandedState.contains(it.item.update.groupByDateAndManga()) + } + }, + expandedState = state.expandedState, + collapseToggle = collapseToggle, + // KMK <-- selectionMode = state.selectionMode, // SY --> preserveReadingPosition = preserveReadingPosition, @@ -222,5 +237,9 @@ private fun UpdatesBottomBar( sealed interface UpdatesUiModel { data class Header(val date: LocalDate) : UpdatesUiModel - data class Item(val item: UpdatesItem) : UpdatesUiModel + open class Item(open val item: UpdatesItem) : UpdatesUiModel + // KMK --> + /** The first [Item] in a group of chapters from same manga */ + data class Leader(override val item: UpdatesItem) : Item(item) + // KMK <-- } diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt index 5229ccea19..c38a8fe2e0 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight 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.foundation.layout.width import androidx.compose.foundation.lazy.LazyListScope @@ -15,7 +16,10 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Bookmark 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.IconButton import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -42,6 +46,7 @@ import eu.kanade.presentation.util.animateItemFastScroll import eu.kanade.presentation.util.relativeTimeSpanString import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.ui.updates.UpdatesItem +import eu.kanade.tachiyomi.ui.updates.groupByDateAndManga import tachiyomi.domain.updates.model.UpdatesWithRelations import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.ListGroupHeader @@ -69,6 +74,10 @@ internal fun LazyListScope.updatesLastUpdatedItem( internal fun LazyListScope.updatesUiItems( uiModels: List, + // KMK --> + expandedState: Set, + collapseToggle: (key: String) -> Unit, + // KMK <-- selectionMode: Boolean, // SY --> preserveReadingPosition: Boolean, @@ -135,6 +144,11 @@ internal fun LazyListScope.updatesUiItems( }.takeIf { !selectionMode }, downloadStateProvider = updatesItem.downloadStateProvider, downloadProgressProvider = updatesItem.downloadProgressProvider, + // KMK --> + isLeader = item is UpdatesUiModel.Leader, + expanded = expandedState.contains(updatesItem.update.groupByDateAndManga()), + collapseToggle = collapseToggle, + // KMK <-- ) } } @@ -153,6 +167,11 @@ private fun UpdatesUiItem( // Download Indicator downloadStateProvider: () -> Download.State, downloadProgressProvider: () -> Int, + // KMK --> + isLeader: Boolean, + expanded: Boolean, + collapseToggle: (key: String) -> Unit, + // KMK <-- modifier: Modifier = Modifier, ) { val haptic = LocalHapticFeedback.current @@ -247,6 +266,15 @@ private fun UpdatesUiItem( } } + // KMK --> + if (isLeader) { + CollapseButton( + expanded = expanded, + collapseToggle = { collapseToggle(update.groupByDateAndManga()) }, + ) + } + // KMK <-- + ChapterDownloadIndicator( enabled = onDownloadChapter != null, modifier = Modifier.padding(start = 4.dp), @@ -256,3 +284,28 @@ private fun UpdatesUiItem( ) } } + +// KMK --> +@Composable +fun CollapseButton( + expanded: Boolean, + collapseToggle: () -> Unit, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .size(IndicatorSize), + contentAlignment = Alignment.Center, + ) { + IconButton(onClick = { collapseToggle() }) { + Icon( + imageVector = if (expanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + ) + } + } +} + +private val IndicatorSize = 18.dp +// KMK <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt index ea03a19ea8..e9ae354fc4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt @@ -23,6 +23,7 @@ import exh.source.EXH_SOURCE_ID import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.mutate import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow @@ -372,16 +373,34 @@ class UpdatesScreenModel( libraryPreferences.newUpdatesCount().set(0) } + // KMK --> + fun toggleExpandedState(key: String) { + mutableState.update { + it.copy( + expandedState = it.expandedState.toMutableSet().apply { + if (it.expandedState.contains(key)) remove(key) else add(key) + }, + ) + } + } + // KMK <-- + @Immutable data class State( val isLoading: Boolean = true, val items: PersistentList = persistentListOf(), + // KMK --> + val expandedState: Set = persistentSetOf(), + // KMK <-- val dialog: Dialog? = null, ) { val selected = items.filter { it.selected } val selectionMode = selected.isNotEmpty() fun getUiModel(): List { + // KMK --> + var lastMangaId = -1L + // KMK <-- return items .map { UpdatesUiModel.Item(it) } .insertSeparators { before, after -> @@ -393,6 +412,21 @@ class UpdatesScreenModel( 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) + } else { + it + } + } + } + // KMK <-- } } @@ -419,3 +453,7 @@ data class UpdatesItem( } // SY <-- } + +// KMK --> +fun UpdatesWithRelations.groupByDateAndManga() = "${dateFetch.toLocalDate().toEpochDay()}-$mangaId" +// KMK <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesTab.kt index 4dbb405a41..99592ed308 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesTab.kt @@ -94,6 +94,9 @@ data object UpdatesTab : Tab { context.startActivity(intent) }, onCalendarClicked = { navigator.push(UpcomingScreen()) }, + // KMK --> + collapseToggle = screenModel::toggleExpandedState, + // KMK <-- ) val onDismissDialog = { screenModel.setDialog(null) } From ad6e4f7922d433c36d52bfdff8f6c92e6b66316a Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Mon, 30 Dec 2024 18:22:13 +0700 Subject: [PATCH 2/3] - Reverse chapter order - Only show cover & marker on the first one --- .../manga/components/MangaCover.kt | 20 +++++---- .../presentation/updates/UpdatesScreen.kt | 4 +- .../presentation/updates/UpdatesUiItem.kt | 42 +++++++++++++------ .../ui/updates/UpdatesScreenModel.kt | 13 ++++-- 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaCover.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaCover.kt index a0e6924c50..74d760587a 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaCover.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaCover.kt @@ -99,9 +99,9 @@ enum class MangaCover(val ratio: Float) { modifier = Modifier .size( when (size) { - Size.Big -> 16.dp - Size.Medium -> 24.dp - else -> 32.dp + Size.Big -> COVER_TEMPLATE_SIZE_BIG + Size.Medium -> COVER_TEMPLATE_SIZE_MEDIUM + else -> COVER_TEMPLATE_SIZE_NORMAL }, ) .align(Alignment.Center), @@ -122,9 +122,9 @@ enum class MangaCover(val ratio: Float) { modifier = Modifier .size( when (size) { - Size.Big -> 16.dp - Size.Medium -> 24.dp - else -> 32.dp + Size.Big -> COVER_TEMPLATE_SIZE_BIG + Size.Medium -> COVER_TEMPLATE_SIZE_MEDIUM + else -> COVER_TEMPLATE_SIZE_NORMAL }, ) .align(Alignment.Center), @@ -149,6 +149,12 @@ enum class MangaCover(val ratio: Float) { contentScale = scale, ) } + + companion object { + val COVER_TEMPLATE_SIZE_BIG = 16.dp + val COVER_TEMPLATE_SIZE_MEDIUM = 24.dp + val COVER_TEMPLATE_SIZE_NORMAL = 32.dp + } } enum class MangaCoverHide(private val ratio: Float) { @@ -200,7 +206,7 @@ enum class MangaCoverHide(private val ratio: Float) { } } -internal val RatioSwitchToPanorama = 0.75f +internal const val RatioSwitchToPanorama = 0.75f internal val CoverPlaceholderColor = Color(0x1F888888) internal val CoverPlaceholderOnBgColor = Color(0x8F888888) diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt index 8d4e9213f1..01bc51eb27 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt @@ -237,9 +237,9 @@ private fun UpdatesBottomBar( sealed interface UpdatesUiModel { data class Header(val date: LocalDate) : UpdatesUiModel - open class Item(open val item: UpdatesItem) : 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 */ - data class Leader(override val item: UpdatesItem) : Item(item) + data class Leader(override val item: UpdatesItem, override val isExpandable: Boolean) : Item(item) // KMK <-- } diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt index c38a8fe2e0..c30e3cd6ff 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -146,6 +147,7 @@ internal fun LazyListScope.updatesUiItems( downloadProgressProvider = updatesItem.downloadProgressProvider, // KMK --> isLeader = item is UpdatesUiModel.Leader, + isExpandable = item.isExpandable, expanded = expandedState.contains(updatesItem.update.groupByDateAndManga()), collapseToggle = collapseToggle, // KMK <-- @@ -169,6 +171,7 @@ private fun UpdatesUiItem( downloadProgressProvider: () -> Int, // KMK --> isLeader: Boolean, + isExpandable: Boolean, expanded: Boolean, collapseToggle: (key: String) -> Unit, // KMK <-- @@ -195,19 +198,32 @@ private fun UpdatesUiItem( val mangaCover = update.coverData val bgColor = mangaCover.dominantCoverColors?.first?.let { Color(it) } val onBgColor = mangaCover.dominantCoverColors?.second - // KMK <-- - MangaCover.Square( - modifier = Modifier - .padding(vertical = 6.dp) - .fillMaxHeight(), - data = mangaCover, - onClick = onClickCover, - // KMK --> - bgColor = bgColor, - tint = onBgColor, - size = MangaCover.Size.Big, + if (isLeader) { // KMK <-- - ) + MangaCover.Square( + modifier = Modifier + .padding(vertical = 6.dp) + .fillMaxHeight(), + data = mangaCover, + onClick = onClickCover, + // KMK --> + bgColor = bgColor, + tint = onBgColor, + size = MangaCover.Size.Big, + ) + } else { + Box( + modifier = Modifier + .padding(vertical = 6.dp) + .fillMaxHeight(), + ) { + Box( + modifier = Modifier + .aspectRatio(1f), + ) + } + // KMK <-- + } Column( modifier = Modifier @@ -267,7 +283,7 @@ private fun UpdatesUiItem( } // KMK --> - if (isLeader) { + if (isLeader && isExpandable) { CollapseButton( expanded = expanded, collapseToggle = { collapseToggle(update.groupByDateAndManga()) }, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt index e9ae354fc4..4ebbe02233 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt @@ -401,8 +401,15 @@ class UpdatesScreenModel( // KMK --> var lastMangaId = -1L // KMK <-- - return items - .map { UpdatesUiModel.Item(it) } + return items.groupBy { it.update.dateFetch.toLocalDate() } + .flatMap { groupDate -> + groupDate.value.groupBy { it.update.mangaId } + .flatMap { groupManga -> + val list = groupManga.value + list.sortedBy { it.update.dateFetch } + .map { UpdatesUiModel.Item(it, list.size > 1) } + } + } .insertSeparators { before, after -> val beforeDate = before?.item?.update?.dateFetch?.toLocalDate() val afterDate = after?.item?.update?.dateFetch?.toLocalDate() @@ -420,7 +427,7 @@ class UpdatesScreenModel( } else { if ((it as UpdatesUiModel.Item).item.update.mangaId != lastMangaId) { lastMangaId = it.item.update.mangaId - UpdatesUiModel.Leader(it.item) + UpdatesUiModel.Leader(it.item, it.isExpandable) } else { it } From 30f167c6713ec75ab6b6b81256bd1f4e2eac0304 Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Mon, 30 Dec 2024 19:04:03 +0700 Subject: [PATCH 3/3] - Bigger cover & support panorama view --- .../presentation/updates/UpdatesScreen.kt | 23 +++++ .../presentation/updates/UpdatesUiItem.kt | 84 +++++++++++++------ 2 files changed, 82 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt index 01bc51eb27..15897da79c 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt @@ -6,8 +6,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.CalendarMonth import androidx.compose.material.icons.outlined.FlipToBack +import androidx.compose.material.icons.outlined.Panorama import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material.icons.outlined.SelectAll +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.TopAppBarScrollBehavior @@ -32,6 +34,7 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.delay import kotlinx.coroutines.launch import tachiyomi.i18n.MR +import tachiyomi.i18n.kmk.KMR import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.material.PullRefresh import tachiyomi.presentation.core.components.material.Scaffold @@ -64,6 +67,9 @@ fun UpdateScreen( collapseToggle: (key: String) -> Unit, // KMK <-- ) { + // KMK --> + val usePanoramaCover = remember { mutableStateOf(false) } + // KMK <-- BackHandler(enabled = state.selectionMode, onBack = { onSelectAll(false) }) Scaffold( @@ -76,6 +82,10 @@ fun UpdateScreen( onInvertSelection = { onInvertSelection() }, onCancelActionMode = { onSelectAll(false) }, scrollBehavior = scrollBehavior, + // KMK --> + usePanoramaCover = usePanoramaCover.value, + usePanoramaCoverClick = { usePanoramaCover.value = !usePanoramaCover.value }, + // KMK ) }, bottomBar = { @@ -131,6 +141,7 @@ fun UpdateScreen( }, expandedState = state.expandedState, collapseToggle = collapseToggle, + usePanoramaCover = usePanoramaCover.value, // KMK <-- selectionMode = state.selectionMode, // SY --> @@ -158,6 +169,10 @@ private fun UpdatesAppBar( onInvertSelection: () -> Unit, onCancelActionMode: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, + // KMK --> + usePanoramaCover: Boolean, + usePanoramaCoverClick: () -> Unit, + // KMK <-- modifier: Modifier = Modifier, ) { AppBar( @@ -166,6 +181,14 @@ private fun UpdatesAppBar( actions = { AppBarActions( persistentListOf( + // KMK --> + AppBar.Action( + title = stringResource(KMR.strings.action_panorama_cover), + icon = Icons.Outlined.Panorama, + iconTint = MaterialTheme.colorScheme.primary.takeIf { usePanoramaCover }, + onClick = usePanoramaCoverClick, + ), + // KMK <-- AppBar.Action( title = stringResource(MR.strings.action_view_upcoming), icon = Icons.Outlined.CalendarMonth, diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt index c30e3cd6ff..c7ec4a15eb 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt @@ -5,8 +5,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -25,7 +23,9 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableFloatState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -43,6 +43,7 @@ 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.RatioSwitchToPanorama import eu.kanade.presentation.util.animateItemFastScroll import eu.kanade.presentation.util.relativeTimeSpanString import eu.kanade.tachiyomi.data.download.model.Download @@ -78,6 +79,7 @@ internal fun LazyListScope.updatesUiItems( // KMK --> expandedState: Set, collapseToggle: (key: String) -> Unit, + usePanoramaCover: Boolean, // KMK <-- selectionMode: Boolean, // SY --> @@ -106,7 +108,10 @@ internal fun LazyListScope.updatesUiItems( when (item) { is UpdatesUiModel.Header -> { ListGroupHeader( - modifier = Modifier.animateItemFastScroll(), + modifier = Modifier.animateItemFastScroll() + // KMK --> + .padding(top = MaterialTheme.padding.extraSmall), + // KMK <-- text = relativeDateText(item.date), ) } @@ -150,6 +155,7 @@ internal fun LazyListScope.updatesUiItems( isExpandable = item.isExpandable, expanded = expandedState.contains(updatesItem.update.groupByDateAndManga()), collapseToggle = collapseToggle, + usePanoramaCover = usePanoramaCover, // KMK <-- ) } @@ -174,6 +180,8 @@ private fun UpdatesUiItem( isExpandable: Boolean, expanded: Boolean, collapseToggle: (key: String) -> Unit, + usePanoramaCover: Boolean, + coverRatio: MutableFloatState = remember { mutableFloatStateOf(1f) }, // KMK <-- modifier: Modifier = Modifier, ) { @@ -190,38 +198,62 @@ private fun UpdatesUiItem( haptic.performHapticFeedback(HapticFeedbackType.LongPress) }, ) - .height(56.dp) - .padding(horizontal = MaterialTheme.padding.medium), + .padding( + // KMK --> + vertical = MaterialTheme.padding.extraSmall, + // 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 <-- - MangaCover.Square( - modifier = Modifier - .padding(vertical = 6.dp) - .fillMaxHeight(), - data = mangaCover, - onClick = onClickCover, - // KMK --> - bgColor = bgColor, - tint = onBgColor, - size = MangaCover.Size.Big, - ) - } else { - Box( - modifier = Modifier - .padding(vertical = 6.dp) - .fillMaxHeight(), - ) { - Box( + 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 - .aspectRatio(1f), + // 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 <-- } @@ -324,4 +356,6 @@ fun CollapseButton( } private val IndicatorSize = 18.dp +private val UpdateItemPanoramaWidth = 126.dp +private val UpdateItemWidth = 56.dp // KMK <--