Skip to content

fix(mobile): Android composer paste no longer drops trailing text - #19590

Open
only21mil wants to merge 2 commits into
pingdotgg:mainfrom
only21mil:fix/android-composer-multi-item-paste
Open

only21mil wants to merge 2 commits into
pingdotgg:mainfrom
only21mil:fix/android-composer-multi-item-paste

Conversation

@only21mil

Copy link
Copy Markdown
Contributor

Problem

Android composer paste interception read only ClipData item 0. If that item triggered interception, trailing text items were silently dropped. A clip with a later URI item could also be partially intercepted, consuming the clip while forwarding only the first item's text.

Change

Join all text items in a URI-free clip with newlines before the existing input-length and byte-size checks, then emit the complete joined text. If any item has a URI, leave the entire clip on the native paste path. The helper checks each URI before coercing that item, so clipboard measurement makes no content-provider reads.

Scope and approval

This is a small, focused fix for obvious clipboard data loss under the exception in CONTRIBUTING.md. The two changed files are T3ComposerEditorView.kt, which owns clipboard extraction, and its existing ComposerPasteTest.kt regression suite in the Android composer module.

The overlap audit found #19114 unrelated to this fix. It changes Office-file preloading. #15030 and #18752 share the Android editor file but change hardware Return submission and touch/caret scrolling, respectively. Neither changes clipboard extraction or paste interception.

Verification

Five new Robolectric API-36 cases cover complete multi-item interception, native fallback with a URI in any item position, empty text, zero items, and single-item native paste with Undo. With JDK 21, the focused command from apps/mobile/android was ./gradlew :t3-composer-editor:testDebugUnitTest --tests 'expo.modules.t3composereditor.ComposerPasteTest' --console=plain.

With the base production file at 7ac952c and the same regression tests, 11 tests ran and two failed, exposing dropped trailing text and interception of a clip with a later URI. With the candidate production file, all 11 tests passed. git diff --check passed. ktlint was unavailable and was not run.

Device check

On Android 16 / API 36, both debug APKs used the same seeded, URI-free, three-item Android ClipData. Each run pasted into an empty composer through the real native long-press menu's Paste action.

Build APK SHA-256 Observed paste
Base 7ac952c 40531aa68986ca2a18c224edcbefefc723efb248851773734c511d46fa2afd09 Only item 1, exactly 32,768 bytes
Candidate 52590aa 74eb3bdce2812171b7cdc0cb7a404127092d89895908f25d15c42b3c3f273318 All three items, exactly 32,782 bytes including two newlines

The app-produced file bytes exactly matched the seeded first item before and the complete newline-joined clip after. Attachments to embed when posting:

  • before-14-preview.png shows the base preview.
  • after-11-preview-proven.png shows ITEM_2 and ITEM_3 below the first item.

Production fix 1b40176 written with Claude Opus 5.5 via claude_auto using the Claude Code harness; tests 52590aa written with GPT-6.1 Sol using the Codex harness, both in T3 Code.

only21mil and others added 2 commits October 14, 2026 12:18
The paste interceptor read only item 0 of the clip, so a folded or
input-limited paste silently dropped every later item. Join all URI-free
text items with newlines, as Android's native paste does, before the size
checks and event emission. Any URI item still leaves the whole clip to the
native path, with no provider read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 14, 2026
@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dd7c2bff-166f-4176-a965-835ecd541b58
📥 Commits

Reviewing files that changed from the base of the PR and between e47bfe4 and 52590aa.

📒 Files selected for processing: 2
  • apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt
  • apps/mobile/modules/t3-composer-editor/android/src/test/java/expo/modules/t3composereditor/ComposerPasteTest.kt

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

📝 Walkthrough

Android clipboard handling now combines text from multiple clipboard items for regular paste. URI-backed and empty clips remain on the native paste path. Tests cover multi-item text, URI-backed clips, empty clips, zero-item clips, and native paste for small single-item text.

Changes: Android clipboard paste

Layer / File(s) Summary
Clipboard text handling and paste coverage
apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt, apps/mobile/modules/t3-composer-editor/android/src/test/java/expo/modules/t3composereditor/ComposerPasteTest.kt
plainText() joins text from all clipboard items with newlines. It returns null if any item has a URI or if the combined text is empty. Tests cover multi-item interception, native handling of URI-backed and empty clips, and native paste with undo for small single-item text.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: chrisdeeming

Merge Risk: ⚪ Minimal · up to 52590

The change addresses trailing text lost during Android paste, and no actionable merge-blocking issue is identified. It is ready for normal merge checks.

Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary Android composer paste fix.
Description check Passed The description covers the problem, implementation, scope justification, regression tests, device verification, observed results, limitations, and agent details.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

This branch has not been deployed

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

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant