Design pass on the web UI: amber for new, EQ bars, keyboard feed list
Works through TODO.md from the 2026-09-11 review. Unread badges, dots and download bars take the icon's amber; the playing item is marked by EQ bars that move only while it plays. The feed list is usable from the keyboard, focus rings show everywhere, and folders get a mosaic of their shows' art with the triangle hung in the margin. Sentence-case labels, fewer bold weights, tinted initials tiles, shorter header lines, "Kept" everywhere, and the list gets the room the empty panes had. Reduced motion is honoured. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TAC7sLVqfKmY6rsTLXzNgk
This commit is contained in:
@@ -111,7 +111,7 @@ else a `401`.
|
||||
| `GET /api/entries` | the same, across every feed you subscribe to (All Subscriptions) |
|
||||
| `POST /api/feeds/{id}/read-all`, `POST /api/feeds/{id}/download-latest` | |
|
||||
| `POST /api/read-all` | everything read in every feed you subscribe to (All Subscriptions) |
|
||||
| `POST /api/entries/{feed}/{guid}/flags`, `…/position` | your read, starred, position |
|
||||
| `POST /api/entries/{feed}/{guid}/flags`, `…/position` | your read, kept, position |
|
||||
| `POST /api/enclosures/{id}/download`, `DELETE /api/enclosures/{id}` | `?force=true` overrides the shared-file warning |
|
||||
| `POST /api/fetch` | |
|
||||
| `GET /api/opml`, `POST /api/opml` | export your subscriptions; subscribe to every feed in an OPML |
|
||||
|
||||
@@ -60,7 +60,7 @@ ipx reap # actually delete
|
||||
```
|
||||
|
||||
Files are deleted to get back under `max_total_gb`, oldest first, and items past `max_age_days`
|
||||
with no file are pruned from the database. **Starred by anyone keeps a file**, and one only counts
|
||||
with no file are pruned from the database. **An item anyone kept keeps its file**, and one only counts
|
||||
as read when everyone subscribed has read it. The enclosure row survives as `reaped`, which is what
|
||||
stops the next scan fetching it again.
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ media_types = ["audio", "video"]
|
||||
be polled *less* often, and a per-feed `schedule` overrides both. Admin-only from the UI.
|
||||
* **`organize`** — `feed` files downloads under the feed's folder; `date` under `YYYY-MM-DD`.
|
||||
* **`max_total_gb`** — the reaper deletes to get back under this, oldest first, keeping a 50 MB
|
||||
pad. Starred items are never deleted, and a file only counts as read once every subscriber has
|
||||
pad. Kept items are never deleted, and a file only counts as read once every subscriber has
|
||||
read it. `0` disables it entirely.
|
||||
* **`max_age_days`** — items older than this with no file on disk are pruned from the database.
|
||||
Starred ones stay. `0` disables it.
|
||||
Kept ones stay. `0` disables it.
|
||||
* **`max_new_per_check`** — the cap that stops a new subscription pulling a whole back catalogue.
|
||||
`0` means unlimited, which is rarely what you want: subscribing to an OPML of 80 feeds with no cap
|
||||
fetched 216 files and 22 GB in one scan.
|
||||
|
||||
@@ -6,6 +6,38 @@ reasoning lives. New write-ups go at the top.
|
||||
|
||||
See [README.md](../README.md) for what the thing is.
|
||||
|
||||
## 2026-09-11 — A design pass on the web UI
|
||||
|
||||
A review against screenshots of every view in all three themes found that Dark and Light read as a
|
||||
generic dark dashboard: one pale blue did every job, most labels were bold, and nothing led. The
|
||||
list it produced, in `TODO.md`, was worked through in one go. What was worth knowing:
|
||||
|
||||
- **Amber means new.** Badges, unread dots and download bars take the icon's EQ amber; blue is left
|
||||
for the primary action and links. Light's amber was `#b06f10`, which gives white text 4.1:1,
|
||||
short of AA for 11 px bold. It is `#9a5f0a` now, 5.2:1.
|
||||
- **EQ bars mark what is playing.** Three `<i>` bars stand at 60, 100 and 40 % and animate only
|
||||
while `body.playing` is set. The first version left the animation on but paused, expecting each
|
||||
bar to hold a different frame. The frames it held were within a pixel of each other, and on
|
||||
screen the bars read as three dots. Under reduced motion one rule drops every animation and
|
||||
transition, which leaves the bars standing.
|
||||
- **The focus ring was clipped.** `.tgroup` and `#topbar` both set `overflow:hidden`, so a ring
|
||||
drawn outside a toolbar button was cut off. Rings inside clipping parents are inset instead.
|
||||
- **The feed list could not be used from the keyboard at all.** Rows were `<div>`s and the triangle
|
||||
a `<span>`, so Tab went from the feed filter to Sign out. Rows now take focus, the triangle is a
|
||||
`<button aria-expanded>`, and `renderFeeds` puts focus back on the same row after redrawing,
|
||||
since every live update replaces every row. The list's own key handler stops Space and the
|
||||
arrows from reaching the player's shortcuts on the document.
|
||||
- **The triangle hangs in the margin.** Every row used to reserve an 18 px slot for it, pushing a
|
||||
hundred feeds 28 px right of the places above for the sake of two folders. It is now absolutely
|
||||
placed in the row's left padding, the full height of the row, so a near miss no longer opens
|
||||
the folder's page.
|
||||
- **A selected tile vanished** because the initials tile and the selected row were both `--raise`.
|
||||
Tiles now mix their tint into `--bg`, which no row uses.
|
||||
- **The Files pane hides itself** with `#split:has(>#files[hidden])`, which collapses its column.
|
||||
The phone layout already hides the pane, and a zero-width extra track there is harmless.
|
||||
- **Flagged became Kept** in the tab, and in the server's refusal to delete a file someone else
|
||||
kept. The filter value and the column stay `flagged`; renaming those buys nothing.
|
||||
|
||||
## 2026-09-11 — A Patreon creator is a list of shows
|
||||
|
||||
Ray asked whether ipx could sync with Patreon. Not in full. The documented API (v2, the
|
||||
|
||||
@@ -8,7 +8,7 @@ fetch, one parse and one file.
|
||||
|
||||
| Yours alone | The same for everyone |
|
||||
|---|---|
|
||||
| Read, starred, playback position | The feed's URL |
|
||||
| Read, kept, playback position | The feed's URL |
|
||||
| Which feeds you see at all | Its download folder |
|
||||
| Keywords, auto-download, explicit, per-scan cap | When it is scanned |
|
||||
| | The file on disk |
|
||||
@@ -34,10 +34,10 @@ is shared.
|
||||
|
||||
Deleting a file deletes everyone's copy. A feed with other subscribers labels the button **Delete
|
||||
for everyone** and names them in the confirmation, and the server has the last word: if anyone else
|
||||
has starred the item or not played it yet, `DELETE /api/enclosures/{id}` answers `409` with the
|
||||
has kept the item or not played it yet, `DELETE /api/enclosures/{id}` answers `409` with the
|
||||
reason, and only `?force=true` goes through.
|
||||
|
||||
Retention follows the same rule: starred by anyone keeps a file, and it counts as read only once
|
||||
Retention follows the same rule: an item anyone kept keeps its file, and it counts as read only once
|
||||
every subscriber has read it.
|
||||
|
||||
## Signing in
|
||||
|
||||
Reference in New Issue
Block a user