History: the icon pass, sorting and the double play; fix a stale changelog line

docs/history.md gets the long-form entry CLAUDE.md asks for: what the
UI pass found, the three bugs it turned up (Escape inside a dialog's
text box, the white password box, the stray dot), why sorting is done
on the server, and how the Files pane came to play a file twice.
CHANGELOG's Added line for the item table named the old columns.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0173mGu6rK18Ne7UGTwAaVJV
This commit is contained in:
2026-09-11 17:32:41 +00:00
parent 669e8b5124
commit 2c34a144ba
2 changed files with 57 additions and 2 deletions

View File

@@ -20,8 +20,8 @@ The long form, with what was wrong before and how it was found, is in
- 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.
- 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,

View File

@@ -6,6 +6,61 @@ reasoning lives. New write-ups go at the top.
See [README.md](../README.md) for what the thing is.
## 2026-09-11 — One meaning per icon, sortable columns, and one player
Ray asked for a pass over the whole UI: consistent icons, and buttons placed next to what they act
on. The pass started from screenshots of every view and dialog, taken against the browser suite's
own daemon and fixtures. Several things did not agree:
- Unsubscribe was a minus in the toolbar but an x in the feed header. There it read as "close this
page", and x also meant Cancel in every dialog.
- Half the dialogs still had word buttons: Log, Add feed, Users, Unsubscribe, OPML, Popular's
Subscribe, the Copy buttons and Sign out.
- The player bar and the folder arrow were font characters, and so was the row's "playing" marker.
Those came out thin and varied from font to font.
- The OPML subscription page laid out its header differently from a feed's, and All Subscriptions
had no buttons at all.
The rule now is one meaning per icon. Minus unsubscribes, x closes or cancels, plus adds, subscribes
or imports, and a dialog's confirm button carries the icon of what it does. The words go in the
tooltip. The toolbar is grouped by what it acts on: add, unsubscribe and scan act on feeds; play,
read and keep act on the selected item. Its read and keep buttons now show that item's state, as
the item's own buttons already did. A browser test opens all eight dialogs and fails on any button
without an icon and a tooltip. It also checks that the toolbar and the page use the same icon for
the same action.
The pass turned up three bugs:
- **Escape ignored inside a dialog's text box.** The keydown handler returned early for any key
typed in a text box, and Escape sat below that check. So Add feed, which opens with the cursor in
its URL box, could not be closed with Escape. It showed up because the screenshot run stalled:
the dialog stayed open, and every later click landed on its overlay until the run timed out.
- **A white password box in the dark theme.** The input rule listed text, search and number
fields, but not password ones.
- **A stray "• •" under an item with no date.** Each detail carried its own trailing dot, whether
or not the next one was there.
All Subscriptions gained Mark everything read, as `POST /api/read-all`. It marks the feeds from the
person's subscriptions, which is the same set the view's query is scoped by. It asks first, since
one click covers every feed.
**Sorting** happens on the server. A list arrives fifty at a time, so sorting in the page would
only have reordered what was loaded. The column name picks one of a fixed set of SQL expressions
(`order_sql`), so nothing the browser sends reaches the query, and an unknown name means newest
first. Ties also fall back to newest first, so "Load more" does not skip or repeat items at a page
boundary. A database test runs every column both ways. Size came out of the File column into its
own, and small files show KB, since whole megabytes made every article image "0 MB".
**The double play.** Ray found that pressing play in the Files pane played the file twice at once.
The pane drew its own `<audio controls>`, and its `onplay` handler also started the player bar on
the same file. That meant two audio elements from one click. The pane now has a play button that
hands that exact file to the player bar, the only player. `play()` now takes the file. Its check
for resuming compares the file as well as the item, so another of an item's files starts from its
beginning instead of carrying on with the first. A test plays from the pane and checks the page
has one `<audio>` element.
---
## 2026-09-11 — The original's layout
Ray pointed at a screenshot of the Mac app (techpp.com, 2012) and asked for its panes, its