summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/data/Daos.kt
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-22 20:37:41 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-22 20:37:41 +0000
commit34b663c6e75a2c360de154418dafb8f616b546a1 (patch)
tree300f7b5a2344925832d13f634abe16470ce668ae /app/src/main/java/org/terst/feedreader/data/Daos.kt
parentee019c91f66b6ba35b7295ea01220c6c13819b1c (diff)
Fix extraction regression on kottke; add Older view, mark-read-from-here
- ReaderExtractor: the un-hide-before-extracting fix (for soft paywalls like West Hawaii Today) was unconditional -- it also un-hid normal, legitimately-collapsed chrome (kottke's footer/membership notice), which Readability then folded into the result alongside the real article. Reported live with a screenshot showing the extracted content wrapped in site footer boilerplate. Now tries the normal (hidden-respecting) pass first and only falls back to the un-hide pass if that came back thin (<500 chars), keeping whichever pass actually found more text. Verified live: the same kottke article now stays clean and stable (no delayed switch to the footer version). - New Unread/Older split: the default Unread view is now clamped to the last 72 hours (RECENT_WINDOW_MS); the rest of the unread backlog moved to a new "Older" view (new FeedListScreen row, ArticleDao.observeUnread now takes a cutoff, observeOlderUnread/observeUnreadCount/ observeOlderUnreadCount added). Undated articles are kept in the main Unread view rather than silently dropped from both. Verified live: 150 recent / 1172 older, summing to the prior combined total. - "Mark read from here": long-press an article row to mark it and everything older in that same filtered list as read in one batch (re-added ArticleDao.markReadBatch, this time as an explicit, confirmed action -- not the implicit on-scroll version that was reverted earlier). Verified live: confirmed a 147-article batch: the tapped article and older were marked read, newer ones above it were not. - BACKLOG.md: added a YouTube-embeds note (JS is off in the reader WebView, so embeds currently show broken -- rough shape is a tap-to-play thumbnail rather than turning JS on for third-party content).
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/data/Daos.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/data/Daos.kt37
1 files changed, 33 insertions, 4 deletions
diff --git a/app/src/main/java/org/terst/feedreader/data/Daos.kt b/app/src/main/java/org/terst/feedreader/data/Daos.kt
index d089885..22f1d22 100644
--- a/app/src/main/java/org/terst/feedreader/data/Daos.kt
+++ b/app/src/main/java/org/terst/feedreader/data/Daos.kt
@@ -61,10 +61,34 @@ private const val ARTICLE_LIST_FROM = "articles LEFT JOIN feeds ON articles.feed
@Dao
interface ArticleDao {
- // Unread-first, newest-first -- the default "what's new" view across every feed.
- @Query("SELECT $ARTICLE_LIST_COLUMNS FROM $ARTICLE_LIST_FROM WHERE articles.isRead = 0 ORDER BY articles.publishedAt DESC")
- fun observeUnread(): Flow<List<ArticleListItem>>
-
+ // The default "what's new" view -- clamped to the last RECENT_WINDOW_MS (see
+ // MainActivity) so a backlog of hundreds of older unread items doesn't bury
+ // what's actually new. Undated articles (publishedAt failed to parse) are kept
+ // here rather than silently dropped from both views.
+ @Query(
+ "SELECT $ARTICLE_LIST_COLUMNS FROM $ARTICLE_LIST_FROM " +
+ "WHERE articles.isRead = 0 AND (articles.publishedAt IS NULL OR articles.publishedAt >= :cutoff) " +
+ "ORDER BY articles.publishedAt DESC"
+ )
+ fun observeUnread(cutoff: Long): Flow<List<ArticleListItem>>
+
+ // The rest of the unread backlog, older than the cutoff -- its own view rather
+ // than mixed into the main one.
+ @Query(
+ "SELECT $ARTICLE_LIST_COLUMNS FROM $ARTICLE_LIST_FROM " +
+ "WHERE articles.isRead = 0 AND articles.publishedAt IS NOT NULL AND articles.publishedAt < :cutoff " +
+ "ORDER BY articles.publishedAt DESC"
+ )
+ fun observeOlderUnread(cutoff: Long): Flow<List<ArticleListItem>>
+
+ @Query("SELECT COUNT(*) FROM articles WHERE isRead = 0 AND (publishedAt IS NULL OR publishedAt >= :cutoff)")
+ fun observeUnreadCount(cutoff: Long): Flow<Int>
+
+ @Query("SELECT COUNT(*) FROM articles WHERE isRead = 0 AND publishedAt IS NOT NULL AND publishedAt < :cutoff")
+ fun observeOlderUnreadCount(cutoff: Long): Flow<Int>
+
+ // Per-feed unread badge counts in the feed list -- deliberately NOT time-clamped,
+ // so a feed's number reflects its whole backlog regardless of the Unread/Older split.
@Query("SELECT feedId, COUNT(*) as count FROM articles WHERE isRead = 0 AND feedId IS NOT NULL GROUP BY feedId")
fun observeUnreadCounts(): Flow<List<FeedUnreadCount>>
@@ -89,6 +113,11 @@ interface ArticleDao {
@Query("UPDATE articles SET isRead = :read WHERE id = :id")
suspend fun setRead(id: String, read: Boolean)
+ // Explicit bulk action ("mark read from here") -- batched per confirmed tap,
+ // never called implicitly (e.g. by scrolling).
+ @Query("UPDATE articles SET isRead = 1 WHERE id IN (:ids)")
+ suspend fun markReadBatch(ids: List<String>)
+
@Query("UPDATE articles SET isRead = 1 WHERE feedId = :feedId")
suspend fun markAllReadForFeed(feedId: String)