diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 589d2249b..a4748ba7f 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -595,3 +595,25 @@ (d/enumerate) (sort comparator-layout-z-index) (mapv second))) + +(defn common-parent-frame + "Search for the common frame for the selected shapes. Otherwise returns the root frame" + [objects selected] + + (loop [frame-id (get-in objects [(first selected) :frame-id]) + frame-parents (get-parent-ids objects frame-id) + selected (rest selected)] + (if (empty? selected) + frame-id + + (let [current (first selected) + parent? (into #{} (get-parent-ids objects current)) + + [frame-id frame-parents] + (if (parent? frame-id) + [frame-id frame-parents] + + (let [frame-id (d/seek parent? frame-parents)] + [frame-id (get-parent-ids objects frame-id)]))] + + (recur frame-id frame-parents (rest selected)))))) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 05c1d8cb3..ec0f3db00 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1304,8 +1304,8 @@ ;; Prepare the shape object. Mainly needed for image shapes ;; for retrieve the image data and convert it to the ;; data-url. - (prepare-object [objects selected+children {:keys [type] :as obj}] - (let [obj (maybe-translate obj objects selected+children)] + (prepare-object [objects parent-frame-id {:keys [type] :as obj}] + (let [obj (maybe-translate obj objects parent-frame-id)] (if (= type :image) (let [url (cf/resolve-file-media (:metadata obj))] (->> (http/send! {:method :get @@ -1328,20 +1328,11 @@ (update res :images conj img-part)) res))) - (maybe-translate [shape objects selected+children] - (let [frame-id (:frame-id shape) - root-frame-id (cph/get-shape-id-root-frame objects (:id shape))] - (cond - (cph/root-frame? shape) shape - (contains? selected+children root-frame-id) shape - - (cph/frame-shape? shape) - (let [frame (get objects root-frame-id)] - (gsh/translate-to-frame shape frame)) - - :else - (let [frame (get objects frame-id)] - (gsh/translate-to-frame shape frame))))) + (maybe-translate [shape objects parent-frame-id] + (if (= parent-frame-id uuid/zero) + shape + (let [frame (get objects parent-frame-id)] + (gsh/translate-to-frame shape frame)))) (on-copy-error [error] (js/console.error "Clipboard blocked:" error) @@ -1354,7 +1345,7 @@ selected (->> (wsh/lookup-selected state) (cph/clean-loops objects)) - selected+children (cph/selected-with-children objects selected) + parent-frame-id (cph/common-parent-frame objects selected) pdata (reduce (partial collect-object-ids objects) {} selected) initial {:type :copied-shapes :file-id (:current-file-id state) @@ -1369,7 +1360,7 @@ (catch :default e (on-copy-error e))) (->> (rx/from (seq (vals pdata))) - (rx/merge-map (partial prepare-object objects selected+children)) + (rx/merge-map (partial prepare-object objects parent-frame-id)) (rx/reduce collect-data initial) (rx/map (partial sort-selected state)) (rx/map t/encode-str)