The rss crate keeps at most one enclosure per item and, when a feed ships
several, silently keeps the last -- so a two-file item lost its first
file. enclosures_by_item reads them from the XML in document order,
unescaping attributes so a URL's & survives. The row summarises the
one you would act on and counts the rest; the pane below lists them all.
Non-media enclosures gain a View link opening in a new tab: the
publisher's URL, or the local copy once downloaded. A direct link, not a
proxy, so the daemon does not become a fetch-anything relay.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
The media-type filter stopped new image enclosures being fetched, but ones
already on disk still got a play button and an <audio> element, because
the UI tested for a path rather than for a playable type. Four places did
this, including play() itself, which picked the first downloaded enclosure
whatever it was.
isPlayable() checks audio/* or video/*, falling back to the extension when
a feed declares no type. A downloaded non-media file now shows as its kind
with Save and Delete, so it stays available without posing as an episode.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
The log view splits into All / Daemon I/O / Scans / HTTP. Daemon I/O is
the control protocol itself, logged where every command funnels through
so it covers socket clients, the CLI and the web UI alike. stderr and the
in-app buffer now have separate filters, so the UI can keep debug detail
the terminal should not carry.
Playwright drives a real browser against a daemon on fixture feeds. Eight
tests, each mapping to a bug that reached a user -- the Rust tests and the
stub-DOM smoke test cannot see a wrong selector or a dead handler.
It immediately found one: OPML folders rendered expanded by default,
because the code stored closed groups, so any folder never toggled counted
as open.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh