Skip to content

Make copied chat content consistent across paste destinations #104772

Open

Description

@carlosmiceli

Problem

Copying chat content creates different results depending on the copy path and paste destination, even when the same message content was copied.

For example, copying two messages can paste as:

first messagesecond message

in a plain-text destination, but as:

first message
second message

in the New Expensify composer because it reads the clipboard's HTML flavor. Copy message can also produce rich HTML, Markdown-only text, or generated plain text depending on the report-action type.

HTML fallback is inconsistent as well: empty or unsupported text/html data can override valid plain text and paste nothing, and HTML clipboard support is not reliably detected or handled when a write fails.

Selection stability, visual ordering, and FlashList behavior are tracked separately in #37447 and are not part of this issue.

Expected result

Copied chat content should have a consistent, destination-appropriate result:

  • Message and paragraph boundaries are preserved in both HTML and plain text.
  • Rich-text destinations retain useful formatting and named links.
  • Plain-text destinations receive readable text without merged rows or unexpected Markdown syntax.
  • Copy message produces the same content as copying the whole visible message, regardless of report-action type.
  • The composer uses valid HTML when available and falls back to valid plain text when HTML is empty, unsupported, or fails to write.
  • Existing URL, email, message-link, and attachment copy/paste behavior remains unchanged.

Implementation considerations

Relevant code includes:

  • src/hooks/useCopySelectionEvent.ts
  • src/libs/Clipboard/index.ts
  • src/libs/Clipboard/getClipboardText
  • src/hooks/useHtmlPaste/index.ts
  • src/pages/inbox/report/ContextMenu/ContextMenuActions.tsx

Prefer one shared clipboard payload contract, such as {html, plainText}, for painted chat selections and Copy message. Report-action-specific code can continue generating the visible message, but its final output should pass through the same clipboard formatter.

Also review HTML capability detection and asynchronous clipboard write failures so valid plain text remains available as a fallback.

Add tests covering single and multiple messages, message boundaries, rich formatting, links, report-action variants, both clipboard MIME flavors, empty HTML, unsupported HTML, and pasting into New Expensify versus a plain-text destination.

Activity

  1. self-assigned this
    on Oct 22, 2026
  2. carlosmiceli commented on Oct 22, 2026

    @carlosmiceli
    ContributorAuthor

    @mountiny @roryabraham would appreciate your feedback on this project's description before I open it up for contributors 🙏

    PS: I'm also just now noticing that we have this issue opened, so not sure if we'd like to merge them somehow, or keep them separate.

  3. changed the title [-]Make chat message copy and paste consistent[/-] [+]Make copied chat content consistent across paste destinations[/+] on Oct 22, 2026
  4. mountiny commented on Oct 23, 2026

    @mountiny
    Contributor

    I think the description looks good and we can align on edge cases the contributor might find along the way later also with the help of a design team

  5. mountiny commented on Oct 23, 2026

    @mountiny
    Contributor

    Might be good to get a C+ to work on this

  6. neerajbachani commented on Oct 23, 2026

    @neerajbachani
    Contributor

    Hi @carlosmiceli @mountiny, I have been working in this area. I fixed the Chrome multi-message copy bug in #102143 for #37447, also the two remaining Chrome drag bugs are a separate follow up in #104594, which I am working on now.. And while I was working on this area I also found the mashed plain-text case (this issue). I called that out as a follow up here: #37447 (comment)

    But this issue is a bigger project than that follow up (i mentioned), and the description makes the scope much clearer. I would love to work on it if that is possible.

    Can I take this on? If not, that is totally fair. If yes, I will post a detailed proposal with what I already know about this copy path.

    cc @Julesssss @eh2077

  7. carlosmiceli commented on Oct 23, 2026

    @carlosmiceli
    ContributorAuthor

    @neerajbachani I think that's a fair request, I actually crafted this proposal based also on what #37447 was not fixing, but I'd defer to whether @mountiny and @Julesssss believe it should be a C+ only.

  8. neerajbachani commented on Oct 26, 2026

    @neerajbachani
    Contributor

    Thanks @carlosmiceli, that's fair. I'll wait for @mountiny and @Julesssss to decide.

    One question while we wait. The description covers web, but I'm not sure what we want on iOS and Android. Native doesn't have an HTML clipboard right now. setHtml does nothing there, and the composer only reads plain text. So Copy message on native writes Markdown, and that's how bold and links still work when you paste back into the composer.

    My suggestion:

    • This issue: keep Markdown as the native clipboard string, and fix web so text/html keeps formatting and text/plain is readable text with message boundaries, as described.

    • Separate follow-up, if wanted: a real HTML clipboard on native. Write HTML and plain text together on copy (ClipData.newHtmlText on Android, an HTML and plain-text pasteboard item on iOS). Then convert pasted HTML back to Markdown before it reaches the composer. @react-native-clipboard/clipboard only exposes setString, so this needs native code. Shipping HTML copy without the paste side would make in-app paste lose formatting.

    Does keeping native as-is for this issue match what you had in mind?

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

Metadata

Metadata

Assignees

Labels

ImprovementItem broken or needs improvement.WeeklyKSv2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions