0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 09:08:31 -05:00

🐛 Enhande handling of detached shapes during migration fixes

This commit is contained in:
Andrés Moya 2024-01-26 12:21:29 +01:00 committed by Andrey Antukh
parent 0fd6cacd17
commit daf77ecc5f

View file

@ -127,15 +127,35 @@
or that are the result of old bugs." or that are the result of old bugs."
[file-data libraries] [file-data libraries]
(let [detached-ids (volatile! #{}) (let [detached-ids (volatile! #{})
detach-shape detach-shape
(fn [container shape] (fn [container shape]
;; Detach a shape. If it's inside a component, add it to detached-ids. This list ;; Detach a shape and make necessary adjustments.
;; is used later to process any other copy that was referencing a detached copy.
(let [is-component? (let [root-shape (ctst/get-shape container (:id container))] (let [is-component? (let [root-shape (ctst/get-shape container (:id container))]
(and (some? root-shape) (nil? (:parent-id root-shape))))] (and (some? root-shape) (nil? (:parent-id root-shape))))
(when is-component? parent (ctst/get-shape container (:parent-id shape))
(vswap! detached-ids conj (:id shape))) in-copy? (ctn/in-any-component? (:objects container) parent)]
(ctk/detach-shape shape)))
(letfn [(detach-recursive [container shape first?]
;; If the shape is inside a component, add it to detached-ids. This list is used
;; later to process other copies that was referencing a detached nested copy.
(when is-component?
(vswap! detached-ids conj (:id shape)))
;; Detach the shape and all children until we find a subinstance.
(if (or first? in-copy? (not (ctk/instance-head? shape)))
(as-> container $
(ctn/update-shape $ (:id shape) ctk/detach-shape)
(reduce #(detach-recursive %1 %2 false)
$
(map (d/getf (:objects container)) (:shapes shape))))
;; If this is a subinstance head and the initial shape whas not itself a
;; nested copy, stop detaching and promote it to root.
(ctn/update-shape container (:id shape) #(assoc % :component-root true))))]
(detach-recursive container shape true))))
fix-bad-children fix-bad-children
(fn [file-data] (fn [file-data]
@ -476,15 +496,16 @@
(fn [file-data] (fn [file-data]
;; Detach shapes that were inside a copy (have :shape-ref) but now they aren't. ;; Detach shapes that were inside a copy (have :shape-ref) but now they aren't.
(letfn [(fix-container [container] (letfn [(fix-container [container]
(d/update-when container :objects update-vals (partial fix-shape container))) (reduce fix-shape container (ctn/shapes-seq container)))
(fix-shape [container shape] (fix-shape [container shape]
(let [parent (ctst/get-shape container (:parent-id shape))] (let [shape (ctst/get-shape container (:id shape)) ; Get the possibly updated shape
parent (ctst/get-shape container (:parent-id shape))]
(if (and (ctk/in-component-copy? shape) (if (and (ctk/in-component-copy? shape)
(not (ctk/instance-head? shape)) (not (ctk/instance-head? shape))
(not (ctk/in-component-copy? parent))) (not (ctk/in-component-copy? parent)))
(detach-shape container shape) (detach-shape container shape)
shape)))] container)))]
(-> file-data (-> file-data
(update :pages-index update-vals fix-container) (update :pages-index update-vals fix-container)
@ -523,11 +544,9 @@
(if (some? direct-shape-2) (if (some? direct-shape-2)
;; If it exists, there is nothing else to do. ;; If it exists, there is nothing else to do.
container container
;; If not found, detach shape and all children (stopping if a nested instance is reached) ;; If not found, detach shape and all children.
(let [children (ctn/get-children-in-instance (:objects container) (:id shape))] ;; container
(reduce #(ctn/update-shape %1 (:id %2) (partial detach-shape %1)) (detach-shape container shape)))))))
container
children))))))))
container))] container))]
(-> file-data (-> file-data
@ -539,14 +558,14 @@
;; If the user has created a copy and then converted into a path or bool, ;; If the user has created a copy and then converted into a path or bool,
;; detach it because the synchronization will no longer work. ;; detach it because the synchronization will no longer work.
(letfn [(fix-container [container] (letfn [(fix-container [container]
(d/update-when container :objects update-vals (partial fix-shape container))) (reduce fix-shape container (ctn/shapes-seq container)))
(fix-shape [container shape] (fix-shape [container shape]
(if (and (ctk/instance-head? shape) (if (and (ctk/instance-head? shape)
(or (cfh/path-shape? shape) (or (cfh/path-shape? shape)
(cfh/bool-shape? shape))) (cfh/bool-shape? shape)))
(detach-shape container shape) (detach-shape container shape)
shape))] container))]
(-> file-data (-> file-data
(update :pages-index update-vals fix-container) (update :pages-index update-vals fix-container)
@ -631,9 +650,8 @@
(fn [file-data] (fn [file-data]
;; Find component heads that are not main-instance but have not :shape-ref. ;; Find component heads that are not main-instance but have not :shape-ref.
;; Also shapes that have :shape-ref but are not in a copy. ;; Also shapes that have :shape-ref but are not in a copy.
(letfn [(fix-container (letfn [(fix-container [container]
[container] (reduce fix-shape container (ctn/shapes-seq container)))
(d/update-when container :objects update-vals (partial fix-shape container)))
(fix-shape (fix-shape
[container shape] [container shape]
@ -643,7 +661,8 @@
(and (ctk/in-component-copy? shape) (and (ctk/in-component-copy? shape)
(nil? (ctn/get-head-shape (:objects container) shape {:allow-main? true})))) (nil? (ctn/get-head-shape (:objects container) shape {:allow-main? true}))))
(detach-shape container shape) (detach-shape container shape)
shape))] container))]
(-> file-data (-> file-data
(update :pages-index update-vals fix-container) (update :pages-index update-vals fix-container)
(d/update-when :components update-vals fix-container)))) (d/update-when :components update-vals fix-container))))