Allow copy-paste variants into another file (#6319)

This commit is contained in:
Pablo Alba 2025-04-16 17:12:12 +02:00 committed by GitHub
parent 8c15296d07
commit ba442e1549
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 21 deletions

View file

@ -1859,20 +1859,26 @@
(assoc change :component-id (:id container))))
(defn generate-add-component-changes
[changes root objects file-id page-id]
[changes root objects file-id page-id variant-props]
(let [name (:name root)
variant-id (when (ctk/is-variant? root) (:parent-id root))
props (when (ctk/is-variant? root) (get variant-props (:component-id root)))
[path name] (cfh/parse-path-name name)
[root-shape updated-shapes]
(ctn/convert-shape-in-component root objects file-id)
changes (-> changes
(pcb/add-component (:id root-shape)
path
name
updated-shapes
(:id root)
page-id))]
changes (-> changes
(pcb/add-component (:id root-shape)
path
name
updated-shapes
(:id root)
page-id
nil
variant-id
props))]
[root-shape changes]))
(defn generate-add-component
@ -1927,7 +1933,7 @@
objects' (assoc objects (:id root) root)
[root-shape changes] (generate-add-component-changes changes root objects' file-id page-id)
[root-shape changes] (generate-add-component-changes changes root objects' file-id page-id nil)
changes (pcb/update-shapes changes
old-root-ids
@ -2193,9 +2199,11 @@
(defn generate-duplicate-shape-change
([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id]
(generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true))
(generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true nil))
([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id variant-props]
(generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true variant-props))
([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id frame-id parent-id duplicating-component? child? remove-swap-slot?]
([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id frame-id parent-id duplicating-component? child? remove-swap-slot? variant-props]
(cond
(nil? obj)
changes
@ -2231,7 +2239,7 @@
regenerate-component
(fn [changes shape]
(let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page))]
(let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page) variant-props)]
changes))
new-obj
@ -2270,7 +2278,13 @@
(d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))
(cond-> (ctl/grid-layout? obj)
(ctl/remap-grid-cells ids-map)))
(ctl/remap-grid-cells ids-map))
(cond-> (ctk/is-variant-container? parent)
(assoc :variant-id parent-id))
(cond-> (not (ctk/is-variant-container? parent))
(dissoc :variant-id)))
new-obj (cond-> new-obj
(not duplicating-component?)
@ -2318,14 +2332,15 @@
;; only remove swap slot of children when the current shape
;; is not a subinstance head nor a instance root
(not subinstance-head?)
(not instance-root?))))
(not instance-root?))
variant-props))
changes
(map (d/getf objects) (:shapes obj)))))))
(defn generate-duplicate-changes
"Prepare objects to duplicate: generate new id, give them unique names,
move to the desired position, and recalculate parents and frames as needed."
[changes all-objects page ids delta libraries library-data file-id]
[changes all-objects page ids delta libraries library-data file-id & {:keys [variant-props]}]
(let [shapes (map (d/getf all-objects) ids)
unames (volatile! (cfh/get-used-names (:objects page)))
update-unames! (fn [new-name] (vswap! unames conj new-name))
@ -2352,7 +2367,8 @@
nil
libraries
library-data
file-id)
file-id
variant-props)
changes))
;; We need to check the changes to get the ids-map

View file

@ -1374,15 +1374,31 @@
(assoc obj ::images images))))
(rx/of obj))))
(collect-variants [state shape]
(let [page-id (:current-page-id state)
data (dsh/lookup-file-data state)
objects (-> (dsh/get-page data page-id)
(get :objects))
components (cfv/find-variant-components data objects (:id shape))]
(into {} (map (juxt :id :variant-properties) components))))
;; Collects all the items together and split images into a
;; separated data structure for a more easy paste process.
(collect-data [result {:keys [id ::images] :as item}]
;; Also collects the variant properties of the copied variants
(collect-data [state result {:keys [id ::images] :as item}]
(cond-> result
:always
(update :objects assoc id (dissoc item ::images))
(some? images)
(update :images into images)))
(update :images into images)
(ctc/is-variant-container? item)
(update :variant-properties merge (collect-variants state item))))
(maybe-translate [shape objects parent-frame-id]
(if (= parent-frame-id uuid/zero)
@ -1467,7 +1483,7 @@
(fn [resolve reject]
(->> (rx/from shapes)
(rx/merge-map (partial prepare-object objects frame-id))
(rx/reduce collect-data initial)
(rx/reduce (partial collect-data state) initial)
(rx/map (partial sort-selected state))
(rx/map (partial advance-copies state selected))
(rx/map #(t/encode-str % {:type :json-verbose}))
@ -1482,7 +1498,7 @@
;; https://caniuse.com/?search=ClipboardItem
(->> (rx/from shapes)
(rx/merge-map (partial prepare-object objects frame-id))
(rx/reduce collect-data initial)
(rx/reduce (partial collect-data state) initial)
(rx/map (partial sort-selected state))
(rx/map (partial advance-copies state selected))
(rx/map #(t/encode-str % {:type :json-verbose}))
@ -2070,6 +2086,9 @@
objects (:objects pdata)
variant-props (:variant-properties pdata)
position (deref ms/mouse-position)
;; Calculate position for the pasted elements
@ -2101,7 +2120,8 @@
(gslg/get-drop-cell frame-id all-objects position))
changes (-> (pcb/empty-changes it)
(cll/generate-duplicate-changes all-objects page selected delta libraries ldata file-id)
(cll/generate-duplicate-changes all-objects page selected delta
libraries ldata file-id {:variant-props variant-props})
(pcb/amend-changes (partial process-rchange media-idx))
(pcb/amend-changes (partial change-add-obj-index objects selected index)))