Skip to content

feat(channels): drag-and-drop file upload into the composer - #215

Merged
prellr merged 2 commits into
mainfrom
feat/channel-composer-drag-drop
Jun 27, 2026
Merged

prellr merged 2 commits into
mainfrom
feat/channel-composer-drag-drop

Conversation

@prellr

@prellr prellr commented Jun 27, 2026 •

Copy link
Copy Markdown
Owner

Answer to "can we add drag-and-drop of images into the chat?": Agent Chat already had it; Channels (and the Concierge drawer) didn't — this adds it.

Composer-level (all channels): the channel composer used the same ContentEditor as Agent Chat but never wired an upload handler into it, so its editor-level file-drop was a no-op — only the paperclip worked. This wires the existing useFileDropZone onto the composer root and routes dropped files through handleAttach (the same api.uploadFile path the paperclip uses), with a FileDropOverlay cue. Drop is disabled when the composer is.

Whole-drawer (Ship Concierge): in a tall narrow drawer you naturally drop onto the transcript, not the small input box. ChannelComposer now exposes an imperative attachFiles() handle, and ShipShell wraps the entire drawer body (conversation + composer) in a drop zone that forwards files into it. The composer keeps its own inner zone — the shared hook's defaultPrevented guard stops a drop on the input from double-firing.

Test plan

  • views typecheck + eslint clean; channel-composer.test.tsx (drop → api.uploadFile, multi-file, and the imperative attachFiles handle) + 207 ship/channels tests green.
  • Browser: drag an image onto a channel composer and anywhere in the Concierge drawer → dashed overlay → uploads → sends as an attachment.

🤖 Generated with Claude Code

prellr and others added 2 commits June 27, 2026 12:53
Agent Chat already supports drag-drop (the editor's file-upload extension
+ a full-area useFileDropZone overlay, with onUploadFile wired). The channel
composer used the same ContentEditor but never wired an upload handler into
it, so it only had the paperclip button — dropping an image did nothing.

Wire the existing useFileDropZone onto the composer root and route dropped
files through handleAttach (the exact upload path the paperclip uses), with
a FileDropOverlay drag cue. Drop is disabled when the composer is. This also
gives the Ship Concierge drawer (a channel) drag-drop for free.

views typecheck + eslint clean; new channel-composer drag-drop test (2 cases)
green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Builds on the composer drop zone: in the tall narrow Concierge drawer you
naturally drop onto the transcript, not the small input box. ChannelComposer
now exposes an imperative attachFiles() handle, and ShipShell wraps the whole
drawer body (conversation + composer) in a drop zone that forwards dropped
files into it. The composer keeps its own inner zone; the shared hook's
defaultPrevented guard means a drop on the input doesn't double-fire.

Test: imperative attachFiles → api.uploadFile. views typecheck + eslint clean;
207 ship + channels tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@prellr
prellr merged commit 10add8d into main Jun 27, 2026
2 checks passed
@prellr
prellr deleted the feat/channel-composer-drag-drop branch June 27, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant