diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index f7e720e5ba..5bbce80fba 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -608,9 +608,16 @@ new-val (get new attr) changed? (not= old-val new-val) + ;; the touched groups are written whole, with the + ;; operation of their own + touched? (= attr :touched) + rops (cond-> rops - changed? + (and changed? touched?) + (conj {:type :set-touched :touched new-val}) + + (and changed? (not touched?)) (conj {:type :set :attr attr :val new-val :ignore-geometry ignore-geometry? :ignore-touched (if (set? ignore-touched) @@ -619,7 +626,7 @@ uops (cond-> uops - changed? + (and changed? (not touched?)) (conj {:type :set :attr attr :val old-val :ignore-touched true}))] @@ -642,10 +649,10 @@ ;; a touch also clears :remote-synced uops (cond-> uops - (seq uops) + (seq rops) (conj {:type :set-touched :touched (:touched old-obj)}) - (and (seq uops) (:remote-synced old-obj)) + (and (seq rops) (:remote-synced old-obj)) (conj {:type :set-remote-synced :remote-synced true})) change (cond-> {:type :mod-obj :id id} @@ -898,9 +905,8 @@ {:type :set :attr :shape-ref :val (:shape-ref shape)} - {:type :set - :attr :touched - :val (:touched shape)}]})] + {:type :set-touched + :touched (:touched shape)}]})] (-> changes (update :redo-changes (fn [redo-changes] diff --git a/common/test/common_tests/logic/comp_touched_test.cljc b/common/test/common_tests/logic/comp_touched_test.cljc index 40bf69268e..ae8dc29763 100644 --- a/common/test/common_tests/logic/comp_touched_test.cljc +++ b/common/test/common_tests/logic/comp_touched_test.cljc @@ -309,6 +309,25 @@ (t/is (true? (:remote-synced (ths/get-shape file'' :copy-child)))) (t/is (nil? (:touched (ths/get-shape file'' :copy-child)))))) +(t/deftest test-an-update-writes-touched-groups-whole + ;; an update that sets the touched groups of a copy shape writes them with + ;; the operation of their own, and its undo gives back the ones it had + (let [file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 :main-root :main-child :copy-root + :copy-root-params {:children-labels [:copy-child]})) + page (thf/current-page file) + changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(thi/id :copy-child)} + #(assoc % :touched #{:shadow-group}) + (:objects page) + {}) + ops (mapcat :operations (:redo-changes changes)) + file' (thf/apply-changes file changes) + file'' (thf/apply-undo-changes file' changes)] + (t/is (= [{:type :set-touched :touched #{:shadow-group}}] ops)) + (t/is (= #{:shadow-group} (:touched (ths/get-shape file' :copy-child)))) + (t/is (nil? (:touched (ths/get-shape file'' :copy-child)))))) + (t/deftest test-touched-set-by-an-update-then-its-attrs-touch ;; an update sets the touched groups of a copy shape and changes an ;; attribute: the attribute touches its group on top of them, whatever the diff --git a/common/test/common_tests/logic/golden_master.edn b/common/test/common_tests/logic/golden_master.edn index 9ac75f3973..43ea637d28 100644 --- a/common/test/common_tests/logic/golden_master.edn +++ b/common/test/common_tests/logic/golden_master.edn @@ -11,7 +11,7 @@ :ad [{:transcript "create-component {:component \"main\", :id sync-main-component}\n create-component {:component \"s1\", :id sync-s1-component}\n make-nested-component {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n instantiate-copy {:component \"main\", :copy sync-main-copyhead-0}\n instantiate-copy {:component \"main\", :copy sync-main-copyhead-1}\n swap-shape {:target #fn, :to \"s1\", :keep-touched? false}\n update-main {:target #fn, :updated sync-main-copyhead-0}", :states ["9835a328e680007d" "8cc31cfc15b28449" "40c27ac7ca18d972"]}] :ae - [{:transcript "create-component {:component \"main\", :id sync-main-component}\n create-component {:component \"s1\", :id sync-s1-component}\n make-nested-component {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n instantiate-copy {:component \"main\", :copy sync-main-copyhead-0}\n swap-shape {:target #fn, :to \"s1\", :keep-touched? false}\n detach {:target #fn, :detached sync-main-copyhead-0}\n change-property {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["a3cb16fb335bc929" "c59b7ba151b736fb" "ccd586f1f2b263e4" "07eb2229667eeb92"]} + [{:transcript "create-component {:component \"main\", :id sync-main-component}\n create-component {:component \"s1\", :id sync-s1-component}\n make-nested-component {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n instantiate-copy {:component \"main\", :copy sync-main-copyhead-0}\n swap-shape {:target #fn, :to \"s1\", :keep-touched? false}\n detach {:target #fn, :detached sync-main-copyhead-0}\n change-property {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["a3cb16fb335bc929" "e10b1283627fbeb6" "9be2dfab826240b0" "1fc0e554196dfd2b"]} {:transcript "create-component {:component \"main\", :id sync-main-component}\n create-component {:component \"s1\", :id sync-s1-component}\n make-nested-component {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n instantiate-copy {:component \"main\", :copy sync-main-copyhead-0}\n swap-shape {:target #fn, :to \"s1\", :keep-touched? false}\n duplicate {:target #fn, :new-head 5}\n change-property {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["a3cb16fb335bc929" "d291c9ca9a187b1b" "99bb6214c05d575b" "0694d4feab3cb633"]}] :af [{:transcript "swap-shape {:target :copy-child, :to :other, :keep-touched? false}\n move-to-cell {:board :main-root, :child :main-child, :row 1, :column 3}", :states ["a3bca1c5fd1b9b29" "8a7fa3fde8815d35" "1c786eab89f462da"]} diff --git a/frontend/test/frontend_tests/composable_tests/golden_master.edn b/frontend/test/frontend_tests/composable_tests/golden_master.edn index e19b6891dc..c2cadbeddf 100644 --- a/frontend/test/frontend_tests/composable_tests/golden_master.edn +++ b/frontend/test/frontend_tests/composable_tests/golden_master.edn @@ -11,7 +11,7 @@ :case-ad-update-main-pushes-a-swapped-child [{:transcript " {:component \"main\", :id sync-main-component}\n {:component \"s1\", :id sync-s1-component}\n {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n {:component \"main\", :copy sync-main-copyhead-0}\n {:component \"main\", :copy sync-main-copyhead-1}\n {:target #fn, :to \"s1\", :keep-touched? false}\n {:target #fn}", :states ["70154c2f90c4d94f" "8276a39e105869aa" "60ae4e382dab157a"]}] :case-ae-detached-or-duplicated-swapped-copy-follows-its-component - [{:transcript " {:component \"main\", :id sync-main-component}\n {:component \"s1\", :id sync-s1-component}\n {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n {:component \"main\", :copy sync-main-copyhead-0}\n {:target #fn, :to \"s1\", :keep-touched? false}\n {:target #fn}\n {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["d74e87bca3fa2eb9" "04d085bb07bb3857" "b886602f9de07d6e" "b57c324aaa781800"]} + [{:transcript " {:component \"main\", :id sync-main-component}\n {:component \"s1\", :id sync-s1-component}\n {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n {:component \"main\", :copy sync-main-copyhead-0}\n {:target #fn, :to \"s1\", :keep-touched? false}\n {:target #fn}\n {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["d74e87bca3fa2eb9" "ffc66442a5849acd" "ad43d75dcc79bc8a" "6fa02ad66793cf43"]} {:transcript " {:component \"main\", :id sync-main-component}\n {:component \"s1\", :id sync-s1-component}\n {:component \"main\", :level 0, :outer sync-main-outercomp-0}\n {:component \"main\", :copy sync-main-copyhead-0}\n {:target #fn, :to \"s1\", :keep-touched? false}\n {:target #fn, :new-head 5}\n {:target #fn, :property :fills, :value \"#0000ff\"}", :states ["d74e87bca3fa2eb9" "e2162174653b4d7b" "0bd8763796243e1f" "f612d9fde86170a6"]}] :case-af-grid-cell-move-reaches-a-swapped-copy-child [{:transcript " {:target :copy-child, :to :other, :keep-touched? false}\n {:board :main-root, :child :main-child, :row 1, :column 3}", :states ["5a6af6c0b8f86ac3" "ec2294c072f52ae5" "8cd63b096547fb1b"]}