From 0ff40d3d389ed24b863e3ee330cbb5d5c34d547d Mon Sep 17 00:00:00 2001 From: AdiEcho <30563671+AdiEcho@users.noreply.github.com> Date: Tue, 2 Dec 2025 01:01:25 +0800 Subject: [PATCH] Add show reading progress function (#2768) * Add reading progress * Optimize reading progress state collection and display logic * Optimize reading progress state collection and add page display to downloads * Enhance download progress display and settings * Optimize state collection for read progress, revert arrangement * Revert arrangement changement --- .../main/kotlin/com/hippo/ehviewer/Settings.kt | 1 + .../com/hippo/ehviewer/ui/main/DownloadCard.kt | 12 +++++++++++- .../com/hippo/ehviewer/ui/main/GalleryInfo.kt | 18 ++++++++++++++++-- .../ehviewer/ui/screen/DownloadsScreen.kt | 3 +++ .../ehviewer/ui/screen/FavoritesScreen.kt | 3 +++ .../ehviewer/ui/screen/GalleryListScreen.kt | 3 +++ .../hippo/ehviewer/ui/screen/HistoryScreen.kt | 2 ++ .../com/hippo/ehviewer/ui/settings/EhScreen.kt | 5 +++++ .../commonMain/moko-resources/base/strings.xml | 2 ++ .../moko-resources/zh-rCN/strings.xml | 2 ++ 10 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt index 5f1cc4487..3a90f4acb 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt @@ -82,6 +82,7 @@ object Settings : DataStorePreferences(null) { val detailSize = intPref("detail_size_2", 0) val thumbColumns = intPref("thumb_columns", 3) val showGalleryPages = boolPref("show_gallery_pages", true) + val showReadingProgress = boolPref("show_reading_progress", false) val showVoteStatus = boolPref("show_vote_status", false) val showComments = boolPref("show_gallery_comments", true) val commentThreshold = intPref("comment_threshold", -100) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/DownloadCard.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/DownloadCard.kt index 038a99068..13b9cb017 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/DownloadCard.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/DownloadCard.kt @@ -26,6 +26,7 @@ import androidx.compose.material3.ShapeDefaults import androidx.compose.material3.Text import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.movableContentOf import androidx.compose.runtime.mutableIntStateOf @@ -45,6 +46,7 @@ import com.ehviewer.core.ui.component.CrystalCard import com.ehviewer.core.ui.component.GalleryListCardRating import com.ehviewer.core.ui.util.TransitionsVisibilityScope import com.ehviewer.core.ui.util.listThumbGenerator +import com.hippo.ehviewer.EhDB import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.download.DownloadManager @@ -60,6 +62,7 @@ fun DownloadCard( onStop: () -> Unit, info: DownloadInfo, selectMode: Boolean, + showProgress: Boolean, modifier: Modifier = Modifier, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) = CrystalCard(modifier = modifier, onClick = onClick, onLongClick = onLongClick, interactionSource = interactionSource) { @@ -99,7 +102,14 @@ fun DownloadCard( DownloadInfo.STATE_NONE -> stringResource(R.string.download_state_none) DownloadInfo.STATE_WAIT -> stringResource(R.string.download_state_wait) DownloadInfo.STATE_FAILED -> if (info.legacy <= 0) stateFailed else stateFailed2 - DownloadInfo.STATE_FINISH -> stringResource(R.string.download_state_finish) + DownloadInfo.STATE_FINISH -> { + if (showProgress) { + val readProgress by remember { EhDB.getReadProgressFlow(info.gid) }.collectAsState(0) + if (readProgress > 0) "${readProgress + 1}/${info.pages}P" else "${info.pages}P" + } else { + "${info.pages}P" + } + } else -> null // The item has been removed and this will be disposed soon } ProvideTextStyle(MaterialTheme.typography.labelLarge) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryInfo.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryInfo.kt index ee9db035e..a6c25818d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryInfo.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/GalleryInfo.kt @@ -25,6 +25,7 @@ import androidx.compose.material3.ShapeDefaults import androidx.compose.material3.Text import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember @@ -46,6 +47,7 @@ import com.ehviewer.core.ui.component.GalleryListCardRating import com.ehviewer.core.ui.util.SharedElementBox import com.ehviewer.core.ui.util.TransitionsVisibilityScope import com.ehviewer.core.ui.util.listThumbGenerator +import com.hippo.ehviewer.EhDB import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.download.DownloadManager @@ -58,6 +60,7 @@ fun GalleryInfoListItem( onLongClick: () -> Unit, info: GalleryInfo, showPages: Boolean, + showProgress: Boolean, modifier: Modifier = Modifier, isInFavScene: Boolean = false, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, @@ -126,7 +129,12 @@ fun GalleryInfoListItem( Text(text = it) } if (info.pages != 0 && showPages) { - Text(text = "${info.pages}P") + val readProgress = if (showProgress) { + remember { EhDB.getReadProgressFlow(info.gid) }.collectAsState(0).value + } else { + 0 + } + Text(text = if (readProgress > 0) "${readProgress + 1}/${info.pages}P" else "${info.pages}P") } } Row(verticalAlignment = Alignment.CenterVertically) { @@ -154,6 +162,7 @@ fun GalleryInfoGridItem( modifier: Modifier = Modifier, showLanguage: Boolean = true, showPages: Boolean = true, + showProgress: Boolean = true, showFavoriteStatus: Boolean = true, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) = ElevatedCard( @@ -191,7 +200,12 @@ fun GalleryInfoGridItem( ) { val shouldShowLanguage = showLanguage && info.simpleLanguage != null if (showPages && info.pages > 0) { - Text(text = "${info.pages}") + val readProgress = if (showProgress) { + remember { EhDB.getReadProgressFlow(info.gid) }.collectAsState(0).value + } else { + 0 + } + Text(text = if (readProgress > 0) "${readProgress + 1}/${info.pages}" else "${info.pages}") if (shouldShowLanguage) { Spacer(modifier = Modifier.width(4.dp)) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt index 8c3d92b8d..109de6562 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt @@ -147,6 +147,7 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) = var gridView by Settings.gridView.asMutableState() var sortMode by Settings.downloadSortMode.asMutableState() val filterMode by Settings.downloadFilterMode.collectAsState { DownloadsFilterMode.from(it) } + val showProgress by Settings.showReadingProgress.collectAsState() var filterState by rememberSerializable { mutableStateOf(DownloadsFilterState(filterMode, Settings.recentDownloadLabel.value)) } var invalidateKey by rememberSaveable { mutableStateOf(false) } var isLoading by rememberSaveable { mutableStateOf(true) } @@ -596,6 +597,7 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) = info = info, modifier = Modifier.thenIf(animateItems) { animateItem() }, showLanguage = false, + showProgress = showProgress, ) } } @@ -635,6 +637,7 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) = onStop = { launchIO { DownloadManager.stopDownload(info.gid) } }, info = info, selectMode = selectMode, + showProgress = showProgress, modifier = Modifier.height(height), interactionSource = interactionSource, ) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt index 5e37d2331..c989a0446 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt @@ -201,6 +201,7 @@ fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator, v val listMode by Settings.listMode.collectAsState() val height by collectListThumbSizeAsState() val showPages by Settings.showGalleryPages.collectAsState() + val showProgress by Settings.showReadingProgress.collectAsState() val searchBarConnection = remember { val slop = ViewConfiguration.get(contextOf()).scaledTouchSlop val topPaddingPx = with(density) { contentPadding.calculateTopPadding().roundToPx() } @@ -245,6 +246,7 @@ fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator, v }, info = info, showPages = showPages, + showProgress = showProgress, modifier = Modifier.height(height), isInFavScene = true, interactionSource = interactionSource, @@ -274,6 +276,7 @@ fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator, v }, info = info, showPages = showPages, + showProgress = showProgress, showFavoriteStatus = false, interactionSource = interactionSource, ) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryListScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryListScreen.kt index fc7303d51..e182601b8 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryListScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryListScreen.kt @@ -507,6 +507,7 @@ fun AnimatedVisibilityScope.GalleryListScreen( ) { contentPadding -> val height by collectListThumbSizeAsState() val showPages by Settings.showGalleryPages.collectAsState() + val showProgress by Settings.showReadingProgress.collectAsState() val searchBarConnection = remember { val slop = ViewConfiguration.get(contextOf()).scaledTouchSlop val topPaddingPx = with(density) { contentPadding.calculateTopPadding().roundToPx() } @@ -535,6 +536,7 @@ fun AnimatedVisibilityScope.GalleryListScreen( onLongClick = { launch { doGalleryInfoAction(info) } }, info = info, showPages = showPages, + showProgress = showProgress, modifier = Modifier.height(height), ) }, @@ -545,6 +547,7 @@ fun AnimatedVisibilityScope.GalleryListScreen( onLongClick = { launch { doGalleryInfoAction(info) } }, info = info, showPages = showPages, + showProgress = showProgress, ) }, searchBarOffsetY = { searchBarOffsetY }, diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/HistoryScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/HistoryScreen.kt index 478b8f706..7c13753d0 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/HistoryScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/HistoryScreen.kt @@ -136,6 +136,7 @@ fun AnimatedVisibilityScope.HistoryScreen(navigator: DestinationsNavigator) = Sc val marginH = dimensionResource(id = com.hippo.ehviewer.R.dimen.gallery_list_margin_h) val cardHeight by collectListThumbSizeAsState() val showPages by Settings.showGalleryPages.collectAsState() + val showProgress by Settings.showReadingProgress.collectAsState() FastScrollLazyColumn( modifier = Modifier.nestedScroll(searchBarConnection).fillMaxSize(), contentPadding = paddingValues, @@ -161,6 +162,7 @@ fun AnimatedVisibilityScope.HistoryScreen(navigator: DestinationsNavigator) = Sc onLongClick = { launch { doGalleryInfoAction(info) } }, info = info, showPages = showPages, + showProgress = showProgress, modifier = Modifier.height(cardHeight).padding(horizontal = marginH), ) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt index d3dcd3f0d..0182348f0 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt @@ -214,6 +214,11 @@ fun AnimatedVisibilityScope.EhScreen(navigator: DestinationsNavigator) = Screen( summary = stringResource(id = R.string.settings_eh_show_gallery_pages_summary), state = Settings.showGalleryPages.asMutableState(), ) + SwitchPreference( + title = stringResource(id = R.string.settings_eh_show_reading_progress), + summary = stringResource(id = R.string.settings_eh_show_reading_progress_summary), + state = Settings.showReadingProgress.asMutableState(), + ) SwitchPreference( title = stringResource(id = R.string.settings_eh_show_vote_status), state = Settings.showVoteStatus.asMutableState(), diff --git a/core/i18n/src/commonMain/moko-resources/base/strings.xml b/core/i18n/src/commonMain/moko-resources/base/strings.xml index a53c333a7..d134586e4 100644 --- a/core/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/core/i18n/src/commonMain/moko-resources/base/strings.xml @@ -317,6 +317,8 @@ Require enabling Japanese Title in Settings on EHentai website Show gallery pages Display the number of pages in the gallery list + Show reading progress + Display reading progress in gallery list Show tag vote status Show gallery comments Show comments on the gallery details page diff --git a/core/i18n/src/commonMain/moko-resources/zh-rCN/strings.xml b/core/i18n/src/commonMain/moko-resources/zh-rCN/strings.xml index bc847995f..6244d7eb7 100644 --- a/core/i18n/src/commonMain/moko-resources/zh-rCN/strings.xml +++ b/core/i18n/src/commonMain/moko-resources/zh-rCN/strings.xml @@ -301,6 +301,8 @@ 需同时在 EHentai 网站设置中启用 Japanese Title 显示画廊页数 在画廊列表中显示页数 + 显示阅读进度 + 在画廊列表中显示阅读进度 显示标签投票状态 显示画廊评论 在画廊详情页中显示评论