mirror of
https://github.com/penpot/penpot.git
synced 2025-02-18 13:04:38 -05:00
♻️ Refactor update master component function
This commit is contained in:
parent
a3eb634740
commit
7c75b75f5b
2 changed files with 122 additions and 88 deletions
|
@ -386,56 +386,18 @@
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (dwc/lookup-page-objects state page-id)
|
objects (dwc/lookup-page-objects state page-id)
|
||||||
root-shape (get objects id)
|
root-shape (get objects id)
|
||||||
|
file-id (get root-shape :component-file)
|
||||||
|
|
||||||
component-id (get root-shape :component-id)
|
components
|
||||||
component-objs (dwc/lookup-component-objects state component-id)
|
(if (nil? file-id)
|
||||||
component-obj (get component-objs component-id)
|
(get-in state [:workspace-data :components])
|
||||||
|
(get-in state [:workspace-libraries file-id :data :components]))
|
||||||
|
|
||||||
;; Clone again the original shape and its children, maintaing
|
[rchanges uchanges]
|
||||||
;; the ids of the cloned shapes. If the original shape has some
|
(dwlh/generate-sync-shape-inverse root-shape
|
||||||
;; new child shapes, the cloned ones will have new generated ids.
|
objects
|
||||||
update-new-shape (fn [new-shape original-shape]
|
components
|
||||||
(cond-> new-shape
|
page-id)]
|
||||||
true
|
|
||||||
(assoc :frame-id nil)
|
|
||||||
|
|
||||||
(= (:component-id original-shape) component-id)
|
|
||||||
(dissoc :component-id)
|
|
||||||
|
|
||||||
(some? (:shape-ref original-shape))
|
|
||||||
(assoc :id (:shape-ref original-shape))))
|
|
||||||
|
|
||||||
touch-shape (fn [original-shape _]
|
|
||||||
(into {} original-shape))
|
|
||||||
|
|
||||||
[new-shape new-shapes original-shapes]
|
|
||||||
(cph/clone-object root-shape nil objects update-new-shape touch-shape)
|
|
||||||
|
|
||||||
rchanges (d/concat
|
|
||||||
[{:type :mod-component
|
|
||||||
:id component-id
|
|
||||||
:name (:name new-shape)
|
|
||||||
:shapes new-shapes}]
|
|
||||||
(map (fn [shape]
|
|
||||||
{:type :mod-obj
|
|
||||||
:page-id page-id
|
|
||||||
:id (:id shape)
|
|
||||||
:operations [{:type :set-touched
|
|
||||||
:touched nil}]})
|
|
||||||
original-shapes))
|
|
||||||
|
|
||||||
uchanges (d/concat
|
|
||||||
[{:type :mod-component
|
|
||||||
:id component-id
|
|
||||||
:name (:name component-obj)
|
|
||||||
:shapes (vals component-objs)}]
|
|
||||||
(map (fn [shape]
|
|
||||||
{:type :mod-obj
|
|
||||||
:page-id page-id
|
|
||||||
:id (:id shape)
|
|
||||||
:operations [{:type :set-touched
|
|
||||||
:touched (:touched shape)}]})
|
|
||||||
original-shapes))]
|
|
||||||
|
|
||||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,53 @@
|
||||||
|
|
||||||
(declare generate-sync-component-components)
|
(declare generate-sync-component-components)
|
||||||
(declare generate-sync-shape-and-children-components)
|
(declare generate-sync-shape-and-children-components)
|
||||||
(declare generate-sync-shape-components)
|
(declare generate-sync-shape-inverse)
|
||||||
|
(declare generate-sync-shape<-component)
|
||||||
|
(declare generate-sync-shape->component)
|
||||||
(declare remove-component-and-ref)
|
(declare remove-component-and-ref)
|
||||||
(declare remove-ref)
|
(declare remove-ref)
|
||||||
|
(declare reset-touched)
|
||||||
(declare update-attrs)
|
(declare update-attrs)
|
||||||
(declare calc-new-pos)
|
(declare calc-new-pos)
|
||||||
|
|
||||||
|
|
||||||
|
;; ---- Create a new component ----
|
||||||
|
|
||||||
|
(defn make-component-shape
|
||||||
|
"Clone the shape and all children. Generate new ids and detach
|
||||||
|
from parent and frame. Update the original shapes to have links
|
||||||
|
to the new ones."
|
||||||
|
[shape objects]
|
||||||
|
(assert (nil? (:component-id shape)))
|
||||||
|
(assert (nil? (:component-file shape)))
|
||||||
|
(assert (nil? (:shape-ref shape)))
|
||||||
|
(let [update-new-shape (fn [new-shape original-shape]
|
||||||
|
(cond-> new-shape
|
||||||
|
true
|
||||||
|
(assoc :frame-id nil)
|
||||||
|
|
||||||
|
(nil? (:parent-id new-shape))
|
||||||
|
(assoc :component-root? true)))
|
||||||
|
|
||||||
|
;; Make the original shape an instance of the new component.
|
||||||
|
;; If one of the original shape children already was a component
|
||||||
|
;; instance, the 'instanceness' is copied into the new component.
|
||||||
|
update-original-shape (fn [original-shape new-shape]
|
||||||
|
(cond-> original-shape
|
||||||
|
true
|
||||||
|
(assoc :shape-ref (:id new-shape))
|
||||||
|
|
||||||
|
(nil? (:parent-id new-shape))
|
||||||
|
(assoc :component-id (:id new-shape)
|
||||||
|
:component-file nil
|
||||||
|
:component-root? true)
|
||||||
|
|
||||||
|
(some? (:parent-id new-shape))
|
||||||
|
(dissoc :component-root?)))]
|
||||||
|
|
||||||
|
(cph/clone-object shape nil objects update-new-shape update-original-shape)))
|
||||||
|
|
||||||
|
|
||||||
;; ---- General library synchronization functions ----
|
;; ---- General library synchronization functions ----
|
||||||
|
|
||||||
(defn generate-sync-file
|
(defn generate-sync-file
|
||||||
|
@ -249,43 +290,6 @@
|
||||||
(generate-sync-text-shape shape page-id component-id update-node)))
|
(generate-sync-text-shape shape page-id component-id update-node)))
|
||||||
|
|
||||||
|
|
||||||
;; ---- Create a new component ----
|
|
||||||
|
|
||||||
(defn make-component-shape
|
|
||||||
"Clone the shape and all children. Generate new ids and detach
|
|
||||||
from parent and frame. Update the original shapes to have links
|
|
||||||
to the new ones."
|
|
||||||
[shape objects]
|
|
||||||
(assert (nil? (:component-id shape)))
|
|
||||||
(assert (nil? (:component-file shape)))
|
|
||||||
(assert (nil? (:shape-ref shape)))
|
|
||||||
(let [update-new-shape (fn [new-shape original-shape]
|
|
||||||
(cond-> new-shape
|
|
||||||
true
|
|
||||||
(assoc :frame-id nil)
|
|
||||||
|
|
||||||
(nil? (:parent-id new-shape))
|
|
||||||
(assoc :component-root? true)))
|
|
||||||
|
|
||||||
;; Make the original shape an instance of the new component.
|
|
||||||
;; If one of the original shape children already was a component
|
|
||||||
;; instance, the 'instanceness' is copied into the new component.
|
|
||||||
update-original-shape (fn [original-shape new-shape]
|
|
||||||
(cond-> original-shape
|
|
||||||
true
|
|
||||||
(assoc :shape-ref (:id new-shape))
|
|
||||||
|
|
||||||
(nil? (:parent-id new-shape))
|
|
||||||
(assoc :component-id (:id new-shape)
|
|
||||||
:component-file nil
|
|
||||||
:component-root? true)
|
|
||||||
|
|
||||||
(some? (:parent-id new-shape))
|
|
||||||
(dissoc :component-root?)))]
|
|
||||||
|
|
||||||
(cph/clone-object shape nil objects update-new-shape update-original-shape)))
|
|
||||||
|
|
||||||
|
|
||||||
;; ---- Component synchronization helpers ----
|
;; ---- Component synchronization helpers ----
|
||||||
|
|
||||||
(defn generate-sync-shape-and-children-components
|
(defn generate-sync-shape-and-children-components
|
||||||
|
@ -305,7 +309,7 @@
|
||||||
(if (nil? shape)
|
(if (nil? shape)
|
||||||
[rchanges uchanges]
|
[rchanges uchanges]
|
||||||
(let [[shape-rchanges shape-uchanges]
|
(let [[shape-rchanges shape-uchanges]
|
||||||
(generate-sync-shape-components
|
(generate-sync-shape<-component
|
||||||
shape
|
shape
|
||||||
root-shape
|
root-shape
|
||||||
root-component
|
root-component
|
||||||
|
@ -317,7 +321,33 @@
|
||||||
(d/concat rchanges shape-rchanges)
|
(d/concat rchanges shape-rchanges)
|
||||||
(d/concat uchanges shape-uchanges))))))))
|
(d/concat uchanges shape-uchanges))))))))
|
||||||
|
|
||||||
(defn generate-sync-shape-components
|
(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. It acts like the above
|
||||||
|
function with reset-touched? as true. Also clears the 'touched' flags
|
||||||
|
in the source shapes."
|
||||||
|
[root-shape objects components page-id]
|
||||||
|
(let [all-shapes (cph/get-object-with-children (:id root-shape) objects)
|
||||||
|
component (get components (:component-id root-shape))
|
||||||
|
root-component (get-in component [:objects (:shape-ref root-shape)])]
|
||||||
|
(loop [shapes (seq all-shapes)
|
||||||
|
rchanges []
|
||||||
|
uchanges []]
|
||||||
|
(let [shape (first shapes)]
|
||||||
|
(if (nil? shape)
|
||||||
|
[rchanges uchanges]
|
||||||
|
(let [[shape-rchanges shape-uchanges]
|
||||||
|
(generate-sync-shape->component
|
||||||
|
shape
|
||||||
|
root-shape
|
||||||
|
root-component
|
||||||
|
component
|
||||||
|
page-id)]
|
||||||
|
(recur (next shapes)
|
||||||
|
(d/concat rchanges shape-rchanges)
|
||||||
|
(d/concat uchanges shape-uchanges))))))))
|
||||||
|
|
||||||
|
(defn generate-sync-shape<-component
|
||||||
"Generate changes to synchronize one shape that is linked to other shape
|
"Generate changes to synchronize one shape that is linked to other shape
|
||||||
inside a component. Same considerations as above about reset-touched?"
|
inside a component. Same considerations as above about reset-touched?"
|
||||||
[shape root-shape root-component component page-id component-id reset-touched?]
|
[shape root-shape root-component component page-id component-id reset-touched?]
|
||||||
|
@ -334,6 +364,33 @@
|
||||||
component-id
|
component-id
|
||||||
reset-touched?)))))
|
reset-touched?)))))
|
||||||
|
|
||||||
|
(defn generate-sync-shape->component
|
||||||
|
"Generate changes to synchronize one shape inside a component, with other
|
||||||
|
shape that is linked to it."
|
||||||
|
[shape root-shape root-component component page-id]
|
||||||
|
(if (nil? component)
|
||||||
|
empty-changes
|
||||||
|
(let [component-shape (get (:objects component) (:shape-ref shape))]
|
||||||
|
(if (nil? component-shape)
|
||||||
|
empty-changes
|
||||||
|
(let [[rchanges1 uchanges1]
|
||||||
|
(update-attrs component-shape
|
||||||
|
shape
|
||||||
|
root-component
|
||||||
|
root-shape
|
||||||
|
nil
|
||||||
|
(:id root-component)
|
||||||
|
true)
|
||||||
|
[rchanges2 uchanges2]
|
||||||
|
(reset-touched shape
|
||||||
|
page-id
|
||||||
|
nil)]
|
||||||
|
[(d/concat rchanges1 rchanges2)
|
||||||
|
(d/concat uchanges2 uchanges2)])))))
|
||||||
|
|
||||||
|
|
||||||
|
; ---- Operation generation helpers ----
|
||||||
|
|
||||||
(defn remove-component-and-ref
|
(defn remove-component-and-ref
|
||||||
[shape page-id component-id]
|
[shape page-id component-id]
|
||||||
[[(d/without-nils {:type :mod-obj
|
[[(d/without-nils {:type :mod-obj
|
||||||
|
@ -388,6 +445,21 @@
|
||||||
{:type :set-touched
|
{:type :set-touched
|
||||||
:touched (:touched shape)}]})]])
|
:touched (:touched shape)}]})]])
|
||||||
|
|
||||||
|
(defn reset-touched
|
||||||
|
[shape page-id component-id]
|
||||||
|
[[(d/without-nils {:type :mod-obj
|
||||||
|
:id (:id shape)
|
||||||
|
:page-id page-id
|
||||||
|
:component-id component-id
|
||||||
|
:operations [{:type :set-touched
|
||||||
|
:touched nil}]})]
|
||||||
|
[(d/without-nils {:type :mod-obj
|
||||||
|
:id (:id shape)
|
||||||
|
:page-id page-id
|
||||||
|
:component-id component-id
|
||||||
|
:operations [{:type :set-touched
|
||||||
|
:touched (:touched shape)}]})]])
|
||||||
|
|
||||||
(defn update-attrs
|
(defn update-attrs
|
||||||
"The main function that implements the sync algorithm."
|
"The main function that implements the sync algorithm."
|
||||||
[shape component-shape root-shape root-component page-id component-id reset-touched?]
|
[shape component-shape root-shape root-component page-id component-id reset-touched?]
|
||||||
|
|
Loading…
Add table
Reference in a new issue