fix: route clipboard image pastes to the attachment strip #295
Reference in New Issue
Block a user
Delete Branch "claude/markdown-image-upload-fix-t9ggfa"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Pasting an image while the markdown editor was focused left it stuck on
ProseMirror's inline "uploading" placeholder instead of going to the
attachment strip. The capture-phase paste interceptor bailed before it
could redirect the file because:
clipboardData.items(
getAsFile), withclipboardData.filesleft empty, andtext/plainentry, which theold
types.includes('text/plain')check mistook for a text paste.Read files from
items(falling back tofiles), and gate on the actualtext payload rather than the advertised type, so real text pastes
(Excel/Word renditions) still paste as text while pure image pastes
become attachments.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01QtNQeBpkDJPC9obiB25pV6
Summary by CodeRabbit
ℹ️ Recent review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Free
Run ID:
7a10ac15-13a3-4cbf-9414-713f26433f2e📥 Commits
Reviewing files that changed from the base of the PR and between
372b12f339andfa88a7c07b.📒 Files selected for processing (1)
js/desktop/src/hooks/use-file-input.ts🚧 Files skipped from review as they are similar to previous changes (1)
📝 Walkthrough
Walkthrough
The PR introduces a shared
transferFileshelper that robustly extracts file objects fromDataTransferby prioritizingitemswith fallback tofiles. TheuseFileInputhook's clipboard paste handler now distinguishes file payloads from text pastes using content-based text detection (getData('text/plain')), while both paste and drop handlers leveragetransferFilesfor file extraction. The markdown editor disables image file uploads by turning offCrepe.Feature.ImageBlock, adds an explicit drop handler to decline dropped files, and updates CSS to constrain rendered image height to 420px.Changes
Compose Editor File and Image Handling
js/desktop/src/lib/data-transfer.tstransferFiles(data: DataTransfer): File[]that extracts file objects by filteringdata.itemsentries of kind'file'viagetAsFile()with null filtering, falling back toArray.from(data.files)when no items are found.js/desktop/src/hooks/use-file-input.tsgetData('text/plain').trim().lengthinstead of checking advertised types, usestransferFilesfor file extraction, and only prevents default/propagation when files are found. Drop handler similarly refactored to usetransferFilesinstead of directArray.from(dataTransfer.files).js/desktop/src/features/compose/markdown-editor.tsx,js/desktop/src/features/compose/markdown-editor.cssCrepe.Feature.ImageBlockfeature flag to prevent image file uploads while allowing image links to render, adds explicit drop handler usingtransferFilesto decline dropped files, and replaces prior CSS that hid image uploader controls with a new rule constraining images in.llink-crepe .milkdown .ProseMirror imgtomax-height: 420px.Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Comment
@coderabbitai helpto get the list of available commands and usage tips.