🐛 Replay rotation nodes as relative turns in the frontend

Pass delta? to increase-rotation when interpreting a Rotate node. Common
turns by the node's angle; the event default instead sets an absolute
rotation, so a 45-degree turn followed by 90 degrees ended at 90 (F171).

The standalone async regression fails before the fix. The full frontend
suite passes 1524 tests and 8683 assertions, including generated replay,
undo checks and existing goldens without recording. Lint and format pass.

AI-assisted-by: GPT-6
This commit is contained in:
alonso.torres 2026-10-24 10:09:43 +02:00
parent 1e9d19b214
commit 3002b6b9f5
2 changed files with 11 additions and 2 deletions

View File

@ -11,6 +11,7 @@
down on purpose, so a step that resolved early would see a half-synced
file."
(:require
[app.common.math :as mth]
[app.common.test-helpers.composable.comp.nodes :as n]
[app.common.test-helpers.composable.comp.setups :as setup]
[app.common.test-helpers.composable.comp.undo-check :as uc]
@ -30,6 +31,14 @@
(t/use-fixtures :each ftm/fixture)
(t/deftest ^:async rotation-nodes-compose-successive-turns
(let [initial (ftm/start-generated (setup/simple-component-with-labeled-copy))
first-turn (await (ftm/run-generated-step initial (n/rotate :copy-root 45)))
second-turn (await (ftm/run-generated-step first-turn (n/rotate :copy-root 90)))
shape (ths/get-shape (ftm/current-file) :copy-root)]
(t/is (mth/close? 135 (:rotation shape) 0.01))
(t/is (empty? (uc/failures second-turn)))))
(def ^:private original "#abcdef")
(def ^:private red "#ff0000")

View File

@ -169,9 +169,9 @@
:original-content (:content shape))])
(instance? n/Rotate op)
;; the sidebar rotation, which decides what it touches in copies (check-delta)
;; A node turns by its angle, including after an earlier rotation.
(let [{:keys [target angle]} op]
[(dwt/increase-rotation [(tm/target-shape-id situation target)] angle)])
[(dwt/increase-rotation [(tm/target-shape-id situation target)] angle {:delta? true})])
(instance? n/MoveShape op)
;; the sidebar position, in page coordinates