feat(desktop): image download, drag-drop prevention, and drop zone indicator#542
Merged
Conversation
Replace the broken native webview "Download image" context menu with a custom implementation. Right-clicking images (thumbnail or lightbox) shows a "Download image" option that fetches from the relay and presents a native save-file dialog. Security: SSRF protection (relay origin + /media/ path validation), 50 MiB size cap with streaming enforcement, 60s timeout, MIME content validation. Errors surface via toast notifications. Download logic lives in media_download.rs to keep media.rs under the file size limit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a file is dropped outside the message composer, the webview navigates to a file:/// URL and displays it fullscreen. Add global dragover/drop event prevention in AppShell to block this default browser behavior while preserving the composer's existing drop-to- upload functionality. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restrict the global dragover/drop handler to only prevent default when the drag contains files, preserving text drag-and-drop into inputs. Fix the accompanying comment to accurately describe why the composer's drop handler still works. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show a dashed-border overlay with "Drop files to upload" text when a file is dragged over the message or forum composer. Uses a dragDepth ref counter for reliable enter/leave tracking across child elements, scoped to file drags only. Window-level drop/dragend listeners reset state when drags end outside the form. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
Author
Screen.Recording.2026-05-11.at.4.07.44.PM.mov |
This was referenced May 28, 2026
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
download_imagecommand. Includes SSRF protection (relay origin +/media/path validation), 50 MiB OOM cap with streaming enforcement, 60s timeout, MIME validation, and error toast feedback. 10 unit tests for URL validation.dragover/dropprevention inAppShell.tsxstops the webview from navigating tofile:///URLs when files are dropped outside the composer. Scoped to file drags only (text drag-and-drop into inputs still works).dragDepthref counter for reliable enter/leave tracking, with window-leveldrop/dragendlisteners as a safety net for edge cases (drag cancel, drop outside form).Files changed (11)
Rust (backend)
src-tauri/src/commands/media_download.rs(NEW) —download_imagecommand +validate_download_url+ 10 testssrc-tauri/src/commands/media.rs—detect_and_validate_mimemadepub(crate)src-tauri/src/commands/export_util.rs—save_bytes_with_dialoggeneralized,save_json_with_dialogdelegatessrc-tauri/src/commands/mod.rs— registeredmedia_downloadmodulesrc-tauri/src/lib.rs— registereddownload_imagein invoke_handlerTypeScript (frontend)
src/shared/ui/markdown.tsx—ImageContextMenucomponent wrapping imagessrc/app/AppShell.tsx— global file drag preventionuseEffectsrc/features/messages/lib/useMediaUpload.ts—isDragOverstate,dragDepthref, drag enter/leave/end handlerssrc/features/messages/ui/ComposerAttachments.tsx— sharedDropZoneOverlaycomponentsrc/features/messages/ui/MessageComposer.tsx— wired drag handlers + overlaysrc/features/forum/ui/ForumComposer.tsx— same treatmentTest plan
🤖 Generated with Claude Code