<feed xmlns='http://www.w3.org/2005/Atom'>
<title>feedreader.git/app/src/main/java/org/terst/feedreader/work, branch master</title>
<subtitle>FeeDreader — personal Android RSS reader
</subtitle>
<id>https://git.terst.org/feedreader.git/atom?h=master</id>
<link rel='self' href='https://git.terst.org/feedreader.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/'/>
<updated>2026-08-24T06:25:19+00:00</updated>
<entry>
<title>Pre-extract reader-mode content during feed fetch, not on article open</title>
<updated>2026-08-24T06:25:19+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-08-24T06:25:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=b299d57d6cc240381aed51f91e5a26f1e633d78d'/>
<id>urn:sha1:b299d57d6cc240381aed51f91e5a26f1e633d78d</id>
<content type='text'>
Feeds like West Hawaii Today need Readability to strip a paywall/
boilerplate wrapper, and that extraction was happening lazily the
first time an article was opened -- a hidden WebView load + JS eval
that left the reader sitting on a spinner. Do it for new articles from
reader-mode feeds right inside FeedFetchWorker.fetchOne instead, so
it's already cached (both on the launch fetch and the 5am morning
fetch) by the time the article is actually opened.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_017GMEkHeqKz6FLkmizowBTK
</content>
</entry>
<entry>
<title>Restore the 5am morning-fetch alarm</title>
<updated>2026-08-22T22:42:15+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-08-22T22:42:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=bc891a67802c837d77726f618e68c2ac84ea22d7'/>
<id>urn:sha1:bc891a67802c837d77726f618e68c2ac84ea22d7</id>
<content type='text'>
Reverts part of the previous commit: the explicit refresh button and
fetch-on-launch stay, but the user still wants the background 5am alarm so
articles are fresh before the app is opened, not just the periodic hourly
WorkManager job.
</content>
</entry>
<entry>
<title>Replace background auto-refresh with fetch-on-launch + explicit button</title>
<updated>2026-08-22T22:35:54+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-08-22T22:35:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=796b6dffd920ec9228430dcca1a1f4ec855ebfc7'/>
<id>urn:sha1:796b6dffd920ec9228430dcca1a1f4ec855ebfc7</id>
<content type='text'>
Periodic hourly WorkManager fetches and the 5am exact-alarm morning fetch
both refreshed without any visible trigger, which surprised the user more
than it helped. Refreshing now only ever happens on a fresh app launch
(MainActivity.onCreate) or an explicit tap of the new refresh button on the
Unread/Older screens' top bar (wired to the fetch-status state that was
already being computed there but never rendered). Drops MorningFetchReceiver
entirely along with its exact-alarm permission and boot receiver.
</content>
</entry>
<entry>
<title>Add a 5am morning-fetch alarm so articles are fresh before you open the app</title>
<updated>2026-08-22T01:08:22+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-08-22T01:08:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=7f324168464934d711953dc748fbc7c65eb88f4b'/>
<id>urn:sha1:7f324168464934d711953dc748fbc7c65eb88f4b</id>
<content type='text'>
FeedFetchWorker's periodic 60-minute WorkManager job can (and does)
get silently deferred for hours by Doze on an idle overnight device.
An exact alarm (setExactAndAllowWhileIdle) wakes the device at a fixed
5am to run a fetch, without requesting the much broader "ignore
battery optimizations" exemption -- battery optimization stays on
otherwise, just this one daily wake-up.

Android 12+ requires a one-time user grant for exact alarms (no in-app
permission dialog); MainActivity requests it via Settings if not
already granted, tracked across rotation via savedInstanceState so a
config change doesn't re-trigger the Settings screen. The alarm also
gets re-armed on BOOT_COMPLETED, since AlarmManager alarms don't
survive a device restart on their own.
</content>
</entry>
<entry>
<title>Concurrent feed fetching with durable fetch-result tracking</title>
<updated>2026-08-22T01:06:35+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-08-22T01:06:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=429594e6bc1069f7e7141060df3a0fd8bf63749b'/>
<id>urn:sha1:429594e6bc1069f7e7141060df3a0fd8bf63749b</id>
<content type='text'>
Feeds are fetched with bounded concurrency (semaphore of 8) instead of
strictly sequentially -- with 100+ subscriptions, one slow/stalling
server no longer delays every feed queued behind it. A process-local
mutex prevents the periodic and manual/alarm-triggered one-time
fetches (two different WorkManager unique-work names, so its own dedup
doesn't cover this) from ever running concurrently and racing writes
to the same feed rows.

Settings.recordFetchResult persists lastFetchAt/lastFetchNewArticles
on every run, not derived from WorkInfo.State -- a PeriodicWorkRequest
cycles back to ENQUEUED after every successful run and never reaches
SUCCEEDED, so anything watching for that only ever saw manual fetches.
ArticleListScreen surfaces this as a "N new articles" snackbar
(acknowledged durably, so returning to the screen doesn't re-show it)
and computes live "Checking feed X of Y" progress from the worker's
tagged WorkInfo, scoped to the Unread/Older views that actually
aggregate every subscription.
</content>
</entry>
<entry>
<title>First round of testing feedback: images, unread landing, dark, delete</title>
<updated>2026-07-22T16:26:45+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-22T16:26:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=52d7877fccd60a1dae33d877ba6aa765dc098a52'/>
<id>urn:sha1:52d7877fccd60a1dae33d877ba6aa765dc098a52</id>
<content type='text'>
- Fix OPML import status message reporting the raw pre-dedup count
  (144) instead of the actual unique feed count after Room's upsert
  collapses duplicates (108) -- cosmetic bug, the DB was already
  correct.
- Article thumbnails: extract media:thumbnail/enclosure or the first
  &lt;img&gt; in feed content, show via Coil in the article list.
- App now lands on Unread instead of the feed list; a top-bar icon
  gets from there to the feed list (forward nav, not back-stack pop,
  since Unread is now the root).
- Dark color scheme by default.
- Delete-feed action (with confirmation) on each feed row -- was
  entirely missing. Deletes its non-saved articles too, so they don't
  linger as orphaned rows in the cross-feed Unread view; saved articles
  are kept regardless.
- Room migration 1-&gt;2 for the new imageUrl column (real migration, not
  destructive fallback, since there's now real on-device subscription
  data from testing).

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
</content>
</entry>
<entry>
<title>Initial commit: Feeds, an Android RSS reader</title>
<updated>2026-07-22T08:08:58+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-22T08:08:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/feedreader.git/commit/?id=d8ce4b3c0f383e844b125d2d3abd618715bb3c89'/>
<id>urn:sha1:d8ce4b3c0f383e844b125d2d3abd618715bb3c89</id>
<content type='text'>
Feed subscriptions (RSS 2.0 + Atom, hand-rolled parser), OPML
import/export, WorkManager periodic fetch with conditional GET,
Room-backed local storage (feeds/articles/filter rules), keyword
mute/highlight filtering.

Reader mode: on-device extraction via Mozilla's Readability.js
(vendored from github.com/mozilla/readability, pinned to release
0.6.0) run in a hidden WebView, for feed articles whose provided
content is too thin to be the real article body.

Save: explicit action (from a feed article, or the Android share-sheet
target for any URL) archives to Stash via POST /artifacts?sync=true,
while a local on-device copy (Readability-extracted) is always kept so
saved articles read offline regardless of Stash's reachability.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
</content>
</entry>
</feed>
