Files
ipodderx-rs/CHANGELOG.md
rays 0efc49519c One icon per meaning across the UI; mark everything read in All Subscriptions
- All Subscriptions' header checks every feed and marks everything read
  (POST /api/read-all, the same feeds the view lists); it asks first.
- Minus unsubscribes everywhere (the feed header's x read as "close"),
  x only closes or cancels, plus adds/subscribes/imports, and a dialog's
  confirm carries its action's icon. Remaining word buttons, the player
  and the folder arrow are Font Awesome 7.3.1 icons.
- Toolbar grouped by what it acts on (add, unsubscribe, scan | play,
  read, keep); read and keep show the selected item's state.
- The OPML subscription page uses the same header as a feed.
- Fixed: Escape ignored inside a dialog's text box (Add feed could not
  be closed with it), white password box in the dark theme, stray dot
  in an undated item's details.
- Tests: one action one icon across toolbar, page and all 8 dialogs;
  All Subscriptions mark everything read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0173mGu6rK18Ne7UGTwAaVJV
2026-09-11 17:05:47 +00:00

11 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

The long form, with what was wrong before and how it was found, is in docs/history.md.

Unreleased

Added

  • A Classic theme after the 2004 Mac app, beside Dark and Light: brushed-metal toolbar, Aqua blue selection, red unread badges, a striped table and Lucida Grande. The theme button steps through all three and remembers the choice.
  • A toolbar across the top, after the original iPodderX: add and unsubscribe, play, mark read and keep for the selected item, scan, a search box for what is showing, and Settings and Log.
  • Directory, Popular and All Subscriptions at the top of the feed list, opening in the main pane. Directory lists every feed anyone here subscribes to, A to Z (GET /api/directory). All Subscriptions lists every item from every feed you subscribe to (GET /api/entries).
  • Items show as a table (unread, kept, item, feed, file, published) with a Files pane beside it, and a status bar with the totals.
  • Mark everything read from All Subscriptions, across every feed you subscribe to (POST /api/read-all). It asks first. All Subscriptions can also check every feed from its header.

Changed

  • Popular shows the top 10, not 20, and counts everyone, you included. Your own feeds stay on it, marked Subscribed, and clicking one opens it.
  • Adding a feed scans it straight away, and an OPML import that added feeds scans them, so their items show without pressing Scan.
  • A file deleted to save space, or by hand, looks as if it was never downloaded: no "reaped" label, just the Download button. The retention summary says "deleted", not "reaped".
  • Buttons are icons, with the words in their tooltips: the Files pane (save, delete, view, download), an item's own buttons (mark read, keep, open the original), the feed header (scan, download latest, mark all read, settings, unsubscribe), and the Settings, feed settings and Download latest dialogs (save, download, cancel). The icons are Font Awesome Free, embedded as SVG: only the ones used, no font to download, and nothing fetched from anyone else. They replace font characters such as ⟳ ⤓ ↗, which came out thin and tiny and differed from font to font. Keep is a flag everywhere, as it was in the original, and mark unread is an envelope.
  • One meaning per icon. Minus unsubscribes, x closes or cancels, plus adds or subscribes, and a dialog's confirm button carries the icon of what it does. The feed header's unsubscribe was an x and read as closing the page. The remaining word buttons are icons too:
    • Log, Add feed, Users, Unsubscribe and OPML.
    • Popular's Subscribe, Copy and Sign out.
    • The player's back, play, forward and close, which were font characters, and the folder arrow.
  • The toolbar's read and keep buttons show the selected item's state, with the same icons as the item's own buttons. Play, read and keep sit together, and Scan sits with add and unsubscribe.
  • An OPML subscription's page has the same header as a feed's, with its buttons in the same places.
  • A file's type is an icon (audio, video, image, PDF, torrent, other), green once it is downloaded and red when the download failed, with the details in its tooltip. One icon per row keeps the column lined up. The DOWNLOADED and PENDING labels are gone.

Fixed

  • The password box in Manage users was white in the dark theme.
  • An item with no date showed a stray dot in its details.
  • Escape did not close a dialog while the cursor was in one of its boxes, so Add feed, which opens in its URL box, could not be closed with Escape.

Security

  • Feeds from paid-feed services (Patreon, Supercast, Supporting Cast, Glow, Memberful) are never listed in Popular or the Directory. A Supercast feed, which keeps its key in the URL's path rather than the query, was being listed.

0.3.0 - 2026-09-11

Added

  • Add feed lists what other people on this server subscribe to, most subscribers first, and subscribes you by id (GET /api/popular, POST /api/popular/{id}). Feeds from an OPML, and feeds with a login or a key in their URL, are never listed.
  • Upload an OPML file to import, beside the paste box. The page checks it looks like OPML before sending it and clears the picker afterwards.
  • Settings → Manage users: add and remove accounts, and choose who is an admin (GET/POST /api/users, PATCH/DELETE /api/users/{id}).
  • Per-user subscriptions, and per-user read, starred and playback state. The existing library is adopted by the admin on first start.
  • Subscribing to a feed someone else already has costs no second fetch and no second copy. Scanning merges every subscriber's wants.
  • Delete on a shared feed reads Delete for everyone, and the server answers 409 while anyone else has starred the item or not played it (?force=true overrides).
  • A shared feed's header says how many other people read it.
  • docs/ for configuration, the CLI, users, SSO and architecture, and CLAUDE.md for anyone working on the code.
  • Browser tests for OPML import and export by every route, user admin, unread ordering, and ipx import/ipx export.

Changed

  • Feeds inside an OPML subscription list the ones with unread items first.
  • OPML import subscribes you to every feed in the file. ipx import subscribes the first admin.
  • OPML export lists only your own subscriptions.
  • Production runs as a Docker image pushed to 192.168.1.130:5000 and recreated with docker compose.
  • This changelog follows Keep a Changelog. The long-form entries moved to docs/history.md.

Fixed

  • Importing another account's OPML export subscribed nobody and reported "Imported 0 feed(s)". Feeds it added had no subscriber, so they were never scanned.
  • Importing something that is not OPML answered 500. It is now 400 "that is not an OPML file", refused before anything changes.
  • Starring stopped protecting a file from the quota and age sweeps once read state became per-user.

Security

  • The log is admin-only (GET /api/logs answers 403, and the Log button is hidden). It names every account, every feed and every failed sign-in.
  • OPML export no longer hands anyone signed in the whole catalogue, including other people's private feed URLs.

0.2.0 - 2026-09-10

Added

  • Web UI served by the daemon: plain HTML and JS compiled into the binary, with feeds, items, filters, search, sanitised show notes and live progress over SSE.
  • Player bar with resume, speed, keyboard shortcuts and lock-screen controls.
  • Three-pane layout: feeds beside, items above, and the selected item's text and files below.
  • Phone layout.
  • Accounts and sign-in: Argon2id passwords, session cookies, ipx user add|list|passwd|rm, and a trusted proxy header for Cloudflare Zero Trust or Authentik (docs/sso.md).
  • Subscribing to an OPML: it is re-read every scan and its feeds show as a folder. A feed dropped from it is removed unless it has downloads.
  • Scheduling: a global interval with per-feed overrides (every 30m, 4h, 1d, 2w).
  • [general] media_types, default audio and video, and max_new_per_check, default 3.
  • Every enclosure of an item, a View link for files that are not audio or video, and per-item artwork.
  • In-app log view with Daemon I/O, Scans and HTTP tabs.
  • Mark all read on an OPML subscription.
  • Editable feed URL with a copy button.
  • Docker image whose healthcheck goes through the control socket.
  • The iPodderX name, icon, and a colour scheme taken from the icon.
  • tests/page-smoke.js and a Playwright browser suite.

Changed

  • Global settings and scan schedules are admin-only. The per-feed schedule picker is gone.
  • Feeds from an OPML live in the database, not config.toml.
  • Opening an item marks it read. Playing it marks it read only at the end or past 90%.
  • "Episodes" became "items", since half the library is text.
  • A burst of scan events causes one refresh, not one per feed.
  • All is the default filter. OPML import and export, Settings and Log moved out of the header.
  • Torrents run detached, two at a time.

Fixed

  • Download fetched the next queued episodes instead of the one clicked.
  • Pressing play made an item vanish from the Unread list.
  • Clearing a folder, schedule or cap from the UI did nothing.
  • The daemon ignored SIGTERM until the current download finished.
  • A missing function stopped the page script and left the whole UI dead.
  • One download painted progress on every pending row.
  • A torrent could freeze scanning for up to an hour.
  • Downloading from an OPML feed failed with "belongs to unsubscribed feed".
  • Image enclosures were downloaded, counted as episodes and given a play button.
  • A feed whose entries had been deleted stayed empty, because the server kept answering 304.
  • An item with several enclosures kept only the last.
  • OPML folders rendered open by default.
  • Mark read in the text pane recursed until the stack overflowed.
  • The Unread, Downloaded and Flagged filters answered 500 without a search term.
  • An OPML subscription always showed 0 unread.
  • Folder names kept doubled spaces where separators were stripped.
  • Sidebar rows had four different left edges.

Security

  • The web UI needs a token or a sign-in. The token is compared in constant time, and an empty token refuses to serve.
  • Show notes are sanitised with ammonia.
  • A proxy's user header is honoured only from an address in trusted_proxies.
  • A feed URL must be http(s), so file:///etc/passwd is refused.
  • Download folders are sanitised per path segment, so ../../etc/Show cannot climb out.

0.1.0 - 2026-09-09

Added

  • ipx, a Rust rewrite of the iPodderX engine: TOML config, SQLite state, and ipx list, add, rm and fetch.
  • RSS and Atom parsing with conditional GET, <ttl> and basic auth.
  • Streaming downloads with explicit, keyword and per-scan filters, deduplicated by enclosure URL.
  • Quota and age retention that never touches a starred file, and ipx reap [--dry-run].
  • ipx daemon with a JSON-lines Unix socket. CLI commands proxy to a running daemon.
  • Torrent enclosures through librqbit, seeding to a ratio or a time, with a stall timeout.
  • ipx import and ipx export for OPML, and systemd units in contrib/.