Skip to content

Conversation

@SannidhyaSah
Copy link
Collaborator

@SannidhyaSah SannidhyaSah commented Oct 26, 2025

Related GitHub Issue

Closes: #8837

Roo Code Task Context (Optional)

No Roo Code task context for this PR

Description

This PR implements the "Quote selection to reply" feature for the chat UI, enabling users to select text within a message and quote it in their response.

Implementation approach:

  • Added selection detection scoped to single messages via data-message-ts attributes on message containers
  • Floating icon-only overlay button (codicon-quote) appears near the selection when valid
  • Compact quote preview above the composer with dismiss control
  • Standardized context block format [context]\n> line1\n> line2\n[/context] prepended to outgoing messages
  • Keyboard shortcut: Cmd/Ctrl+Shift+Q to capture current selection
  • Overlay hides on scroll, blur, and selection changes for clean UX

Key design decisions:

  • Used useCallback for stable selection helpers to satisfy React hook dependencies
  • Fixed positioning for overlay to work with virtualized message lists
  • 1000-character clamp on quoted text to prevent excessive payloads
  • Plain text rendering in preview to avoid XSS risks

Files changed:

  • webview-ui/src/components/chat/ChatView.tsx: Core selection logic, overlay, preview, and injection
  • webview-ui/src/components/chat/ChatRow.tsx: Added data-message-ts attribute for selection scoping

Test Procedure

Automated tests:

cd webview-ui && npx vitest run

All existing tests pass (92 test files, 1094 tests passed).

Manual testing:

  1. Select text within a single message → quote overlay appears
  2. Select across multiple messages → overlay does not appear
  3. Click quote button → preview appears above composer
  4. Click dismiss X → preview disappears
  5. Send message with active quote → context block prepended correctly
  6. Use Cmd/Ctrl+Shift+Q → captures selection as quote
  7. Scroll while overlay visible → overlay hides

Lint validation:

pnpm lint

All lint checks pass (11 tasks successful).

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

Before:
No quote selection feature.

After:
Icon-only quote overlay appears near selection:

  • Codicon quote glyph in a rounded blue tile
  • Positioned just above the selected text
  • Accessible via aria-label and keyboard shortcut

Quote preview above composer:

  • Compact strip with quote icon, truncated text, and dismiss button
  • Clears after send

Documentation Updates

  • No documentation updates are required.

Additional Notes

The feature is entirely client-side and integrates cleanly with the existing virtualized message list. Future enhancements could include:

  • i18n for the "Quote selection" aria-label
  • Message metadata (author/timestamp) in preview
  • Context menu fallback for additional accessibility

Get in Touch

Discord username not provided


Important

Introduces a "Quote selection to reply" feature in chat, allowing users to quote selected text with an overlay button and keyboard shortcut, implemented in ChatView.tsx and ChatRow.tsx.

  • Behavior:
    • Adds "Quote selection to reply" feature in ChatView.tsx and ChatRow.tsx.
    • Users can select text in a message to quote it in their response.
    • Floating overlay button appears near selection; quote preview shown above composer.
    • Supports Cmd/Ctrl+Shift+Q shortcut for quoting selection.
    • Overlay hides on scroll, blur, or selection changes.
  • Implementation:
    • Uses data-message-ts for selection scoping in ChatRow.tsx.
    • asContextBlock() formats quoted text in ChatView.tsx.
    • Handles selection and overlay logic with useCallback and useState in ChatView.tsx.
    • Limits quoted text to 1000 characters to prevent excessive payloads.
  • UI/UX:
    • Quote overlay button uses codicon-quote icon.
    • Quote preview includes dismiss button and plain text rendering to avoid XSS.
    • Adjusts overlay position based on selection bounding box.

This description was created by Ellipsis for 6a3c407. You can customize this summary. It will automatically update as commits are pushed.

Use codicon-quote glyph in a rounded tile; keep aria-label for a11y. Wrap selection-scoping helpers in useCallback and add deps to satisfy lint. Ensure message containers carry data-message-ts for selection scoping.
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused labels Oct 26, 2025
@roomote
Copy link

roomote bot commented Oct 26, 2025

Review Complete

No issues found. The implementation is clean and well-structured:

✅ Uses useCallback correctly with proper dependencies
✅ Handles edge cases appropriately (empty selections, cross-message selections)
✅ Integrates cleanly with existing message sending logic
✅ Provides proper accessibility attributes
✅ Prevents XSS with plain text rendering
✅ Limits quote length to prevent excessive payloads

Follow Along on Roo Code Cloud

{quoteOverlay.visible && (
<button
type="button"
aria-label="Quote selection"
Copy link

Choose a reason for hiding this comment

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

Consider making the ARIA label for the quote overlay button translatable (e.g. using t('chat:quoteSelection')) instead of the hardcoded "Quote selection" to support i18n.

Suggested change
aria-label="Quote selection"
aria-label={t('chat:quoteSelection')}

This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX.

<div className="text-sm whitespace-pre-wrap flex-1 max-h-20 overflow-hidden">{activeQuote}</div>
<button
type="button"
aria-label="Dismiss quote"
Copy link

Choose a reason for hiding this comment

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

Similarly, the dismiss button uses a hardcoded ARIA label "Dismiss quote". Please update this to use a translatable string (e.g. t('chat:dismissQuote')).

Suggested change
aria-label="Dismiss quote"
aria-label={t('chat:dismissQuote')}

This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX.

@SannidhyaSah
Copy link
Collaborator Author

SannidhyaSah commented Oct 26, 2025

Screenshot 2025-10-26 at 1 12 55 PM Looks something like this Screenshot 2025-10-26 at 2 12 22 PM

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Oct 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

Add Quote Selection to Reply overlay in Chat UI

2 participants