0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-22 14:39:45 -05:00

🐛 Do recursive swap-slot finding

This commit is contained in:
Andrés Moya 2024-03-07 13:09:43 +01:00 committed by Alejandro Alonso
parent bad0fb912b
commit 2c740df767
4 changed files with 45 additions and 21 deletions

View file

@ -204,7 +204,7 @@
(defn find-ref-shape
"Locate the nearest component in the local file or libraries, and retrieve the shape
referenced by the instance shape."
[file page libraries shape & {:keys [include-deleted? with-context?] :or {include-deleted? false with-context? false}}]
[file container libraries shape & {:keys [include-deleted? with-context?] :or {include-deleted? false with-context? false}}]
(let [find-ref-shape-in-head
(fn [head-shape]
(let [component-file (find-component-file file libraries (:component-file head-shape))
@ -213,7 +213,7 @@
(when (some? component)
(get-ref-shape (:data component-file) component shape :with-context? with-context?))))]
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects page) shape))))
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects container) shape))))
(defn find-ref-component
"Locate the nearest component in the local file or libraries that is referenced by the
@ -265,14 +265,13 @@
(true? (= (:id component) (:id ref-component)))))
(defn find-swap-slot
[shape page file libraries]
(dm/assert! "expected shape is head" (ctk/instance-head? shape))
[shape container file libraries]
;; (js/console.log "find-swap-slot" (clj->js shape))
(if-let [swap-slot (ctk/get-swap-slot shape)]
;; (do (js/console.log "uno" (str swap-slot)) swap-slot)
swap-slot
(let [ref-shape (find-ref-shape file
page
container
libraries
shape
:include-deleted? true
@ -292,11 +291,12 @@
(find-swap-slot ref-shape ref-container ref-file libraries)))))))
(defn match-swap-slot?
[shape-main shape-inst page-inst page-main file libraries]
(let [slot-main (find-swap-slot shape-main page-main file libraries)
slot-inst (find-swap-slot shape-inst page-inst file libraries)]
(or (= slot-main slot-inst)
(= (:id shape-main) slot-inst))))
[shape-main shape-inst container-inst container-main file libraries]
(let [slot-main (find-swap-slot shape-main container-main file libraries)
slot-inst (find-swap-slot shape-inst container-inst file libraries)]
(when (some? slot-inst)
(or (= slot-main slot-inst)
(= (:id shape-main) slot-inst)))))
(defn get-component-shapes
"Retrieve all shapes of the component"

View file

@ -699,6 +699,7 @@
(watch [it state _]
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
(let [file (wsh/get-local-file state)
file-full (wsh/get-local-file-full state)
libraries (wsh/get-libraries state)
page-id (:current-page-id state)
@ -711,7 +712,7 @@
(-> (pcb/empty-changes it)
(pcb/with-container container)
(pcb/with-objects (:objects container))
(dwlh/generate-sync-shape-direct libraries container id true components-v2))]
(dwlh/generate-sync-shape-direct file-full libraries container id true components-v2))]
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
(:redo-changes changes)
@ -750,6 +751,7 @@
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id) :undo-group undo-group)
(let [page-id (get state :current-page-id)
local-file (wsh/get-local-file state)
full-file (wsh/get-local-file-full state)
container (cfh/get-container local-file :page page-id)
shape (ctn/get-shape container id)
components-v2 (features/active-feature? state "components/v2")]
@ -761,7 +763,7 @@
(-> (pcb/empty-changes it)
(pcb/set-undo-group undo-group)
(pcb/with-container container)
(dwlh/generate-sync-shape-inverse libraries container id components-v2))
(dwlh/generate-sync-shape-inverse full-file libraries container id components-v2))
file-id (:component-file shape)
file (wsh/get-file state file-id)

View file

@ -425,8 +425,9 @@
(defmethod generate-sync-shape :components
[_ changes _library-id state container shape components-v2]
(let [shape-id (:id shape)
file (wsh/get-local-file-full state)
libraries (wsh/get-libraries state)]
(generate-sync-shape-direct changes libraries container shape-id false components-v2)))
(generate-sync-shape-direct changes file libraries container shape-id false components-v2)))
(defmethod generate-sync-shape :colors
[_ changes library-id state _ shape _]
@ -594,7 +595,7 @@
(defn generate-sync-shape-direct
"Generate changes to synchronize one shape that is the root of a component
instance, and all its children, from the given component."
[changes libraries container shape-id reset? components-v2]
[changes file libraries container shape-id reset? components-v2]
(log/debug :msg "Sync shape direct" :shape-inst (str shape-id) :reset? reset?)
(let [shape-inst (ctn/get-shape container shape-id)
library (dm/get-in libraries [(:component-file shape-inst) :data])
@ -623,6 +624,8 @@
shape-inst
component
library
file
libraries
shape-main
root-inst
root-main
@ -655,7 +658,7 @@
nil))))))
(defn- generate-sync-shape-direct-recursive
[changes container shape-inst component library shape-main root-inst root-main reset? initial-root? redirect-shaperef components-v2]
[changes container shape-inst component library file libraries shape-main root-inst root-main reset? initial-root? redirect-shaperef components-v2]
(log/debug :msg "Sync shape direct recursive"
:shape-inst (str (:name shape-inst) " " (pretty-uuid (:id shape-inst)))
:component (:name component))
@ -752,6 +755,8 @@
child-inst
component
library
file
libraries
child-main
root-inst
root-main
@ -782,6 +787,10 @@
(compare-children changes
children-inst
children-main
container
component-container
file
libraries
only-inst
only-main
both
@ -812,7 +821,7 @@
(defn generate-sync-shape-inverse
"Generate changes to update the component a shape is linked to, from
the values in the shape and all its children."
[changes libraries container shape-id components-v2]
[changes file libraries container shape-id components-v2]
(log/debug :msg "Sync shape inverse" :shape (str shape-id))
(let [redirect-shaperef (partial redirect-shaperef container libraries)
shape-inst (ctn/get-shape container shape-id)
@ -843,6 +852,8 @@
shape-inst
component
library
file
libraries
shape-main
root-inst
root-main
@ -852,7 +863,7 @@
changes)))
(defn- generate-sync-shape-inverse-recursive
[changes container shape-inst component library shape-main root-inst root-main initial-root? redirect-shaperef components-v2]
[changes container shape-inst component library file libraries shape-main root-inst root-main initial-root? redirect-shaperef components-v2]
(log/trace :msg "Sync shape inverse recursive"
:shape (str (:name shape-inst))
:component (:name component))
@ -935,6 +946,8 @@
child-inst
component
library
file
libraries
child-main
root-inst
root-main
@ -962,6 +975,10 @@
(compare-children changes
children-inst
children-main
container
component-container
file
libraries
only-inst
only-main
both
@ -986,7 +1003,7 @@
;; ---- Operation generation helpers ----
(defn- compare-children
[changes children-inst children-main only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset?]
[changes children-inst children-main container-inst container-main file libraries only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset?]
(log/trace :msg "Compare children")
(loop [children-inst (seq (or children-inst []))
children-main (seq (or children-main []))
@ -1007,7 +1024,7 @@
:else
(if (or (ctk/is-main-of? child-main child-inst)
(ctk/match-swap-slot? child-main child-inst))
(ctf/match-swap-slot? child-main child-inst container-inst container-main file libraries))
(recur (next children-inst)
(next children-main)
(if (or (ctk/is-main-of? child-main child-inst) reset?)
@ -1015,10 +1032,10 @@
(swapped-cb changes child-inst child-main)))
(let [child-inst' (d/seek #(or (ctk/is-main-of? child-main %)
(ctk/match-swap-slot? child-main %))
(ctf/match-swap-slot? child-main % container-inst container-main file libraries))
children-inst)
child-main' (d/seek #(or (ctk/is-main-of? % child-inst)
(ctk/match-swap-slot? % child-inst))
(ctf/match-swap-slot? % child-inst container-inst container-main file libraries))
children-main)]
(cond
(nil? child-inst')

View file

@ -110,6 +110,11 @@
[state]
(get state :workspace-data))
(defn get-local-file-full
[state]
(-> (get state :workspace-file)
(assoc :data (get state :workspace-data))))
(defn get-file
"Get the data content of the given file (it may be the current file
or one library)."