Skip to content

fix: intercept drops at root level and add max-images UX feedback#90

Merged
quiet-node merged 2 commits intomainfrom
worktree-frolicking-stargazing-hearth
Apr 14, 2026
Merged

fix: intercept drops at root level and add max-images UX feedback#90
quiet-node merged 2 commits intomainfrom
worktree-frolicking-stargazing-hearth

Conversation

@quiet-node
Copy link
Copy Markdown
Owner

Closes #89

Summary

  • Bug fix: Drag handlers were only on AskBarView's inner div. In chat mode, ConversationView covers most of the window; dropping an image there had no preventDefault(), causing the WebView to navigate full-screen (the "floating image" reported in Uploading second image fails #89). Handlers are now on the root h-screen div so every drop anywhere in the window is intercepted.
  • UX: drag at max: When dragging a file over the window while already at 3 images, the ring turns red and a "Max 3 images" label appears. Disappears on drop or drag-leave.
  • UX: paste at max: Pasting an image when at max shows the same "Max 3 images" label inline; it auto-dismisses after 2 s.

Test Plan

  • Open app, drop one image, send a message, then drop a second image onto the chat area — should attach as thumbnail instead of going full-screen
  • Attach 3 images, then drag a 4th over the window — red ring + "Max 3 images" label visible during hover
  • Attach 3 images, paste a 4th — "Max 3 images" label appears and fades after 2 s
  • bun run test — 519 tests pass
  • bun run validate-build — clean

Fixes #89 — dropping a second image after a
conversation caused the WebView to navigate full-screen because drag
handlers only existed on the AskBarView div. ConversationView, which
occupies most of the window in chat mode, had no handlers to call
preventDefault().

Changes:
- Move onDragOver/onDragLeave/onDrop from AskBarView to the root
  h-screen div in App so every drop in the window is intercepted
- AskBarView now receives isDragOver as a prop ('normal' | 'max')
  rather than managing its own drag state
- When dragging over a full attachment slot: red ring + "Max 3 images"
  label replaces the normal violet ring
- When pasting an image at max capacity: same label appears inline and
  auto-dismisses after 2 s

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
- Remove em dashes from newly added comments (CLAUDE.md forbids them)
- Fix showMaxLabel contradiction: suppress paste error label while a
  drag is active so the ring color and label always agree
- Fix onImagesAttached JSDoc: remove stale "or drops" (drops now handled
  at root level in App, not in AskBarView)
- Add missing branch coverage for handleRootDrop (non-image file, null
  dataTransfer, at-max drop, drop-during-generation) and AskBarView
  paste-at-max false branch (non-image clipboard content)
- Mark handleRootDragLeave internal-transition branch with v8 ignore:
  jsdom cannot set relatedTarget on DragEvent to simulate cursor
  moving between child elements

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node merged commit c304af8 into main Apr 14, 2026
3 checks passed
@quiet-node quiet-node deleted the worktree-frolicking-stargazing-hearth branch April 14, 2026 16:30
This was referenced Apr 14, 2026
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.

Uploading second image fails

1 participant