♻️ Remove duplicated code

This commit is contained in:
Andrés Moya 2020-08-10 10:01:51 +02:00 committed by Andrey Antukh
parent d349e46cd8
commit 93bde62581
16 changed files with 188 additions and 306 deletions

View file

@ -57,6 +57,9 @@
;; Related info on how thumbnails generation ;; Related info on how thumbnails generation
;; http://www.imagemagick.org/Usage/thumbnails/ ;; http://www.imagemagick.org/Usage/thumbnails/
(def valid-media-types
#{"image/jpeg", "image/png", "image/webp", "image/svg+xml"})
(defn format->extension (defn format->extension
[format] [format]
(case format (case format
@ -196,6 +199,13 @@
(us/assert (s/coll-of vector?) pairs) (us/assert (s/coll-of vector?) pairs)
(reduce #(resolve-uri mst/media-storage %1 (nth %2 0) (nth %2 1)) row 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 (defn download-media-object
[url] [url]
(let [result (http/get! url {:as :byte-array}) (let [result (http/get! url {:as :byte-array})

View file

@ -45,12 +45,9 @@
(declare persist-media-object-on-fs) (declare persist-media-object-on-fs)
(declare persist-media-thumbnail-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/filename ::us/string)
(s/def :uxbox$upload/size ::us/integer) (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 :uxbox$upload/tempfile any?)
(s/def ::upload (s/def ::upload
@ -64,11 +61,11 @@
(s/def ::is-local ::us/boolean) (s/def ::is-local ::us/boolean)
(s/def ::add-media-object-from-url (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])) :opt-un [::id]))
(s/def ::upload-media-object (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])) :opt-un [::id]))
(sm/defmutation ::add-media-object-from-url (sm/defmutation ::add-media-object-from-url
@ -89,12 +86,8 @@
(create-media-object conn params)))) (create-media-object conn params))))
(defn create-media-object (defn create-media-object
[conn {:keys [id content file-id name is-local]}] [conn {:keys [id file-id is-local name content]}]
(when-not (valid-media-object-types? (:content-type content)) (media/validate-media-type (:content-type content))
(ex/raise :type :validation
:code :media-type-not-allowed
:hint "Seems like you are uploading an invalid media object."))
(let [info (media/run {:cmd :info :input {:path (:tempfile content) (let [info (media/run {:cmd :info :input {:path (:tempfile content)
:mtype (:content-type content)}}) :mtype (:content-type content)}})
path (persist-media-object-on-fs content) path (persist-media-object-on-fs content)

View file

@ -272,15 +272,11 @@
(sm/defmutation ::update-profile-photo (sm/defmutation ::update-profile-photo
[{:keys [profile-id file] :as params}] [{:keys [profile-id file] :as params}]
(when-not (media-mutations/valid-media-object-types? (:content-type file)) (media/validate-media-type (:content-type file))
(ex/raise :type :validation
:code :media-type-not-allowed
:hint "Seems like you are uploading an invalid media object"))
(db/with-atomic [conn db/pool] (db/with-atomic [conn db/pool]
(let [profile (profile/retrieve-profile conn profile-id) (let [profile (profile/retrieve-profile conn profile-id)
_ (media/run {:cmd :info :input {:path (:tempfile file) _ (media/run {:cmd :info :input {:path (:tempfile file)
:mtype (:content-type file)}}) :mtype (:content-type file)}})
photo (upload-photo conn params)] photo (upload-photo conn params)]
;; Schedule deletion of old photo ;; Schedule deletion of old photo

View file

@ -35,8 +35,8 @@
:id object-id-1 :id object-id-1
:profile-id (:id prof) :profile-id (:id prof)
:file-id (:id file) :file-id (:id file)
:url url :is-local true
:is-local true} :url url}
out (th/try-on! (sm/handle data))] out (th/try-on! (sm/handle data))]
;; (th/print-result! out) ;; (th/print-result! out)
@ -61,9 +61,9 @@
:id object-id-2 :id object-id-2
:profile-id (:id prof) :profile-id (:id prof)
:file-id (:id file) :file-id (:id file)
:is-local true
:name "testfile" :name "testfile"
:content content :content content}
:is-local true}
out (th/try-on! (sm/handle data))] out (th/try-on! (sm/handle data))]
;; (th/print-result! out) ;; (th/print-result! out)

View file

@ -41,7 +41,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> 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)))))) (assoc-in [:workspace-local :color-for-rename] (:id color))))))
(def clear-color-for-rename (def clear-color-for-rename
@ -67,7 +67,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (-> state
(assoc-in [:workspace-colors (:id color)] color))))) (assoc-in [:workspace-colors-library (:id color)] color)))))
(declare update-color-result) (declare update-color-result)
@ -86,7 +86,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (-> state
(assoc-in [:workspace-colors (:id color)] color))))) (assoc-in [:workspace-colors-library (:id color)] color)))))
(declare delete-color-result) (declare delete-color-result)
@ -104,5 +104,5 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(-> state (-> state
(d/dissoc-in [:workspace-colors color-id]))))) (d/dissoc-in [:workspace-colors-library color-id])))))

View file

@ -24,16 +24,14 @@
;; --- Specs ;; --- Specs
(s/def ::id uuid?)
(s/def ::name string?) (s/def ::name string?)
(s/def ::width number?) (s/def ::width number?)
(s/def ::height number?) (s/def ::height number?)
(s/def ::modified-at inst?)
(s/def ::created-at inst?) (s/def ::created-at inst?)
(s/def ::modified-at inst?)
(s/def ::mtype string?) (s/def ::mtype string?)
;; (s/def ::thumbnail string?)
(s/def ::id uuid?)
(s/def ::uri string?) (s/def ::uri string?)
(s/def ::user-id uuid?)
(s/def ::media-object (s/def ::media-object
(s/keys :req-un [::id (s/keys :req-un [::id
@ -43,83 +41,49 @@
::mtype ::mtype
::created-at ::created-at
::modified-at ::modified-at
::uri ::uri]))
;; ::thumb-uri
::user-id]))
;; --- 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-media-types #{"image/jpeg" "image/png" "image/webp" "image/svg+xml"})
(def allowed-file-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)) (def max-file-size (* 5 1024 1024))
;; TODO: unify with upload-media-object at main/data/workspace/persistence.cljs ;; --- Utility functions
;; and update-photo at main/data/users.cljs
;; https://tree.taiga.io/project/uxboxproject/us/440
(defn create-media-objects (defn validate-file
([file-id files] (create-media-objects file-id files identity)) ;; Check that a file obtained with the file javascript API is valid.
([file-id files on-uploaded] [file]
(us/verify (s/nilable ::us/uuid) file-id) (when (> (.-size file) max-file-size)
(us/verify fn? on-uploaded) (throw (ex-info (tr "errors.media-too-large") {})))
(ptk/reify ::create-media-objects (when-not (contains? allowed-media-types (.-type file))
ptk/WatchEvent (throw (ex-info (tr "errors.media-format-unsupported") {})))
(watch [_ state stream] file)
(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)
on-success #(do (st/emit! dm/hide) (defn notify-start-loading
(on-uploaded %)) []
(st/emit! (dm/show {:content (tr "media.loading")
:type :info
:timeout nil})))
on-error #(do (st/emit! dm/hide) (defn notify-finished-loading
(let [msg (cond []
(.-message %) (st/emit! dm/hide))
(.-message %)
(= (:code %) :media-type-not-allowed) (defn process-error
(tr "errors.media-type-not-allowed") [error]
(let [msg (cond
(.-message error)
(.-message error)
(= (:code %) :media-type-mismatch) (= (:code error) :media-type-not-allowed)
(tr "errors.media-type-mismatch") (tr "errors.media-type-not-allowed")
:else (= (:code error) :media-type-mismatch)
(tr "errors.unexpected-error"))] (tr "errors.media-type-mismatch")
(rx/of (dm/error msg))))
prepare :else
(fn [file] (tr "errors.unexpected-error"))]
{:name (.-name file) (rx/of (dm/error msg))))
: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)))))

View file

@ -15,6 +15,7 @@
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.repo :as rp] [uxbox.main.repo :as rp]
[uxbox.main.data.messages :as dm] [uxbox.main.data.messages :as dm]
[uxbox.main.data.media :as di]
[uxbox.util.router :as rt] [uxbox.util.router :as rt]
[uxbox.util.i18n :as i18n :refer [tr]] [uxbox.util.i18n :as i18n :refer [tr]]
[uxbox.util.storage :refer [storage]] [uxbox.util.storage :refer [storage]]
@ -155,58 +156,28 @@
;; --- Update Photo ;; --- 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 (defn update-photo
[file] [file]
(us/verify ::file file) (us/verify ::di/js-file file)
(ptk/reify ::update-photo (ptk/reify ::update-photo
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (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] (fn [file]
(when (> (.-size file) max-file-size) {:file file})]
(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)) (di/notify-start-loading)
on-error #(do (st/emit! dm/hide) (->> (rx/of file)
(let [msg (cond (rx/map di/validate-file)
(.-message %) (rx/map prepare)
(.-message %) (rx/mapcat #(rp/mutation :update-profile-photo %))
(rx/do on-success)
(= (:code %) :media-type-not-allowed) (rx/map (constantly fetch-profile))
(tr "errors.media-type-not-allowed") (rx/catch on-error))))))
(= (: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))))))

View file

@ -1169,9 +1169,6 @@
:metadata {:width (:width image) :metadata {:width (:width image)
:height (:height image) :height (:height image)
:uri (:uri 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))] aspect-ratio (/ (:width image) (:height image))]
(st/emit! (create-and-add-shape :image shape aspect-ratio)))) (st/emit! (create-and-add-shape :image shape aspect-ratio))))
@ -1180,7 +1177,8 @@
(ptk/reify ::paste-bin-impl (ptk/reify ::paste-bin-impl
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (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 (def paste
(ptk/reify ::paste (ptk/reify ::paste
@ -1435,16 +1433,17 @@
;; Persistence ;; Persistence
(def set-file-shared dwp/set-file-shared) (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 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 delete-media-object dwp/delete-media-object)
(def fetch-colors dwp/fetch-colors)
(def rename-page dwp/rename-page) (def rename-page dwp/rename-page)
(def delete-page dwp/delete-page) (def delete-page dwp/delete-page)
(def create-empty-page dwp/create-empty-page) (def create-empty-page dwp/create-empty-page)
;; Selection ;; Selection
(def select-shape dws/select-shape) (def select-shape dws/select-shape)
(def deselect-all dws/deselect-all) (def deselect-all dws/deselect-all)
(def select-shapes dws/select-shapes) (def select-shapes dws/select-shapes)

View file

@ -18,6 +18,7 @@
[uxbox.common.spec :as us] [uxbox.common.spec :as us]
[uxbox.main.data.dashboard :as dd] [uxbox.main.data.dashboard :as dd]
[uxbox.main.data.messages :as dm] [uxbox.main.data.messages :as dm]
[uxbox.main.data.media :as di]
[uxbox.main.data.workspace.common :as dwc] [uxbox.main.data.workspace.common :as dwc]
[uxbox.main.repo :as rp] [uxbox.main.repo :as rp]
[uxbox.main.store :as st] [uxbox.main.store :as st]
@ -296,178 +297,127 @@
(rx/of go-to-file) (rx/of go-to-file)
(rx/empty)))))))))) (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] [file-id]
(ptk/reify ::fetch-media-objects (ptk/reify ::fetch-media-library
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(->> (rp/query :media-objects {:file-id file-id :is-local false}) (->> (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] [media-objects]
(ptk/reify ::media-objects-fetched (ptk/reify ::media-library-fetched
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [media-objects (d/index-by :id media-objects)] (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] [file-id]
(ptk/reify ::fetch-colors (ptk/reify ::fetch-colors-library
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(->> (rp/query :colors {:file-id file-id}) (->> (rp/query :colors {:file-id file-id})
(rx/map colors-fetched))))) (rx/map colors-library-fetched)))))
(defn colors-fetched (defn colors-library-fetched
[colors] [colors]
(ptk/reify ::colors-fetched (ptk/reify ::colors-library-fetched
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [colors (d/index-by :id colors)] (let [colors (d/index-by :id colors)]
(assoc state :workspace-colors colors))))) (assoc state :workspace-colors-library colors)))))
;; --- Upload local media objects ;; --- Upload local media objects
(declare media-object-uploaded) (declare upload-media-objects-result)
(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
(defn add-media-object-from-url (defn add-media-object-from-url
([url] (add-media-object-from-url url identity)) ([file-id is-local url] (add-media-object-from-url file-id is-local url identity))
([url on-added] ([file-id is-local url on-added]
(us/verify ::us/url url)
(us/verify fn? on-added) (us/verify fn? on-added)
(us/verify ::us/boolean is-local)
(ptk/reify ::add-media-object-from-url (ptk/reify ::add-media-object-from-url
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [file-id (get-in state [:workspace-page :file-id]) (let [on-success #(do (di/notify-finished-loading)
on-success #(do (st/emit! dm/hide)
(on-added %)) (on-added %))
on-error #(do (st/emit! dm/hide) on-error #(do (di/notify-finished-loading)
(let [msg (cond (di/process-error %))
(.-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 prepare
(fn [url] (fn [url]
{:file-id file-id {:file-id file-id
:url url :is-local is-local
:is-local true})] :url url})]
(di/notify-start-loading)
(st/emit! (dm/show {:content (tr "media.loading")
:type :info
:timeout nil}))
(->> (rx/of url) (->> (rx/of url)
(rx/map prepare) (rx/map prepare)
(rx/mapcat #(rp/mutation! :add-media-object-from-url %)) (rx/mapcat #(rp/mutation! :add-media-object-from-url %))
(rx/do on-success) (rx/do on-success)
(rx/map media-object-uploaded) (rx/map (partial upload-media-objects-result file-id is-local))
(rx/catch on-error))))))) (rx/catch on-error)))))))
(defn upload-media-object (defn upload-media-objects
([file] (upload-media-object file identity)) ([file-id is-local js-files] (upload-media-objects file-id is-local js-files identity))
([file on-uploaded] ([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) (us/verify fn? on-uploaded)
(ptk/reify ::upload-media-object (ptk/reify ::upload-media-objects
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [file-id (get-in state [:workspace-page :file-id]) (let [on-success #(do (di/notify-finished-loading)
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)
(on-uploaded %)) (on-uploaded %))
on-error #(do (st/emit! dm/hide) on-error #(do (di/notify-finished-loading)
(let [msg (cond (di/process-error %))
(.-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 prepare
(fn [file] (fn [js-file]
{:name (.-name file) {:name (.-name js-file)
:file-id file-id :file-id file-id
:content file :content js-file
:is-local true})] :is-local is-local})]
(st/emit! (dm/show {:content (tr "media.loading") (di/notify-start-loading)
:type :info
:timeout nil})) (->> (rx/from js-files)
(->> (rx/of file) (rx/map di/validate-file)
(rx/map check-file)
(rx/map prepare) (rx/map prepare)
(rx/mapcat #(rp/mutation! :upload-media-object %)) (rx/mapcat #(rp/mutation! :upload-media-object %))
(rx/do on-success) (rx/do on-success)
(rx/map media-object-uploaded) (rx/map (partial upload-media-objects-result file-id is-local))
(rx/catch on-error))))))) (rx/catch on-error)))))))
(defn upload-media-objects-result
(s/def ::id ::us/uuid) [file-id is-local media-object]
(s/def ::name ::us/string) (us/verify ::us/uuid file-id)
(s/def ::width ::us/number) (us/verify ::us/boolean is-local)
(s/def ::height ::us/number) (us/verify ::di/media-object media-object)
(s/def ::mtype ::us/string) (ptk/reify ::upload-media-objects-result
(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
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
state))) (if is-local
;; (update state :workspace-media assoc (:id item) item)))) state
(assoc-in state
[:workspace-media-library (:id media-object)]
media-object)))))
;; --- Delete media object ;; --- Delete media object
@ -477,7 +427,7 @@
(ptk/reify ::delete-media-object (ptk/reify ::delete-media-object
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(update state :workspace-media dissoc id)) (update state :workspace-media-library dissoc id))
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]

View file

@ -57,11 +57,11 @@
(def workspace-project (def workspace-project
(l/derived :workspace-project st/state)) (l/derived :workspace-project st/state))
(def workspace-media (def workspace-media-library
(l/derived :workspace-media st/state)) (l/derived :workspace-media-library st/state))
(def workspace-colors (def workspace-colors-library
(l/derived :workspace-colors st/state)) (l/derived :workspace-colors-library st/state))
(def workspace-users (def workspace-users
(l/derived :workspace-users st/state)) (l/derived :workspace-users st/state))

View file

@ -23,7 +23,6 @@
(st/emit! (st/emit!
(some-> target (some-> target
(dom/get-files) (dom/get-files)
(array-seq)
(opt-pick-one) (opt-pick-one)
(on-selected))) (on-selected)))
(dom/clean-value! target)))] (dom/clean-value! target)))]

View file

@ -12,6 +12,7 @@
(:require (:require
[rumext.alpha :as mf] [rumext.alpha :as mf]
[uxbox.main.refs :as refs] [uxbox.main.refs :as refs]
[uxbox.main.data.media :as di]
[uxbox.main.data.workspace :as dw] [uxbox.main.data.workspace :as dw]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.ui.components.file-uploader :refer [file-uploader]] [uxbox.main.ui.components.file-uploader :refer [file-uploader]]
@ -27,6 +28,7 @@
selected-drawtool (mf/deref refs/selected-drawing-tool) selected-drawtool (mf/deref refs/selected-drawing-tool)
select-drawtool #(st/emit! :interrupt select-drawtool #(st/emit! :interrupt
(dw/select-for-drawing %)) (dw/select-for-drawing %))
file (mf/deref refs/workspace-file)
locale (i18n/use-locale) locale (i18n/use-locale)
on-image #(dom/click (mf/ref-val file-input)) on-image #(dom/click (mf/ref-val file-input))
@ -41,8 +43,8 @@
(st/emit! (dw/create-and-add-shape :image shape aspect-ratio)))) (st/emit! (dw/create-and-add-shape :image shape aspect-ratio))))
on-files-selected on-files-selected
(fn [files] (fn [js-files]
(run! #(st/emit! (dw/upload-media-object % on-uploaded)) files))] (st/emit! (dw/upload-media-objects (:id file) true js-files on-uploaded)))]
[:aside.left-toolbar [:aside.left-toolbar
[:div.left-toolbar-inside [:div.left-toolbar-inside
@ -72,7 +74,7 @@
:on-click on-image} :on-click on-image}
[:* [:*
i/image i/image
[:& file-uploader {:accept "image/jpeg,image/png,image/webp" [:& file-uploader {:accept di/str-media-types
:multi true :multi true
:input-ref file-input :input-ref file-input
:on-selected on-files-selected}]]] :on-selected on-files-selected}]]]

View file

@ -17,8 +17,8 @@
[uxbox.common.geom.shapes :as geom] [uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.point :as gpt] [uxbox.common.geom.point :as gpt]
[uxbox.main.ui.icons :as i] [uxbox.main.ui.icons :as i]
[uxbox.main.data.workspace :as dw]
[uxbox.main.data.media :as di] [uxbox.main.data.media :as di]
[uxbox.main.data.workspace :as dw]
[uxbox.main.data.colors :as dcol] [uxbox.main.data.colors :as dcol]
[uxbox.main.refs :as refs] [uxbox.main.refs :as refs]
[uxbox.main.store :as st] [uxbox.main.store :as st]
@ -72,7 +72,7 @@
[:a.close {:href "#" :on-click cancel} i/close]]]))) [:a.close {:href "#" :on-click cancel} i/close]]])))
(mf/defc graphics-box (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 (let [state (mf/use-state {:menu-open false
:top nil :top nil
:left nil :left nil
@ -87,8 +87,8 @@
#(st/emit! (dw/delete-media-object (:object-id @state))) #(st/emit! (dw/delete-media-object (:object-id @state)))
on-files-selected on-files-selected
(fn [files] (fn [js-files]
(st/emit! (di/create-media-objects library-id files))) (st/emit! (dw/upload-media-objects file-id false js-files)))
on-context-menu on-context-menu
(fn [object-id] (fn [object-id]
@ -114,7 +114,7 @@
[:span (str "\u00A0(") (count media-objects) ")"] ;; Unicode 00A0 is non-breaking space [:span (str "\u00A0(") (count media-objects) ")"] ;; Unicode 00A0 is non-breaking space
[:div.group-button {:on-click add-graphic} [:div.group-button {:on-click add-graphic}
i/plus i/plus
[:& file-uploader {:accept "image/jpeg,image/png,image/webp,image/svg+xml" [:& file-uploader {:accept di/str-media-types
:multi true :multi true
:input-ref file-input :input-ref file-input
:on-selected on-files-selected}]]] :on-selected on-files-selected}]]]
@ -137,7 +137,7 @@
(mf/defc color-item (mf/defc color-item
[{:keys [color library-id] :as props}] [{:keys [color file-id] :as props}]
(let [workspace-local @refs/workspace-local (let [workspace-local @refs/workspace-local
color-for-rename (:color-for-rename workspace-local) color-for-rename (:color-for-rename workspace-local)
@ -150,15 +150,15 @@
rename-color rename-color
(fn [name] (fn [name]
(st/emit! (dcol/rename-color library-id (:id color) name))) (st/emit! (dcol/rename-color file-id (:id color) name)))
edit-color edit-color
(fn [value opacity] (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 delete-color
(fn [] (fn []
(st/emit! (dcol/delete-color library-id (:id color)))) (st/emit! (dcol/delete-color file-id (:id color))))
rename-color-clicked rename-color-clicked
(fn [event] (fn [event]
@ -231,10 +231,10 @@
[(tr "workspace.assets.delete") delete-color]]}]])) [(tr "workspace.assets.delete") delete-color]]}]]))
(mf/defc colors-box (mf/defc colors-box
[{:keys [library-id colors] :as props}] [{:keys [file-id colors] :as props}]
(let [add-color (let [add-color
(fn [value opacity] (fn [value opacity]
(st/emit! (dcol/create-color library-id value))) (st/emit! (dcol/create-color file-id value)))
add-color-clicked add-color-clicked
(fn [event] (fn [event]
@ -251,10 +251,10 @@
(for [color (sort-by :name colors)] (for [color (sort-by :name colors)]
[:& color-item {:key (:id color) [:& color-item {:key (:id color)
:color color :color color
:library-id library-id}])]])) :file-id file-id}])]]))
(mf/defc library-toolbox (mf/defc file-library-toolbox
[{:keys [library-id [{:keys [file-id
shared? shared?
media-objects media-objects
colors colors
@ -279,9 +279,9 @@
(or (> (count colors) 0) (str/empty? search-term)))] (or (> (count colors) 0) (str/empty? search-term)))]
[:div.tool-window-content [:div.tool-window-content
(when show-graphics (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 (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)) (when (and (not show-graphics) (not show-colors))
[:div.asset-group [:div.asset-group
[:div.group-title (tr "workspace.assets.not-found")]])]))])) [:div.group-title (tr "workspace.assets.not-found")]])]))]))
@ -291,8 +291,8 @@
(let [team-id (-> refs/workspace-project mf/deref :team-id) (let [team-id (-> refs/workspace-project mf/deref :team-id)
file (mf/deref refs/workspace-file) file (mf/deref refs/workspace-file)
file-id (:id file) file-id (:id file)
file-media (mf/deref refs/workspace-media) file-media (mf/deref refs/workspace-media-library)
file-colors (mf/deref refs/workspace-colors) file-colors (mf/deref refs/workspace-colors-library)
state (mf/use-state {:search-term "" state (mf/use-state {:search-term ""
:box-filter :all}) :box-filter :all})
@ -321,8 +321,8 @@
(mf/use-effect (mf/use-effect
(mf/deps file-id) (mf/deps file-id)
#(when file-id #(when file-id
(st/emit! (dw/fetch-media-objects file-id)) (st/emit! (dw/fetch-media-library file-id))
(st/emit! (dw/fetch-colors file-id)))) (st/emit! (dw/fetch-colors-library file-id))))
[:div.assets-bar [:div.assets-bar
@ -350,11 +350,11 @@
[:option {:value ":colors"} (tr "workspace.assets.box-filter-colors")]] [:option {:value ":colors"} (tr "workspace.assets.box-filter-colors")]]
]] ]]
[:& library-toolbox {:library-id file-id [:& file-library-toolbox {:file-id file-id
:shared? (:is-shared file) :shared? (:is-shared file)
:media-objects filtered-media-objects :media-objects filtered-media-objects
:colors filtered-colors :colors filtered-colors
:initial-open? true :initial-open? true
:search-term (:search-term @state) :search-term (:search-term @state)
:box-filter (:box-filter @state)}]])) :box-filter (:box-filter @state)}]]))

View file

@ -169,6 +169,7 @@
selected selected
panning]} local panning]} local
file (mf/deref refs/workspace-file)
viewport-ref (mf/use-ref nil) viewport-ref (mf/use-ref nil)
last-position (mf/use-var nil) last-position (mf/use-var nil)
@ -354,9 +355,6 @@
:metadata {:width (:width image) :metadata {:width (:width image)
:height (:height image) :height (:height image)
:uri (:uri 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))] aspect-ratio (/ (:width image) (:height image))]
(st/emit! (dw/create-and-add-shape :image shape aspect-ratio)))) (st/emit! (dw/create-and-add-shape :image shape aspect-ratio))))
@ -381,11 +379,11 @@
urls (filter #(and (not (str/blank? %)) urls (filter #(and (not (str/blank? %))
(not (str/starts-with? % "#"))) (not (str/starts-with? % "#")))
lines)] 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 :else
(let [files (dnd/get-files event)] (let [js-files (dnd/get-files event)]
(run! #(st/emit! (dw/upload-media-object % on-uploaded)) files)))) (st/emit! (dw/upload-media-objects (:id file) true js-files on-uploaded)))))
on-resize on-resize
(fn [event] (fn [event]

View file

@ -85,7 +85,7 @@
(defn get-files (defn get-files
"Extract the files from dom node." "Extract the files from dom node."
[node] [node]
(.-files node)) (array-seq (.-files node)))
(defn checked? (defn checked?
"Check if the node that represents a radio "Check if the node that represents a radio

View file

@ -111,7 +111,7 @@
(defn get-files (defn get-files
[e] [e]
(let [dt (.-dataTransfer e)] (let [dt (.-dataTransfer e)]
(.-files dt))) (array-seq (.-files dt))))
(defn drop-side (defn drop-side
[e detect-center?] [e detect-center?]