feat/client: embed images inline in notes#54
Open
ClemPera wants to merge 5 commits into
Open
Conversation
Images can now be inserted anywhere in a note via a toolbar button, paste, or drag-and-drop, and render at the position the user placed them. Images are embedded as base64 data URIs directly in the markdown content (standard `` syntax), so they flow through the existing note encryption and sync pipeline unchanged: no new server endpoints, tables, or sync logic. Uploaded images are downscaled/recompressed client-side (max 1600px, JPEG quality 0.85) to keep the encrypted note blob within the server's 16MB column limit; GIFs are left untouched to preserve animation, and oversized originals or still-too-large results are rejected with a toast before insertion.
…drop works Tauri v2 enables its own OS-level drag-drop handling by default (dragDropEnabled: true), which intercepts drag/drop at the WebView layer and prevents the browser's native HTML5 drop event from carrying real file data through dataTransfer.files. This is why the editor's dropcursor indicator showed correctly (dragover still fires) but the actual drop silently did nothing: handleDrop's dataTransfer lookup found no files. Nothing in the app uses Tauri's native onDragDropEvent API, so disabling it is safe and restores standard browser drag-and-drop behavior for the note editor. Ref: tauri-apps/tauri#14373
Enables tiptap's built-in resize handles on note images (drag a corner, aspect ratio locked). The default renderMarkdown for images only emits plain ``, which has no field for width/height, so a resize would silently revert on the next save. ResizableImage overrides renderMarkdown to fall back to a raw `<img width height>` tag whenever a size is set, and plain markdown syntax otherwise; parseMarkdown already round-trips raw HTML images via the schema's normal HTML parsing, so this is lossless in both directions.
The resize node view sets width/height as inline styles directly on the <img>, which beats any CSS class rule (including height: auto) short of !important. When the note pane got narrower than a resized image's stored width, max-width: 100% clamped the rendered width but the inline height stayed pinned at its old value, since a plain height: auto rule can't win against an inline style, producing the squished/stretched look. Forcing height: auto with !important makes the rendered height always follow the (possibly clamped) width via the image's own intrinsic aspect ratio instead of trusting a separately-tracked pixel value that can drift out of sync with it.
…ts Files With dragDropEnabled disabled, OS file drops now reach the browser's drop event, but WebKitGTK still doesn't populate dataTransfer.files for them: it only exposes a file:// URI via text/uri-list (this is what showed up as inserted text before this fix). There's no way to read a file's bytes from the frontend given just this path due to browser sandboxing, so handleDrop now falls back to extracting that path and reading it through a new read_dropped_image Tauri command, then feeds the resulting bytes through the same prepareImageForInsert pipeline used everywhere else. Adds: - read_image_file in commands.rs (sync, size-capped at 20MB, unit tested) plus the read_dropped_image command wrapper - fileUriToPath/mimeTypeForFilename in lib/image.ts to resolve the URI and infer a mime type from the extension, since raw bytes alone don't carry one
Owner
Author
To test
Issue
|
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.
Images can now be inserted anywhere in a note via a toolbar button, paste, or drag-and-drop, and render at the position the user placed them.
Images are embedded as base64 data URIs directly in the markdown content (standard
syntax), so they flow through the existing note encryption and sync pipeline unchanged: no new server endpoints, tables, or sync logic. Uploaded images are downscaled/recompressed client-side (max 1600px, JPEG quality 0.85) to keep the encrypted note blob within the server's 16MB column limit; GIFs are left untouched to preserve animation, and oversized originals or still-too-large results are rejected with a toast before insertion.