From b1ef9d63d4415099c4ff48aa2aed5bb74e6c95cb Mon Sep 17 00:00:00 2001 From: Logan Date: Tue, 18 Aug 2026 11:02:31 -0400 Subject: [PATCH] fix(explore): repaint the tracklist when a track is requested The album page's downloadStore subscription assigned canDownload and re-synced isRequested, both of which are about the *release group* -- so requesting a **track** changed no reactive property, Lit had no reason to re-render, and every row's badge kept the plus it was drawn with. The request was filed and visible in Downloads; the control that filed it appeared to do nothing, which is what making it a button was meant to stop. libraryStatusFor() reads the store at render time, so the fix is to say so: one explicit requestUpdate on the subscription. The badge is also no longer revealed on hover. That rule was inherited from the green ticks it replaced, and it does not survive the reason those went: a tick marked the common case, this marks the rows that are *not* here. A mark on the exception is the information, and one that exists only under the pointer cannot be seen, counted, or reached by a finger or a keyboard. Refs #33 --- .../explore-album-details.ts | 45 +++--- .../components/album-track-request.test.ts | 153 ++++++++++++++++++ 2 files changed, 173 insertions(+), 25 deletions(-) create mode 100644 frontend/test/components/album-track-request.test.ts diff --git a/frontend/src/components/explore-album-details/explore-album-details.ts b/frontend/src/components/explore-album-details/explore-album-details.ts index 45a02d5..cafb795 100644 --- a/frontend/src/components/explore-album-details/explore-album-details.ts +++ b/frontend/src/components/explore-album-details/explore-album-details.ts @@ -662,34 +662,20 @@ export class ExploreAlbumDetails extends LitElement implements ContextMenuHost { font-weight: 400; } - /* The request control is only offered where there is - * something to request, and only when the row is being - * attended to — a column of plus signs down a mostly-owned - * album is the clutter the green ticks were. + /* The request control is offered on every row that has + * something to request, and is not revealed on hover. * - * Hidden with opacity, never display:none or visibility, - * so it keeps its place in the layout (rows do not reflow - * as the pointer moves) and stays in the tab order and the - * accessibility tree. focus-within is what makes it - * reachable without a mouse: tabbing to the button reveals - * it, and the row's own focus reveals it before you get - * there. */ + * It used to be transparent until the row was hovered or + * focused, on the reasoning that a column of plus signs is + * clutter. That reasoning was inherited from the green + * ticks it replaced and does not survive the rule those + * were removed for: a tick marked the *common* case, while + * this marks the rows that are **not** here. A mark on + * the exception is the information, and one that appears + * only under the pointer cannot be seen, counted, or found + * by anyone driving this with a finger or a keyboard. */ .track-row .track-request { flex-shrink: 0; - opacity: 0; - transition: opacity 0.12s ease; - } - - .track-row:hover .track-request, - .track-row:focus-within .track-request, - .track-row .track-request:focus-visible { - opacity: 1; - } - - @media (prefers-reduced-motion: reduce) { - .track-row .track-request { - transition: none; - } } `, ]; @@ -720,9 +706,18 @@ export class ExploreAlbumDetails extends LitElement implements ContextMenuHost { // The download button only appears once a client is connected, // so this tracks the provider list rather than assuming. + // + // The explicit `requestUpdate` is what makes a *track*'s badge + // move. `canDownload` and `syncRequested` are both about the + // release group, so neither changes when a row is requested — + // and every row's badge reads `libraryStatusFor(...)` out of + // the store at render time, so with no reactive property + // changed Lit had no reason to re-render and the badge sat on + // a plus for a request that had already been filed. this.downloadUnsub = downloadStore.subscribe(() => { this.canDownload = downloadStore.available; this.syncRequested(); + this.requestUpdate(); }); void downloadStore.init().then(() => { diff --git a/frontend/test/components/album-track-request.test.ts b/frontend/test/components/album-track-request.test.ts new file mode 100644 index 0000000..9e65a24 --- /dev/null +++ b/frontend/test/components/album-track-request.test.ts @@ -0,0 +1,153 @@ +/** + * Asking for a track from an album's tracklist. + * + * The badge on an unowned row is a `