Remove copying props for multiple elements (#5700)

This commit is contained in:
Alonso Torres 2025-01-28 16:44:44 +01:00 committed by GitHub
parent 1ebd5be3b1
commit 34e2eb829b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 39 deletions

View file

@ -1568,48 +1568,52 @@
(js/console.error "clipboard blocked:" error) (js/console.error "clipboard blocked:" error)
(rx/empty))] (rx/empty))]
(let [selected (->> (dsh/lookup-selected state) first) (let [selected (dsh/lookup-selected state)]
objects (dsh/lookup-page-objects state)] (if (> (count selected) 1)
;; If multiple items are selected don't do anything
(rx/empty)
(when-let [shape (get objects selected)] (let [selected (->> (dsh/lookup-selected state) first)
(let [props (cts/extract-props shape) objects (dsh/lookup-page-objects state)]
features (-> (features/get-team-enabled-features state) (when-let [shape (get objects selected)]
(set/difference cfeat/frontend-only-features)) (let [props (cts/extract-props shape)
version (-> (dsh/lookup-file state) :version) features (-> (features/get-team-enabled-features state)
(set/difference cfeat/frontend-only-features))
version (-> (dsh/lookup-file state) :version)
copy-data {:type :copied-props copy-data {:type :copied-props
:features features :features features
:version version :version version
:props props :props props
:images #{}}] :images #{}}]
;; The clipboard API doesn't handle well asynchronous calls because it expects to use ;; The clipboard API doesn't handle well asynchronous calls because it expects to use
;; the clipboard in an user interaction. If you do an async call the callback is outside ;; the clipboard in an user interaction. If you do an async call the callback is outside
;; the thread of the UI and so Safari blocks the copying event. ;; the thread of the UI and so Safari blocks the copying event.
;; We use the API `ClipboardItem` that allows promises to be passed and so the event ;; We use the API `ClipboardItem` that allows promises to be passed and so the event
;; will wait for the promise to resolve and everything should work as expected. ;; will wait for the promise to resolve and everything should work as expected.
;; This only works in the current versions of the browsers. ;; This only works in the current versions of the browsers.
(if (some? (unchecked-get ug/global "ClipboardItem")) (if (some? (unchecked-get ug/global "ClipboardItem"))
(let [resolve-data-promise (let [resolve-data-promise
(p/create (p/create
(fn [resolve reject] (fn [resolve reject]
(->> (rx/of copy-data) (->> (rx/of copy-data)
(rx/mapcat resolve-images) (rx/mapcat resolve-images)
(rx/map #(t/encode-str % {:type :json-verbose})) (rx/map #(t/encode-str % {:type :json-verbose}))
(rx/map #(wapi/create-blob % "text/plain")) (rx/map #(wapi/create-blob % "text/plain"))
(rx/subs! resolve reject))))] (rx/subs! resolve reject))))]
(->> (rx/from (wapi/write-to-clipboard-promise "text/plain" resolve-data-promise)) (->> (rx/from (wapi/write-to-clipboard-promise "text/plain" resolve-data-promise))
(rx/catch on-copy-error) (rx/catch on-copy-error)
(rx/ignore))) (rx/ignore)))
;; FIXME: this is to support Firefox versions below 116 that don't support ;; FIXME: this is to support Firefox versions below 116 that don't support
;; `ClipboardItem` after the version 116 is less common we could remove this. ;; `ClipboardItem` after the version 116 is less common we could remove this.
;; https://caniuse.com/?search=ClipboardItem ;; https://caniuse.com/?search=ClipboardItem
(->> (rx/of copy-data) (->> (rx/of copy-data)
(rx/mapcat resolve-images) (rx/mapcat resolve-images)
(rx/map #(wapi/write-to-clipboard (t/encode-str % {:type :json-verbose}))) (rx/map #(wapi/write-to-clipboard (t/encode-str % {:type :json-verbose})))
(rx/catch on-copy-error) (rx/catch on-copy-error)
(rx/ignore)))))))))) (rx/ignore))))))))))))
(defn paste-selected-props (defn paste-selected-props
[] []

View file

@ -138,7 +138,7 @@
(mf/defc context-menu-edit* (mf/defc context-menu-edit*
{::mf/props :obj {::mf/props :obj
::mf/private true} ::mf/private true}
[] [{:keys [shapes]}]
(let [do-copy #(st/emit! (dw/copy-selected)) (let [do-copy #(st/emit! (dw/copy-selected))
do-copy-link #(st/emit! (dw/copy-link-to-clipboard)) do-copy-link #(st/emit! (dw/copy-link-to-clipboard))
@ -206,6 +206,7 @@
[:> menu-entry* {:title (tr "workspace.shape.menu.copy-props") [:> menu-entry* {:title (tr "workspace.shape.menu.copy-props")
:shortcut (sc/get-tooltip :copy-props) :shortcut (sc/get-tooltip :copy-props)
:disabled (> (count shapes) 1)
:on-click handle-copy-props}] :on-click handle-copy-props}]
[:> menu-entry* {:title (tr "workspace.shape.menu.paste-props") [:> menu-entry* {:title (tr "workspace.shape.menu.paste-props")
:shortcut (sc/get-tooltip :paste-props) :shortcut (sc/get-tooltip :paste-props)