mirror of
https://github.com/penpot/penpot.git
synced 2025-04-01 09:31:26 -05:00
♻️ Remove duplicated code
This commit is contained in:
parent
d349e46cd8
commit
93bde62581
16 changed files with 188 additions and 306 deletions
|
@ -57,6 +57,9 @@
|
|||
;; Related info on how thumbnails generation
|
||||
;; http://www.imagemagick.org/Usage/thumbnails/
|
||||
|
||||
(def valid-media-types
|
||||
#{"image/jpeg", "image/png", "image/webp", "image/svg+xml"})
|
||||
|
||||
(defn format->extension
|
||||
[format]
|
||||
(case format
|
||||
|
@ -196,6 +199,13 @@
|
|||
(us/assert (s/coll-of vector?) pairs)
|
||||
(reduce #(resolve-uri mst/media-storage %1 (nth %2 0) (nth %2 1)) row pairs))
|
||||
|
||||
(defn validate-media-type
|
||||
[media-type]
|
||||
(when-not (valid-media-types media-type)
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid media object")))
|
||||
|
||||
(defn download-media-object
|
||||
[url]
|
||||
(let [result (http/get! url {:as :byte-array})
|
||||
|
|
|
@ -45,12 +45,9 @@
|
|||
(declare persist-media-object-on-fs)
|
||||
(declare persist-media-thumbnail-on-fs)
|
||||
|
||||
(def valid-media-object-types?
|
||||
#{"image/jpeg", "image/png", "image/webp", "image/svg+xml"})
|
||||
|
||||
(s/def :uxbox$upload/filename ::us/string)
|
||||
(s/def :uxbox$upload/size ::us/integer)
|
||||
(s/def :uxbox$upload/content-type valid-media-object-types?)
|
||||
(s/def :uxbox$upload/content-type media/valid-media-types)
|
||||
(s/def :uxbox$upload/tempfile any?)
|
||||
|
||||
(s/def ::upload
|
||||
|
@ -64,11 +61,11 @@
|
|||
(s/def ::is-local ::us/boolean)
|
||||
|
||||
(s/def ::add-media-object-from-url
|
||||
(s/keys :req-un [::profile-id ::file-id ::url ::is-local]
|
||||
(s/keys :req-un [::profile-id ::file-id ::is-local ::url]
|
||||
:opt-un [::id]))
|
||||
|
||||
(s/def ::upload-media-object
|
||||
(s/keys :req-un [::profile-id ::file-id ::name ::content ::is-local]
|
||||
(s/keys :req-un [::profile-id ::file-id ::is-local ::name ::content]
|
||||
:opt-un [::id]))
|
||||
|
||||
(sm/defmutation ::add-media-object-from-url
|
||||
|
@ -89,12 +86,8 @@
|
|||
(create-media-object conn params))))
|
||||
|
||||
(defn create-media-object
|
||||
[conn {:keys [id content file-id name is-local]}]
|
||||
(when-not (valid-media-object-types? (:content-type content))
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid media object."))
|
||||
|
||||
[conn {:keys [id file-id is-local name content]}]
|
||||
(media/validate-media-type (:content-type content))
|
||||
(let [info (media/run {:cmd :info :input {:path (:tempfile content)
|
||||
:mtype (:content-type content)}})
|
||||
path (persist-media-object-on-fs content)
|
||||
|
|
|
@ -272,15 +272,11 @@
|
|||
|
||||
(sm/defmutation ::update-profile-photo
|
||||
[{:keys [profile-id file] :as params}]
|
||||
(when-not (media-mutations/valid-media-object-types? (:content-type file))
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid media object"))
|
||||
|
||||
(media/validate-media-type (:content-type file))
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [profile (profile/retrieve-profile conn profile-id)
|
||||
_ (media/run {:cmd :info :input {:path (:tempfile file)
|
||||
:mtype (:content-type file)}})
|
||||
:mtype (:content-type file)}})
|
||||
photo (upload-photo conn params)]
|
||||
|
||||
;; Schedule deletion of old photo
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
:id object-id-1
|
||||
:profile-id (:id prof)
|
||||
:file-id (:id file)
|
||||
:url url
|
||||
:is-local true}
|
||||
:is-local true
|
||||
:url url}
|
||||
out (th/try-on! (sm/handle data))]
|
||||
|
||||
;; (th/print-result! out)
|
||||
|
@ -61,9 +61,9 @@
|
|||
:id object-id-2
|
||||
:profile-id (:id prof)
|
||||
:file-id (:id file)
|
||||
:is-local true
|
||||
:name "testfile"
|
||||
:content content
|
||||
:is-local true}
|
||||
:content content}
|
||||
out (th/try-on! (sm/handle data))]
|
||||
|
||||
;; (th/print-result! out)
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-colors (:id color)] color)
|
||||
(assoc-in [:workspace-colors-library (:id color)] color)
|
||||
(assoc-in [:workspace-local :color-for-rename] (:id color))))))
|
||||
|
||||
(def clear-color-for-rename
|
||||
|
@ -67,7 +67,7 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-colors (:id color)] color)))))
|
||||
(assoc-in [:workspace-colors-library (:id color)] color)))))
|
||||
|
||||
(declare update-color-result)
|
||||
|
||||
|
@ -86,7 +86,7 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-colors (:id color)] color)))))
|
||||
(assoc-in [:workspace-colors-library (:id color)] color)))))
|
||||
|
||||
(declare delete-color-result)
|
||||
|
||||
|
@ -104,5 +104,5 @@
|
|||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(d/dissoc-in [:workspace-colors color-id])))))
|
||||
(d/dissoc-in [:workspace-colors-library color-id])))))
|
||||
|
||||
|
|
|
@ -24,16 +24,14 @@
|
|||
|
||||
;; --- Specs
|
||||
|
||||
(s/def ::id uuid?)
|
||||
(s/def ::name string?)
|
||||
(s/def ::width number?)
|
||||
(s/def ::height number?)
|
||||
(s/def ::modified-at inst?)
|
||||
(s/def ::created-at inst?)
|
||||
(s/def ::modified-at inst?)
|
||||
(s/def ::mtype string?)
|
||||
;; (s/def ::thumbnail string?)
|
||||
(s/def ::id uuid?)
|
||||
(s/def ::uri string?)
|
||||
(s/def ::user-id uuid?)
|
||||
|
||||
(s/def ::media-object
|
||||
(s/keys :req-un [::id
|
||||
|
@ -43,83 +41,49 @@
|
|||
::mtype
|
||||
::created-at
|
||||
::modified-at
|
||||
::uri
|
||||
;; ::thumb-uri
|
||||
::user-id]))
|
||||
::uri]))
|
||||
|
||||
;; --- Create library Media Objects
|
||||
(s/def ::js-file #(instance? js/Blob %))
|
||||
(s/def ::js-files (s/coll-of ::js-file))
|
||||
|
||||
(declare create-media-objects-result)
|
||||
(def allowed-file-types #{"image/jpeg" "image/png" "image/webp" "image/svg+xml"})
|
||||
(def allowed-media-types #{"image/jpeg" "image/png" "image/webp" "image/svg+xml"})
|
||||
(def str-media-types (str/join "," allowed-media-types))
|
||||
(def max-file-size (* 5 1024 1024))
|
||||
|
||||
;; TODO: unify with upload-media-object at main/data/workspace/persistence.cljs
|
||||
;; and update-photo at main/data/users.cljs
|
||||
;; https://tree.taiga.io/project/uxboxproject/us/440
|
||||
;; --- Utility functions
|
||||
|
||||
(defn create-media-objects
|
||||
([file-id files] (create-media-objects file-id files identity))
|
||||
([file-id files on-uploaded]
|
||||
(us/verify (s/nilable ::us/uuid) file-id)
|
||||
(us/verify fn? on-uploaded)
|
||||
(ptk/reify ::create-media-objects
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [check-file
|
||||
(fn [file]
|
||||
(when (> (.-size file) max-file-size)
|
||||
(throw (ex-info (tr "errors.media-too-large") {})))
|
||||
(when-not (contains? allowed-file-types (.-type file))
|
||||
(throw (ex-info (tr "errors.media-format-unsupported") {})))
|
||||
file)
|
||||
(defn validate-file
|
||||
;; Check that a file obtained with the file javascript API is valid.
|
||||
[file]
|
||||
(when (> (.-size file) max-file-size)
|
||||
(throw (ex-info (tr "errors.media-too-large") {})))
|
||||
(when-not (contains? allowed-media-types (.-type file))
|
||||
(throw (ex-info (tr "errors.media-format-unsupported") {})))
|
||||
file)
|
||||
|
||||
on-success #(do (st/emit! dm/hide)
|
||||
(on-uploaded %))
|
||||
(defn notify-start-loading
|
||||
[]
|
||||
(st/emit! (dm/show {:content (tr "media.loading")
|
||||
:type :info
|
||||
:timeout nil})))
|
||||
|
||||
on-error #(do (st/emit! dm/hide)
|
||||
(let [msg (cond
|
||||
(.-message %)
|
||||
(.-message %)
|
||||
(defn notify-finished-loading
|
||||
[]
|
||||
(st/emit! dm/hide))
|
||||
|
||||
(= (:code %) :media-type-not-allowed)
|
||||
(tr "errors.media-type-not-allowed")
|
||||
(defn process-error
|
||||
[error]
|
||||
(let [msg (cond
|
||||
(.-message error)
|
||||
(.-message error)
|
||||
|
||||
(= (:code %) :media-type-mismatch)
|
||||
(tr "errors.media-type-mismatch")
|
||||
(= (:code error) :media-type-not-allowed)
|
||||
(tr "errors.media-type-not-allowed")
|
||||
|
||||
:else
|
||||
(tr "errors.unexpected-error"))]
|
||||
(rx/of (dm/error msg))))
|
||||
(= (:code error) :media-type-mismatch)
|
||||
(tr "errors.media-type-mismatch")
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
{:name (.-name file)
|
||||
:file-id file-id
|
||||
:content file
|
||||
:is-local false})]
|
||||
|
||||
(st/emit! (dm/show {:content (tr "media.loading")
|
||||
:type :info
|
||||
:timeout nil}))
|
||||
|
||||
(->> (rx/from files)
|
||||
(rx/map check-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation! :upload-media-object %))
|
||||
(rx/reduce conj [])
|
||||
(rx/do on-success)
|
||||
(rx/mapcat identity)
|
||||
(rx/map (partial create-media-objects-result file-id))
|
||||
(rx/catch on-error)))))))
|
||||
|
||||
;; --- Media object Created
|
||||
|
||||
(defn create-media-objects-result
|
||||
[file-id media-object]
|
||||
#_(us/verify ::media-object media-object)
|
||||
(ptk/reify ::create-media-objects-result
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-media (:id media-object)] media-object)))))
|
||||
:else
|
||||
(tr "errors.unexpected-error"))]
|
||||
(rx/of (dm/error msg))))
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[uxbox.main.store :as st]
|
||||
[uxbox.main.repo :as rp]
|
||||
[uxbox.main.data.messages :as dm]
|
||||
[uxbox.main.data.media :as di]
|
||||
[uxbox.util.router :as rt]
|
||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||
[uxbox.util.storage :refer [storage]]
|
||||
|
@ -155,58 +156,28 @@
|
|||
|
||||
;; --- Update Photo
|
||||
|
||||
(s/def ::file #(instance? js/File %))
|
||||
(def allowed-file-types #{"image/jpeg" "image/png" "image/webp"})
|
||||
(def max-file-size (* 5 1024 1024))
|
||||
|
||||
;; TODO: unify with create-media-objects at main/data/media.cljs
|
||||
;; and upload-media-object at main/data/workspace/persistence.cljs
|
||||
;; https://tree.taiga.io/project/uxboxproject/us/440
|
||||
|
||||
(defn update-photo
|
||||
[file]
|
||||
(us/verify ::file file)
|
||||
(us/verify ::di/js-file file)
|
||||
(ptk/reify ::update-photo
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [check-file
|
||||
(let [on-success di/notify-finished-loading
|
||||
|
||||
on-error #(do (di/notify-finished-loading)
|
||||
(di/process-error %))
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
(when (> (.-size file) max-file-size)
|
||||
(throw (ex-info (tr "errors.media-too-large") {})))
|
||||
(when-not (contains? allowed-file-types (.-type file))
|
||||
(throw (ex-info (tr "errors.media-format-unsupported") {})))
|
||||
file)
|
||||
{:file file})]
|
||||
|
||||
on-success #(do (st/emit! dm/hide))
|
||||
(di/notify-start-loading)
|
||||
|
||||
on-error #(do (st/emit! dm/hide)
|
||||
(let [msg (cond
|
||||
(.-message %)
|
||||
(.-message %)
|
||||
|
||||
(= (:code %) :media-type-not-allowed)
|
||||
(tr "errors.media-type-not-allowed")
|
||||
|
||||
(= (:code %) :media-type-mismatch)
|
||||
(tr "errors.media-type-mismatch")
|
||||
|
||||
:else
|
||||
(tr "errors.unexpected-error"))]
|
||||
(rx/of (dm/error msg))))
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
{:file file})]
|
||||
|
||||
(st/emit! (dm/show {:content (tr "media.loading")
|
||||
:type :info
|
||||
:timeout nil}))
|
||||
|
||||
(->> (rx/of file)
|
||||
(rx/map check-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation :update-profile-photo %))
|
||||
(rx/do on-success)
|
||||
(rx/map (constantly fetch-profile))
|
||||
(rx/catch on-error))))))
|
||||
(->> (rx/of file)
|
||||
(rx/map di/validate-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation :update-profile-photo %))
|
||||
(rx/do on-success)
|
||||
(rx/map (constantly fetch-profile))
|
||||
(rx/catch on-error))))))
|
||||
|
||||
|
|
|
@ -1169,9 +1169,6 @@
|
|||
:metadata {:width (:width image)
|
||||
:height (:height image)
|
||||
:uri (:uri image)}}
|
||||
;; :thumb-width (:thumb-width image)
|
||||
;; :thumb-height (:thumb-height image)
|
||||
;; :thumb-uri (:thumb-uri image)}}
|
||||
aspect-ratio (/ (:width image) (:height image))]
|
||||
(st/emit! (create-and-add-shape :image shape aspect-ratio))))
|
||||
|
||||
|
@ -1180,7 +1177,8 @@
|
|||
(ptk/reify ::paste-bin-impl
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (dwp/upload-media-object image image-uploaded)))))
|
||||
(let [file-id (get-in state [:workspace-page :file-id])]
|
||||
(rx/of (dwp/upload-media-objects file-id true [image] image-uploaded))))))
|
||||
|
||||
(def paste
|
||||
(ptk/reify ::paste
|
||||
|
@ -1435,16 +1433,17 @@
|
|||
;; Persistence
|
||||
|
||||
(def set-file-shared dwp/set-file-shared)
|
||||
(def fetch-media-objects dwp/fetch-media-objects)
|
||||
(def fetch-media-library dwp/fetch-media-library)
|
||||
(def fetch-colors-library dwp/fetch-colors-library)
|
||||
(def add-media-object-from-url dwp/add-media-object-from-url)
|
||||
(def upload-media-object dwp/upload-media-object)
|
||||
(def upload-media-objects dwp/upload-media-objects)
|
||||
(def delete-media-object dwp/delete-media-object)
|
||||
(def fetch-colors dwp/fetch-colors)
|
||||
(def rename-page dwp/rename-page)
|
||||
(def delete-page dwp/delete-page)
|
||||
(def create-empty-page dwp/create-empty-page)
|
||||
|
||||
;; Selection
|
||||
|
||||
(def select-shape dws/select-shape)
|
||||
(def deselect-all dws/deselect-all)
|
||||
(def select-shapes dws/select-shapes)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[uxbox.common.spec :as us]
|
||||
[uxbox.main.data.dashboard :as dd]
|
||||
[uxbox.main.data.messages :as dm]
|
||||
[uxbox.main.data.media :as di]
|
||||
[uxbox.main.data.workspace.common :as dwc]
|
||||
[uxbox.main.repo :as rp]
|
||||
[uxbox.main.store :as st]
|
||||
|
@ -296,178 +297,127 @@
|
|||
(rx/of go-to-file)
|
||||
(rx/empty))))))))))
|
||||
|
||||
;; --- Fetch Workspace Graphics
|
||||
;; --- Fetch Workspace Media library
|
||||
|
||||
(declare media-objects-fetched)
|
||||
(declare media-library-fetched)
|
||||
|
||||
(defn fetch-media-objects
|
||||
(defn fetch-media-library
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-media-objects
|
||||
(ptk/reify ::fetch-media-library
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :media-objects {:file-id file-id :is-local false})
|
||||
(rx/map media-objects-fetched)))))
|
||||
(rx/map media-library-fetched)))))
|
||||
|
||||
(defn media-objects-fetched
|
||||
(defn media-library-fetched
|
||||
[media-objects]
|
||||
(ptk/reify ::media-objects-fetched
|
||||
(ptk/reify ::media-library-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [media-objects (d/index-by :id media-objects)]
|
||||
(assoc state :workspace-media media-objects)))))
|
||||
(assoc state :workspace-media-library media-objects)))))
|
||||
|
||||
;; --- Fetch Workspace Colors
|
||||
;; --- Fetch Workspace Colors library
|
||||
|
||||
(declare colors-fetched)
|
||||
(declare colors-library-fetched)
|
||||
|
||||
(defn fetch-colors
|
||||
(defn fetch-colors-library
|
||||
[file-id]
|
||||
(ptk/reify ::fetch-colors
|
||||
(ptk/reify ::fetch-colors-library
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query :colors {:file-id file-id})
|
||||
(rx/map colors-fetched)))))
|
||||
(rx/map colors-library-fetched)))))
|
||||
|
||||
(defn colors-fetched
|
||||
(defn colors-library-fetched
|
||||
[colors]
|
||||
(ptk/reify ::colors-fetched
|
||||
(ptk/reify ::colors-library-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [colors (d/index-by :id colors)]
|
||||
(assoc state :workspace-colors colors)))))
|
||||
(assoc state :workspace-colors-library colors)))))
|
||||
|
||||
|
||||
;; --- Upload local media objects
|
||||
|
||||
(declare media-object-uploaded)
|
||||
(def allowed-file-types #{"image/jpeg" "image/png" "image/webp" "image/svg+xml"})
|
||||
(def max-file-size (* 5 1024 1024))
|
||||
|
||||
;; TODO: unify with create-media-objects at main/data/media.cljs
|
||||
;; and update-photo at main/data/users.cljs
|
||||
;; https://tree.taiga.io/project/uxboxproject/us/440
|
||||
(declare upload-media-objects-result)
|
||||
|
||||
(defn add-media-object-from-url
|
||||
([url] (add-media-object-from-url url identity))
|
||||
([url on-added]
|
||||
([file-id is-local url] (add-media-object-from-url file-id is-local url identity))
|
||||
([file-id is-local url on-added]
|
||||
(us/verify ::us/url url)
|
||||
(us/verify fn? on-added)
|
||||
(us/verify ::us/boolean is-local)
|
||||
(ptk/reify ::add-media-object-from-url
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [file-id (get-in state [:workspace-page :file-id])
|
||||
|
||||
on-success #(do (st/emit! dm/hide)
|
||||
(let [on-success #(do (di/notify-finished-loading)
|
||||
(on-added %))
|
||||
|
||||
on-error #(do (st/emit! dm/hide)
|
||||
(let [msg (cond
|
||||
(.-message %)
|
||||
(.-message %)
|
||||
|
||||
(= (:code %) :media-type-not-allowed)
|
||||
(tr "errors.media-type-not-allowed")
|
||||
|
||||
(= (:code %) :media-type-mismatch)
|
||||
(tr "errors.media-type-mismatch")
|
||||
|
||||
:else
|
||||
(tr "errors.unexpected-error"))]
|
||||
(rx/of (dm/error msg))))
|
||||
|
||||
on-error #(do (di/notify-finished-loading)
|
||||
(di/process-error %))
|
||||
|
||||
prepare
|
||||
(fn [url]
|
||||
{:file-id file-id
|
||||
:url url
|
||||
:is-local true})]
|
||||
:is-local is-local
|
||||
:url url})]
|
||||
|
||||
(di/notify-start-loading)
|
||||
|
||||
(st/emit! (dm/show {:content (tr "media.loading")
|
||||
:type :info
|
||||
:timeout nil}))
|
||||
(->> (rx/of url)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation! :add-media-object-from-url %))
|
||||
(rx/do on-success)
|
||||
(rx/map media-object-uploaded)
|
||||
(rx/map (partial upload-media-objects-result file-id is-local))
|
||||
(rx/catch on-error)))))))
|
||||
|
||||
(defn upload-media-object
|
||||
([file] (upload-media-object file identity))
|
||||
([file on-uploaded]
|
||||
(defn upload-media-objects
|
||||
([file-id is-local js-files] (upload-media-objects file-id is-local js-files identity))
|
||||
([file-id is-local js-files on-uploaded]
|
||||
(us/verify ::us/uuid file-id)
|
||||
(us/verify ::us/boolean is-local)
|
||||
(us/verify ::di/js-files js-files)
|
||||
(us/verify fn? on-uploaded)
|
||||
(ptk/reify ::upload-media-object
|
||||
(ptk/reify ::upload-media-objects
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [file-id (get-in state [:workspace-page :file-id])
|
||||
|
||||
check-file
|
||||
(fn [file]
|
||||
(when (> (.-size file) max-file-size)
|
||||
(throw (ex-info (tr "errors.media-too-large") {})))
|
||||
(when-not (contains? allowed-file-types (.-type file))
|
||||
(throw (ex-info (tr "errors.media-format-unsupported") {})))
|
||||
file)
|
||||
|
||||
on-success #(do (st/emit! dm/hide)
|
||||
(let [on-success #(do (di/notify-finished-loading)
|
||||
(on-uploaded %))
|
||||
|
||||
on-error #(do (st/emit! dm/hide)
|
||||
(let [msg (cond
|
||||
(.-message %)
|
||||
(.-message %)
|
||||
|
||||
(= (:code %) :media-type-not-allowed)
|
||||
(tr "errors.media-type-not-allowed")
|
||||
|
||||
(= (:code %) :media-type-mismatch)
|
||||
(tr "errors.media-type-mismatch")
|
||||
|
||||
:else
|
||||
(tr "errors.unexpected-error"))]
|
||||
(rx/of (dm/error msg))))
|
||||
on-error #(do (di/notify-finished-loading)
|
||||
(di/process-error %))
|
||||
|
||||
prepare
|
||||
(fn [file]
|
||||
{:name (.-name file)
|
||||
(fn [js-file]
|
||||
{:name (.-name js-file)
|
||||
:file-id file-id
|
||||
:content file
|
||||
:is-local true})]
|
||||
:content js-file
|
||||
:is-local is-local})]
|
||||
|
||||
(st/emit! (dm/show {:content (tr "media.loading")
|
||||
:type :info
|
||||
:timeout nil}))
|
||||
(->> (rx/of file)
|
||||
(rx/map check-file)
|
||||
(di/notify-start-loading)
|
||||
|
||||
(->> (rx/from js-files)
|
||||
(rx/map di/validate-file)
|
||||
(rx/map prepare)
|
||||
(rx/mapcat #(rp/mutation! :upload-media-object %))
|
||||
(rx/do on-success)
|
||||
(rx/map media-object-uploaded)
|
||||
(rx/map (partial upload-media-objects-result file-id is-local))
|
||||
(rx/catch on-error)))))))
|
||||
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::width ::us/number)
|
||||
(s/def ::height ::us/number)
|
||||
(s/def ::mtype ::us/string)
|
||||
(s/def ::uri ::us/string)
|
||||
;; (s/def ::thumb-uri ::us/string)
|
||||
|
||||
(s/def ::media-object
|
||||
(s/keys :req-un [::id
|
||||
::name
|
||||
::width
|
||||
::height
|
||||
::uri]))
|
||||
;; ::thumb-uri]))
|
||||
|
||||
(defn media-object-uploaded
|
||||
[item]
|
||||
(us/verify ::media-object item)
|
||||
(ptk/reify ::media-object-uploaded
|
||||
(defn upload-media-objects-result
|
||||
[file-id is-local media-object]
|
||||
(us/verify ::us/uuid file-id)
|
||||
(us/verify ::us/boolean is-local)
|
||||
(us/verify ::di/media-object media-object)
|
||||
(ptk/reify ::upload-media-objects-result
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
state)))
|
||||
;; (update state :workspace-media assoc (:id item) item))))
|
||||
(if is-local
|
||||
state
|
||||
(assoc-in state
|
||||
[:workspace-media-library (:id media-object)]
|
||||
media-object)))))
|
||||
|
||||
|
||||
;; --- Delete media object
|
||||
|
@ -477,7 +427,7 @@
|
|||
(ptk/reify ::delete-media-object
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :workspace-media dissoc id))
|
||||
(update state :workspace-media-library dissoc id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
|
|
|
@ -57,11 +57,11 @@
|
|||
(def workspace-project
|
||||
(l/derived :workspace-project st/state))
|
||||
|
||||
(def workspace-media
|
||||
(l/derived :workspace-media st/state))
|
||||
(def workspace-media-library
|
||||
(l/derived :workspace-media-library st/state))
|
||||
|
||||
(def workspace-colors
|
||||
(l/derived :workspace-colors st/state))
|
||||
(def workspace-colors-library
|
||||
(l/derived :workspace-colors-library st/state))
|
||||
|
||||
(def workspace-users
|
||||
(l/derived :workspace-users st/state))
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
(st/emit!
|
||||
(some-> target
|
||||
(dom/get-files)
|
||||
(array-seq)
|
||||
(opt-pick-one)
|
||||
(on-selected)))
|
||||
(dom/clean-value! target)))]
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.data.media :as di]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
|
@ -27,6 +28,7 @@
|
|||
selected-drawtool (mf/deref refs/selected-drawing-tool)
|
||||
select-drawtool #(st/emit! :interrupt
|
||||
(dw/select-for-drawing %))
|
||||
file (mf/deref refs/workspace-file)
|
||||
locale (i18n/use-locale)
|
||||
|
||||
on-image #(dom/click (mf/ref-val file-input))
|
||||
|
@ -41,8 +43,8 @@
|
|||
(st/emit! (dw/create-and-add-shape :image shape aspect-ratio))))
|
||||
|
||||
on-files-selected
|
||||
(fn [files]
|
||||
(run! #(st/emit! (dw/upload-media-object % on-uploaded)) files))]
|
||||
(fn [js-files]
|
||||
(st/emit! (dw/upload-media-objects (:id file) true js-files on-uploaded)))]
|
||||
|
||||
[:aside.left-toolbar
|
||||
[:div.left-toolbar-inside
|
||||
|
@ -72,7 +74,7 @@
|
|||
:on-click on-image}
|
||||
[:*
|
||||
i/image
|
||||
[:& file-uploader {:accept "image/jpeg,image/png,image/webp"
|
||||
[:& file-uploader {:accept di/str-media-types
|
||||
:multi true
|
||||
:input-ref file-input
|
||||
:on-selected on-files-selected}]]]
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
[uxbox.common.geom.shapes :as geom]
|
||||
[uxbox.common.geom.point :as gpt]
|
||||
[uxbox.main.ui.icons :as i]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.data.media :as di]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.data.colors :as dcol]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
|
@ -72,7 +72,7 @@
|
|||
[:a.close {:href "#" :on-click cancel} i/close]]])))
|
||||
|
||||
(mf/defc graphics-box
|
||||
[{:keys [library-id media-objects] :as props}]
|
||||
[{:keys [file-id media-objects] :as props}]
|
||||
(let [state (mf/use-state {:menu-open false
|
||||
:top nil
|
||||
:left nil
|
||||
|
@ -87,8 +87,8 @@
|
|||
#(st/emit! (dw/delete-media-object (:object-id @state)))
|
||||
|
||||
on-files-selected
|
||||
(fn [files]
|
||||
(st/emit! (di/create-media-objects library-id files)))
|
||||
(fn [js-files]
|
||||
(st/emit! (dw/upload-media-objects file-id false js-files)))
|
||||
|
||||
on-context-menu
|
||||
(fn [object-id]
|
||||
|
@ -114,7 +114,7 @@
|
|||
[:span (str "\u00A0(") (count media-objects) ")"] ;; Unicode 00A0 is non-breaking space
|
||||
[:div.group-button {:on-click add-graphic}
|
||||
i/plus
|
||||
[:& file-uploader {:accept "image/jpeg,image/png,image/webp,image/svg+xml"
|
||||
[:& file-uploader {:accept di/str-media-types
|
||||
:multi true
|
||||
:input-ref file-input
|
||||
:on-selected on-files-selected}]]]
|
||||
|
@ -137,7 +137,7 @@
|
|||
|
||||
|
||||
(mf/defc color-item
|
||||
[{:keys [color library-id] :as props}]
|
||||
[{:keys [color file-id] :as props}]
|
||||
(let [workspace-local @refs/workspace-local
|
||||
color-for-rename (:color-for-rename workspace-local)
|
||||
|
||||
|
@ -150,15 +150,15 @@
|
|||
|
||||
rename-color
|
||||
(fn [name]
|
||||
(st/emit! (dcol/rename-color library-id (:id color) name)))
|
||||
(st/emit! (dcol/rename-color file-id (:id color) name)))
|
||||
|
||||
edit-color
|
||||
(fn [value opacity]
|
||||
(st/emit! (dcol/update-color library-id (:id color) value)))
|
||||
(st/emit! (dcol/update-color file-id (:id color) value)))
|
||||
|
||||
delete-color
|
||||
(fn []
|
||||
(st/emit! (dcol/delete-color library-id (:id color))))
|
||||
(st/emit! (dcol/delete-color file-id (:id color))))
|
||||
|
||||
rename-color-clicked
|
||||
(fn [event]
|
||||
|
@ -231,10 +231,10 @@
|
|||
[(tr "workspace.assets.delete") delete-color]]}]]))
|
||||
|
||||
(mf/defc colors-box
|
||||
[{:keys [library-id colors] :as props}]
|
||||
[{:keys [file-id colors] :as props}]
|
||||
(let [add-color
|
||||
(fn [value opacity]
|
||||
(st/emit! (dcol/create-color library-id value)))
|
||||
(st/emit! (dcol/create-color file-id value)))
|
||||
|
||||
add-color-clicked
|
||||
(fn [event]
|
||||
|
@ -251,10 +251,10 @@
|
|||
(for [color (sort-by :name colors)]
|
||||
[:& color-item {:key (:id color)
|
||||
:color color
|
||||
:library-id library-id}])]]))
|
||||
:file-id file-id}])]]))
|
||||
|
||||
(mf/defc library-toolbox
|
||||
[{:keys [library-id
|
||||
(mf/defc file-library-toolbox
|
||||
[{:keys [file-id
|
||||
shared?
|
||||
media-objects
|
||||
colors
|
||||
|
@ -279,9 +279,9 @@
|
|||
(or (> (count colors) 0) (str/empty? search-term)))]
|
||||
[:div.tool-window-content
|
||||
(when show-graphics
|
||||
[:& graphics-box {:library-id library-id :media-objects media-objects}])
|
||||
[:& graphics-box {:file-id file-id :media-objects media-objects}])
|
||||
(when show-colors
|
||||
[:& colors-box {:library-id library-id :colors colors}])
|
||||
[:& colors-box {:file-id file-id :colors colors}])
|
||||
(when (and (not show-graphics) (not show-colors))
|
||||
[:div.asset-group
|
||||
[:div.group-title (tr "workspace.assets.not-found")]])]))]))
|
||||
|
@ -291,8 +291,8 @@
|
|||
(let [team-id (-> refs/workspace-project mf/deref :team-id)
|
||||
file (mf/deref refs/workspace-file)
|
||||
file-id (:id file)
|
||||
file-media (mf/deref refs/workspace-media)
|
||||
file-colors (mf/deref refs/workspace-colors)
|
||||
file-media (mf/deref refs/workspace-media-library)
|
||||
file-colors (mf/deref refs/workspace-colors-library)
|
||||
|
||||
state (mf/use-state {:search-term ""
|
||||
:box-filter :all})
|
||||
|
@ -321,8 +321,8 @@
|
|||
(mf/use-effect
|
||||
(mf/deps file-id)
|
||||
#(when file-id
|
||||
(st/emit! (dw/fetch-media-objects file-id))
|
||||
(st/emit! (dw/fetch-colors file-id))))
|
||||
(st/emit! (dw/fetch-media-library file-id))
|
||||
(st/emit! (dw/fetch-colors-library file-id))))
|
||||
|
||||
[:div.assets-bar
|
||||
|
||||
|
@ -350,11 +350,11 @@
|
|||
[:option {:value ":colors"} (tr "workspace.assets.box-filter-colors")]]
|
||||
]]
|
||||
|
||||
[:& library-toolbox {:library-id file-id
|
||||
:shared? (:is-shared file)
|
||||
:media-objects filtered-media-objects
|
||||
:colors filtered-colors
|
||||
:initial-open? true
|
||||
:search-term (:search-term @state)
|
||||
:box-filter (:box-filter @state)}]]))
|
||||
[:& file-library-toolbox {:file-id file-id
|
||||
:shared? (:is-shared file)
|
||||
:media-objects filtered-media-objects
|
||||
:colors filtered-colors
|
||||
:initial-open? true
|
||||
:search-term (:search-term @state)
|
||||
:box-filter (:box-filter @state)}]]))
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
selected
|
||||
panning]} local
|
||||
|
||||
file (mf/deref refs/workspace-file)
|
||||
viewport-ref (mf/use-ref nil)
|
||||
last-position (mf/use-var nil)
|
||||
|
||||
|
@ -354,9 +355,6 @@
|
|||
:metadata {:width (:width image)
|
||||
:height (:height image)
|
||||
:uri (:uri image)}}
|
||||
;; :thumb-width (:thumb-width image)
|
||||
;; :thumb-height (:thumb-height image)
|
||||
;; :thumb-uri (:thumb-uri image)}}
|
||||
aspect-ratio (/ (:width image) (:height image))]
|
||||
(st/emit! (dw/create-and-add-shape :image shape aspect-ratio))))
|
||||
|
||||
|
@ -381,11 +379,11 @@
|
|||
urls (filter #(and (not (str/blank? %))
|
||||
(not (str/starts-with? % "#")))
|
||||
lines)]
|
||||
(run! #(st/emit! (dw/add-media-object-from-url % on-uploaded)) urls))
|
||||
(run! #(st/emit! (dw/add-media-object-from-url (:id file) true % on-uploaded)) urls))
|
||||
|
||||
:else
|
||||
(let [files (dnd/get-files event)]
|
||||
(run! #(st/emit! (dw/upload-media-object % on-uploaded)) files))))
|
||||
(let [js-files (dnd/get-files event)]
|
||||
(st/emit! (dw/upload-media-objects (:id file) true js-files on-uploaded)))))
|
||||
|
||||
on-resize
|
||||
(fn [event]
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
(defn get-files
|
||||
"Extract the files from dom node."
|
||||
[node]
|
||||
(.-files node))
|
||||
(array-seq (.-files node)))
|
||||
|
||||
(defn checked?
|
||||
"Check if the node that represents a radio
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
(defn get-files
|
||||
[e]
|
||||
(let [dt (.-dataTransfer e)]
|
||||
(.-files dt)))
|
||||
(array-seq (.-files dt))))
|
||||
|
||||
(defn drop-side
|
||||
[e detect-center?]
|
||||
|
|
Loading…
Add table
Reference in a new issue