Repository navigation
fix(mobile): terminal Paste says why when nothing is pasted - #31640
Conversation
iOS answers null for a clipboard image after Don't Allow Paste, when the read is not authorized, or for a format it cannot decode, and the paste stopped without a word. A paste dropped after its upload, because the connection went away, the terminal changed, or typed input queued ahead of it failed to send, was dropped quietly too.
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟡 Minor · Use the current connection state in the catch block. · use-mobile-terminal-paste.ts:149
mobile/src/session/use-mobile-terminal-paste.ts:149
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse the current connection state in the catch block.
If a disconnect rejects the image upload or pending-input flush, execution skips the new connection check. This catch block reads the earlier
connStatevalue and can showPaste failedinstead ofPaste failed (disconnected). ReadconnStateRef.currenthere. The new disconnection test changes the state after upload, so it does not cover this path.
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
df3fb6f2-4970-46a8-8b43-7012bec15786
📒 Files selected for processing: 2
mobile/src/session/use-mobile-terminal-paste-dropped.test.tsmobile/src/session/use-mobile-terminal-paste.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
Refs #20686
What users saw
In a mobile terminal, tapping Paste with only an image on the clipboard could do nothing. The iOS paste prompt closed and nothing was pasted. There was no toast and no error haptic.
Now
When the paste can't send anything, the user is told why:
Root cause
useMobileTerminalPastetreated a null image read as an empty clipboard and returned quietly. On iOS, null also covers:PBErrorDomain 13 "Operation not authorized").UIPasteboard.imagecan't decode. A WebP or HEIC copied on its own counts as no image at all (hasImagesfalse).On an iOS 26 simulator, a probe app making expo-clipboard's exact reads got the image back after Allow every time: a PNG copied from another app, a 6016×6016 Photos copy, and an image offered lazily through an item provider. So "Allow, then null" didn't reproduce here and needs a real device to pin.
The paste also had a second quiet exit, after the upload finished. It returned without a word when the connection, terminal or pending typed input changed underneath it. Those checks now run before the false-flush return, so each case gets a message.
The change is in the shared hook, so both the OTA page and the native screen get it. The host side is unchanged. Android's
getImageAsyncreturns null only when there's noimage/*clip and throws on a failed read (which already toasts), so the same message covers it.Not in this PR: reading the clipboard without the consent prompt, using the system paste control (
UIPasteControl). On iOS 27 that's the only way the Paste button gets the image. It needs a native shell change and a store build.How verified
Visual Proof
Before (main): Paste does nothing.
before.mp4
After: Paste says it couldn't read the clipboard.
after.mp4