8492 Commits

Author SHA1 Message Date
Andrey Antukh
eda5aa76f0 Merge remote-tracking branch 'origin/main' into staging 2026-07-27 08:52:31 +02:00
Eva Marco
d94b139071
🐛 Fix text edition state when relesecting (#10798)
* 🐛 Fix text edition state when relesecting

* 🐛 Fix CI
2026-07-24 12:15:16 +02:00
Andrey Antukh
d5d6c61ba4 💄 Remove unused app.common.pprint import in errors.cljs
AI-assisted-by: deepseek-v4-flash
2026-07-23 15:05:18 +00:00
Alejandro Alonso
8bf411c347
🐛 Fix viewer wasm position data init (#10805) 2026-07-23 12:58:20 +02:00
Andrey Antukh
66b978c01e Add wall-clock timestamps to last-events buffer
Each event entry in `last-events` is now wrapped as
`{:name <event-type> :t (app.common.time/now)}` so every event carries a
wall-clock timestamp. A new helper `format-last-events` renders the
buffer as a multi-line string with ISO time and delta-since-previous-
event in ms, replacing the previous pprint dump in error reports.

This lets support/devs tell whether the events leading up to a crash
were spaced out (user action) or jammed together (runaway loop).

AI-assisted-by: minimax-m3
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-07-23 10:50:06 +02:00
Andrey Antukh
b3091399cd
Add timestamp to the frontend error report (#10772) 2026-07-23 10:26:41 +02:00
Andrey Antukh
707cfac375
🐛 Throttle nudge stream to cap re-renders under fast key-repeat (#10736)
Holding an arrow key on a selection with a fast OS key-repeat rate
crashed the workspace with React error #185 (Maximum update depth
exceeded): each OS key-repeat event was converted 1:1 into a
`set-modifiers`/`set-wasm-modifiers` store write inside
`nudge-selected-shapes` with no throttle, starving the renderer.

The sibling mouse-driven resize/rotate/move paths got an `rx/sample`
throttle in PR #10560; the keyboard-nudge path was the only transform
stream left un-throttled. This change applies the same `rx/sample`
throttle to the nudge stream, mirroring the drag-path structure, and
adds a regression test guarding the final committed position
invariant under a burst of 20 `move-selected` events for both the WASM
and legacy (non-WASM) branches.

Closes #10726

AI-assisted-by: glm-5.2
2026-07-23 09:57:28 +02:00
Andrey Antukh
702a435569 📎 Add token id to the dom for more easy identify the token id 2026-07-23 09:29:45 +02:00
Andrey Antukh
eb1e0ad186
🐛 Guard team-container* when team-id is not a uuid (#10645)
The dashboard route can be reached without a `:team-id` query parameter
(e.g. `/#/dashboard/recent`). When that happened, `team-container*` was
emitting `dtm/initialize-team` with a `nil` team-id, which set
`:current-team-id` to `nil` in the application state. The dashboard
and workspace initialize events then built `df/fetch-fonts` with a
`nil` team-id, producing a `:get-font-variants` RPC with empty params
`{}` that the backend rejected with HTTP 400.

Guard `team-container*` so it does not emit `initialize-team` /
`finalize-team` and does not render the children when `team-id` is
not a uuid. The `with-effect` body and the render are guarded
independently; the cleanup closure captures the same `team-id` as the
setup, so the finalize still fires correctly when transitioning between
valid teams.

AI-assisted-by: minimax-m3
2026-07-22 16:57:46 +02:00
Andrey Antukh
73bfc0dc15
🐛 Guard workspace-page* when file-id is not a uuid (#10655)
The workspace route can be reached without a `:file-id` query parameter
(e.g. `/#/workspace?team-id=...`). When that happened, `workspace*` was
emitting `dw/initialize-workspace` with a nil file-id, which stored nil
in `:current-file-id`. The `fetch-profiles` event then read nil from
state and called `:get-profiles-for-file-comments` with `{:file-id
nil}`, producing a 400 response.

Move the `use-equal-memo` calls for `file-id` and `page-id` from
`workspace*` up to `workspace-page*`, and guard the render with
`(when (uuid? file-id) ...)` so `workspace*` only mounts when `file-id`
is a valid uuid. Since `workspace*` never mounts with a nil `file-id`,
`initialize-workspace` is never emitted with nil, and the 400 is
prevented at the source.

AI-assisted-by: minimax-m3
2026-07-22 09:00:43 +02:00
Andrey Antukh
e69fdef1dc Merge remote-tracking branch 'origin/main' into staging 2026-07-20 14:48:39 +02:00
Andrey Antukh
26c4ec18fe
🐛 Return 400 instead of 500 when ImageMagick fails on invalid images (#10643)
When ImageMagick fails to process an uploaded image (e.g., corrupted PNG
with invalid IHDR data), the backend was raising :type :internal with
:code :imagemagick-error, which mapped to HTTP 500. The frontend treated
this as a server error and displayed the full error page.

Changed exec-magick! to raise :type :validation with :code :invalid-image
instead. This flows through the existing :invalid-image handler in
errors.clj which returns HTTP 400. The frontend's handle-media-error and
process-error now catch this code and show a notification banner.

AI-assisted-by: qwen3.7-plus
2026-07-20 11:56:07 +02:00
Andrey Antukh
7f60e3735d
🐛 Remove hardcoded metadata URI default on webhook form (#10723)
The webhook creation form used a hardcoded AWS instance metadata
endpoint (http://169.254.169.254/...) as the default :uri value for
new webhooks. This leaked an internal cloud credential endpoint into
the UI defaults and could expose it to users.

Remove the default :uri so new webhooks start with an empty URI
instead of a sensitive hardcoded value.
2026-07-16 14:04:06 +02:00
Elena Torró
ab58d00d66
Improve bool intersection perfomance (#10671) 2026-07-14 07:43:52 +02:00
Eva Marco
3708cf31d4
🐛 Fix stroke cap selects (#10631) 2026-07-10 11:05:09 +02:00
Andrey Antukh
3400d6afbb
🐛 Fix too much recursion when clicking shape in comments mode (#10622)
* 🐛 Fix too much recursion when clicking shape in comments mode

Remove `deselect-all` from `handle-interrupt` in comments mode. The
`select-shape` event emits `:interrupt` which the comments stream
watcher routes to `handle-interrupt`. In comments mode, calling
`deselect-all` cleared the selection and emitted a competing
`rt/nav`, creating a synchronous recursion cycle in the potok store
that overflowed the JS call stack.

Fixes #10620

AI-assisted-by: opencode

* 🐛 Add unit tests for comments handle-interrupt

Make `handle-interrupt` public (defn- → defn) and add 4 tests covering
each branch: draft thread, open thread, comments mode, and noop.

AI-assisted-by: opencode
2026-07-09 18:04:05 +02:00
Andrey Antukh
28fd798c52
🐛 Fix crash with degenerate selrect in text pipeline (#10618)
Guard remaining text pipeline locations that accessed :selrect directly
against nil/zero-dimension selrects by using safe-size-rect, which
provides a 4-level fallback chain (selrect -> points -> shape fields ->
empty 0.01x0.01 rect).

Fixes:
- fix-position in viewport_texts_html.cljs: replaced dm/get-prop
  :selrect with ctm/safe-size-rect for both old and new shape
- assoc-position-data in modifiers.cljs: replaced (:selrect ...)
  with ctm/safe-size-rect for delta computation
- change-orientation-modifiers in modifiers.cljc: replaced raw
  :selrect access with safe-size-rect for scale and origin computation

Closes #10617

AI-assisted-by: mimo-v2.5-pro
2026-07-09 11:03:06 +02:00
Andrey Antukh
47a3158602
🐛 Fix component variant panel crash with mismatched property counts (#10616)
Use `get` instead of `nth` to avoid index-out-of-bounds when a selected
component copy has fewer variant properties than the first component in
the selection.

Closes #10615

AI-assisted-by: deepseek-v4-pro
2026-07-09 11:01:08 +02:00
Elena Torró
8ac2e8c8a8
🐛 Fix sidebar scroll to shape (#10600) 2026-07-08 20:38:16 +02:00
Elena Torró
d656d342fe
🐛 Fix text selrect size (#10566)
* 🐛 Fix text selrect size

* 🐛 Fix blinks on complex files

---------

Co-authored-by: Belén Albeza <belen@hey.com>
2026-07-08 13:56:58 +02:00
Eva Marco
ff0d56a86e
🐛 Fix blur menu width (#10575) 2026-07-08 10:06:23 +02:00
Juan de la Cruz
8b16bb8874
Add new slides content for 2.17 release (#10577)
*  Add new slides content for 2.17 release

* 📎 Fix linter issues

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-07-08 09:39:38 +02:00
Alonso Torres
7655f854a4
Improved api test suite (#10533)
* 🐛 Fix plugins api issues

* 🐛 Fix problem with text weight

* 🐛 Fix api problems

*  Updated plugins test suite

* 🐛 Referential integrity tests

*  Add resetOverrides method

* 🐛 Fix plugins components structure poluting
2026-07-07 16:12:12 +02:00
Dr. Dominik Jain
c88d9f568b
🐛 Preserve component order when combining components as variants (#10562) 2026-07-06 16:49:29 +02:00
Alonso Torres
2dfb1046f7
🐛 Fix problem with rotations crashing (#10560) 2026-07-06 11:56:46 +02:00
Luis de Dios
e5d3ea14d1
🐛 Fix size badge shows "x" instead of dimensions when creating a path (#10550) 2026-07-03 14:58:43 +02:00
Luis de Dios
d795a1f110
Manage rotation and color of selection size badge (#10393)
*  Rotate and move size badge when shape is rotated

* 🐛 Fix wrong text color in selection size badge

*  Add tests

* ♻️ Extract common constants
2026-07-02 14:59:33 +02:00
Eva Marco
f1f5a30624
🐛 Fix alignment selector for strokes (#10532) 2026-07-02 13:01:58 +02:00
Eva Marco
e6a341ff30
🐛 Fix text layout item menu (#10516) 2026-07-01 14:39:34 +02:00
Eva Marco
04254c9fd1
🐛 Fix token tooltips (#10515) 2026-07-01 14:30:18 +02:00
Eva Marco
665e8e018e
🐛 Fix overlay position grid (#10512) 2026-07-01 13:40:12 +02:00
Eva Marco
abbd28d101
🐛 Fix long text inside color tooltip (#10511) 2026-07-01 13:38:51 +02:00
Luis de Dios
7e8590b04c
🐛 Fix inspect in workspace displays shape size twice when selecting a shape (#10507) 2026-07-01 13:08:35 +02:00
Eva Marco
920c6d4e76
🐛 Fix token tooltips on numeric-input, color and typography (#10480) 2026-06-30 16:26:49 +02:00
Luis de Dios
28afe223f4
🐛 Invitations to a team can be sent to existing members without displaying any error (#10489)
* 🐛 Fix team invitations can be sent to existing members without displaying any error

*  Add tests
2026-06-30 15:39:59 +02:00
Alonso Torres
8823f7ac4d
Make v2 plugins default throw on error (#10433) 2026-06-30 14:50:50 +02:00
Alonso Torres
ca81776d04
🐛 Fix problems when dragging frame with comments (#10460)
* 🐛 Fix undo frame position not undoing comments

* 🐛 Fix problem with hover capturing dragging event

* 🐛 Fix watch updates for comment bubbles

* 🐛 Fix "Maximum update depth" crash on SVG shape transforms

* 🐛 Fix comment geometry problems
2026-06-30 13:33:47 +02:00
Alonso Torres
f993f203bd
🐛 Fix problems with plugins API (#10412)
*  Adds static dispatch safe stubs in tests

* 🐛 Fix shapesColors metadata key to match ColorShapeInfo

* 🐛 Fix CommentThread.remove rejecting the owner's own threads

* 🐛 Fix page.removeCommentThread throwing on a spurious Promise

*  Implement ShapeBase.swapComponent in the plugin API

*  Expose File.revn in the plugin API

* 🐛 Fix FileVersion.createdAt calling Luxon method on a js/Date

* 🐛 Fix plugin font/typography application to text and ranges

* 🐛 Default plugin overlay interaction position for non-manual types

* 🐛 Fix plugin interaction setters passing an id-only shape

* 🐛 Fix grid addColumnAtIndex rejecting valid track types

* 🐛 Expose libraryId on library color/typography/component proxies

*  Implement LibraryTypography.setFont in the plugin API

* 🐛 Fix typography.applyToTextRange reading unexposed range bounds

* 🐛 Fix utils.geometry.center argument mismatch

* 🐛 Fix localStorage.removeItem calling getItem

* 🐛 Fix shape backgroundBlur proxy key casing

* 🐛 Report boolean shape type as 'boolean' in the plugin API

* 🐛 Return the resulting paths from plugin flatten

* 🐛 Make plugin z-order methods act on the target shape

* 🐛 Make is-variant-container? return a boolean

*  Implement Group.isMask in the plugin API

* 🐛 Return a shape proxy from TextRange.shape

* 🐛 Return the duplicated set from TokenSet.duplicate

* 🐛 Fix theme addSet/removeSet reading set name with a keyword

* 🐛 Accept string fontFamilies token value in the plugin API

* 🐛 Fix combineAsVariants ignoring the passed component ids

* 🐛 Fix board removeRulerGuide ignoring its argument

* 🐛 Fix board guides setter schema and parser

* 🐛 Avoid 0-byte allocation when syncing empty grid tracks

* 🐛 Validate grid track indices in the plugin API

* 🐛 Return null for empty input in group() and centerShapes()

* 🐛 Return TokenTypographyValue[] from a typography token's resolvedValue

* 🐛 Return TokenShadowValue[] from a shadow token's resolvedValue

* 🐛 Return string[] from a fontFamilies token's resolvedValue

* 🐛 Clear mutually-exclusive reps when setting LibraryColor gradient/image

* 🐛 Add readonly tags to types, deprecate Image type

* 📚 Update plugins changelog
2026-06-29 17:32:15 +02:00
Alonso Torres
a47b0122c7
🐛 Fix problem with measures menu (#10445) 2026-06-29 09:24:37 +02:00
Belén Albeza
e9c0982a94
Disable hot swap of render engines (#10444) 2026-06-26 15:04:52 +02:00
Alejandro Alonso
44e39a1008
🐛 Sync WASM viewport when locating board in grid layout editor (#10443) 2026-06-26 14:24:44 +02:00
Eva Marco
6a79383082
🐛 Blur info doesn't show on inspect in certain shapes (#10427)
* 🐛 Blur info doesn't show on inspect in certain shapes

* 🎉 Add test
2026-06-26 14:10:41 +02:00
Belén Albeza
10147b6abd
🐛 Fix pixel grid and board pixel grid shown on top of rulers (#10430)
* 🐛 Fix pixel grid shown on top of rulers

* 🐛 Fix board pixel grid being rendered above rulers
2026-06-26 11:53:11 +02:00
Luis de Dios
8e9fb91959
🐛 Fix view mode is not persisted in color picker (#10369) 2026-06-26 11:38:51 +02:00
Elena Torró
89f882ecda
🐛 Fix viewer rendering on Firefox+NVIDIA setup (#10385) 2026-06-26 10:59:22 +02:00
Luis de Dios
d16a2c93e0
🐛 Fix long typography token name in tooltip in design tab (#10387) 2026-06-26 10:50:19 +02:00
Luis de Dios
66719a14f5
🐛 Fix assets typography container is longer than others (#10406)
* 🐛 Fix assets typography container is longer than others

* ♻️ Use new SCSS guidelines
2026-06-26 09:42:22 +02:00
Alejandro Alonso
345affc687
🐛 Fix premature WASM view-interaction end during pan (#10425) 2026-06-25 15:07:37 +02:00
Andrey Antukh
9259b596dc Merge remote-tracking branch 'origin/main' into staging 2026-06-23 12:26:17 +02:00
Andrey Antukh
f967a0fc83
Add improvements for frontend tests (#10380) 2026-06-23 11:21:53 +02:00