Skip to content

fix(desktop): render text reaction fallbacks safely - #4996

Open
AaronGoldsmith wants to merge 4 commits into
block:mainfrom
AaronGoldsmith:boz/reaction-text-fallback
Open

fix(desktop): render text reaction fallbacks safely#4996
AaronGoldsmith wants to merge 4 commits into
block:mainfrom
AaronGoldsmith:boz/reaction-text-fallback

Conversation

@AaronGoldsmith

@AaronGoldsmith AaronGoldsmith commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Render no-URL literal kind-7 reactions as bounded text unless the content is exactly one well-formed native emoji grapheme.
  • Strip only valid outer shortcode colons for presentation (for example, :missing_reaction: displays as missing_reaction), while preserving raw reaction content for titles, accessibility, and toggle identity.
  • Apply the same bounded fallback presentation in hover popovers so unresolved shortcodes and long arbitrary text cannot overflow the fixed glyph area; the separate reaction name remains raw.
  • Keep image custom emoji exclusively driven by the NIP-30 emojiUrl branch.
  • Bound and left-align long literal reaction text so it truncates without overlapping its count.

Kind-7 reaction content is literal under NIP-25, so existing or legacy arbitrary-text events retain their meaning and are rendered safely rather than rejected. NIP-30's matching emoji tag / resolved emojiUrl remains the only custom-image signal.

This is intentionally different from:

This PR is Desktop-only: it changes no relay ingest, persistence, protocol, or channel derivation. A possible CLI warning for an unknown :shortcode: sent without --emoji-url is intentionally deferred and not coupled to rendering compatibility.

Reproduction

buzz reactions add --event <event-id> --emoji :missing_reaction:

The resulting kind-7 event has no matching NIP-30 emoji tag, so Desktop must treat the content as a text fallback rather than forcing it into a native-emoji box.

Testing

  • pnpm biome check src/features/messages/ui/MessageReactions.tsx src/features/messages/lib/reactionGlyphPresentation.ts src/features/messages/lib/reactionGlyphPresentation.test.mjs src/shared/lib/emojiOnly.ts tests/e2e/reaction-names.spec.ts
  • pnpm test (4,373 passed)
  • pnpm build:e2e
  • pnpm exec playwright test tests/e2e/reaction-names.spec.ts (3 passed), covering:
    • NIP-30 custom-image hover regression
    • unresolved shortcode pill + hover popover
    • arbitrary ship it pill + hover popover
    • long literal pill/count geometry, truncation, and hover overflow bounds
  • sq agents review main...HEAD --local ... after addressing its malformed-ZWJ finding (final local review: no findings)
Screenshots from Testing

Pill row: unresolved shortcode, arbitrary text, and long literal text — each bounded, left-aligned, and truncated without overlapping its count

reaction-text-fallback
Case Rendering
Short unresolved shortcode in hover popover — outer colons preserved in the raw reaction name short-name-after
Max-length literal content in hover popover — wraps within the popover instead of overflowing the glyph area max-length-after

Original UI rendering bug example

image

Bozo and others added 4 commits August 5, 2026 17:54
Co-authored-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Signed-off-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Co-authored-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Signed-off-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Co-authored-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Signed-off-by: Bozo <c52c3b2f8ad8558a64330f4f9929518e12d500f76e2d7d3aca75ebe7f7a79ea7@buzz.block.builderlab.xyz>
Co-authored-by: SmartyP <bc4b2dcdb5359ccde0d49f65d1dda695890634a6a3bcc82346e38232934a75d9@buzz.block.builderlab.xyz>
Co-authored-by: Smarty <bc4b2dcdb5359ccde0d49f65d1dda695890634a6a3bcc82346e38232934a75d9@buzz.block.builderlab.xyz>
Signed-off-by: SmartyP <bc4b2dcdb5359ccde0d49f65d1dda695890634a6a3bcc82346e38232934a75d9@buzz.block.builderlab.xyz>
@AaronGoldsmith
AaronGoldsmith marked this pull request as ready for review August 6, 2026 14:45
@AaronGoldsmith
AaronGoldsmith requested a review from a team as a code owner August 6, 2026 14:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e051586218

ℹ️ 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".

}

function isNativeEmojiCluster(cluster: string): boolean {
export function isNativeEmojiCluster(cluster: string): boolean {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document or stop exporting the emoji helpers

This commit turns both isNativeEmojiCluster and readGrapheme into exported APIs without adding doc comments, even though both remain implementation details used only within emojiOnly.ts. Keep them private or document the contract and edge-case behavior of each exported helper as required for new public APIs.

AGENTS.md reference: AGENTS.md:L116-L116

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant