Files
ipodderx-rs/TODO.md
rays 8d84f9fe8c Halve child-feed indent; update TODO with error-log findings
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
2026-09-14 20:45:55 +00:00

50 lines
3.8 KiB
Markdown

# 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 to `None` -- 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, once `FLAG_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.** `ParsedFeed` only carries per-episode
`categories` (`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 to `FeedSummary` and 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/popular` and `/api/directory`.** `PopularRow` (`src/web.rs`) is id,
title, image, subscribers, subscribed today; add `category: 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 treatment
`unread` counts 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`/
`--accent2` and 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`)