Skip to content

feat(messages): quote selected message text into the composer - #2392

Merged
rnc505 merged 3 commits into
block:mainfrom
rnc505:robbyc/quote-selection
Nov 13, 2026
Merged

rnc505 merged 3 commits into
block:mainfrom
rnc505:robbyc/quote-selection

Conversation

@rnc505

@rnc505 rnc505 commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

What

Select text in a message, then click the Quote button that appears (or press Q) to add it to your draft as a quote. A selection in a thread goes into that thread's reply box.

Why

Replying to one specific line currently means copying, pasting and formatting the quote by hand.

How

  • The composer gets insertQuote(html), which appends the timeline's existing copy payload as a blockquote in one undo step. Quoted mentions don't notify anyone.
  • A floating SelectionQuote button and a "Quote selected text" host shortcut (Q, rebindable) send the selection to the composer of the list it belongs to. No FOUNDATION files change.

Testing

  • 12 new unit tests cover the composer insert, selection routing, the button and Q. The button-press test fails without the second commit's fix.
  • No browser journeys were added; selection placement was checked by hand in Chromium on the relay-composer fixture.
  • Robby tested it in the desktop app. CI's WebKit journeys pass; light theme and narrow windows weren't checked separately.

Demo

The demo uses the local relay-composer fixture with made-up messages. The phrase selections are scripted; the clicks, Q and typing are real input.

quote-selection-demo-captioned.mp4

buzz-review-completed

🤖 Generated with Claude Code

@rnc505
rnc505 marked this pull request as ready for review November 4, 2026 15:27
@rnc505
rnc505 requested a review from a team as a code owner November 4, 2026 15:27

@kazemek21 kazemek21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 Kyle reviewed the PR and the Nexus review-tracker notes and approved with the non-blocking comment below.

Posted by Codex (gpt-6.1-sol) on behalf of kylez

current.current.onPasteTooLong?.();
return false;
}
editor.dispatch(tr.scrollIntoView());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 [P2] Keep reply typing separate from the quote’s undo step

If I quote a message and immediately type below it, the new text can join the quote insertion’s history group. Undo then removes both my reply and the quote. Should this set the existing separateHistory flag after the insertion succeeds, so the first Undo removes only the reply and the next removes the quote?

Posted by Codex (gpt-6.1-sol) on behalf of kylez

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 Good catch, fixed in 0219e9c. insertQuote now sets separateHistory after a successful dispatch, the same as the pending-mention insert. The existing undo test now checks each step: the first Undo removes only the reply, and the second removes the quote. It fails without the fix.

@gilgtm gilgtm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 Approved as requested for commit 08bd3bcc9de786cf9c097bcadbc88f4f6621486b.

Posted by Codex (gpt-6.1-sol/high) on behalf of gilgtm.

@rnc505
rnc505 force-pushed the robbyc/quote-selection branch from 08bd3bc to 0219e9c Compare November 9, 2026 18:53
rnc505 and others added 3 commits November 9, 2026 13:37
Selecting text in a channel timeline or thread shows a Quote button beside
the selection; Q does the same. The selection is added after that
conversation's own draft as a blockquote, with the caret on a new line
below it. Quoted formatting and links survive as they do through copy and
paste, but quoting never adds notification recipients.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Signed-off-by: Robby Cohen <[email protected]>
Pressing Quote no longer hides it before the click lands. It also hides
behind modals, while its selection is scrolled out of the list, and while
the composer is editing a sent message, which a quote must not rewrite.
The copy and quote paths share one timeline payload helper.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Signed-off-by: Robby Cohen <[email protected]>
Typing straight after quoting could join the quote's undo step, so one
Undo removed both. Mark the next edit as a separate history step, as the
pending-mention insert already does.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Signed-off-by: Robby Cohen <[email protected]>
@rnc505
rnc505 force-pushed the robbyc/quote-selection branch from 0219e9c to 34fe068 Compare November 9, 2026 19:41
@tellaho

tellaho commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

🤖 Could we hold the new Quote action and Q shortcut until after the Nov 10 event? They add a core composer interaction beyond the contained repairs allowed during the current UI/UX frost. New UX follows the external-plugin policy.

@rnc505

rnc505 commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

🤖 @tellaho The Nov 10 event has passed, and buzz-app has been merging feature work again since Nov 12 (e.g. #3316 right-click message actions, #2550 find-on-screen). Should we treat the UI/UX frost as lifted and land this as reviewed? The PR is approved and CI is green — happy to ship it as a plugin instead if you'd still prefer that.

🤖 @gilgtm @kazemek21 — you both approved this PR and CI is green at 34fe068. Once Taylor confirms the frost is lifted, could either of you merge it?

@rnc505
rnc505 merged commit fb3e403 into block:main Nov 13, 2026
62 checks passed
joshfriend added a commit that referenced this pull request Nov 13, 2026
* origin/main: (153 commits)
  feat(agents): preview where interrupted agents were working before resume (#3494)
  perf(messages): close the editor and delete dialog on submit (#3493)
  feat(messages): quote selected message text into the composer (#2392)
  perf(toast): scope docked clearance to the toast host (#3489)
  fix(unread): undo exact captured ordinary reads conditionally (#3473)
  fix(solo): keep navigation responsive during chat deletion (#3488)
  fix(channels): keep custom thread tab names until the tab closes (#3458)
  perf(relay): verify cached history in the native host (#3426)
  fix(settings): refine claude and typesafe key setup dialogs (#3391)
  Update bundled help for Bestie and agent settings (#3194)
  feat(profiles): share and show a local time zone (#3332)
  Revert "feat(link-previews): unfurl web links below messages by default" (#3480)
  Show disabled plugin chats in Solo (#3456)
  perf(messages): host one context menu per message list (#3465)
  test(claude): keep the quit-release test copy above the minimum version (#3477)
  fix(profiles): restore verified names from the device cache (#3382)
  fix(mentions): show addressed agents first in Solo audience picker (#2856)
  perf: count member access once and scope find highlights to painting (#3464)
  perf(messages): prepare a message once for its renderer and link previews (#3466)
  fix(composer): speed up long pastes and paste office text as text (#3441)
  ...

# Conflicts:
#	docs/plugin-authoring-guide.md
joshfriend added a commit that referenced this pull request Nov 13, 2026
…when-ready

* origin/main: (21 commits)
  fix(agents): report a conversation wake that fails before its turn starts (#2192)
  fix(usage): read Claude transcripts over 50 MB a page at a time (#3498)
  feat(agents): preview where interrupted agents were working before resume (#3494)
  perf(messages): close the editor and delete dialog on submit (#3493)
  feat(messages): quote selected message text into the composer (#2392)
  perf(toast): scope docked clearance to the toast host (#3489)
  fix(unread): undo exact captured ordinary reads conditionally (#3473)
  fix(solo): keep navigation responsive during chat deletion (#3488)
  fix(channels): keep custom thread tab names until the tab closes (#3458)
  perf(relay): verify cached history in the native host (#3426)
  fix(settings): refine claude and typesafe key setup dialogs (#3391)
  Update bundled help for Bestie and agent settings (#3194)
  feat(profiles): share and show a local time zone (#3332)
  Revert "feat(link-previews): unfurl web links below messages by default" (#3480)
  Show disabled plugin chats in Solo (#3456)
  perf(messages): host one context menu per message list (#3465)
  test(claude): keep the quit-release test copy above the minimum version (#3477)
  fix(profiles): restore verified names from the device cache (#3382)
  fix(mentions): show addressed agents first in Solo audience picker (#2856)
  perf: count member access once and scope find highlights to painting (#3464)
  ...
joshfriend added a commit that referenced this pull request Nov 13, 2026
…n-on-github

* origin/main: (21 commits)
  fix(agents): report a conversation wake that fails before its turn starts (#2192)
  fix(usage): read Claude transcripts over 50 MB a page at a time (#3498)
  feat(agents): preview where interrupted agents were working before resume (#3494)
  perf(messages): close the editor and delete dialog on submit (#3493)
  feat(messages): quote selected message text into the composer (#2392)
  perf(toast): scope docked clearance to the toast host (#3489)
  fix(unread): undo exact captured ordinary reads conditionally (#3473)
  fix(solo): keep navigation responsive during chat deletion (#3488)
  fix(channels): keep custom thread tab names until the tab closes (#3458)
  perf(relay): verify cached history in the native host (#3426)
  fix(settings): refine claude and typesafe key setup dialogs (#3391)
  Update bundled help for Bestie and agent settings (#3194)
  feat(profiles): share and show a local time zone (#3332)
  Revert "feat(link-previews): unfurl web links below messages by default" (#3480)
  Show disabled plugin chats in Solo (#3456)
  perf(messages): host one context menu per message list (#3465)
  test(claude): keep the quit-release test copy above the minimum version (#3477)
  fix(profiles): restore verified names from the device cache (#3382)
  fix(mentions): show addressed agents first in Solo audience picker (#2856)
  perf: count member access once and scope find highlights to painting (#3464)
  ...
joshfriend added a commit that referenced this pull request Nov 13, 2026
* origin/main: (31 commits)
  Let plugin panels name their tab with panels.useTabTitle (#3251)
  fix(agents): report a conversation wake that fails before its turn starts (#2192)
  fix(usage): read Claude transcripts over 50 MB a page at a time (#3498)
  feat(agents): preview where interrupted agents were working before resume (#3494)
  perf(messages): close the editor and delete dialog on submit (#3493)
  feat(messages): quote selected message text into the composer (#2392)
  perf(toast): scope docked clearance to the toast host (#3489)
  fix(unread): undo exact captured ordinary reads conditionally (#3473)
  fix(solo): keep navigation responsive during chat deletion (#3488)
  fix(channels): keep custom thread tab names until the tab closes (#3458)
  perf(relay): verify cached history in the native host (#3426)
  fix(settings): refine claude and typesafe key setup dialogs (#3391)
  Update bundled help for Bestie and agent settings (#3194)
  feat(profiles): share and show a local time zone (#3332)
  Revert "feat(link-previews): unfurl web links below messages by default" (#3480)
  Show disabled plugin chats in Solo (#3456)
  perf(messages): host one context menu per message list (#3465)
  test(claude): keep the quit-release test copy above the minimum version (#3477)
  fix(profiles): restore verified names from the device cache (#3382)
  fix(mentions): show addressed agents first in Solo audience picker (#2856)
  ...
philazar added a commit that referenced this pull request Nov 13, 2026
…ve-client

* origin/main:
  feat(solo): smooth chat recency reordering (#3502)
  Reject self-mentions that cannot wake another session (#3513)
  feat(status): offer don't clear for every status (#3515)
  Let plugin panels name their tab with panels.useTabTitle (#3251)
  fix(agents): report a conversation wake that fails before its turn starts (#2192)
  fix(usage): read Claude transcripts over 50 MB a page at a time (#3498)
  feat(agents): preview where interrupted agents were working before resume (#3494)
  perf(messages): close the editor and delete dialog on submit (#3493)
  feat(messages): quote selected message text into the composer (#2392)
  perf(toast): scope docked clearance to the toast host (#3489)
  fix(unread): undo exact captured ordinary reads conditionally (#3473)

Signed-off-by: Philip Azar <[email protected]>
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.

4 participants