0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-28 15:41:25 -05:00

🐛 Improve selection of near copies to sync

This commit is contained in:
Andrés Moya 2024-02-22 09:37:33 +01:00 committed by Andrey Antukh
parent 7dd0745429
commit c5f24331a3
3 changed files with 49 additions and 16 deletions

View file

@ -150,6 +150,22 @@
:else
(get-head-shape objects (get objects (:parent-id shape)) options))))
(defn get-parent-heads
"Get all component heads that are ancestors of the shape, in top-down order
(include self if it's also a head)."
[objects shape]
(->> (cfh/get-parents-with-self objects (:id shape))
(filter ctk/instance-head?)
(reverse)))
(defn get-parent-copy-heads
"Get all component heads that are ancestors of the shape, in top-down order,
excluding mains (include self if it's also a head)."
[objects shape]
(->> (cfh/get-parents-with-self objects (:id shape))
(filter #(and (ctk/instance-head? %) (ctk/in-component-copy? %)))
(reverse)))
(defn get-instance-root
"Get the parent shape at the top of the component instance (main or copy)."
[objects shape]

View file

@ -117,6 +117,12 @@
[libraries component-id & {:keys [include-deleted?] :or {include-deleted? false}}]
(some #(ctkl/get-component (:data %) component-id include-deleted?) (vals libraries)))
(defn find-component-file
[file libraries component-file]
(if (and (some? file) (= component-file (:id file)))
file
(get libraries component-file)))
(defn get-component
"Retrieve a component from a library."
[libraries library-id component-id & {:keys [include-deleted?] :or {include-deleted? false}}]
@ -188,21 +194,30 @@
"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?] :or {include-deleted? false}}]
(let [parent-heads (->> (cfh/get-parents-with-self (:objects page) (:id shape))
(filter ctk/instance-head?)
(reverse))
find-ref-shape-in-head
(let [find-ref-shape-in-head
(fn [head-shape]
(let [head-file (if (and (some? file) (= (:component-file head-shape) (:id file)))
file
(get libraries (:component-file head-shape)))
(let [head-file (find-component-file file libraries (:component-file head-shape))
head-component (when (some? head-file)
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
(when (some? head-component)
(get-ref-shape (:data head-file) head-component shape))))]
(some find-ref-shape-in-head parent-heads)))
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects page) shape))))
(defn find-ref-component
"Locate the nearest component in the local file or libraries that is referenced by the
instance shape."
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
(let [find-ref-component-in-head
(fn [head-shape]
(let [head-file (find-component-file file libraries (:component-file head-shape))
head-component (when (some? head-file)
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
(when (some? head-component)
(when (get-ref-shape (:data head-file) head-component shape)
head-component))))]
(some find-ref-component-in-head (ctn/get-parent-copy-heads (:objects page) shape))))
(defn find-remote-shape
"Recursively go back by the :shape-ref of the shape until find the correct shape of the original component"
@ -229,6 +244,13 @@
remote-shape
(find-remote-shape component-container libraries remote-shape)))))
(defn direct-copy?
"Check if the shape is in a direct copy of the component (i.e. the shape-ref points to shapes inside
the component)."
[shape component page file libraries]
(let [ref-component (find-ref-component file page libraries shape :include-deleted? true)]
(true? (= (:id component) (:id ref-component)))))
(defn get-component-shapes
"Retrieve all shapes of the component"
[file-data component]

View file

@ -599,15 +599,10 @@
library (dm/get-in libraries [(:component-file shape-inst) :data])
component (or (ctkl/get-component library (:component-id shape-inst))
(and reset?
(ctkl/get-deleted-component library (:component-id shape-inst))))
component-shape (ctn/get-component-shape (:objects container) shape-inst)]
(ctkl/get-deleted-component library (:component-id shape-inst))))]
(if (and (ctk/in-component-copy? shape-inst)
(or (= (:id component) (:component-id component-shape)) reset?)) ; In a normal sync, we don't want to sync remote mains, only near
(or (ctf/direct-copy? shape-inst component container nil libraries) reset?)) ; In a normal sync, we don't want to sync remote mains, only direct/near
(let [redirect-shaperef (partial redirect-shaperef container libraries)
library (dm/get-in libraries [(:component-file shape-inst) :data])
component (or (ctkl/get-component library (:component-id shape-inst))
(and reset?
(ctkl/get-deleted-component library (:component-id shape-inst))))
shape-main (when component
(if (and reset? components-v2)