0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

♻️ Refactor files upload effects

This commit is contained in:
alonso.torres 2021-01-07 19:02:18 +01:00
parent 802f19453d
commit 27a85ce0da
10 changed files with 318 additions and 319 deletions

View file

@ -553,32 +553,6 @@
(assoc :zoom zoom)
(update :vbox merge srect)))))))))))
;; --- Add shape to Workspace
(defn- viewport-center
[state]
(let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
[(+ x (/ width 2)) (+ y (/ height 2))]))
(defn create-and-add-shape
[type frame-x frame-y data]
(ptk/reify ::create-and-add-shape
ptk/WatchEvent
(watch [_ state stream]
(let [{:keys [width height]} data
[vbc-x vbc-y] (viewport-center state)
x (:x data (- vbc-x (/ width 2)))
y (:y data (- vbc-y (/ height 2)))
page-id (:current-page-id state)
frame-id (-> (dwc/lookup-page-objects state page-id)
(cp/frame-id-by-position {:x frame-x :y frame-y}))
shape (-> (cp/make-minimal-shape type)
(merge data)
(merge {:x x :y y})
(assoc :frame-id frame-id)
(gsh/setup-selrect))]
(rx/of (dwc/add-shape shape))))))
;; --- Update Shape Attrs
@ -1414,119 +1388,16 @@
(dwc/add-shape shape)
(dwc/commit-undo-transaction))))))
(defn image-upload [image x y]
(ptk/reify ::add-image
ptk/WatchEvent
(watch [_ state stream]
(let [{:keys [name width height id mtype]} image
shape {:name name
:width width
:height height
:x (- x (/ width 2))
:y (- y (/ height 2))
:metadata {:width width
:height height
:mtype mtype
:id id}}]
(rx/of (create-and-add-shape :image x y shape))))))
(defn- svg-dimensions [data]
(let [width (get-in data [:attrs :width] 100)
height (get-in data [:attrs :height] 100)
viewbox (get-in data [:attrs :viewBox] (str "0 0 " width " " height))
[_ _ width-str height-str] (str/split viewbox " ")
width (d/parse-integer width-str)
height (d/parse-integer height-str)]
[width height]))
(defn svg-upload [data x y]
(ptk/reify ::svg-upload
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id)
frame-id (cp/frame-id-by-position objects {:x x :y y})
[width height] (svg-dimensions data)
x (- x (/ width 2))
y (- y (/ height 2))
create-svg-raw
(fn [{:keys [tag] :as data} unames root-id]
(let [base (cond (string? tag) tag
(keyword? tag) (name tag)
(nil? tag) "node"
:else (str tag))]
(-> {:id (uuid/next)
:type :svg-raw
:name (dwc/generate-unique-name unames (str "svg-" base))
:frame-id frame-id
;; For svg children we set its coordinates as the root of the svg
:width width
:height height
:x x
:y y
:content data
:root-id root-id}
(gsh/setup-selrect))))
add-svg-child
(fn add-svg-child [parent-id root-id [unames [rchs uchs]] [index {:keys [content] :as data}]]
(let [shape (create-svg-raw data unames root-id)
shape-id (:id shape)
[rch1 uch1] (dwc/add-shape-changes page-id shape)
;; Mov-objects won't have undo because we "delete" the object in the undo of the
;; previous operation
rch2 [{:type :mov-objects
:parent-id parent-id
:frame-id frame-id
:page-id page-id
:index index
:shapes [shape-id]}]
;; Careful! the undo changes are concatenated reversed (we undo in reverse order
changes [(d/concat rchs rch1 rch2) (d/concat uch1 uchs)]
unames (conj unames (:name shape))]
(reduce (partial add-svg-child shape-id root-id) [unames changes] (d/enumerate (:content data)))))
unames (dwc/retrieve-used-names objects)
svg-name (->> (str/replace (:name data) ".svg" "")
(dwc/generate-unique-name unames))
root-shape (create-svg-raw data unames nil)
root-shape (-> root-shape
(assoc :name svg-name))
root-id (:id root-shape)
changes (dwc/add-shape-changes page-id root-shape)
[_ [rchanges uchanges]] (reduce (partial add-svg-child root-id root-id) [unames changes] (d/enumerate (:content data)))]
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
(dwc/select-shapes (d/ordered-set root-id)))
))))
(defn- paste-image
[image]
(ptk/reify ::paste-bin-impl
ptk/WatchEvent
(watch [_ state stream]
(let [response-sb (rx/subject)
file-id (get-in state [:workspace-file :id])
(let [file-id (get-in state [:workspace-file :id])
params {:file-id file-id
:local? true
:data [image]}]
(rx/concat (rx/of (dwp/upload-media-objects
(with-meta params
{:on-image
#(let [{:keys [x y]} @ms/mouse-position]
(rx/push! response-sb (image-upload % x y)))
:on-svg
#(let [{:keys [x y]} @ms/mouse-position]
(rx/push! response-sb (svg-upload % x y)))})))
(rx/take 1 response-sb))))))
(rx/of (dwp/upload-media-workspace params @ms/mouse-position))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Interactions
@ -1642,8 +1513,10 @@
(d/export dwp/fetch-shared-files)
(d/export dwp/link-file-to-library)
(d/export dwp/unlink-file-from-library)
(d/export dwp/upload-media-objects)
(d/export dwp/upload-media-asset)
(d/export dwp/upload-media-workspace)
(d/export dwp/clone-media-object)
(d/export dwc/image-uploaded)
;; Selection

View file

@ -21,6 +21,7 @@
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[clojure.set :as set]
[cuerdas.core :as str]
[potok.core :as ptk]))
;; Change this to :info :debug or :trace to debug this module
@ -601,3 +602,123 @@
:index index
:shapes [shape-id]})))]
(rx/of (commit-changes rchanges uchanges {:commit-local? true}))))))
;; --- Add shape to Workspace
(defn- viewport-center
[state]
(let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
[(+ x (/ width 2)) (+ y (/ height 2))]))
(defn create-and-add-shape
[type frame-x frame-y data]
(ptk/reify ::create-and-add-shape
ptk/WatchEvent
(watch [_ state stream]
(let [{:keys [width height]} data
[vbc-x vbc-y] (viewport-center state)
x (:x data (- vbc-x (/ width 2)))
y (:y data (- vbc-y (/ height 2)))
page-id (:current-page-id state)
frame-id (-> (lookup-page-objects state page-id)
(cp/frame-id-by-position {:x frame-x :y frame-y}))
shape (-> (cp/make-minimal-shape type)
(merge data)
(merge {:x x :y y})
(assoc :frame-id frame-id)
(gsh/setup-selrect))]
(rx/of (add-shape shape))))))
(defn image-uploaded [image x y]
(ptk/reify ::image-uploaded
ptk/WatchEvent
(watch [_ state stream]
(let [{:keys [name width height id mtype]} image
shape {:name name
:width width
:height height
:x (- x (/ width 2))
:y (- y (/ height 2))
:metadata {:width width
:height height
:mtype mtype
:id id}}]
(rx/of (create-and-add-shape :image x y shape))))))
(defn- svg-dimensions [data]
(let [width (get-in data [:attrs :width] 100)
height (get-in data [:attrs :height] 100)
viewbox (get-in data [:attrs :viewBox] (str "0 0 " width " " height))
[_ _ width-str height-str] (str/split viewbox " ")
width (d/parse-integer width-str)
height (d/parse-integer height-str)]
[width height]))
(defn svg-uploaded [data x y]
(ptk/reify ::svg-uploaded
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)
objects (lookup-page-objects state page-id)
frame-id (cp/frame-id-by-position objects {:x x :y y})
[width height] (svg-dimensions data)
x (- x (/ width 2))
y (- y (/ height 2))
create-svg-raw
(fn [{:keys [tag] :as data} unames root-id]
(let [base (cond (string? tag) tag
(keyword? tag) (name tag)
(nil? tag) "node"
:else (str tag))]
(-> {:id (uuid/next)
:type :svg-raw
:name (generate-unique-name unames (str "svg-" base))
:frame-id frame-id
;; For svg children we set its coordinates as the root of the svg
:width width
:height height
:x x
:y y
:content data
:root-id root-id}
(gsh/setup-selrect))))
add-svg-child
(fn add-svg-child [parent-id root-id [unames [rchs uchs]] [index {:keys [content] :as data}]]
(let [shape (create-svg-raw data unames root-id)
shape-id (:id shape)
[rch1 uch1] (add-shape-changes page-id shape)
;; Mov-objects won't have undo because we "delete" the object in the undo of the
;; previous operation
rch2 [{:type :mov-objects
:parent-id parent-id
:frame-id frame-id
:page-id page-id
:index index
:shapes [shape-id]}]
;; Careful! the undo changes are concatenated reversed (we undo in reverse order
changes [(d/concat rchs rch1 rch2) (d/concat uch1 uchs)]
unames (conj unames (:name shape))]
(reduce (partial add-svg-child shape-id root-id) [unames changes] (d/enumerate (:content data)))))
unames (retrieve-used-names objects)
svg-name (->> (str/replace (:name data) ".svg" "")
(generate-unique-name unames))
root-shape (create-svg-raw data unames nil)
root-shape (-> root-shape
(assoc :name svg-name))
root-id (:id root-shape)
changes (add-shape-changes page-id root-shape)
[_ [rchanges uchanges]] (reduce (partial add-svg-child root-id root-id) [unames changes] (d/enumerate (:content data)))]
(rx/of (commit-changes rchanges uchanges {:commit-local? true})
(select-shapes (d/ordered-set root-id)))))))

View file

@ -21,6 +21,7 @@
[app.main.data.media :as di]
[app.main.data.messages :as dm]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.libraries :as dwl]
[app.main.repo :as rp]
[app.main.store :as st]
[app.util.i18n :as i18n :refer [tr]]
@ -31,7 +32,8 @@
[app.util.avatars :as avatars]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[potok.core :as ptk]))
[potok.core :as ptk]
[app.main.store :as st]))
(declare persist-changes)
(declare shapes-changes-persisted)
@ -372,6 +374,89 @@
(->> (http/send! {:method :get :uri uri})
(rx/map :body)))
(defn url-name [url]
(let [query-idx (str/last-index-of url "?")
url (if (> query-idx 0) (subs url 0 query-idx) url)
filename (->> (str/split url "/") (last))
ext-idx (str/last-index-of filename ".")]
(if (> ext-idx 0) (subs filename 0 ext-idx) filename)))
(defn- handle-upload-error [on-error stream]
(->> stream
(rx/catch
(fn [error]
(cond
(= (:code error) :media-type-not-allowed)
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
(= (:code error) :media-type-mismatch)
(rx/of (dm/error (tr "errors.media-type-mismatch")))
(= (:code error) :unable-to-optimize)
(rx/of (dm/error (:hint error)))
(fn? on-error)
(do
(on-error error)
(rx/empty))
:else
(rx/throw error))))))
(defn- upload-uris [file-id local? name uris mtype on-image on-svg]
(letfn [(svg-url? [url]
(or (and mtype (= mtype "image/svg+xml"))
(str/ends-with? url ".svg")))
(prepare-uri [uri]
{:file-id file-id
:is-local local?
:name (or name (url-name uri))
:url uri})]
(rx/merge
(->> (rx/from uris)
(rx/filter (comp not svg-url?))
(rx/map prepare-uri)
(rx/mapcat #(rp/mutation! :create-file-media-object-from-url %))
(rx/do on-image))
(->> (rx/from uris)
(rx/filter svg-url?)
(rx/merge-map fetch-svg)
(rx/merge-map parse-svg)
(rx/with-latest vector uris)
(rx/map #(assoc (first %) :name (or name (url-name (second %)))))
(rx/do on-svg)))))
(defn- upload-data [file-id local? name data force-media on-image on-svg]
(let [svg-blob? (fn [blob]
(and (not force-media)
(= (.-type blob) "image/svg+xml")))
prepare-file
(fn [blob]
(let [name (or name (if (di/file? blob) (.-name blob) "blob"))]
{:file-id file-id
:name name
:is-local local?
:content blob}))
file-stream (->> (rx/from data)
(rx/map di/validate-file))]
(rx/merge
(->> file-stream
(rx/filter (comp not svg-blob?))
(rx/map prepare-file)
(rx/mapcat #(rp/mutation! :upload-file-media-object %))
(rx/do on-image))
(->> file-stream
(rx/filter svg-blob?)
(rx/merge-map #(.text %))
(rx/merge-map parse-svg)
(rx/with-latest vector file-stream)
(rx/map #(assoc (first %) :name (.-name (second %))))
(rx/do on-svg)))))
(defn upload-media-objects
[{:keys [file-id local? data name uris mtype svg-as-images] :as params}]
(us/assert ::upload-media-objects params)
@ -380,113 +465,52 @@
(watch [_ state stream]
(let [{:keys [on-image on-svg on-error]
:or {on-image identity
on-svg identity}} (meta params)
svg? (fn [blob]
(= (.-type blob) "image/svg+xml"))
svg-url? (fn [url]
(or (and mtype (= mtype "image/svg+xml"))
(str/ends-with? url ".svg")))
url-name (fn [url]
(let [query-idx (str/last-index-of url "?")
url (if (> query-idx 0) (subs url 0 query-idx) url)
filename (->> (str/split url "/") (last))
ext-idx (str/last-index-of filename ".")]
(if (> ext-idx 0) (subs filename 0 ext-idx) filename)))
prepare-file
(fn [blob]
(let [name (or name (if (di/file? blob) (.-name blob) "blob"))]
{:name name
:file-id file-id
:content blob
:is-local local?}))
prepare-uri
(fn [uri]
{:file-id file-id
:is-local local?
:url uri
:name (or name (url-name uri))})
file-stream
(when data
(->> (rx/from data)
(rx/map di/validate-file)))
image-stream
(cond
(seq uris)
(rx/merge
(->> (rx/from uris)
(rx/filter (comp not svg-url?))
(rx/map prepare-uri)
(rx/mapcat #(rp/mutation! :create-file-media-object-from-url %))
(rx/do on-image))
(->> (rx/from uris)
(rx/filter svg-url?)
(rx/merge-map fetch-svg)
(rx/merge-map parse-svg)
(rx/with-latest vector uris)
(rx/map #(assoc (first %) :name (or name (url-name (second %)))))
(rx/do on-svg)))
:else
(rx/merge
(->> file-stream
(rx/filter #(or svg-as-images (not (svg? %))))
(rx/map prepare-file)
(rx/mapcat #(rp/mutation! :upload-file-media-object %))
(rx/do on-image))
(->> file-stream
(rx/filter #(and (not svg-as-images) (svg? %)))
(rx/merge-map #(.text %))
(rx/merge-map parse-svg)
(rx/with-latest vector file-stream)
(rx/map #(assoc (first %) :name (.-name (second %))))
(rx/do on-svg))))]
on-svg identity}} (meta params)]
(rx/concat
(rx/of (dm/show {:content (tr "media.loading")
:type :info
:timeout nil
:tag :media-loading}))
(->> image-stream
(rx/catch (fn [error]
(cond
(= (:code error) :media-type-not-allowed)
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
(->> (if (seq uris)
;; Media objects is a list of URL's pointing to the path
(upload-uris file-id local? name uris mtype on-image on-svg)
;; Media objects are blob of data to be upload
(upload-data file-id local? name data svg-as-images on-image on-svg))
;; Every stream has its own sideffect. We need to ignore the result
(rx/ignore)
(handle-upload-error on-error)
(rx/finalize (st/emitf (dm/hide-tag :media-loading)))))))))
(= (:code error) :media-type-mismatch)
(rx/of (dm/error (tr "errors.media-type-mismatch")))
(defn upload-media-asset [params]
(let [params (-> params
(assoc :svg-as-images true)
(assoc :local? false)
(with-meta {:on-image #(st/emit! (dwl/add-media %))}))]
(upload-media-objects params)))
(= (:code error) :unable-to-optimize)
(rx/of (dm/error (:hint error)))
(defn upload-media-workspace
[params position]
(let [{:keys [x y]} position
params (-> params
(assoc :local? true)
(with-meta
{:on-image
#(st/emit! (dwc/image-uploaded % x y))
:on-svg
#(st/emit! (dwc/svg-uploaded % x y))}))]
(upload-media-objects params)))
(fn? on-error)
(do
(on-error error)
(rx/empty))
:else
(rx/throw error))))
(rx/finalize (fn []
(st/emit! (dm/hide-tag :media-loading))))))))))
;; --- Upload File Media objects
(s/def ::object-id ::us/uuid)
(s/def ::clone-media-objects-params
(s/keys :req-un [::file-id ::local? ::object-id]))
(s/keys :req-un [::file-id ::object-id]))
(defn clone-media-object
[{:keys [file-id local? object-id] :as params}]
[{:keys [file-id object-id] :as params}]
(us/assert ::clone-media-objects-params params)
(ptk/reify ::clone-media-objects
ptk/WatchEvent
@ -494,7 +518,7 @@
(let [{:keys [on-success on-error]
:or {on-success identity
on-error identity}} (meta params)
params {:is-local local?
params {:is-local true
:file-id file-id
:id object-id}]

View file

@ -99,10 +99,10 @@
(when (and shape (not (:hidden shape)))
(let [shape (-> (gsh/transform-shape shape)
(gsh/translate-to-frame frame))
opts #js {:shape shape}]
(if (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))
[:> svg-raw-wrapper {:shape shape :frame frame}]
opts #js {:shape shape}
svg-element? (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))]
(if-not svg-element?
[:> shape-container {:shape shape}
(case (:type shape)
:text [:> text/text-shape opts]
@ -113,7 +113,10 @@
:frame [:> frame-wrapper {:shape shape}]
:group [:> group-wrapper {:shape shape :frame frame}]
:svg-raw [:> svg-raw-wrapper {:shape shape :frame frame}]
nil)]))))))
nil)]
;; Don't wrap svg elements inside a <g> otherwise some can break
[:> svg-raw-wrapper {:shape shape :frame frame}]))))))
(defn get-viewbox [{:keys [x y width height] :or {x 0 y 0 width 100 height 100}}]
(str/fmt "%s %s %s %s" x y width height))

View file

@ -62,13 +62,11 @@
[props]
(let [shape (unchecked-get props "shape")
childs (unchecked-get props "childs")
frame (unchecked-get props "frame")]
frame (unchecked-get props "frame")
svg-element? (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))]
(if (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))
[:& component {:shape shape
:frame frame
:childs childs}]
(if-not svg-element?
[:> shape-container {:shape shape
:on-mouse-enter (handle-hover-shape shape true)
:on-mouse-leave (handle-hover-shape shape false)
@ -76,7 +74,12 @@
[:& component {:shape shape
:frame frame
:childs childs
:is-child-selected? true}]]))))
:is-child-selected? true}]]
;; Don't wrap svg elements inside a <g> otherwise some can break
[:& component {:shape shape
:frame frame
:childs childs}]))))
(defn frame-container-factory
[objects]

View file

@ -55,13 +55,12 @@
on-mouse-down (mf/use-callback
(mf/deps shape)
#(on-mouse-down % shape))]
#(on-mouse-down % shape))
(if (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))
[:& component {:shape shape
:frame frame
:childs childs}]
svg-element? (and (= :svg-raw (:type shape))
(not= :svg (get-in shape [:content :tag])))]
(if-not svg-element?
[:> shape-container {:shape shape
:on-mouse-down on-mouse-down
:cursor (when (seq (:interactions shape)) "pointer")}
@ -77,7 +76,12 @@
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width 1
:fill-opacity 0.2}])]))))
:fill-opacity 0.2}])]
;; Don't wrap svg elements inside a <g> otherwise some can break
[:& component {:shape shape
:frame frame
:childs childs}]))))
(defn frame-wrapper
[shape-container show-interactions?]
@ -187,8 +191,7 @@
:image [:> image-wrapper opts]
:circle [:> circle-wrapper opts]
:group [:> group-container {:shape shape :frame frame}]
:svg-raw [:> svg-raw-container {:shape shape :frame frame}]
)))))))
:svg-raw [:> svg-raw-container {:shape shape :frame frame}])))))))
(mf/defc frame-svg
{::mf/wrap [mf/memo]}

View file

@ -9,16 +9,17 @@
(ns app.main.ui.workspace.left-toolbar
(:require
[rumext.alpha :as mf]
[app.common.geom.point :as gpt]
[app.common.media :as cm]
[app.main.refs :as refs]
[app.main.data.workspace :as dw]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.util.object :as obj]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.main.ui.icons :as i]))
[app.util.object :as obj]
[rumext.alpha :as mf]))
(mf/defc image-upload
{::mf/wrap [mf/memo]}
@ -29,26 +30,13 @@
on-click
(mf/use-callback #(dom/click (mf/ref-val ref)))
handle-image-upload
(mf/use-callback
(fn [image]
(st/emit! (dw/image-upload image 0 0))))
handle-svg-upload
(mf/use-callback
(fn [svg]
(st/emit! (dw/svg-upload svg 0 0))))
on-files-selected
(mf/use-callback
(mf/deps file)
(fn [blobs]
(st/emit! (dw/upload-media-objects
(with-meta {:file-id (:id file)
:local? true
:data (seq blobs)}
{:on-image handle-image-upload
:on-svg handle-svg-upload})))))]
(let [params {:file-id (:id file)
:data (seq blobs)}]
(st/emit! (dw/upload-media-workspace params (gpt/point 0 0))))))]
[:li.tooltip.tooltip-right
{:alt (tr "workspace.toolbar.image")

View file

@ -82,31 +82,35 @@
alt? (hooks/use-rxsub ms/keyboard-alt)
moving-iref (mf/use-memo (mf/deps (:id shape)) (make-is-moving-ref (:id shape)))
moving? (mf/deref moving-iref)]
moving? (mf/deref moving-iref)
svg-element? (and (= (:type shape) :svg-raw)
(not= :svg (get-in shape [:content :tag])))]
(when (and shape
(or ghost? (not moving?))
(not (:hidden shape)))
(if (and (= (:type shape) :svg-raw)
(not= :svg (get-in shape [:content :tag])))
;; When we don't want to add a wrapper to internal raw svg elements
[:> svg-raw-wrapper opts]
[:g.shape-wrapper {:style {:cursor (if alt? cur/duplicate nil)}}
(case (:type shape)
:path [:> path/path-wrapper opts]
:text [:> text/text-wrapper opts]
:group [:> group-wrapper opts]
:rect [:> rect-wrapper opts]
:image [:> image-wrapper opts]
:circle [:> circle-wrapper opts]
:svg-raw [:> svg-raw-wrapper opts]
[:*
(if-not svg-element?
[:g.shape-wrapper {:style {:cursor (if alt? cur/duplicate nil)}}
(case (:type shape)
:path [:> path/path-wrapper opts]
:text [:> text/text-wrapper opts]
:group [:> group-wrapper opts]
:rect [:> rect-wrapper opts]
:image [:> image-wrapper opts]
:circle [:> circle-wrapper opts]
:svg-raw [:> svg-raw-wrapper opts]
;; Only used when drawing a new frame.
:frame [:> frame-wrapper {:shape shape}]
nil)
;; Only used when drawing a new frame.
:frame [:> frame-wrapper {:shape shape}]
(when (debug? :bounding-boxes)
[:& bounding-box {:shape shape :frame frame}])]))))
nil)]
;; Don't wrap svg elements inside a <g> otherwise some can break
[:> svg-raw-wrapper opts])
(when (debug? :bounding-boxes)
[:& bounding-box {:shape shape :frame frame}])])))
(def group-wrapper (group/group-wrapper-factory shape-wrapper))
(def svg-raw-wrapper (svg-raw/svg-raw-wrapper-factory shape-wrapper))

View file

@ -164,12 +164,9 @@
(mf/use-callback
(mf/deps file-id)
(fn [blobs]
(let [params (with-meta {:file-id file-id
:local? false
:data (seq blobs)
:svg-as-images true}
{:on-image on-media-uploaded})]
(st/emit! (dw/upload-media-objects params)))))
(let [params {:file-id file-id
:data (seq blobs)}]
(st/emit! (dw/upload-media-asset params)))))
on-delete
(mf/use-callback

View file

@ -456,12 +456,7 @@
on-image-uploaded
(mf/use-callback
(fn [image {:keys [x y]}]
(st/emit! (dw/image-upload image x y))))
on-svg-uploaded
(mf/use-callback
(fn [image {:keys [x y]}]
(st/emit! (dw/svg-upload image x y))))
(st/emit! (dw/image-uploaded image x y))))
on-drop
(mf/use-callback
@ -497,31 +492,23 @@
lines (str/lines data)
urls (filter #(and (not (str/blank? %))
(not (str/starts-with? % "#")))
lines)]
(st/emit!
(dw/upload-media-objects
(with-meta {:file-id (:id file)
:local? true
:uris urls}
{:on-image #(on-image-uploaded % viewport-coord)
:on-svg #(on-svg-uploaded % viewport-coord)}))))
lines)
params {:file-id (:id file)
:uris urls}]
(st/emit! (dw/upload-media-workspace params viewport-coord)))
;; Will trigger when the user drags an SVG asset from the assets panel
(and (dnd/has-type? event "text/asset-id") (= asset-type "image/svg+xml"))
(let [path (cfg/resolve-file-media {:id asset-id})]
(st/emit!
(dw/upload-media-objects
(with-meta {:file-id (:id file)
:local? true
:uris [path]
:name asset-name
:mtype asset-type}
{:on-svg #(on-svg-uploaded % viewport-coord)}))))
(let [path (cfg/resolve-file-media {:id asset-id})
params {:file-id (:id file)
:uris [path]
:name asset-name
:mtype asset-type}]
(st/emit! (dw/upload-media-workspace params viewport-coord)))
;; Will trigger when the user drags an image from the assets SVG
(dnd/has-type? event "text/asset-id")
(let [params {:file-id (:id file)
:local? true
:object-id asset-id
:name asset-name}]
(st/emit! (dw/clone-media-object
@ -534,12 +521,8 @@
:else
(let [files (dnd/get-files event)
params {:file-id (:id file)
:local? true
:data (seq files)}]
(st/emit! (dw/upload-media-objects
(with-meta params
{:on-image #(on-image-uploaded % viewport-coord)
:on-svg #(on-svg-uploaded % viewport-coord)}))))))))
(st/emit! (dw/upload-media-workspace params viewport-coord)))))))
on-paste
(mf/use-callback