diff --git a/frontend/src/app/main/data/media.cljs b/frontend/src/app/main/data/media.cljs index e7f9cd3c3..b18eb9185 100644 --- a/frontend/src/app/main/data/media.cljs +++ b/frontend/src/app/main/data/media.cljs @@ -13,6 +13,7 @@ [app.common.media :as cm] [app.common.spec :as us] [app.common.uuid :as uuid] + [app.common.exceptions :as ex] [app.main.data.messages :as dm] [app.main.repo :as rp] [app.main.store :as st] @@ -50,9 +51,13 @@ ;; Check that a file obtained with the file javascript API is valid. [file] (when (> (.-size file) cm/max-file-size) - (throw (ex-info (tr "errors.media-too-large") {}))) + (ex/raise :type :validation + :code :media-too-large + :hint (str/fmt "media size is large than 5mb (size: %s)" (.-size file)))) (when-not (contains? cm/valid-media-types (.-type file)) - (throw (ex-info (tr "errors.media-format-unsupported") {}))) + (ex/raise :type :validation + :code :media-type-not-allowed + :hint (str/fmt "media type %s is not supported" (.-type file)))) file) (defn notify-start-loading diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 295cdc50a..8ab42f532 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1289,7 +1289,6 @@ ;; Clipboard ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (defn copy-selected [] (letfn [;; Retrieve all ids of selected shapes with corresponding @@ -1408,12 +1407,22 @@ (let [paste-data (wapi/read-from-paste-event event) image-data (wapi/extract-images paste-data) text-data (wapi/extract-text paste-data) - decoded-data (and (t/transit? text-data) (t/decode text-data))] + decoded-data (and (t/transit? text-data) + (t/decode text-data))] (cond - (seq image-data) (rx/from (map paste-image image-data)) - decoded-data (rx/of (paste-shape decoded-data in-viewport?)) - (string? text-data) (rx/of (paste-text text-data)) - :else (rx/empty))) + (seq image-data) + (rx/from (map paste-image image-data)) + + (coll? decoded-data) + (->> (rx/of decoded-data) + (rx/filter #(= :copied-shapes (:type %))) + (rx/map #(paste-shape % in-viewport?))) + + (string? text-data) + (rx/of (paste-text text-data)) + + :else + (rx/empty))) (catch :default err (js/console.error "Clipboard error:" err)))))) diff --git a/frontend/src/app/main/data/workspace/persistence.cljs b/frontend/src/app/main/data/workspace/persistence.cljs index 88a02b159..e2909022e 100644 --- a/frontend/src/app/main/data/workspace/persistence.cljs +++ b/frontend/src/app/main/data/workspace/persistence.cljs @@ -9,9 +9,8 @@ (ns app.main.data.workspace.persistence (:require - [cuerdas.core :as str] - [app.util.http :as http] [app.common.data :as d] + [app.common.exceptions :as ex] [app.common.geom.point :as gpt] [app.common.media :as cm] [app.common.pages :as cp] @@ -21,21 +20,22 @@ [app.main.data.media :as di] [app.main.data.messages :as dm] [app.main.data.workspace.common :as dwc] - [app.main.data.workspace.svg-upload :as svg] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.selection :as dws] + [app.main.data.workspace.svg-upload :as svg] [app.main.repo :as rp] [app.main.store :as st] + [app.util.avatars :as avatars] + [app.util.http :as http] [app.util.i18n :as i18n :refer [tr]] [app.util.object :as obj] [app.util.router :as rt] [app.util.time :as dt] [app.util.transit :as t] - [app.util.avatars :as avatars] [beicon.core :as rx] [cljs.spec.alpha :as s] - [potok.core :as ptk] - [app.main.store :as st])) + [cuerdas.core :as str] + [potok.core :as ptk])) (declare persist-changes) (declare persist-sychronous-changes) @@ -417,24 +417,27 @@ (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"))) + (fn on-error [error] + (if (ex/ex-info? error) + (on-error (ex-data 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) :media-too-large) + (rx/of (dm/error (tr "errors.media-too-large"))) - (= (:code error) :unable-to-optimize) - (rx/of (dm/error (:hint error))) + (= (:code error) :media-type-mismatch) + (rx/of (dm/error (tr "errors.media-type-mismatch"))) - (fn? on-error) - (do + (= (:code error) :unable-to-optimize) + (rx/of (dm/error (:hint error))) + + (fn? on-error) (on-error error) - (rx/empty)) - :else - (rx/throw error)))))) + :else + (rx/throw error))))))) (defn- upload-uris [file-id local? name uris mtype on-image on-svg] (letfn [(svg-url? [url] @@ -499,7 +502,6 @@ (let [{:keys [on-image on-svg on-error] :or {on-image identity on-svg identity}} (meta params)] - (rx/concat (rx/of (dm/show {:content (tr "media.loading") :type :info @@ -515,7 +517,8 @@ (handle-upload-error on-error) (rx/finalize (st/emitf (dm/hide-tag :media-loading))))))))) -(defn upload-media-asset [params] +(defn upload-media-asset + [params] (let [params (-> params (assoc :svg-as-images true) (assoc :local? false) @@ -525,13 +528,12 @@ (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! (svg/svg-uploaded % x y))}))] + mdata {:on-image #(st/emit! (dwc/image-uploaded % x y)) + :on-svg #(st/emit! (svg/svg-uploaded % x y))} + + params (-> (assoc params :local? true) + (with-meta mdata))] + (upload-media-objects params))) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 2d1000323..d5c02a297 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -229,13 +229,14 @@ :timeout 3000}))) ;; Print to the console some debug info. - (js/console.group "Server Error") - (js/console.info - (with-out-str - (pprint (dissoc error :explain)))) - (when-let [explain (:explain error)] - (js/console.error explain)) - (js/console.endGroup "Server Error")) + (js/console.group "Validation Error") + (ex/ignoring + (js/console.info + (with-out-str + (pprint (dissoc error :explain)))) + (when-let [explain (:explain error)] + (js/console.error explain))) + (js/console.groupEnd "Validation Error")) ;; This is a pure frontend error that can be caused by an active ;; assertion (assertion that is preserved on production builds). From