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 16:54:03 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-22 16:54:03 +0000
commit39cca1cb3650edb066f57d0891b1873b767b1c43 (patch)
tree0a966be07f4d4440cfad0f4eeb8bffd1617f3ea0 /app/src/main/java/org/terst/feedreader/data/Daos.kt
parent52d7877fccd60a1dae33d877ba6aa765dc098a52 (diff)
Fix Unread/startup crash; add reader-mode toggle and swipe navigation
- Root cause of the reported crashes: observeUnread/observeByFeed/ observeSaved used SELECT *, pulling feedContentHtml/extractedContent (potentially large per-article blobs) just to render a list row. With 107 feeds worth of real articles this blows past Android's CursorWindow/memory limits, scaling with item count -- and since Unread is now the landing screen, it crashed at startup too. Added an ArticleListItem projection excluding the heavy content columns; list queries now only select what a row actually renders. - FilterRuleEngine now takes a small Titled interface (title/feedId) instead of the full entity, so it works with both ArticleEntity and the new lighter projection. - Reader-mode toggle: a button in the reader to manually switch between feed-provided content and Readability-extracted full text, matching Inoreader's full-text-view toggle (previously only an automatic fallback when feed content was thin). - Swipe between articles: ReaderScreen now wraps a HorizontalPager over a snapshot of the current list's article-id order, so swiping moves to the next/previous article. Snapshotted rather than live, since marking an article read would otherwise drop it from the live Unread query mid-swipe and shift every later page underneath the user. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
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.kt35
1 files changed, 29 insertions, 6 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 2240ff4..f80cce3 100644
--- a/app/src/main/java/org/terst/feedreader/data/Daos.kt
+++ b/app/src/main/java/org/terst/feedreader/data/Daos.kt
@@ -31,20 +31,43 @@ interface FeedDao {
data class FeedUnreadCount(val feedId: String, val count: Int)
+// A projection excluding feedContentHtml/extractedContent -- the potentially
+// large per-article content blobs that list views (row title/date/thumbnail)
+// never need. Selecting them for every row of a big result set is what was
+// crashing the Unread view once real feed volume (107 feeds worth of
+// articles) hit it: Android's per-row/CursorWindow limits are sized for
+// "many small rows," not "many rows each carrying a full article's HTML."
+data class ArticleListItem(
+ val id: String,
+ override val feedId: String?,
+ override val title: String,
+ val link: String,
+ val author: String?,
+ val publishedAt: Long?,
+ val imageUrl: String?,
+ val isRead: Boolean,
+ val isSaved: Boolean,
+ val stashArtifactId: String?,
+ val createdAt: Long
+) : Titled
+
+private const val ARTICLE_LIST_COLUMNS =
+ "id, feedId, title, link, author, publishedAt, imageUrl, isRead, isSaved, stashArtifactId, createdAt"
+
@Dao
interface ArticleDao {
// Unread-first, newest-first -- the default "what's new" view across every feed.
- @Query("SELECT * FROM articles WHERE isRead = 0 ORDER BY publishedAt DESC")
- fun observeUnread(): Flow<List<ArticleEntity>>
+ @Query("SELECT $ARTICLE_LIST_COLUMNS FROM articles WHERE isRead = 0 ORDER BY publishedAt DESC")
+ fun observeUnread(): Flow<List<ArticleListItem>>
@Query("SELECT feedId, COUNT(*) as count FROM articles WHERE isRead = 0 AND feedId IS NOT NULL GROUP BY feedId")
fun observeUnreadCounts(): Flow<List<FeedUnreadCount>>
- @Query("SELECT * FROM articles WHERE feedId = :feedId ORDER BY publishedAt DESC")
- fun observeByFeed(feedId: String): Flow<List<ArticleEntity>>
+ @Query("SELECT $ARTICLE_LIST_COLUMNS FROM articles WHERE feedId = :feedId ORDER BY publishedAt DESC")
+ fun observeByFeed(feedId: String): Flow<List<ArticleListItem>>
- @Query("SELECT * FROM articles WHERE isSaved = 1 ORDER BY createdAt DESC")
- fun observeSaved(): Flow<List<ArticleEntity>>
+ @Query("SELECT $ARTICLE_LIST_COLUMNS FROM articles WHERE isSaved = 1 ORDER BY createdAt DESC")
+ fun observeSaved(): Flow<List<ArticleListItem>>
@Query("SELECT * FROM articles WHERE id = :id")
suspend fun getById(id: String): ArticleEntity?