phase 3b T9/T10/T12: drag overlay + composer paste + attach button#639
Merged
Conversation
Closes T9 / T10 / T12 from `docs/plans/2026-05-08-ui-phase-3b-files-inline.md`:
- **T9.** Composer's `+` IconBtn (`composer__attach`) flips
`UploadQueue::open` directly; standalone `<FileShareButton>`
paperclip retired (mounts removed from `app.rs` + `mobile_shell.rs`,
component marked `#[deprecated]` so out-of-tree callers still build
while migrating).
- **T10.** New `<DragOverlay>` mounts at the app shell, installs
`dragenter` / `dragover` / `dragleave` / `drop` listeners on the
document, and renders a tinted full-viewport overlay with the spec
copy `drop to attach` while `queue.drag_active` is true. Drop
enqueues files into the shared `UploadQueue` and flips
`queue.open`. Depth-counter pattern collapses the
enter/leave-during-drag noise so the overlay only hides when the
cursor truly leaves the window.
- **T12.** Composer textarea grows an `on:paste` handler. When the
ClipboardEvent carries files (screenshots, copied attachments),
the textarea call is preventDefault'd and files route to the same
upload queue. Pasted images that arrive without a meaningful
filename get `pasted-{YYYY-MM-DD-HH-mm-ss}.png` per spec.
Refactor: `enqueue_file_list` helper in `upload_dialog.rs` is the
single FileList → upload-queue pump used by all three call paths
(picker, drop, paste). `MAX_ATTACHMENT_SIZE` moves to
`upload_state.rs` so the pump enforces the 25 MB cap consistently.
`spawn_upload_for_file` becomes `pub(crate)` (was already named for
this — just promoted visibility for the new callers).
Spec: docs/specs/2026-04-19-ui-design/files-inline.md
§Drag-and-drop, §Paste-to-upload, §Upload dialog.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… spec
- Browser tier (`crates/web/tests/browser.rs`):
- `phase_3b_drag_overlay::overlay_visibility_tracks_drag_active_signal`
pins overlay mount/unmount, the spec `drop to attach` copy, and
the decorative `aria-hidden="true"` per spec accessibility table.
- `phase_3b_paste_filename::filename_matches_spec_pattern` locks
in the `pasted-YYYY-MM-DD-HH-mm-ss.png` format from
`pasted_image_filename()`.
- Playwright (`e2e/files-inline.spec.ts`): real DataTransfer drop
through the page-level handler — overlay surfaces on dragenter,
drop closes the overlay and opens the upload dialog with the
dropped file in the list. Lives at the e2e tier per CLAUDE.md
"real-browser-only" rule (synthetic DragEvent in headless wasm-pack
can't carry actual files).
- Spec (`docs/specs/2026-04-19-ui-design/files-inline.md`): tick the
drag-and-drop, paste-to-upload, and ARIA acceptance criteria — all
three close out with this PR. Voice-note row stays open pending T6.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…leave Review feedback on PR #639: - Move `<UploadDialog>` from inside the desktop chat view to the app shell, alongside `<DragOverlay>` and `<AddFriendDialog>`. The previous mount sat inside `.shell-desktop` (which CSS sets to `display:none` on mobile), so the composer's `+` attach button flipped `queue.open` to true on mobile but the dialog never rendered. Single mount now serves both shells; CSS positions the dialog as a fixed overlay regardless of parent. - `dragleave` whose `relatedTarget` is null indicates the cursor truly left the window. Firefox occasionally drops the final dragleave during nested drags, leaving the depth counter > 0 and the overlay stuck open. Treating null-related dragleaves as a hard reset (`depth = 0`) recovers without asking the user to refresh. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the deferred T9 / T10 / T12 from
docs/plans/2026-05-08-ui-phase-3b-files-inline.md— files-inline phase 3b is now feature-complete except for T6 (voice notes), which depends on the unshipped audio waveform pipeline.Composer's+IconBtn flipsUploadQueue::opendirectly. Standalone<FileShareButton>paperclip retired (mounts removed fromapp.rs+mobile_shell.rs; component marked#[deprecated]).<DragOverlay>mounts at the app shell, installs page-level drag/drop listeners, and renders the spec's tinted overlay withdrop to attach. Drop enqueues files and opens<UploadDialog>.on:pastehandler that routes ClipboardEvent files into the upload queue (and away from the textarea). Pasted images getpasted-{YYYY-MM-DD-HH-mm-ss}.png.Refactor
enqueue_file_listinupload_dialog.rsis the single FileList → upload-queue pump used by all three call paths (picker, drop, paste).MAX_ATTACHMENT_SIZEmoves toupload_state.rs.spawn_upload_for_fileispub(crate).Tests
phase_3b_drag_overlay(overlay mount/unmount + spec copy + decorative aria-hidden) andphase_3b_paste_filename(locks in thepasted-YYYY-MM-DD-HH-mm-ss.pngformat).e2e/files-inline.spec.tsconstructs a realDataTransfer, firesdragenter+dropon document, asserts the overlay surfaces then the dialog opens with the dropped file in the list.Spec
docs/specs/2026-04-19-ui-design/files-inline.mdticks: drag-and-drop, paste-to-upload, ARIA labels. Voice-note row stays open pending T6.Test plan
just check— fmt + clippy + native + WASM, zero warningsjust test-browser— 383 tests passing (incl. 2 new)attach to message→ file lands in chatpasted-{ts}.pngrow🤖 Generated with Claude Code