Skip to content

Feat/image assets - #43

Merged
lassediercks merged 8 commits into
mainfrom
feat/image-assets
Jul 22, 2026
Merged

Feat/image assets#43
lassediercks merged 8 commits into
mainfrom
feat/image-assets

Conversation

@lassediercks

Copy link
Copy Markdown
Owner

No description provided.

exaptation and others added 8 commits July 21, 2026 12:24
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>
@lassediercks
lassediercks merged commit a5009dd into main Jul 22, 2026
2 checks passed
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.

1 participant