556 lines
30 KiB
Markdown
556 lines
30 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to this project will be documented in this file.
|
||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||
|
||
## [Unreleased]
|
||
|
||
### Added
|
||
|
||
- Four themes, each in light and dark: Catppuccin (Latte and Mocha), Gruvbox, Solarized, and High
|
||
contrast, black and white with every colour at 7:1 or more.
|
||
|
||
### Changed
|
||
|
||
- The themes in Settings are listed in alphabetical order.
|
||
|
||
### Fixed
|
||
|
||
- Links in Classic, and hints and headings in Modern's dark half, are dark or light enough to
|
||
read comfortably. A failed-action message is easier to read in every theme.
|
||
|
||
## [0.8.1] - 2026-09-19
|
||
|
||
### Changed
|
||
|
||
- A feed being checked shows a small spinner in place of its unread count (and its folder's),
|
||
instead of toasts: no more "Scanning…" or "1 new" pop-ups, and none at all for feeds you do not read. A
|
||
"Downloaded" toast is only for a file on your screen.
|
||
- "Check every feed" checks every feed you subscribe to, not every feed on the server.
|
||
- The Classic theme is listed in Settings as just "Classic".
|
||
- Settings and the keyboard shortcuts close from an X in their top corner, not a button at the bottom.
|
||
|
||
### Fixed
|
||
|
||
- Unread counts, the unread dot and the Gone and Error tags are readable in every theme: several
|
||
light themes (Flat Remix, Paper, Adwaita, Nordic, Modern) drew them below AA contrast.
|
||
- The sign-in page follows the system's light or dark setting, and fits a phone's screen instead of
|
||
drawing at desktop width.
|
||
- In Classic, a selected item's play and delete buttons are white on the blue, not grey.
|
||
- In Nordic's dark half, button and toolbar borders show.
|
||
- A zero unread count on the selected feed no longer disappears into the selection.
|
||
|
||
## [0.8.0] - 2026-09-18
|
||
|
||
### Added
|
||
|
||
- ipx can keep its data in Postgres: set `IPX_DATABASE_URL` to a `postgres://` URL. Without it,
|
||
it is the SQLite `state.db` as before. `ipx copy-db <state.db>` moves an existing database
|
||
across, everything in one go.
|
||
- The catalogue of feeds and the server settings the admin page edits are kept in the database
|
||
rather than config.toml, which keeps where things are, the torrent settings and who may sign
|
||
in. The first start takes them from config.toml and trims it, keeping the original as
|
||
`config.toml.pre-database`; feeds added to config.toml after that are ignored, with a warning.
|
||
|
||
### Changed
|
||
|
||
- The database is reached through SeaORM, which is what lets it be SQLite or Postgres; on SQLite
|
||
nothing you see changes. On Postgres, sorting by title or feed follows the language's order (an
|
||
accented letter beside the plain one) rather than raw bytes. A database from before 0.7 has to
|
||
be opened by a 0.7 release first, which brings its tables up to date.
|
||
|
||
## [0.7.0] - 2026-09-18
|
||
|
||
### Added
|
||
|
||
- Six more themes in Settings: Dracula, Material, Adwaita, Flat Remix, Paper and Nordic, beside
|
||
Classic and Modern (the existing dark and light). Each that comes both ways has its own Light,
|
||
Dark or Auto setting; Classic and Paper come one way only, so that setting is hidden for them.
|
||
A theme chosen before this carries over.
|
||
- Your theme is kept on your account rather than in the browser, so it follows you to another
|
||
browser or computer, and the page arrives in it with no flash of the default. The theme a
|
||
browser already had is saved to your account the first time you load the page.
|
||
- Pin a feed to the top of the feed list with the pin on its page, a feed from inside an OPML or
|
||
Patreon folder included, which comes out of the folder while pinned. Pins are yours alone.
|
||
- Touch gestures: pull the item list down from its top to check the feed for new items, and
|
||
swipe the item you are reading left for the next one and right for the one before, or back
|
||
to the list from the first.
|
||
|
||
### Changed
|
||
|
||
- The server's settings, the accounts and the log are on their own admin page, /admin, reached by
|
||
the wrench in the header. Only an admin is sent the page, its script, or the link to it.
|
||
Settings is now yours alone: your theme and your subscriptions.
|
||
- A feed that fails to check gets a red exclamation mark in the feed list, in the margin where a
|
||
folder's triangle sits, and its page says why, in place of a pop-up per failure that everyone
|
||
saw during a scan of every feed. A folder holding a failing feed has its triangle turn red.
|
||
- The theme is chosen in Settings only; the button beside the iPodderX name is gone.
|
||
- Add a feed asks only for the feed; Popular and Directory in the sidebar are where you browse.
|
||
- On a phone, an item's files, with play and delete, sit above its show notes rather than below
|
||
them, where long notes left them looking missing.
|
||
- On a phone, an item with no files goes straight to its text, without a box saying "No files".
|
||
- The page is served minified, about a quarter smaller. Its script is now TypeScript in
|
||
`web/src`, type-checked, and built with swc; building ipx needs node.
|
||
- The script is its own file, `/app.js`, rather than inside the page. Your browser keeps it
|
||
between visits and fetches it again only when an update changes it.
|
||
|
||
### Fixed
|
||
|
||
- Switching tabs straight after marking everything read no longer shows the previous tab's
|
||
items: of two lists asked for at once, only the later one is shown.
|
||
- ipx has a favicon: the logo, squared up, also at /favicon.ico for browsers that ask there on
|
||
their own, and on white for an iPhone's home screen.
|
||
- The file icon of an item not yet downloaded sits level with the rest of its row, instead of
|
||
higher than a downloaded one's.
|
||
- Images in posts from sites that refuse images to other sites' pages, such as Jeff Geerling's,
|
||
now show: ipx asks for them without saying it is the page showing them.
|
||
- While an episode plays, its play buttons in the files pane, its row and the toolbar show
|
||
pause, as the player bar's does, and pause it when pressed.
|
||
- An item you open stays read. A list refresh that crossed with marking it read could put its
|
||
unread dot back until the next refresh.
|
||
- On the Unread tab, the item you were reading leaves the list as soon as you move to the next
|
||
one, rather than a few read items lingering until a refresh cleared them.
|
||
- The Log button no longer shows for a moment on every load for anyone but an admin; the server
|
||
leaves it out of their page.
|
||
- An image or link in a post given relative to the post, such as The Observation Deck's, now
|
||
points at the post's site rather than at ipx, and shows.
|
||
|
||
## [0.6.1] - 2026-09-15
|
||
|
||
### Fixed
|
||
|
||
- Time left, and when an episode counts as finished, go by the length your player measured
|
||
rather than the feed's, which can be minutes out: one episode said 0:08 left with 2:33 to play.
|
||
- A player left open in another tab or on another device no longer saves its older place over
|
||
where you have got to since, which could drop an episode out of Currently Listening.
|
||
|
||
## [0.6.0] - 2026-09-15
|
||
|
||
### Added
|
||
|
||
- Each episode in Currently Listening has a cross that takes it off the list. It forgets where you
|
||
got to, so playing it again starts from the beginning.
|
||
- An admin can give a feed a Directory category in its settings (`category` in config.toml), for
|
||
the blogs and other feeds that name none of their own. A feed's own iTunes category still wins.
|
||
- Keyboard shortcuts after Feedly's: j and k through items, Shift-J and Shift-K through feeds,
|
||
g and a letter to go to a place, o to play, s to pin, and more. Press ? for the whole list.
|
||
- Directory can be filtered to Podcasts or Blogs, and by each show's own iTunes category as a row
|
||
of chips, the narrower one where a show gives two (Games, not Leisure). The two combine, and
|
||
both filter in place.
|
||
|
||
### Changed
|
||
|
||
- Currently Listening marks the episode in the player with the EQ bars, as the item list does,
|
||
and its progress and time left move as it plays. Each row says how much is left.
|
||
- Directory shows each feed as its cover art in a grid, title and subscriber count underneath,
|
||
instead of a list. Popular and the Add a feed dialog keep their rows.
|
||
- The pages are set in Inter, served by ipx itself. Classic keeps Lucida Grande.
|
||
- Keeping an item is now pinning it: a thumbtack in place of the flag, and Pin, Pinned and Unpin
|
||
in place of Keep, Kept and Stop keeping. A pinned item is still never deleted.
|
||
- Currently Listening is its own place in the feed list, below Popular, instead of a section at
|
||
the bottom of the Popular page.
|
||
- The first scan after upgrading fetches every feed in full once, on its usual schedule, so each
|
||
picks up its category without waiting for the publisher to change something.
|
||
|
||
### Fixed
|
||
|
||
- An episode that fails to load, or is paused before it has, no longer forgets where you left off
|
||
in it, and so no longer drops out of Currently Listening.
|
||
- Currently Listening lists the episodes you have started. It left out anything marked read, and
|
||
opening an episode marks it read, so it usually showed nothing. An episode now leaves the list
|
||
once 90% of it has played.
|
||
- A WordPress post that embeds the file it encloses no longer lists, and downloads, that file
|
||
twice. Items that already had it twice are folded into one at startup, and the spare copy
|
||
deleted.
|
||
- The pinned column's heading lines up with the pins under it, and every heading sits a pixel
|
||
further right, over its column.
|
||
- The feeds left behind by an OPML subscription removed before ipx retired them are cleared at
|
||
startup: forgotten if nothing was downloaded, kept as orphaned if something was. Feeds from it
|
||
that have since been given their own settings stay as they are, with their items. Removing an
|
||
OPML or Patreon subscription no longer deletes the items of a feed inside it that has its own
|
||
settings.
|
||
- Titles that arrive as HTML, such as The Verge's, no longer show their entities as text:
|
||
"Meta’s" reads "Meta’s". Titles already stored are corrected the next time their feed
|
||
changes.
|
||
|
||
## [0.5.5] - 2026-09-14
|
||
|
||
### Changed
|
||
|
||
- A feed whose site sends a message instead of the feed, such as "Unable to establish a DB
|
||
connection", now shows that message and is flagged as the publisher's problem, instead of two
|
||
parser errors about reaching the end of input.
|
||
|
||
### Removed
|
||
|
||
- An unused icon glyph (`minus`) left over from before Unsubscribe settled on `circleMinus`.
|
||
|
||
### Fixed
|
||
|
||
- Add a feed opened over Directory or Popular now shows its Popular list instead of staying on
|
||
"Loading…", and no longer cuts the Directory behind it down to ten.
|
||
|
||
## [0.5.4] - 2026-09-14
|
||
|
||
### Added
|
||
|
||
- Currently Listening, below Popular: episodes you started and have not finished, across every
|
||
feed you subscribe to. Tap one to pick up where you left off.
|
||
- Theme has an Auto option, alongside Dark, Light and Classic, that follows your system's
|
||
light/dark setting. All four are now also in Settings, as a dropdown next to the header
|
||
button's one-click-at-a-time toggle -- the same setting either way.
|
||
|
||
### Changed
|
||
|
||
- The feed (or Directory/Popular/All Subscriptions) and the tab you had open are remembered
|
||
across a reload or a new visit. A feed you no longer subscribe to, or a first visit with
|
||
nothing remembered yet, lands on All Subscriptions instead of the first feed alphabetically.
|
||
|
||
### Fixed
|
||
|
||
- On iOS, the topbar (the hamburger menu included) could stop responding to taps until a hard
|
||
refresh. The page sized itself with `100vh`, which iOS Safari measures against the address
|
||
bar's collapsed state rather than what is actually visible; `100dvh` tracks the real viewport
|
||
as the bar shows and hides.
|
||
|
||
## [0.5.3] - 2026-09-14
|
||
|
||
### Added
|
||
|
||
- A feed that has been failing for a day shows a plain-English reason in the sidebar and on its
|
||
own page, sorted from a 404, a 401/403, a 402, a name that no longer resolves, or a web page in
|
||
place of the feed -- with Unsubscribe or, when the page links its new feed, Use the new address.
|
||
A feed that fails once and reads fine again within a day is never flagged.
|
||
|
||
### Changed
|
||
|
||
- Unsubscribing from the last person's OPML or Patreon subscription now retires the feeds it
|
||
listed, the same as a feed the list itself drops: removed if nothing was downloaded, kept and
|
||
marked orphaned otherwise. Until now they stayed in the database and kept being scanned hourly
|
||
with auto-download on, which is how 922 defunct `davewiner` feeds outlived the OPML that listed
|
||
them.
|
||
|
||
### Fixed
|
||
|
||
- A feed whose XML uses a bare `&` instead of `&` (kcpw, both feedland feeds) is now read
|
||
instead of refused.
|
||
- A feed URL that now serves a web page says so, and names the feed the page links to when it has
|
||
one, instead of a raw XML parser error.
|
||
- A publisher answering with an empty body (British Antarctic Survey's 202) is read as nothing new
|
||
to report, not a parse failure.
|
||
- A link in an item's show notes opens in a new tab instead of navigating away from ipx.
|
||
- A video file plays as video, in a small floating pane above the player bar, instead of silently
|
||
as sound only.
|
||
- On the Unread tab, opening an item no longer makes it disappear from the list -- it stays until
|
||
you open a different one, even if a scan finishes and refreshes the list while it is open.
|
||
- Subscribe and Unsubscribe have their own icons (a circled check and a circled minus) instead of
|
||
sharing the generic plus and minus used for adding feeds, users and imports.
|
||
- Settings no longer disappears for a non-admin account. It was hiding the whole Settings modal
|
||
along with the log and the users screen, but a non-admin has settings of their own in there --
|
||
their subscriptions' Export and Import, and the schedule and quota are worth seeing even without
|
||
a say in them. Only the log and the users screen, which the server also refuses them, are gone.
|
||
|
||
## [0.5.2] - 2026-09-12
|
||
|
||
### Added
|
||
|
||
- Settings → Users and `ipx user list` show when each account was added and when it last signed
|
||
in, to the hour.
|
||
- `ipx user rename <name> <new name>` renames an account and keeps its feeds, read state and admin
|
||
rights. An account made before the proxy was set up can take the name the proxy signs it in as.
|
||
|
||
### Changed
|
||
|
||
- Directory and Popular list the feeds inside an OPML one by one, and no longer the OPML itself,
|
||
so you can subscribe to just the shows you want.
|
||
- The database no longer records when subscriptions and sign-in sessions were created. Nothing
|
||
ever read it, and an existing database drops the columns on its next start.
|
||
|
||
### Fixed
|
||
|
||
- Show notes that the podcast's host cut off in the middle of a tag no longer open with a scrap of
|
||
HTML: the item's other copy of its notes is used instead, from the next time the feed changes.
|
||
Daily Meditation Podcast had 57.
|
||
- Docker no longer shows ipodderx as starting, or calls it unhealthy, while it scans or downloads:
|
||
`ipx status` answers at once instead of waiting for the job in progress to finish.
|
||
- Signing out after signing in through Cloudflare Access no longer lands on ipodderx's own password
|
||
page. With the new `sign_out_url` set, Sign out ends the Access session, and the password page
|
||
sends anyone the proxy signs in straight to their feeds.
|
||
- The sign-in guide, `docs/sso.md`, describes the setup ipodderx.sdf1.net really runs: Authentik as
|
||
Cloudflare Access's identity provider, and how to find the address ipx has to trust. It had never
|
||
been checked against a real setup, and pointed at the wrong address.
|
||
|
||
## [0.5.1] - 2026-09-12
|
||
|
||
### Fixed
|
||
|
||
- The triangle that opens an OPML or Patreon folder was cramped against the folder's art. It has
|
||
more room now, and a wider target to click.
|
||
|
||
## [0.5.0] - 2026-09-12
|
||
|
||
### Added
|
||
|
||
- A Patreon token pasted into Add feed, or a creator's RSS link without `&show=`, becomes a folder
|
||
of that creator's shows, kept in step on every scan like a subscribed OPML. A creator with only
|
||
one show stays a plain feed. One already added as a single long feed is split into its shows on
|
||
its next scan, keeping its files and what you had read.
|
||
- Add feed has an "Allow items marked explicit" box, so a new feed's first scan no longer skips
|
||
every explicit item.
|
||
|
||
### Changed
|
||
|
||
- Unread counts, unread dots and download progress are amber, the colour of the icon's EQ bars.
|
||
Blue is kept for the primary action and links, so a count no longer looks like a button.
|
||
- What is playing is marked by small EQ bars, in its row and in the player. They move only while it
|
||
plays.
|
||
- A folder in the sidebar shows its first four shows' art as a mosaic, and its shows sit under its
|
||
title. Only folders have a triangle, so every feed lines up with Directory and Popular above.
|
||
- Feeds without art get initials in a colour of their own, instead of all the same grey.
|
||
- The Flagged tab is called Kept, as the Keep button and Settings already said.
|
||
- A feed's header is one short line; when it checks next is in its tooltip.
|
||
- The item list takes more of the window, and the Files pane shows only when the item has files.
|
||
- Column headings and tags are in sentence case, and fewer things are bold.
|
||
- Unsubscribe is a round button beside the feed's other actions.
|
||
- Export and Import in Settings say what they do.
|
||
- The sign-in page shows the original icon large.
|
||
- Nothing animates when your system asks for reduced motion.
|
||
- The pages are about 90 KB smaller: the icon is served once instead of written into each.
|
||
- A web token generated for a new install is 64 characters instead of 32.
|
||
- The README is a short overview of what ipx does and how to run it, and points into `docs/` for
|
||
the rest. It still described the layout from before 0.4.0.
|
||
|
||
### Removed
|
||
|
||
- The systemd units in `contrib/`. Run ipx with Docker, or point a unit of your own at
|
||
`ipx daemon`.
|
||
- Upgrading from before 0.3.0 directly: what was read, kept or part-played before accounts is no
|
||
longer carried over to the admin, and OPML feeds that old versions wrote into `config.toml` are
|
||
no longer moved out of it. Upgrade through 0.4.0 first.
|
||
- `interval_mins` in `config.toml` is ignored; use `schedule`.
|
||
|
||
### Fixed
|
||
|
||
- The feed list works from the keyboard: Tab reaches every feed, Enter opens it, and Right and Left
|
||
open and close a folder. Every button shows where the focus is, including in the toolbar, which
|
||
used to clip the ring.
|
||
- "1 items" reads "1 item".
|
||
- A selected feed without art no longer loses its initials tile in Dark and Light.
|
||
- The player shows the feed's initials when there is no art, not the episode's.
|
||
- Turning on Allow explicit, or changing keywords or auto-download, brings back what those settings
|
||
had skipped on the feed's next scan. Before, an item was judged once, when first seen, and a
|
||
skipped one stayed skipped whatever you changed.
|
||
- Feeds inside an OPML or a Patreon creator follow your settings on the folder unless you set their
|
||
own, as the folder's settings dialog said they did. Before, the folder's settings reached nothing
|
||
inside it.
|
||
- A new feed no longer takes the name of one you removed earlier and shows that feed's old items.
|
||
Re-adding the same feed still gets its old name, and its history, back.
|
||
|
||
## [0.4.0] - 2026-09-11
|
||
|
||
### 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, title, feed, file, size, 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.
|
||
- Click a column heading in the item table to sort by it (kept, title, feed, file type, size,
|
||
published); click again to reverse. The server sorts, so it covers the whole list, not just the
|
||
fifty shown, and the choice is remembered.
|
||
|
||
### 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 Subscribed label in Popular, the Directory and Add feed, which is now a green check.
|
||
- 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.
|
||
- The item table's size has its own column, apart from the file's type, and shows KB for small
|
||
files instead of "0 MB". The Item heading is now Title.
|
||
- 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
|
||
|
||
- Playing a file from the Files pane played it twice at once, in the pane and in the player bar.
|
||
The pane has a play button now, and the player bar is the only player.
|
||
- 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/`.
|
||
|
||
[unreleased]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.6.1...main
|
||
[0.8.1]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.8.0...v0.8.1
|
||
[0.8.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.7.0...v0.8.0
|
||
[0.7.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.6.1...v0.7.0
|
||
[0.6.1]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.6.0...v0.6.1
|
||
[0.6.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.5...v0.6.0
|
||
[0.5.5]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.4...v0.5.5
|
||
[0.5.4]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.3...v0.5.4
|
||
[0.5.3]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.2...v0.5.3
|
||
[0.5.2]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.1...v0.5.2
|
||
[0.5.1]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.5.0...v0.5.1
|
||
[0.5.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.4.0...v0.5.0
|
||
[0.4.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.3.0...v0.4.0
|
||
[0.3.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.2.0...v0.3.0
|
||
[0.2.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.1.0...v0.2.0
|
||
[0.1.0]: https://git.sdf1.net/rays/ipodderx-rs/releases/tag/v0.1.0
|