summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-08-22 01:13:30 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-08-22 01:13:30 +0000
commit55cdfc8fab6ddd1052593f8fd53dbb5bf730cc63 (patch)
tree2c44a9e63e89dd925c98b0606c5c1e6e29f48d10 /app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
parenta5f728648dda46e84959a4568a3f04d5cc7bb11f (diff)
Keep a just-read article visible (and Previous-reachable) until the next fetch
The Unread/Older views are live Room Flow queries filtered on isRead = 0, so marking an article read (which only happens on Next/Previous, not on open) makes it vanish from the list the instant Room re-emits -- mid-scroll, or from underneath the reader's own Previous button, which re-queries this same flow to find its neighbors. Concretely: Next from C to D marks C read and prunes it from the live list; Previous from D then can't find C anymore, and jumps past it to whatever was unread before C. A misclick or the in-flight prune could cost you the article you meant to keep reading. Adds ArticleEntity.readAt (set whenever isRead flips true, cleared on explicit "mark unread"); observeUnread/observeOlderUnread now match "isRead = 0 OR readAt >= sinceFetch", where sinceFetch is Settings.lastFetchAt -- the same durable signal the new-articles snackbar already uses. A read article now lingers (shown dimmed via the existing showReadState styling) until the next real fetch actually completes, not the next DB write, and Previous/Next read from the same still-inclusive query so stepping back to what you just read finds it right where it was.
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt15
1 files changed, 10 insertions, 5 deletions
diff --git a/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt b/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
index 4317073..4c74e5a 100644
--- a/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
+++ b/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
@@ -57,6 +57,7 @@ import kotlinx.coroutines.launch
import org.terst.feedreader.data.AppDatabase
import org.terst.feedreader.data.ArticleEntity
import org.terst.feedreader.data.FeedEntity
+import org.terst.feedreader.data.Settings
import org.terst.feedreader.data.ensureStandaloneArticle
import org.terst.feedreader.data.saveArticleToStash
import org.terst.feedreader.data.setReaderModeEnabled
@@ -96,6 +97,7 @@ fun ReaderScreen(
) {
val context = LocalContext.current
val db = remember { AppDatabase.get(context) }
+ val settings = remember { Settings(context) }
val scope = rememberCoroutineScope()
var previousId by remember(articleId) { mutableStateOf<String?>(null) }
@@ -104,11 +106,14 @@ fun ReaderScreen(
// Looked up fresh every time articleId changes (i.e. every navigation), not cached --
// always reflects the CURRENT live Unread/Older/Saved/feed ordering, so there's no
// stale-snapshot state to fall out of sync with anything, on rotation or otherwise.
+ // sinceFetch (Settings.lastFetchAt) is what keeps a just-read article from vanishing
+ // out of this same list before Previous/Next can find it -- see observeUnread's comment.
LaunchedEffect(articleId) {
val cutoff = System.currentTimeMillis() - RECENT_WINDOW_MS
+ val sinceFetch = settings.lastFetchAt.first()
val flow = when (feedId) {
- UNREAD_FEED_ID -> db.articleDao().observeUnread(cutoff)
- OLDER_FEED_ID -> db.articleDao().observeOlderUnread(cutoff)
+ UNREAD_FEED_ID -> db.articleDao().observeUnread(cutoff, sinceFetch)
+ OLDER_FEED_ID -> db.articleDao().observeOlderUnread(cutoff, sinceFetch)
SAVED_FEED_ID -> db.articleDao().observeSaved()
else -> db.articleDao().observeByFeed(feedId)
}
@@ -124,14 +129,14 @@ fun ReaderScreen(
fun goToPreviousArticle() {
val target = previousId ?: return
scope.launch {
- db.articleDao().setRead(articleId, true)
+ db.articleDao().setRead(articleId, true, System.currentTimeMillis())
onNavigateToArticle(target)
}
}
fun goToNextArticle() {
val target = nextId ?: return
scope.launch {
- db.articleDao().setRead(articleId, true)
+ db.articleDao().setRead(articleId, true, System.currentTimeMillis())
onNavigateToArticle(target)
}
}
@@ -345,7 +350,7 @@ private fun ReaderContent(
val a = currentArticle ?: return@DropdownMenuItem
article = a.copy(isRead = false)
scope.launch {
- db.articleDao().setRead(a.id, false)
+ db.articleDao().setRead(a.id, false, null)
snackbarHostState.showSnackbar("Marked unread")
}
}