#67: tapping a small text link inside a row to reach an artist or album
page is fiddly on a phone. Its Findings say why in the code rather than
in taste — utils/explore-link.ts' click handling is explicitly a desktop compromise (the navigation is held for one double-click
interval so double-clicking the row can still play it), and since #63 a
claimed yj-tap has its click swallowed anyway, so on touch the link
was unreachable as well as small.
What changed
commit
issue
feat(android): a name is not a link on a phone, the menu carries it
utils/explore-link.ts owns the rule, which is what the Findings
ask for: below PHONE_QUERY a track/album/artist name renders as
plain text. artistLink, albumLink, trackLink and creditLink
all take it; a decomposed credit falls back to creditText, so the
join phrases survive and only the affordance changes.
utils/go-to-menu.ts is the other half. "Go to Artist" / "Go to
Album", drawn under exactly the condition the link is not, from explore-link's own exported routing (openArtistPage / openAlbumPage) — so an untagged entity reaches the library page by
the same lookup rather than a second one that can disagree.
Seven menus carry it: track-list, queue-panel, both playlist
detail views, cover-grid's album cards, Explore's cards and
recording rows, and the artist page's top tracks (album only — the
artist is the page you are on).
Three decisions worth reading
keepOnPhone is an exception with a reason, not a preference.
Three surfaces draw a name with no menu to carry the destination — now-playing-view, explore-album-details' header credit and top-results-row. Suppressing those takes the action away rather than
moving it, which is what plan 018's "no action is unreachable at any
supported size" refuses. Each call site says so in a comment.
One row or none. The items follow the Play item's stated rule: one
row is a position, several are an explicit choice of those tracks,
and "go to the album" of five different albums means nothing.
There is no "Go to Genre", which the issue asks for. No row in the
app renders a genre link, so there is nothing for the phone to take
away — it would be new navigation rather than a replacement, and
belongs in its own issue if it is wanted. Said on the issue when
claiming it.
The desktop is untouched: the name beside the row is still a link, and goToMenuItems returns nothing above the breakpoint.
Verification
make ui-test — 1100 passed, including 8 new in frontend/test/components/phone-entity-links.test.ts: the rule for
all four link shapes, the keepOnPhone exception, the items'
presence and absence, the navigation they fire, and the one-row rule.
make e2e — 241 passed against make dev-headless SEED=default
(chromium; Playwright's WebKit is CI-only on this machine), including
the new e2e/specs/phone-entity-links.spec.ts, which asserts the
phone and the desktop in the same breath: plain text and the two
items at 424x439, a link and neither item at 1280x800.
The e2e half was proved non-vacuous: with inlineLinksSuppressed()
forced false and a rebuild, the phone test fails on the link count
and the desktop test still passes.
A screenshot at 424x439 of the queue's bottom sheet, which is how
the finding below was found.
npx tsc --noEmit, make css-check — clean. No Go, .sql or .templ changed, so make lint, make test, make generate and make bindings were not run.
Filed rather than fixed here
#207 — the track list's sheet is now 8 items and its last one
("Remove from Library") ends at y=470 in a 439px viewport. It is reachable — the sheet's body is overflow-y: auto and scrolling it
39px brings the item fully into view — but nothing says the list
continues. The limit was already reached before this: seven 48px rows
is 364px in a 373px body, so the queue's menu fits with 8px to spare
and the track list's fitted exactly. It is a property of components/menu-surface/, not of any one menu's items. Measurements
are in .planning/NOTES.md.
Deliberately not done
No "Go to Genre" (above).
The desktop menus are unchanged; a menu item that repeats a link two
centimetres away is furniture.
explore-album-details' own tracklist rows are untouched — they have
never rendered links, so they lost nothing.
## What the issue was
#67: tapping a small text link inside a row to reach an artist or album
page is fiddly on a phone. Its Findings say why in the code rather than
in taste — `utils/explore-link.ts`' click handling is explicitly a
*desktop* compromise (the navigation is held for one double-click
interval so double-clicking the row can still play it), and since #63 a
claimed `yj-tap` has its click swallowed anyway, so on touch the link
was unreachable as well as small.
## What changed
| commit | issue |
|---|---|
| `feat(android): a name is not a link on a phone, the menu carries it` | #67 |
- **`utils/explore-link.ts` owns the rule**, which is what the Findings
ask for: below `PHONE_QUERY` a track/album/artist name renders as
plain text. `artistLink`, `albumLink`, `trackLink` and `creditLink`
all take it; a decomposed credit falls back to `creditText`, so the
join phrases survive and only the affordance changes.
- **`utils/go-to-menu.ts` is the other half.** "Go to Artist" / "Go to
Album", drawn under exactly the condition the link is *not*, from
`explore-link`'s own exported routing (`openArtistPage` /
`openAlbumPage`) — so an untagged entity reaches the library page by
the same lookup rather than a second one that can disagree.
- Seven menus carry it: `track-list`, `queue-panel`, both playlist
detail views, `cover-grid`'s album cards, Explore's cards and
recording rows, and the artist page's top tracks (album only — the
artist is the page you are on).
### Three decisions worth reading
**`keepOnPhone` is an exception with a reason, not a preference.**
Three surfaces draw a name with **no menu to carry the destination** —
`now-playing-view`, `explore-album-details`' header credit and
`top-results-row`. Suppressing those takes the action away rather than
moving it, which is what plan 018's "no action is unreachable at any
supported size" refuses. Each call site says so in a comment.
**One row or none.** The items follow the Play item's stated rule: one
row is a position, several are an explicit choice of *those* tracks,
and "go to the album" of five different albums means nothing.
**There is no "Go to Genre"**, which the issue asks for. No row in the
app renders a genre link, so there is nothing for the phone to take
away — it would be new navigation rather than a replacement, and
belongs in its own issue if it is wanted. Said on the issue when
claiming it.
The desktop is untouched: the name beside the row is still a link, and
`goToMenuItems` returns `nothing` above the breakpoint.
## Verification
- **`make ui-test`** — 1100 passed, including 8 new in
`frontend/test/components/phone-entity-links.test.ts`: the rule for
all four link shapes, the `keepOnPhone` exception, the items'
presence and absence, the navigation they fire, and the one-row rule.
- **`make e2e`** — 241 passed against `make dev-headless SEED=default`
(chromium; Playwright's WebKit is CI-only on this machine), including
the new `e2e/specs/phone-entity-links.spec.ts`, which asserts the
phone and the desktop in the same breath: plain text **and** the two
items at 424x439, a link **and** neither item at 1280x800.
- **The e2e half was proved non-vacuous**: with `inlineLinksSuppressed()`
forced `false` and a rebuild, the phone test fails on the link count
and the desktop test still passes.
- **A screenshot at 424x439** of the queue's bottom sheet, which is how
the finding below was found.
- `npx tsc --noEmit`, `make css-check` — clean. No Go, `.sql` or
`.templ` changed, so `make lint`, `make test`, `make generate` and
`make bindings` were not run.
## Filed rather than fixed here
**#207** — the track list's sheet is now 8 items and its last one
("Remove from Library") ends at y=470 in a 439px viewport. It is
**reachable** — the sheet's body is `overflow-y: auto` and scrolling it
39px brings the item fully into view — but nothing says the list
continues. The limit was already reached before this: seven 48px rows
is 364px in a 373px body, so the queue's menu fits with 8px to spare
and the track list's fitted exactly. It is a property of
`components/menu-surface/`, not of any one menu's items. Measurements
are in `.planning/NOTES.md`.
## Deliberately not done
- No "Go to Genre" (above).
- The desktop menus are unchanged; a menu item that repeats a link two
centimetres away is furniture.
- `explore-album-details`' own tracklist rows are untouched — they have
never rendered links, so they lost nothing.
Closes #67
check: lint, test (three build configurations), typecheck, make ui-test, make bindings-check, make skill-check, CSS literals, commit messages — all success.
e2e: both engines ran — E2E — chromium success and E2E — webkit success. Worth stating rather than reading off the job's conclusion, since a chromium failure has silently skipped the WebKit step before.
Nothing was re-run and nothing flaked.
**CI is green** — run 17663.
- `check`: lint, test (three build configurations), typecheck, `make ui-test`, `make bindings-check`, `make skill-check`, CSS literals, commit messages — all success.
- `e2e`: **both engines ran** — `E2E — chromium` success and `E2E — webkit` success. Worth stating rather than reading off the job's conclusion, since a chromium failure has silently skipped the WebKit step before.
Nothing was re-run and nothing flaked.
Every track, album and artist name in the app navigates through
`utils/explore-link.ts`, and every sentence of how it does that is a
desktop compromise: the navigation is held for one double-click
interval so double-clicking the row can still play it, and the target
is a few characters of text inside a row. On touch that is a delay on
an ambiguous target, and since #63 the row's own tap claims the click
anyway -- so the link was unreachable as well as fiddly.
So below the phone breakpoint a name renders as plain text and the
row's context menu carries the destination instead: `go-to-menu.ts`
draws "Go to Artist" / "Go to Album" under exactly the condition the
link is not, using `explore-link`'s own exported routing so an untagged
entity reaches the library page by the same lookup.
Three things this leans on. Suppressing a link with no menu behind it
is not a smaller affordance but a destination the phone cannot reach,
so `keepOnPhone` is the exception for the three surfaces with no row
menu. The items are drawn for a single selection only, which is the
Play item's rule one step on. And there is no "Go to Genre", because
no row renders a genre link to lose -- that would be new navigation
rather than a replacement.
Closes#67
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What the issue was
#67: tapping a small text link inside a row to reach an artist or album
page is fiddly on a phone. Its Findings say why in the code rather than
in taste —
utils/explore-link.ts' click handling is explicitly adesktop compromise (the navigation is held for one double-click
interval so double-clicking the row can still play it), and since #63 a
claimed
yj-taphas its click swallowed anyway, so on touch the linkwas unreachable as well as small.
What changed
feat(android): a name is not a link on a phone, the menu carries itutils/explore-link.tsowns the rule, which is what the Findingsask for: below
PHONE_QUERYa track/album/artist name renders asplain text.
artistLink,albumLink,trackLinkandcreditLinkall take it; a decomposed credit falls back to
creditText, so thejoin phrases survive and only the affordance changes.
utils/go-to-menu.tsis the other half. "Go to Artist" / "Go toAlbum", drawn under exactly the condition the link is not, from
explore-link's own exported routing (openArtistPage/openAlbumPage) — so an untagged entity reaches the library page bythe same lookup rather than a second one that can disagree.
track-list,queue-panel, both playlistdetail views,
cover-grid's album cards, Explore's cards andrecording rows, and the artist page's top tracks (album only — the
artist is the page you are on).
Three decisions worth reading
keepOnPhoneis an exception with a reason, not a preference.Three surfaces draw a name with no menu to carry the destination —
now-playing-view,explore-album-details' header credit andtop-results-row. Suppressing those takes the action away rather thanmoving it, which is what plan 018's "no action is unreachable at any
supported size" refuses. Each call site says so in a comment.
One row or none. The items follow the Play item's stated rule: one
row is a position, several are an explicit choice of those tracks,
and "go to the album" of five different albums means nothing.
There is no "Go to Genre", which the issue asks for. No row in the
app renders a genre link, so there is nothing for the phone to take
away — it would be new navigation rather than a replacement, and
belongs in its own issue if it is wanted. Said on the issue when
claiming it.
The desktop is untouched: the name beside the row is still a link, and
goToMenuItemsreturnsnothingabove the breakpoint.Verification
make ui-test— 1100 passed, including 8 new infrontend/test/components/phone-entity-links.test.ts: the rule forall four link shapes, the
keepOnPhoneexception, the items'presence and absence, the navigation they fire, and the one-row rule.
make e2e— 241 passed againstmake dev-headless SEED=default(chromium; Playwright's WebKit is CI-only on this machine), including
the new
e2e/specs/phone-entity-links.spec.ts, which asserts thephone and the desktop in the same breath: plain text and the two
items at 424x439, a link and neither item at 1280x800.
inlineLinksSuppressed()forced
falseand a rebuild, the phone test fails on the link countand the desktop test still passes.
the finding below was found.
npx tsc --noEmit,make css-check— clean. No Go,.sqlor.templchanged, somake lint,make test,make generateandmake bindingswere not run.Filed rather than fixed here
#207 — the track list's sheet is now 8 items and its last one
("Remove from Library") ends at y=470 in a 439px viewport. It is
reachable — the sheet's body is
overflow-y: autoand scrolling it39px brings the item fully into view — but nothing says the list
continues. The limit was already reached before this: seven 48px rows
is 364px in a 373px body, so the queue's menu fits with 8px to spare
and the track list's fitted exactly. It is a property of
components/menu-surface/, not of any one menu's items. Measurementsare in
.planning/NOTES.md.Deliberately not done
centimetres away is furniture.
explore-album-details' own tracklist rows are untouched — they havenever rendered links, so they lost nothing.
Closes #67
CI is green — run 17663.
check: lint, test (three build configurations), typecheck,make ui-test,make bindings-check,make skill-check, CSS literals, commit messages — all success.e2e: both engines ran —E2E — chromiumsuccess andE2E — webkitsuccess. Worth stating rather than reading off the job's conclusion, since a chromium failure has silently skipped the WebKit step before.Nothing was re-run and nothing flaked.
9da657baf5to8de412cf36