Repository navigation
feat(messages): trim the workflow message card to a hover heads-up - #2385
Merged
Merged
Conversation
The ⓘ card on a workflow kick-off message repeated the owner's name from the byline beside it and printed the owner and relay npubs in full. At about 224 × 438 px it covered the message it described. The card now shows its title and one plain description: "Sent automatically by a workflow. Its owner set it up but didn't send this message personally." The owner and relay keys, the owner row and the "run details not included" footer are gone. The relay signing key is no longer shown anywhere in the UI, which changes the disclosure agreed in #663; docs/workflows.md now describes the card instead. The owner's npub is still reachable from the byline's profile link, which offers Copy npub. The trigger uses the shared PopoverTrigger openOnHover="preview" bucket, so the card opens after a 0.3 s pointer rest. Enter and click still open it, and Escape closes it and returns focus to ⓘ. Base UI does not move focus for a hover open, and a click right after a hover open keeps the card open. The IconButton has no title, so no hint tooltip competes with the card. WorkflowByline no longer takes a signer prop, and the unused .workflowDetails rules are deleted. The signerId field on ChannelMessage stays; removing it is a separate cleanup. The gallery specimen description is updated. Tests: the MessageRow tests now cover the Enter/Escape/click path, the card's description with no npub or owner name, and a hover test showing that nothing opens at 299 ms, the card opens at 300 ms with no tooltip and no focus move, a click keeps it open and Escape closes it. The hover test fails without openOnHover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
…k paths Addresses review of a06c980 on the workflow ⓘ card tests. The click-open check used user.click and findByRole. user.click moves the pointer onto the trigger, which starts the 300 ms preview rest timer, and findByRole polls for a second, so the hover could open the card even if the click did nothing. With user.hover in place of the click, the old check still passed. The test now opens the card with fireEvent.click, which moves no pointer, and finds the card synchronously. The hover test checked that focus was outside the card, which would also pass if a hover open moved focus to the trigger. It now records the focused element before the hover and asserts it is unchanged. The hover test also pins Base UI's patient-click window. A click within 500 ms of a hover open keeps the card open. A click after that toggles it closed. This matches every other openOnHover="preview" popover, so the card keeps the library behaviour rather than overriding it. Each new assertion fails when its behaviour breaks: a blocked Base UI click handler, a focus move during hover, and a click at 499 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Addresses review of 2627d5d. docs/workflows.md still said a workflow row keeps a separate signing key "so the disclosure still identifies the actual relay". The card no longer shows any key, and the paragraph on message attribution says so. The passage now says the row keeps the signing key for row identity only and does not display it. signerId is read only by sameRow in row-identity.ts. The workflow hover test advanced the clock by a bare 500 ms to pass Base UI's patient-click window. That number is a Base UI internal, not a Buzz hover-timing token, so a library change would fail the test with no hint why. It is now a local BASE_UI_PATIENT_CLICK_MS named after Base UI's PATIENT_CLICK_THRESHOLD. The behaviour under test is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
matt2e
marked this pull request as ready for review
November 4, 2026 04:20
kalvinnchau
approved these changes
Nov 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A workflow kick-off message has the byline Workflow · owned by Priya Shah and an ⓘ button. The ⓘ card opened only on click. It repeated the owner's name from the byline beside it and printed the owner and relay npubs in full. At 224 × 438 CSS px it covered the message it described and reached down over the composer.
Change
The card now shows its title and one sentence:
PopoverTrigger openOnHover="preview"bucket, so the card opens after a 0.3 s rest on ⓘ. Click and Enter still open it, and Escape closes it and returns focus to ⓘ. A hover open doesn't move focus. TheIconButtonhas notitle, so no tooltip competes with the card.WorkflowBylineno longer takes asignerprop, and the unused.workflowDetailsCSS is deleted.docs/workflows.mddescribes the new card. It also says the row keeps the signing key for row identity only and doesn't display it.tests/fixtures/message-gallery/examples.ts) matches the new card.The owner's npub is still available: the owner's name in the byline opens their profile, which offers Copy npub.
signerIdstays onChannelMessagebecausesameRowinrow-identity.tsstill reads it. Removing it is a separate cleanup.Decisions to confirm
openOnHover="preview". The card used to open only on click. It now uses the same hover bucket as the app's other preview popovers. One behaviour comes from Base UI: a click within 500 ms of a hover open keeps the card open, and a later click toggles it closed. Every otheropenOnHover="preview"popover does the same, so the card keeps the library behaviour rather than overriding it, and a test pins it. Touch input never triggers the hover. Moving keyboard focus onto ⓘ doesn't open the card; Enter does, as with the other hover popovers.Before / after
Side-by-side video, 13 s, with the same scripted pointer path in both panes. The pointer glides onto the message, then onto ⓘ at about 3.5 s. After opens the card at about 4.8 s from the pointer rest alone. Before opens only on the click at 5.5 s. From 7 s the pointer moves down the card, and Escape closes it at 11.5 s. The panes are labelled BEFORE and AFTER and carry no other annotations.
side-by-side.mp4
Individual screenshots of the open card:
These were recorded in Chromium on the browser-journey fixture app (production frontend, dev broker and modeled relay), light theme, 1024 × 640 CSS px at 2×, pointer only. The npubs are fixture keys. The before take is from the tree before
a06c9808a. The after take is from2627d5d70; the only later commit,f5672282e, changes docs and a test constant.Tests
src/features/messages/MessageRow.test.tsx:fireEvent.click, which moves no pointer, so the hover timer can't open the card in its place.Each new assertion was checked to fail when its behaviour breaks: removing
openOnHover, blocking Base UI's click handler, moving focus during hover, and clicking at 499 ms.Validation
MessageRow.test.tsx: 161/161 passed.design:checkpassed.--no-verify, so the pre-push hook didn't run.Not tested yet: dark theme, narrow widths, enlarged text, keyboard-only use, WebKit, and a manual check in the app. One case worth checking by hand: rest on ⓘ until the card opens, wait more than half a second, then click. The card should close.
Checklist
a06c9808aand2627d5d70. Its findings (two loose test assertions, a stale docs passage, a bare500in a test) are fixed in2627d5d70andf5672282e.🤖 Generated with Claude Code