Skip to content

feat(mobile): copy button on each code block in chat - #34039

Merged
AmoabaKelvin merged 4 commits into
mainfrom
mobile-chat-code-block-copy
Oct 26, 2026
Merged

AmoabaKelvin merged 4 commits into
mainfrom
mobile-chat-code-block-copy

Conversation

@AmoabaKelvin

@AmoabaKelvin AmoabaKelvin commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 6 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​12 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​12
Prod 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​18 $\color{#cf222e}{\Huge{\mathbf{−}}}$​8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​10

ELI5

Code blocks in the phone's chat now have their own copy button. You can grab just the command instead of copying the whole reply and trimming it.

What Changed

Before: the only copy button in mobile chat copied the whole message.

After: each code block has a small copy icon in its top-right corner. It copies only that block's code. After a tap the icon turns into a green check for 1.5s, the same feedback as the message copy button. Empty code blocks get no button.

How: renderCode in mobile/src/components/mobile-markdown-blocks.tsx lays the block out as a row: the language label and code on the left, and the existing MobileSourceCopyButton on the right. Every MobileMarkdown surface goes through this one renderer, so task comments and the Markdown file preview get the button too, as desktop's markdown preview already does. A Mermaid fence keeps the button while it's still showing as code and loses it when the diagram replaces the block, the same as desktop chat.

Why

Copying one command out of a long reply on a phone meant copying everything and editing it down by hand. Desktop chat has had a per-block copy button since #20357.

This builds on #32270 by @radut, the issue's author, and keeps their two commits. My two commits on top:

  • Mermaid: removed the rule that hid the button on a streaming Mermaid fence, to match desktop.
  • Layout: moved the button out of the header row into a column beside the code. Before, an unlabeled block grew a 24pt empty strip above the code just to hold the button. Now labeled blocks keep their height, and an unlabeled one-line block grows by about 3pt.

Linked Issue

Fixes #32280

Linear: STA-11848. Copy for shell commands detected outside code fences is a separate ticket: STA-11907 / #32773.

Visual Proof

iPhone 18 Pro simulator, iOS 27, Safari, in a react-native-web harness of MobileMarkdown with chat props. iOS builds draw chat in that web page.

Before (main) After After tapping copy

Tap, then the check, then the copy icon again after 1.5s:

after-copy.mp4

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • Manual: on the iOS simulator, tapping the first block's button put exactly pnpm test --filter mobile on the clipboard, and the second block's put git push -u origin my-branch. A long line still wraps inside the narrower code column.

  • New test: MobileMarkdown.rendering.test.tsx checks that each block's button holds only that block's code. It fails on main.

  • Test mocks: five markdown test files mock the button, the same way they already mock MermaidDiagram.

  • Focused runs: the mobile src/components, src/session, src/files and src/tasks tests pass (485 files), as do the page route grant census, check:code-quality:changed and check:react-doctor:changed.

AI Disclosure

Review

  • Clipboard permission on iOS: on iOS the page writes the clipboard through the app's native.clipboard.write verb. Every page route that renders MobileMarkdown (session, tasks, file explorer and preview, source control, review) already declares that permission, and the grant census test passes.
  • Android: on Android the native app writes through expo-clipboard.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

The change is mobile only. It touches no desktop, SSH or wire protocol code, so phone and desktop versions can mix freely. PR comment code blocks (pr-sidebar/CommentMarkdown.tsx) have their own renderer and are left as they are.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@AmoabaKelvin
AmoabaKelvin marked this pull request as ready for review October 26, 2026 19:46
@coderabbitai

coderabbitai Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3f16b430-1982-4ae7-bf0b-3c1ac708c532
Commits

Reviewing files that changed from the base of the PR and between caa49c8 and 5f62df3.

Files selected for processing: 8
  • mobile/src/components/MobileMarkdown.file-links.test.ts
  • mobile/src/components/MobileMarkdown.rendering.test.tsx
  • mobile/src/components/mobile-markdown-android-selection.test.tsx
  • mobile/src/components/mobile-markdown-blocks.tsx
  • mobile/src/components/mobile-markdown-mermaid-routing.test.ts
  • mobile/src/components/mobile-markdown-selectable.test.tsx
  • mobile/src/components/mobile-markdown-styles.ts
  • mobile/src/components/mobile-markdown-table.test.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

Walkthrough

Mobile Markdown code blocks now show a “Copy code” button when their source is nonempty. The code block layout places the language label and selectable source text beside the button. Rendering tests check that separate code blocks receive buttons with only their own code. Other MobileMarkdown tests mock the button component.

Priority: Low

Severity of issue fixed: Low

Merge Risk: Minimal · up to 5f62d

No actionable merge-blocking risk remains from the reviewed changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 8 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: adding a copy button to each mobile chat code block.
Description check Passed The description is complete and aligned with the repository template. It includes the user-facing change, rationale, linked issue, visual proof, testing details, review notes, scope, and checklist. Th…
Linked Issues check Passed Issue #32280 requires a separate copy button for each mobile code block. renderCode in mobile/src/components/mobile-markdown-blocks.tsx renders MobileSourceCopyButton with the block's `node.valu…
Out of Scope Changes check Passed The changed production files implement the shared mobile Markdown code-block layout and button. The changed test files mock that button or verify its block-specific values. The style change supports t…
Full details: Description check

Explanation

The description is complete and aligned with the repository template. It includes the user-facing change, rationale, linked issue, visual proof, testing details, review notes, scope, and checklist. The full lint, typecheck, test, and build commands remain unchecked, but this is not critical because focused validation and CI coverage are documented.

Full details: Linked Issues check

Explanation

Issue #32280 requires a separate copy button for each mobile code block. renderCode in mobile/src/components/mobile-markdown-blocks.tsx renders MobileSourceCopyButton with the block's node.value and omits it for empty blocks. Mermaid blocks keep this path while they render as code and switch to MermaidDiagram when complete. MobileMarkdown.rendering.test.tsx verifies that two buttons receive only their respective code values. The existing button supplies the copy action and 1.5-second success feedback.

Full details: Out of Scope Changes check

Explanation

The changed production files implement the shared mobile Markdown code-block layout and button. The changed test files mock that button or verify its block-specific values. The style change supports the requested row layout. These changes support issue #32280. No unrelated desktop, SSH, wire protocol, or separate shell-command detection implementation is present in the supplied change summary.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AmoabaKelvin
AmoabaKelvin merged commit c4f8fe5 into main Oct 26, 2026
45 checks passed
@AmoabaKelvin
AmoabaKelvin deleted the mobile-chat-code-block-copy branch October 26, 2026 20:00
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.

Mobile chat: no copy button on individual code blocks

2 participants