The Patreon/OPML group indent (44px) read as too deep; 22px still reads as nested without eating that much row width. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019Tk3nAVF6n4dtjQS17FRFr
3.8 KiB
3.8 KiB
To do
Errors in the log
Checked production on 2026-09-14: 76 of 1,102 feeds carry a stored error. 55 are stale entries on
the davewiner OPML's derived feeds, from before it left config.toml -- confirmed that fix is
actually working: those feeds stopped being scanned six hours ago and the old error text was just
never cleared. Of the rest, everything with a subscriber classifies cleanly through
explain_failure (404, 401/403, DNS gone, a web page in place of the feed) except one:
- Explain a feed that fails to parse, not just one that fails to fetch.
explain_failure(src/feed.rs:107) turns an HTTP status or a DNS failure into a plain-English reason, but a feed that comes back 200 and then fails to parse as RSS or Atom falls through toNone-- no reason, no suggested fix, ever, even after it has failed for a day.doghouse(http://feeds2.feedburner.com/thedoghousediaries/feed) is failing that way right now: "not RSS (reached end of input without finding a complete channel) and not Atom (unexpected end of input)" -- could be a permanently broken feed or a publisher that occasionally truncates the response; either way, onceFLAG_AFTER_SECS(src/web.rs:508) passes a subscriber gets nothing in the sidebar, unlike every other failure class. Add a generic "this feed isn't coming back clean" reason for the parse-failure case, same as the others get. (src/feed.rs)
Directory Overhaul
- Give feeds a real category, from the feed itself.
ParsedFeedonly carries per-episodecategories(src/feed.rs:24); nothing at the channel level survives parsing today, so there is nothing to browse the directory by. Parse<itunes:category>(and its<itunes:subcategory>if present) off the channel the same way entry categories already are, keep the first one a feed reports rather than building a multi-tag facet, and add it toFeedSummaryand the feeds table via a migration. Most feeds will not carry one; a feed with none counts only under "All". (src/feed.rs,src/db.rs) - Expose category on
/api/popularand/api/directory.PopularRow(src/web.rs) is id, title, image, subscribers, subscribed today; addcategory: Option<String>once a feed carries one, so the client can group and filter without a second request. - Replace the flat alphabetical list with a category rail over an artwork grid. Today
Directory is a single-column list of rows: a thumbnail, a title, a subscriber count, a subscribe
button (
renderListed/listFeeds,web/index.html:1649). Put a horizontal row of category chips above it — "All" plus whatever categories actually occur in the catalogue, never an empty one — and turn the list itself into a grid of square cover-art tiles with the title underneath: podcast art is designed to be recognized at a glance, the way the app's own iPod-screen styling already leans on imagery over text. Keep the subscriber count as a small corner badge (the same treatmentunreadcounts already get in the feed list) and move the subscribe button to appear on hover/focus instead of sitting on every row permanently. Selecting a chip filters the grid in place; the active chip gets the EQ-amber underline (--accent2) the level meter already uses, rather than a new color. No new palette and no new typeface — reuse--bg/--fg/--accent/--accent2and the existing Lucida Grande stack so Directory still looks like the rest of ipx, not a bolted-on card kit: no border, shadow or radius beyond what the app already uses elsewhere. On phone width the chip row scrolls horizontally in place rather than wrapping, so it never pushes the grid down. Popular can stay a plain top-ten list for now, or get the same tile treatment later — worth deciding separately rather than folding into this. (web/index.html)