From 55cdfc8fab6ddd1052593f8fd53dbb5bf730cc63 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sat, 22 Aug 2026 01:13:30 +0000 Subject: 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. --- app/src/main/java/org/terst/feedreader/data/AppDatabase.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/org/terst/feedreader/data/AppDatabase.kt') diff --git a/app/src/main/java/org/terst/feedreader/data/AppDatabase.kt b/app/src/main/java/org/terst/feedreader/data/AppDatabase.kt index 7f33439..2fd5816 100644 --- a/app/src/main/java/org/terst/feedreader/data/AppDatabase.kt +++ b/app/src/main/java/org/terst/feedreader/data/AppDatabase.kt @@ -12,7 +12,7 @@ private const val TAG = "FeedMigration" @Database( entities = [FeedEntity::class, ArticleEntity::class, FilterRuleEntity::class], - version = 9, + version = 10, exportSchema = false ) abstract class AppDatabase : RoomDatabase() { @@ -258,6 +258,16 @@ abstract class AppDatabase : RoomDatabase() { } } + // v10: added ArticleEntity.readAt (epoch millis, null while unread). Plain nullable + // ADD COLUMN is safe here the way v2/v3's were -- no column is being removed or + // renamed, so there's nothing for Room's exact-match post-migration validation to + // trip on (see v4's comment above for what DOES require a full rebuild). + private val MIGRATION_9_10 = object : Migration(9, 10) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE articles ADD COLUMN readAt INTEGER") + } + } + fun get(context: Context): AppDatabase = instance ?: synchronized(this) { instance ?: Room.databaseBuilder( context.applicationContext, @@ -265,7 +275,7 @@ abstract class AppDatabase : RoomDatabase() { "feedreader.db" ).addMigrations( MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, - MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9 + MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, MIGRATION_9_10 ).build().also { instance = it } } } -- cgit v1.2.3