Skip to content

feat(web-chat): add hover copy button for user/assistant messages - #948

Merged
zmanian merged 6 commits into
nearai:stagingfrom
G7CNF:codex/issue-946-hover-copy-chat
Mar 12, 2026
Merged

zmanian merged 6 commits into
nearai:stagingfrom
G7CNF:codex/issue-946-hover-copy-chat

Conversation

@G7CNF

@G7CNF G7CNF commented Mar 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds OpenClaw-style message-level copy controls to the web chat UI.

Changes

  • Add Copy button on user and assistant message bubbles.
  • Show button on hover/focus (and always visible on touch devices).
  • Copy full message content to clipboard with quick feedback (Copied/Failed).
  • Preserve existing code-block copy behavior.
  • Keep assistant streaming updates compatible by rendering into .message-content while keeping copy controls intact.

Before

  • No message-level copy control existed for full user/assistant bubbles.
  • Only code blocks had copy buttons.

After

  • Every user/assistant bubble has a copy affordance matching common chat UX.
  • Clicking copy on a bubble copies the full message content.

Validation

  • Browser smoke test on local web UI (http://127.0.0.1:3000):
    • .message-copy-btn present for rendered conversation bubbles.
    • Clicking first message copy button changed label Copy -> Copied.
    • Count observed in-session: 37 copy buttons for loaded history.
  • Runtime rebuild/restart completed on local install:
    • ironclaw 0.17.0
    • service running/loaded

Tracking

Closes #946

@github-actions github-actions Bot added scope: channel/web Web gateway channel scope: ci CI/CD workflows size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: new First-time contributor labels Mar 11, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant user experience improvement by adding intuitive message-level copy controls to the web chat interface. Users can now easily copy the full content of any user or assistant message, bringing the UI in line with common chat application patterns and enhancing overall usability.

Highlights

  • Message-level Copy Controls: Added a 'Copy' button to both user and assistant message bubbles within the web chat UI.
  • Dynamic Visibility: The copy button now appears on hover or focus for desktop users and remains always visible on touch devices.
  • Clipboard Functionality: Implemented functionality to copy the full message content to the clipboard, providing quick feedback like 'Copied' or 'Failed'.
  • Compatibility: Ensured that existing code-block copy behavior is preserved and that assistant message streaming updates remain compatible with the new copy controls.
Changelog
  • src/channels/web/static/app.js
    • Introduced a new copyMessage function to handle clipboard operations for message content.
    • Refactored the addMessage function to utilize the new createMessageElement for message rendering.
    • Modified appendToLastAssistant to correctly set data-copy-text and update content within the new .message-content element during streaming.
    • Enhanced createMessageElement to dynamically add a copy button and wrap message content in a .message-content div for user and assistant roles.
  • src/channels/web/static/style.css
    • Added position: relative to the .message class to correctly position the new copy button.
    • Introduced new CSS classes (.message.has-copy, .message-content, .message-copy-btn) to style the copy button and its container.
    • Implemented styles for hover and focus states to control the visibility of the copy button.
    • Added a media query to ensure the copy button is always visible on touch devices.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/staging-ci.yml
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds a useful copy button to user and assistant messages, improving the chat UI's usability. The implementation is mostly solid, with good use of CSS for a clean user experience on both desktop and mobile. I've found a couple of potential issues in the JavaScript logic: one is a minor UI bug in the copy button's state handling, and the other is a more significant issue where the copy button could be removed during message streaming. My review includes suggestions to fix both.

Comment thread src/channels/web/static/app.js Outdated
Comment thread src/channels/web/static/app.js Outdated

@zmanian zmanian left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good -- clean implementation.

XSS: Safe. User content set via textContent. Assistant content goes through DOMPurify. The data-copy-text attribute is only read via getAttribute() and passed to clipboard.writeText(), never injected as HTML.

Accessibility: Solid. aria-label, :focus-visible outline, :focus-within on parent to reveal button on keyboard navigation.

CSS: Clean use of CSS custom properties, appropriate position: relative anchor, good @media (hover: none) fallback for touch devices.

CSP: The new copy button uses addEventListener -- CSP-compliant. (Note: the pre-existing copyCodeBlock in renderMarkdown still uses inline onclick attribute injection on line 673, which is a CSP violation with the current script-src policy that lacks unsafe-inline. Not introduced by this PR, but worth a follow-up.)

UX: Hover-to-reveal with "Copied"/"Failed" feedback is good. The fallback chain (data-copy-text -> data-raw -> textContent) correctly handles both streamed and static messages.

LGTM.

@zmanian
zmanian merged commit 0b122cb into nearai:staging Mar 12, 2026
2 checks passed
@ironclaw-ci ironclaw-ci Bot mentioned this pull request Mar 12, 2026
@G7CNF
G7CNF deleted the codex/issue-946-hover-copy-chat branch March 15, 2026 14:31
bkutasi pushed a commit to bkutasi/ironclaw that referenced this pull request Mar 28, 2026
…arai#948)

* ci(staging): use default branch instead of hardcoded main

* feat(web-chat): add hover copy button for message bubbles

* fix(web-chat): address Gemini review for copy state and streaming safety

* chore(pr): drop unrelated staging workflow change from nearai#948
drchirag1991 pushed a commit to drchirag1991/ironclaw that referenced this pull request Apr 8, 2026
…arai#948)

* ci(staging): use default branch instead of hardcoded main

* feat(web-chat): add hover copy button for message bubbles

* fix(web-chat): address Gemini review for copy state and streaming safety

* chore(pr): drop unrelated staging workflow change from nearai#948
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: new First-time contributor risk: medium Business logic, config, or moderate-risk modules scope: channel/web Web gateway channel scope: ci CI/CD workflows size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(web-chat): hover copy button for user and assistant messages

2 participants