You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make copied chat content consistent across paste destinations #104772
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.
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.
changed the title [-]Make chat message copy and paste consistent[/-][+]Make copied chat content consistent across paste destinations[/+]on Oct 22, 2026
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.
@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.
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?
Activity
carlosmiceli commentedon Oct 22, 2026
@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.
[-]Make chat message copy and paste consistent[/-][+]Make copied chat content consistent across paste destinations[/+]mountiny commentedon Oct 23, 2026
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
mountiny commentedon Oct 23, 2026
Might be good to get a C+ to work on this
neerajbachani commentedon Oct 23, 2026
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
carlosmiceli commentedon Oct 23, 2026
@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.
neerajbachani commentedon Oct 26, 2026
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.
setHtmldoes 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/htmlkeeps formatting andtext/plainis 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.newHtmlTexton 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/clipboardonly exposessetString, 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?