From 99c74f0df9a43e820b0c6c53d8fd7ab44684908f Mon Sep 17 00:00:00 2001 From: Josiah Campbell <9521010+jocmp@users.noreply.github.com> Date: Sun, 2 Aug 2026 17:18:56 -0500 Subject: [PATCH] Clamp scroll high water mark to list size --- .../capyreader/app/ui/articles/ArticleScreen.kt | 8 ++++++++ .../app/ui/articles/ArticleScreenViewModel.kt | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreen.kt b/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreen.kt index 796fb4174..a0a9c6ef0 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreen.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreen.kt @@ -293,6 +293,7 @@ fun ArticleScreen( articles = articles, scrollHighWaterMark = viewModel.scrollHighWaterMark, updateScrollHighWaterMark = viewModel::updateScrollHighWaterMark, + clampScrollHighWaterMark = viewModel::clampScrollHighWaterMark, markReadOnScroll = viewModel::markReadOnScroll, resetScrollBehaviorOffset = resetScrollBehaviorOffset, ) @@ -903,6 +904,7 @@ private fun MarkReadOnScroll( articles: LazyPagingItems
, scrollHighWaterMark: Int, updateScrollHighWaterMark: (Int) -> Unit, + clampScrollHighWaterMark: (Int) -> Unit, markReadOnScroll: (String) -> Unit, resetScrollBehaviorOffset: () -> Unit, ) { @@ -923,6 +925,12 @@ private fun MarkReadOnScroll( } } + LaunchedEffect(listState) { + snapshotFlow { articles.itemCount } + .distinctUntilChanged() + .collect(clampScrollHighWaterMark) + } + LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex - 1 diff --git a/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreenViewModel.kt b/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreenViewModel.kt index d498c0a54..b9af26556 100644 --- a/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreenViewModel.kt +++ b/app/src/main/java/com/capyreader/app/ui/articles/ArticleScreenViewModel.kt @@ -503,6 +503,21 @@ class ArticleScreenViewModel( } } + fun clampScrollHighWaterMark(itemCount: Int) { + val lastIndex = itemCount - 1 + + if (_scrollHighWaterMark <= lastIndex) { + return + } + + CapyLog.debug( + "scroll_high_water_mark:clamp", + mapOf("previous" to _scrollHighWaterMark, "new" to lastIndex) + ) + + _scrollHighWaterMark = lastIndex + } + fun resetScrollHighWaterMark() { CapyLog.debug( "scroll_high_water_mark:reset",