diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 42a4c76ac..63f693195 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -502,3 +502,20 @@ (reduce process-shape (transient {})) (persistent!)) persistent!))) + +(defn selected-subtree + "Given a set of shapes, returns an objects subtree with the parents + of the selected items up to the root. Useful to calculate a partial z-index" + [objects selected] + + (let [selected+parents + (into selected + (mapcat #(get-parent-ids objects %)) + selected) + + remove-children + (fn [shape] + (update shape :shapes #(filterv selected+parents %)))] + + (-> (select-keys objects selected+parents) + (d/update-vals remove-children)))) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index d9c38e714..62cf0adba 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -49,7 +49,6 @@ [app.main.data.workspace.zoom :as dwz] [app.main.repo :as rp] [app.main.streams :as ms] - [app.main.worker :as uw] [app.util.dom :as dom] [app.util.globals :as ug] [app.util.http :as http] @@ -1193,28 +1192,14 @@ (defn copy-selected [] - (letfn [;; Sort objects so they have the same relative ordering - ;; when pasted later. - (sort-selected-async [state data] - (let [selected (wsh/lookup-selected state) - objects (wsh/lookup-page-objects state) - page-id (:current-page-id state)] - (->> (uw/ask! {:cmd :selection/query-z-index - :page-id page-id - :objects objects - :ids selected}) - (rx/map (fn [z-indexes] - (assoc data :selected - (->> (d/zip selected z-indexes) - (sort-by second) - (map first) - (into (d/ordered-set))))))))) - - ;; We cannot call to a remote procedure in Safari (for the copy) so we need - ;; to calculate it here instead of on the worker - (sort-selected-sync [state data] + (letfn [(sort-selected [state data] (let [selected (wsh/lookup-selected state) objects (wsh/lookup-page-objects state) + + ;; Narrow the objects map so it contains only relevant data for + ;; selected and its parents + objects (cph/selected-subtree objects selected) + z-index (cp/calculate-z-index objects) z-values (->> selected (map #(vector % @@ -1289,18 +1274,13 @@ :file-id (:current-file-id state) :selected selected :objects {} - :images #{}} + :images #{}}] + - sort-results - (fn [obs] - ;; Safari doesn't allow asynchronous sorting on the copy - (if (cfg/check-browser? :safari) - (rx/map (partial sort-selected-sync state) obs) - (rx/mapcat (partial sort-selected-async state) obs)))] (->> (rx/from (seq (vals pdata))) (rx/merge-map (partial prepare-object objects selected)) (rx/reduce collect-data initial) - (sort-results) + (rx/map (partial sort-selected state)) (rx/map t/encode-str) (rx/map wapi/write-to-clipboard) (rx/catch on-copy-error)