Feat/image assets - #43
Merged
Merged
Conversation
Introduce an `image <id> <src> <x> <y> <width> <height>` directive so a map can reference raster assets. `src` is a path relative to the .flowgo file (the binary lives in a flowgo-media/ sibling folder, never inline). Mirrors the change across both serializers so Go and TS output stays byte-identical: new Image struct + NamedMap.Images with parse/serialize in pkg/graph, ImageData + serialize block in src/graph, and validation for id collisions / empty src / non-positive size. Round-trip tests on both sides. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Local (single-file) mode gains two routes next to /state and /save:
POST /media writes an uploaded image into the flowgo-media/
folder beside the .flowgo file, named by content
hash (sha256[:16]+ext) so identical pastes dedup,
and returns {"src":"flowgo-media/<name>"}.
GET /flowgo-media/* serves a stored asset, with the filename
sanitised to a bare base name so a crafted path
can't escape the media folder.
Only wired in local mode (serve/public mode has no local filesystem).
Tests cover the round-trip, dedup, non-image rejection, and traversal
guard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Paste an image (Cmd/Ctrl+V) or drag an image file onto the canvas and it
becomes a first-class element: move it, resize it from the corner grip,
copy/clone/delete it like a box. New src/editor/media.ts owns the paste
+ drop handlers and the POST /media upload; the element threads through
the existing seams (render, movers, attach, factories, clipboard, clone,
mutations, ensureMap) plus its CSS.
Two deliberate design points:
- Drag handlers live at the document level: a drop can land on any
layer (bg grid, SVG overlays, a box), so interception has to be
document-wide or the browser just opens the file.
- Cmd/Ctrl+V is no longer intercepted in keys.ts; that preventDefault
suppressed the native `paste` event, which is the only way to read a
clipboard image. The paste event is now the single arbiter — image
if present, else the internal buffer (pasteSelection).
Clipboard/drag collections are iterated by index, not for..of, since
DataTransferItemList isn't reliably iterable across browsers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The toolbar (which holds the "↑ Up" button) had no default hidden state, so it flashed visible on every load at the root map until the async load() ran renderPath() and hid it. Default it to display:none — like the download/reshare buttons already do — and let renderPath() reveal it only inside a submap or snapshot view. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Zoom now happens only with Cmd/Ctrl held (or a pinch, which the browser reports as a ctrlKey wheel event); a bare two-finger trackpad swipe pans in any direction. Drop the old looksLikeMouseWheel heuristic — a pure-vertical swipe (deltaX === 0) was indistinguishable from a mouse notch, so it zoomed when the user meant to pan. Requiring a modifier removes the guess. Note: a bare mouse wheel now pans too; zoom with Cmd/Ctrl + wheel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`just dev` now detects the host's LAN IP (macOS ipconfig, Linux hostname -I / ip route) and passes it into the container as FLOWGO_DISPLAY_HOST, so the URL the server prints is reachable from other devices on the network instead of the useless in-container localhost/bridge address. compose forwards the value (default localhost). Docker already published the ports on 0.0.0.0 — only the advertised hostname needed fixing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`just dev` opens map.flowgo at the repo root and stores pasted/dropped images in flowgo-media/. Both are local runtime state, not source. Anchored to the root so pkg/graph/map.flowgo stays tracked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate the Go-embedded pkg/flowgo/dist/index.html from source so HEAD's bundle carries the image-assets, toolbar, and zoom changes. Co-Authored-By: Claude Opus 4.8 (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.
No description provided.