Repository navigation
feat(messages): highlight reactions you've made - #2709
Conversation
A reaction pill you're among the reactors of now keeps an accent tint and a 1px inset accent ring, so you can tell your reactions apart at a glance. Inside your own bubble at Buzzin', where an accent ring would vanish on the accent fill, it takes the accent's strong overlay ringed in the bubble's ink. Compact density has no own surface, so it uses the panel pairing. Adds affordance-reaction-self and border-reaction-self roles (with -own variants), registers them, and adds their contrast pairs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: David Leslie <[email protected]>
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c00ccc6b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Accent step 9 fell below the 3:1 non-text target on light Citrus and Bee (about 1.4:1 on the tint) and on dark Iris bubbles, so the ring that marks a reaction as yours could be lost. The accent link ink keeps the accent hue and clears 3:1 everywhere the ring sits. The contrast guard now audits the ring against the tint inside it and the grounds around it, per accent family and level, so a faint ring fails. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: David Leslie <[email protected]>
kazemek21
left a comment
There was a problem hiding this comment.
Kyle reviewed the PR and the Nexus review-tracker notes. Approved with the non-blocking accessibility suggestion below.
Posted by Codex (gpt-6.1-sol) on behalf of kylez
Forced colors drop the inset ring's box-shadow and replace the tint, which removed both cues that a reaction is yours. A 1px Highlight outline, inset like the ring, keeps it visible for high-contrast users. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: David Leslie <[email protected]>
* eva/huddle-audio-fixes: (29 commits) fix(huddle): keep calls flowing under stalled sends and multiple devices fix(channels): wrap unread conversation stepping around the sidebar (#2682) fix(navigation): let bare buzz:// open Buzz without a broken-link notice (#2718) fix(inbox): open DM thread rows as the thread (#2587) test(channels): complete the context navigation fixture (#2783) fix(channels): open a thread's channel at its root message from the #channel link (#2377) fix(people): find people by a pasted npub or hex key (#2396) test(bestie): open the narrow long-history thread with clickRow (#2723) Account-first onboarding and sign-in recovery (#2579) fix(agents): scroll the avatar dock with a mouse wheel (#2567) fix(avatars): keep Done in view when the avatar popup is short (#2706) feat(messages): highlight reactions you've made (#2709) feat(usage): move Usage from the sidebar into Settings (#2742) fix(messages): keep a playing row mounted in the channel timeline (#2695) Fix plugin status declaration closure for author consumers (#2643) fix(navigation): keep empty new chats out of Back history (#1617) [buzz-app] Recover remote agent message outcomes (#2542) feat(messages): name background send destinations and attach the files that fit (#2406) feat(drafts): clear a draft from its row (#2725) Authorize external application identities in Buzz (#2685) ... Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Tyler Longwell <[email protected]> Signed-off-by: Tyler Longwell <[email protected]> # Conflicts: # docs/huddles.md # src-tauri/src/relay/huddle/audio.rs
…leanup * origin/main: (84 commits) Restore macOS Cmd-W window closing when no tab handles it (#2443) Make agent transcripts quieter and link finished replies to activity (#2424) fix(channels): wrap unread conversation stepping around the sidebar (#2682) fix(navigation): let bare buzz:// open Buzz without a broken-link notice (#2718) fix(inbox): open DM thread rows as the thread (#2587) test(channels): complete the context navigation fixture (#2783) fix(channels): open a thread's channel at its root message from the #channel link (#2377) fix(people): find people by a pasted npub or hex key (#2396) test(bestie): open the narrow long-history thread with clickRow (#2723) Account-first onboarding and sign-in recovery (#2579) fix(agents): scroll the avatar dock with a mouse wheel (#2567) fix(avatars): keep Done in view when the avatar popup is short (#2706) feat(messages): highlight reactions you've made (#2709) feat(usage): move Usage from the sidebar into Settings (#2742) fix(messages): keep a playing row mounted in the channel timeline (#2695) Fix plugin status declaration closure for author consumers (#2643) fix(navigation): keep empty new chats out of Back history (#1617) [buzz-app] Recover remote agent message outcomes (#2542) feat(messages): name background send destinations and attach the files that fit (#2406) feat(drafts): clear a draft from its row (#2725) ... # Conflicts: # src/bundled/builderlab/adapter-type/Activity.test.tsx
) ## Problem Three costs add up while a busy channel is open and new messages arrive. - **Reading observation restarts on every message.** `useReading` lists `latestMessageId` as an effect dependency, so each new latest message tears down the effect and runs it again. That disposes the reading lease, the observers and the listeners, then measures rows synchronously in the passive-effect phase (`getClientRects` / `getBoundingClientRect`). The result is a forced layout per message, and a dwell that new messages arriving faster than 300 ms never let complete. - **Activity reactions feed pruning.** #2638 added this feed. On every channel-list notification, which live messages trigger, it prunes up to 100 items with `allowed(item.channelId)`. Each call rescans the list and runs `members.includes(viewer)`, even though the callback has just built the same allowed set. - **Own-reaction ring.** #2709 draws the ring with an inset `box-shadow`, which adds paint-bound long-animation-frame blocking while the pointer rests on a message. ## Change This PR combines three changes: - `useReading` reads the latest message id through `useEffectEvent` at measurement time, and it is no longer an effect dependency. A new latest message already mutates the list, and the existing mutation observer remeasures it in the next frame. - The reactions prune filter uses `next.has(item.channelId)`, the set built a few lines above from the same list snapshot and predicate. - The own-reaction ring is drawn with `outline: 1px solid` and `outline-offset: -1px` instead of the inset shadow. It uses the same color variables, and in forced-colors mode only `outline-color: Highlight` is set. ## No behavior changes - **Reading.** - The latest id is read when the bottom row is measured, so catch-up still targets the newest rendered row. `catchUp` itself still skips when a newer row exists and revalidates its target. - If the latest id changes with no DOM mutation, the bottom check finds no matching shown row, the same outcome as the old restart. - `rootId`, `channelId`, `session` and `enabled` still restart the effect. - A new test checks that a new latest id neither restarts observation nor takes a lease, and that catch-up reaches the new row after it is measured. The test fails without this change. - **Reactions.** `next` holds exactly the ids `allowed` would accept, built from the same snapshot with no `await` before the filter. `load` and `eventVisibility` still call `allowed`. - **Ring.** It has the same width, color and position, inside the pill's border box, and follows the capsule radius. An outline paints above the pill's content and an inset shadow below it. The pill's button is transparent at rest and the hover glyph is transformed, so the ring looks the same. Outlines follow `border-radius` from Safari 16.4 / WebKitGTK 2.40. ## Evidence Main `8c0cb0c1e` and this PR were interleaved for 6 rounds on 4 Linux and 5 macOS workstations. Each workstation's median is taken first, and the table shows the mean of those medians. - **Browser rows.** Production build, Chromium at 4× CPU throttling. Traffic appends a message every 200 ms to the open channel and to another one. - **pointer on message:** the pointer rests on a message, which reveals its action bar, for 4.5 s. - **no pointer:** the same run with the pointer away. - **at rest:** the channel stays open for 3 s with no interaction. - **Unit row.** Vitest micro-benchmark with 400 channels, one of them with 5,001 members and the viewer at the end of its list, and 100 reaction items in that channel. It delivers 50 channel-list notifications. It ran on 2 Linux and 2 macOS workstations. | metric | Linux: main | Linux: this PR | Linux Δ % | macOS: main | macOS: this PR | macOS Δ % | |---|---|---|---|---|---|---| | pointer on message: blocking | 156.2 ms | 35.3 ms | −77.4% | 32.3 ms | 0.0 ms | −100% | | pointer on message: task | 2,017.7 ms | 1,997.4 ms | −1.0% | 1,458.1 ms | 1,461.7 ms | +0.2% (noise) | | pointer on message: script | 1,028.8 ms | 1,010.5 ms | −1.8% | 644.5 ms | 640.2 ms | −0.7% (noise) | | no pointer: blocking | 133.9 ms | 13.7 ms | −89.8% | 25.6 ms | 0.0 ms | −100% | | no pointer: task | 1,843.9 ms | 1,864.5 ms | +1.1% (noise) | 1,365.2 ms | 1,353.7 ms | −0.8% | | at rest: task | 318.0 ms | 324.4 ms | +2.0% (noise, one box +11%) | 235.1 ms | 236.0 ms | +0.4% (noise) | | reactions list callback ×50 (unit) | 464.4 ms | 6.9 ms | −98.5% | 309.0 ms | 4.0 ms | −98.7% | Lower is better. Blocking is long-animation-frame blocking time. Every workstation moved the same way on both blocking rows (per box: Linux −77.0% to −77.9% and −88.1% to −91.9%; macOS −100% on all five). Neither variant blocks in the at-rest run. Checks: - The `messages` vitest suites pass (96 files, 2,835 tests). - `inbox-reactions` passes (10 tests). - `tsc`, `biome` and `check-contrast` pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
…ring (#2949) Follow-up to #2709, per design review feedback. Reactions you've made drop the 1px ring, and their fill swaps between the two bubble colors so they never sit as a highlight on a highlight. - **On someone else's message (and on the panel):** your reaction takes your own bubble's fill and ink (`surface-message-own` / `text-message-own`). - **On your own message:** it takes the received bubble's fill and ink (`surface-message` / `text-standard`). - New `text-reaction-self` / `text-reaction-self-own` roles pair the count's ink with each fill. `affordance-reaction-self` / `-own` now point at the bubble fills, and the Buzzin' strong-overlay override is gone. - Removes the `border-reaction-self` / `border-reaction-self-own` tokens, their utilities, registry entries and contrast checks. - Forced-colors mode keeps a `Highlight` ring, since it replaces the fills and the ring is then the only visual mark. - Updates DESIGN.md and buzz-help.md. Checks: `pnpm design:check` (contrast pairs updated), `pnpm design:test`, `MessageReactions.test.tsx`, biome. Screenshots taken in Chromium from `tests/fixtures/emoji.html?reactions&wrap` (with a local, uncommitted tweak that makes the message someone else's), light/dark × Chillin'/Buzzin'. --------- Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Reactions you've made now stand out from everyone else's. A reaction pill that includes you keeps an accent tint and a thin accent ring after the pointer leaves, so you can see at a glance which emoji you've already added.
How it looks
Changes
MessageReactionsmarks the pill withdata-mine, reusing themineflag it already computes foraria-pressed.Messages.module.cssstyles that marker through the same per-bubble--reaction-*overrides the existing reaction colors use.affordance-reaction-selfandborder-reaction-self, plus-ownvariants for inside your bubble. They're defined intokens.css, registered in the token registry and the--border-color-*theme namespace, and paired in the contrast guard.DESIGN.mdandbuzz-help.mddescribe the new state.Reactions used to have a pressed highlight, which was dropped in the message-bubble redesign (#773). Design should confirm bringing a highlight back in this form.
Screenshots
Fixture message with a teammate's reactions, where you've also reacted 👍 and ✅.
🤖 Generated with Claude Code