0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-21 06:02:32 -05:00

Fix linter issues on frontend (part 6).

This commit is contained in:
Andrey Antukh 2021-06-18 10:23:03 +02:00 committed by Andrés Moya
parent 0f3e4c289c
commit e796c3dfba
55 changed files with 629 additions and 771 deletions

View file

@ -7,14 +7,17 @@
:hooks
{:analyze-call {app.common.data/export hooks.export/export
potok.core/reify hooks.export/potok-reify}}
potok.core/reify hooks.export/potok-reify
cljs.core/specify! hooks.export/clojure-specify}}
:output
{:exclude-files
["data_readers.clj"
"app/util/perf.cljs"
"app/common/exceptions.cljc"
"app/util/import/.*"
"app/worker/.*"
"app/worker/export.cljs"
"app/worker/import.cljs"
"app/libs/.*"
"app/main/data/workspace/path/selection.cljs"
"app/main/data/workspace/transforms.cljs"
@ -31,6 +34,9 @@
:single-key-in
{:level :warning}
:redundant-do
{:level :off}
:unused-binding
{:exclude-destructured-as true
:exclude-destructured-keys-in-fn-args false

View file

@ -19,3 +19,12 @@
(api/vector-node [])]
other))]
{:node result}))
(defn clojure-specify
[{:keys [:node]}]
(let [[rnode rtype & other] (:children node)
result (api/list-node
(into [(api/token-node (symbol "extend-type"))
(api/token-node (gensym (:string-value rtype)))]
other))]
{:node result}))

View file

@ -11,8 +11,8 @@
(:require-macros [app.common.data]))
(:require
[app.common.math :as mth]
[cljs.analyzer.api :as aapi]
[clojure.set :as set]
#?(:clj [cljs.analyzer.api :as aapi])
#?(:cljs [cljs.reader :as r]
:clj [clojure.edn :as r])
#?(:cljs [cljs.core :as core]
@ -275,7 +275,7 @@
;; Data Parsing / Conversion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- nan?
(defn nan?
[v]
(not= v v))
@ -506,7 +506,7 @@
(defn- extract-numeric-suffix
[basename]
(if-let [[match p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
(if-let [[_ p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
[p1 (+ 1 (parse-integer p2))]
[basename 1]))

View file

@ -31,7 +31,7 @@
(defn str->matrix
[matrix-str]
(let [params (->> (re-seq number-regex matrix-str)
(filter #(-> % first empty? not))
(filter #(-> % first seq))
(map (comp d/parse-double first)))]
(apply matrix params)))
@ -52,12 +52,11 @@
"Given two TRANSLATE matrixes (only e and f have significative
values), combine them. Quicker than multiplying them, for this
precise case."
([{m1a :a m1b :b m1c :c m1d :d m1e :e m1f :f}
{m2a :a m2b :b m2c :c m2d :d m2e :e m2f :f}]
([{m1e :e m1f :f} {m2e :e m2f :f}]
(Matrix.
1
0
0
1
0
0
1
(+ m1e m2e)
(+ m1f m2f)))

View file

@ -32,13 +32,10 @@
(when verify?
(us/assert ::spec/changes items))
(let [pages (into #{} (map :page-id) items)
result (->> items
(reduce #(or (process-change %1 %2) %1) data))]
(let [result (reduce #(or (process-change %1 %2) %1) data items)]
;; Validate result shapes (only on the backend)
#?(:clj
(doseq [page-id pages]
(doseq [page-id (into #{} (map :page-id) items)]
(let [page (get-in result [:pages-index page-id])]
(doseq [[id shape] (:objects page)]
(when-not (= shape (get-in data [:pages-index page-id :objects id]))

View file

@ -395,11 +395,11 @@
:internal.media-object/mtype]))
(s/def ::media-object-update
(s/keys :req-un [::id]
:req-opt [::name
:internal.media-object/width
:internal.media-object/height
:internal.media-object/mtype]))
(s/keys :req-un [::id]
:opt-un [::name
:internal.media-object/width
:internal.media-object/height
:internal.media-object/mtype]))
(s/def :internal.file/colors
(s/map-of ::uuid ::color))

View file

@ -15,11 +15,11 @@
;; NOTE: don't remove this, causes exception on advanced build
;; because of some strange interaction with cljs.spec.alpha and
;; modules spliting.
[expound.alpha]
[app.common.exceptions :as ex]
[app.common.geom.point :as gpt]
[app.common.uuid :as uuid]
[cuerdas.core :as str]))
[cuerdas.core :as str]
[expound.alpha]))
(s/check-asserts true)

View file

@ -7,7 +7,7 @@
(ns app.common.uuid
(:refer-clojure :exclude [next uuid zero?])
(:require
[app.common.data :as d]
#?(:clj [app.common.data :as d])
#?(:clj [clj-uuid :as impl])
#?(:clj [clojure.core :as c])
#?(:cljs [app.common.uuid-impl :as impl])

View file

@ -45,7 +45,7 @@
(apply min-key first)
second)))
(defn- snap-frame-id [shapes]
(defn snap-frame-id [shapes]
(let [frames (into #{} (map :frame-id shapes))]
(cond
;; Only shapes from one frame. The common is the only one

View file

@ -6,15 +6,12 @@
(ns app.main.ui
(:require
[app.config :as cf]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.spec :as us]
[app.common.uuid :as uuid]
[app.config :as cfg]
[app.main.data.users :as du]
[app.main.data.messages :as dm]
[app.config :as cf]
[app.main.data.events :as ev]
[app.main.data.messages :as dm]
[app.main.data.users :as du]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.auth :refer [auth]]
@ -32,8 +29,6 @@
[app.main.ui.static :as static]
[app.main.ui.viewer :refer [viewer-page]]
[app.main.ui.workspace :as workspace]
[app.util.i18n :as i18n :refer [tr t]]
[app.util.router :as rt]
[app.util.timers :as ts]
[cljs.pprint :refer [pprint]]
[cljs.spec.alpha :as s]
@ -60,11 +55,11 @@
(def routes
[["/auth"
["/login" :auth-login]
(when cfg/registration-enabled
(when cf/registration-enabled
["/register" :auth-register])
(when cfg/registration-enabled
(when cf/registration-enabled
["/register/validate" :auth-register-validate])
(when cfg/registration-enabled
(when cf/registration-enabled
["/register/success" :auth-register-success])
["/recovery/request" :auth-recovery-request]
["/recovery" :auth-recovery]
@ -102,9 +97,8 @@
(mf/defc on-main-error
[{:keys [error] :as props}]
(let [data (ex-data error)]
(mf/use-effect #(ptk/handle-error error))
[:span "Internal application errror"]))
(mf/use-effect #(ptk/handle-error error))
[:span "Internal application errror"])
(mf/defc main-page
{::mf/wrap [#(mf/catch % {:fallback on-main-error})]}
@ -211,14 +205,14 @@
(derive :service-unavailable ::exceptional-state)
(defmethod ptk/handle-error ::exceptional-state
[{:keys [status] :as error}]
[error]
(ts/schedule
(st/emitf (dm/assign-exception error))))
;; We receive a explicit authentication error; this explicitly clears
;; all profile data and redirect the user to the login page.
(defmethod ptk/handle-error :authentication
[error]
[_]
(ts/schedule (st/emitf (du/logout))))
;; Error that happens on an active bussines model validation does not
@ -245,7 +239,7 @@
;; Error on parsing an SVG
(defmethod ptk/handle-error :svg-parser
[error]
[_]
(ts/schedule
(st/emitf
(dm/show {:content "SVG is invalid or malformed"
@ -261,7 +255,7 @@
context (str/fmt "ns: '%s'\nname: '%s'\nfile: '%s:%s'"
(:ns context)
(:name context)
(str cfg/public-uri "js/cljs-runtime/" (:file context))
(str cf/public-uri "js/cljs-runtime/" (:file context))
(:line context))]
(ts/schedule
(st/emitf

View file

@ -68,7 +68,7 @@
(st/emit! (dm/error (tr "errors.generic")))))
(defn- handle-prepare-register-success
[form {:keys [token] :as result}]
[_form {:keys [token] :as result}]
(st/emit! (rt/nav :auth-register-validate {} {:token token})))
(mf/defc register-form
@ -163,7 +163,7 @@
(st/emit! (dm/error (tr "errors.generic"))))))
(defn- handle-register-success
[form data]
[_form data]
(cond
(some? (:invitation-token data))
(let [token (:invitation-token data)]
@ -197,7 +197,7 @@
on-submit
(mf/use-callback
(fn [form event]
(fn [form _event]
(reset! submitted? true)
(let [params (:clean-data @form)]
(->> (rp/mutation :register-profile params)

View file

@ -6,14 +6,10 @@
(ns app.main.ui.workspace.sidebar.options.common
(:require
[rumext.alpha :as mf]
[app.util.dom :as dom]))
[rumext.alpha :as mf]))
(mf/defc advanced-options [{:keys [visible? on-close children]}]
(let [ref (mf/use-ref nil)
handle-click (fn [event] (when on-close
(do (dom/stop-propagation event)
(on-close))))]
(mf/defc advanced-options [{:keys [visible? children]}]
(let [ref (mf/use-ref nil)]
(mf/use-effect
(mf/deps visible?)
(fn []

View file

@ -6,16 +6,13 @@
(ns app.main.ui.workspace.sidebar.options.menus.blur
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.common.uuid :as uuid]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.changes :as dch]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]))
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(def blur-attrs [:blur])
@ -27,8 +24,7 @@
:hidden false}))
(mf/defc blur-menu [{:keys [ids type values]}]
(let [locale (i18n/use-locale)
blur (:blur values)
(let [blur (:blur values)
has-value? (not (nil? blur))
multiple? (= blur :multiple)
@ -59,9 +55,9 @@
[:div.element-set-title
[:span
(case type
:multiple (t locale "workspace.options.blur-options.title.multiple")
:group (t locale "workspace.options.blur-options.title.group")
(t locale "workspace.options.blur-options.title"))]
:multiple (tr "workspace.options.blur-options.title.multiple")
:group (tr "workspace.options.blur-options.title.group")
(tr "workspace.options.blur-options.title"))]
[:div.element-set-title-actions
(when (and has-value? (not multiple?))
@ -78,5 +74,5 @@
:class "pixels"
:min 0
:value (:value blur)
:placeholder (t locale "settings.multiple")
:placeholder (tr "settings.multiple")
:on-change handle-change}]])]))

View file

@ -6,20 +6,19 @@
(ns app.main.ui.workspace.sidebar.options.menus.component
(:require
[rumext.alpha :as mf]
[app.common.pages :as cp]
[app.main.data.modal :as modal]
[app.main.data.workspace :as dw]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.undo :as dwu]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.context-menu :refer [context-menu]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.components.context-menu :refer [context-menu]]
[app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.undo :as dwu]
[app.main.data.workspace.libraries :as dwl]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]
[app.util.dom :as dom]))
[rumext.alpha :as mf]))
(def component-attrs [:component-id :component-file :shape-ref])

View file

@ -6,19 +6,16 @@
(ns app.main.ui.workspace.sidebar.options.menus.exports
(:require
[cuerdas.core :as str]
[beicon.core :as rx]
[rumext.alpha :as mf]
[app.common.data :as d]
[app.main.repo :as rp]
[app.main.ui.icons :as i]
[app.main.data.messages :as dm]
[app.main.data.workspace :as udw]
[app.main.repo :as rp]
[app.main.store :as st]
[app.util.object :as obj]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.http :as http]
[app.util.i18n :as i18n :refer [tr t]]))
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[rumext.alpha :as mf]))
(defn request-export
[shape exports]
@ -31,8 +28,7 @@
(mf/defc exports-menu
[{:keys [shape page-id file-id] :as props}]
(let [locale (mf/deref i18n/locale)
exports (:exports shape [])
(let [exports (:exports shape [])
loading? (mf/use-state false)
filename (cond-> (:name shape)
@ -50,7 +46,7 @@
(rx/subs
(fn [body]
(dom/trigger-download filename body))
(fn [error]
(fn [_error]
(swap! loading? not)
(st/emit! (dm/error (tr "errors.unexpected-error"))))
(fn []
@ -108,7 +104,7 @@
[:div.element-set.exports-options
[:div.element-set-title
[:span (t locale "workspace.options.export")]
[:span (tr "workspace.options.export")]
[:div.add-page {:on-click add-export} i/close]]
(when (seq exports)
[:div.element-set-content
@ -141,6 +137,6 @@
:btn-disabled @loading?)
:disabled @loading?}
(if @loading?
(t locale "workspace.options.exporting-object")
(t locale "workspace.options.export-object"))]])]))
(tr "workspace.options.exporting-object")
(tr "workspace.options.export-object"))]])]))

View file

@ -8,16 +8,12 @@
(:require
[app.common.pages :as cp]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.undo :as dwu]
[app.main.data.workspace.texts :as dwt]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.util.color :as uc]
[app.util.i18n :as i18n :refer [tr t]]
[app.util.object :as obj]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(def fill-attrs
@ -30,14 +26,13 @@
(mf/defc fill-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]}
[{:keys [ids type values] :as props}]
(let [locale (mf/deref i18n/locale)
show? (or (not (nil? (:fill-color values)))
(not (nil? (:fill-color-gradient values))))
(let [show? (or (not (nil? (:fill-color values)))
(not (nil? (:fill-color-gradient values))))
label (case type
:multiple (t locale "workspace.options.selection-fill")
:group (t locale "workspace.options.group-fill")
(t locale "workspace.options.fill"))
:multiple (tr "workspace.options.selection-fill")
:group (tr "workspace.options.group-fill")
(tr "workspace.options.fill"))
color {:color (:fill-color values)
:opacity (:fill-opacity values)
@ -48,21 +43,21 @@
on-add
(mf/use-callback
(mf/deps ids)
(fn [event]
(fn [_]
(st/emit! (dc/change-fill ids {:color cp/default-color
:opacity 1}))))
on-delete
(mf/use-callback
(mf/deps ids)
(fn [event]
(fn [_]
(st/emit! (dc/change-fill ids (into {} uc/empty-color)))))
on-change
(mf/use-callback
(mf/deps ids)
(fn [color]
(let [remove-multiple (fn [[key value]] (not= value :multiple))
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
color (into {} (filter remove-multiple) color)]
(st/emit! (dc/change-fill ids color)))))
@ -70,7 +65,7 @@
(mf/use-callback
(mf/deps ids)
(fn []
(let [remove-multiple (fn [[key value]] (not= value :multiple))
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
color (-> (into {} (filter remove-multiple) color)
(assoc :id nil :file-id nil))]
(st/emit! (dc/change-fill ids color)))))
@ -78,13 +73,13 @@
on-open-picker
(mf/use-callback
(mf/deps ids)
(fn [value opacity id file-id]
(fn [_value _opacity _id _file-id]
(st/emit! (dwu/start-undo-transaction))))
on-close-picker
(mf/use-callback
(mf/deps ids)
(fn [value opacity id file-id]
(fn [_value _opacity _id _file-id]
(st/emit! (dwu/commit-undo-transaction))))]
(if show?

View file

@ -6,38 +6,34 @@
(ns app.main.ui.workspace.sidebar.options.menus.frame-grid
(:require
[rumext.alpha :as mf]
[okulary.core :as l]
[app.util.dom :as dom]
[app.util.data :as d]
[app.common.math :as mth]
[app.common.data :refer [parse-integer]]
[app.main.store :as st]
[app.main.refs :as refs]
[app.main.data.workspace.grid :as dw]
[app.util.geom.grid :as gg]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.util.i18n :as i18n :refer [tr t]]))
[app.util.data :as d]
[app.util.geom.grid :as gg]
[app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.alpha :as mf]))
(def workspace-saved-grids
(l/derived :saved-grids refs/workspace-page-options))
(defn- get-size-options [locale]
[{:value :auto :label (t locale "workspace.options.grid.auto")}
(defn- get-size-options []
[{:value :auto :label (tr "workspace.options.grid.auto")}
:separator
18 12 10 8 6 4 3 2])
(mf/defc grid-options
[{:keys [grid frame default-grid-params on-change on-remove on-save-grid]}]
(let [locale (i18n/use-locale)
size-options (get-size-options locale)
(let [size-options (get-size-options)
state (mf/use-state {:show-advanced-options false})
{:keys [type display params]} grid
@ -45,12 +41,12 @@
#(swap! state update :show-advanced-options not)
handle-toggle-visibility
(fn [event]
(fn [_]
(when on-change
(on-change (update grid :display #(if (nil? %) false (not %))))))
handle-remove-grid
(fn [event]
(fn [_]
(when on-remove (on-remove)))
handle-change-type
@ -82,7 +78,7 @@
handle-change-item-length
(fn [item-length]
(let [{:keys [margin gutter size]} (:params grid)
(let [size (get-in grid [:params :size])
size (if (and (nil? item-length) (or (nil? size) (= :auto size))) 12 size)]
(when on-change
(on-change (-> grid
@ -128,9 +124,9 @@
[:& select {:class "flex-grow"
:default-value type
:options [{:value :square :label (t locale "workspace.options.grid.square")}
{:value :column :label (t locale "workspace.options.grid.column")}
{:value :row :label (t locale "workspace.options.grid.row")}]
:options [{:value :square :label (tr "workspace.options.grid.square")}
{:value :column :label (tr "workspace.options.grid.column")}
{:value :row :label (tr "workspace.options.grid.row")}]
:on-change handle-change-type}]
(if (= type :square)
@ -154,14 +150,14 @@
:on-close toggle-advanced-options}
[:button.custom-button {:on-click toggle-advanced-options} i/actions]
(when (= :square type)
[:& input-row {:label (t locale "workspace.options.grid.params.size")
[:& input-row {:label (tr "workspace.options.grid.params.size")
:class "pixels"
:min 1
:value (:size params)
:on-change (handle-change :params :size)}])
(when (= :row type)
[:& input-row {:label (t locale "workspace.options.grid.params.rows")
[:& input-row {:label (tr "workspace.options.grid.params.rows")
:type :editable-select
:options size-options
:value (:size params)
@ -170,7 +166,7 @@
:on-change handle-change-size}])
(when (= :column type)
[:& input-row {:label (t locale "workspace.options.grid.params.columns")
[:& input-row {:label (tr "workspace.options.grid.params.columns")
:type :editable-select
:options size-options
:value (:size params)
@ -179,23 +175,23 @@
:on-change handle-change-size}])
(when (#{:row :column} type)
[:& input-row {:label (t locale "workspace.options.grid.params.type")
[:& input-row {:label (tr "workspace.options.grid.params.type")
:type :select
:options [{:value :stretch :label (t locale "workspace.options.grid.params.type.stretch")}
:options [{:value :stretch :label (tr "workspace.options.grid.params.type.stretch")}
{:value :left :label (if (= type :row)
(t locale "workspace.options.grid.params.type.top")
(t locale "workspace.options.grid.params.type.left"))}
{:value :center :label (t locale "workspace.options.grid.params.type.center")}
(tr "workspace.options.grid.params.type.top")
(tr "workspace.options.grid.params.type.left"))}
{:value :center :label (tr "workspace.options.grid.params.type.center")}
{:value :right :label (if (= type :row)
(t locale "workspace.options.grid.params.type.bottom")
(t locale "workspace.options.grid.params.type.right"))}]
(tr "workspace.options.grid.params.type.bottom")
(tr "workspace.options.grid.params.type.right"))}]
:value (:type params)
:on-change (handle-change :params :type)}])
(when (#{:row :column} type)
[:& input-row {:label (if (= :row type)
(t locale "workspace.options.grid.params.height")
(t locale "workspace.options.grid.params.width"))
(tr "workspace.options.grid.params.height")
(tr "workspace.options.grid.params.width"))
:class "pixels"
:placeholder "Auto"
:value (or (:item-length params) "")
@ -203,13 +199,13 @@
(when (#{:row :column} type)
[:*
[:& input-row {:label (t locale "workspace.options.grid.params.gutter")
[:& input-row {:label (tr "workspace.options.grid.params.gutter")
:class "pixels"
:value (:gutter params)
:min 0
:placeholder "0"
:on-change (handle-change :params :gutter)}]
[:& input-row {:label (t locale "workspace.options.grid.params.margin")
[:& input-row {:label (tr "workspace.options.grid.params.margin")
:class "pixels"
:min 0
:placeholder "0"
@ -222,13 +218,12 @@
:on-detach handle-detach-color}]
[:div.row-flex
[:button.btn-options {:disabled is-default
:on-click handle-use-default} (t locale "workspace.options.grid.params.use-default")]
:on-click handle-use-default} (tr "workspace.options.grid.params.use-default")]
[:button.btn-options {:disabled is-default
:on-click handle-set-as-default} (t locale "workspace.options.grid.params.set-default")]]]]))
:on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]]]]))
(mf/defc frame-grid [{:keys [shape]}]
(let [locale (i18n/use-locale)
id (:id shape)
(let [id (:id shape)
default-grid-params (merge dw/default-grid-params (mf/deref workspace-saved-grids))
handle-create-grid #(st/emit! (dw/add-frame-grid id))
handle-remove-grid (fn [index] #(st/emit! (dw/remove-frame-grid id index)))
@ -236,10 +231,10 @@
handle-save-grid (fn [grid] (st/emit! (dw/set-default-grid (:type grid) (:params grid))))]
[:div.element-set
[:div.element-set-title
[:span (t locale "workspace.options.grid.title")]
[:span (tr "workspace.options.grid.title")]
[:div.add-page {:on-click handle-create-grid} i/close]]
(when (not (empty? (:grids shape)))
(when (seq (:grids shape))
[:div.element-set-content
(for [[index grid] (map-indexed vector (:grids shape))]
[:& grid-options {:key (str (:id shape) "-" index)

View file

@ -6,7 +6,6 @@
(ns app.main.ui.workspace.sidebar.options.menus.interactions
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.common.pages :as cp]
[app.main.data.workspace :as dw]
@ -14,13 +13,12 @@
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]))
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(mf/defc interactions-menu
[{:keys [shape] :as props}]
(let [locale (mf/deref i18n/locale)
objects (deref refs/workspace-page-objects)
(let [objects (deref refs/workspace-page-objects)
interaction (first (:interactions shape)) ; TODO: in the
; future we may
; have several
@ -48,26 +46,26 @@
(if (not shape)
[:*
[:div.interactions-help-icon i/interaction]
[:div.interactions-help (t locale "workspace.options.select-a-shape")]
[:div.interactions-help (tr "workspace.options.select-a-shape")]
[:div.interactions-help-icon i/play]
[:div.interactions-help (t locale "workspace.options.use-play-button")]]
[:div.interactions-help (tr "workspace.options.use-play-button")]]
[:div.element-set {:on-blur on-set-blur}
[:div.element-set-title
[:span (t locale "workspace.options.navigate-to")]]
[:span (tr "workspace.options.navigate-to")]]
[:div.element-set-content
[:div.row-flex
[:div.custom-select.flex-grow {:on-click #(reset! show-frames-dropdown? true)}
(if destination
[:span (:name destination)]
[:span (t locale "workspace.options.select-artboard")])
[:span (tr "workspace.options.select-artboard")])
[:span.dropdown-button i/arrow-down]
[:& dropdown {:show @show-frames-dropdown?
:on-close #(reset! show-frames-dropdown? false)}
[:ul.custom-select-dropdown
[:li.dropdown-separator
{:on-click #(on-select-destination nil)}
(t locale "workspace.options.none")]
(tr "workspace.options.none")]
(for [frame frames]
(when (and (not= (:id frame) (:id shape)) ; A frame cannot navigate to itself

View file

@ -8,7 +8,6 @@
(:require
[app.common.data :as d]
[app.common.math :as mth]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.changes :as dch]
[app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input]]
@ -54,25 +53,25 @@
handle-set-hidden
(mf/use-callback
(mf/deps change!)
(fn [event]
(fn [_]
(change! :hidden true)))
handle-set-visible
(mf/use-callback
(mf/deps change!)
(fn [event]
(fn [_]
(change! :hidden false)))
handle-set-blocked
(mf/use-callback
(mf/deps change!)
(fn [event]
(fn [_]
(change! :blocked true)))
handle-set-unblocked
(mf/use-callback
(mf/deps change!)
(fn [event]
(fn [_]
(change! :blocked false)))]
[:div.element-set
@ -92,7 +91,7 @@
[:option {:value "multiple"} "--"])
[:option {:value "normal"} (tr "workspace.options.layer-options.blend-mode.normal")]
[:option {:value "darken"} (tr "workspace.options.layer-options.blend-mode.darken")]
[:option {:value "multiply"} (tr "workspace.options.layer-options.blend-mode.multiply")]
[:option {:value "color-burn"} (tr "workspace.options.layer-options.blend-mode.color-burn")]
@ -127,13 +126,13 @@
(cond
(or (= :multiple (:hidden values)) (not (:hidden values)))
[:div.element-set-actions-button {:on-click handle-set-hidden} i/eye]
:else
[:div.element-set-actions-button {:on-click handle-set-visible} i/eye-closed])
(cond
(or (= :multiple (:blocked values)) (not (:blocked values)))
[:div.element-set-actions-button {:on-click handle-set-blocked} i/unlock]
:else
[:div.element-set-actions-button {:on-click handle-set-unblocked} i/lock])]]]]))

View file

@ -6,24 +6,21 @@
(ns app.main.ui.workspace.sidebar.options.menus.measures
(:require
[cuerdas.core :as str]
[rumext.alpha :as mf]
[app.main.ui.icons :as i]
[app.main.store :as st]
[app.main.refs :as refs]
[app.common.data :as d]
[app.util.dom :as dom]
[app.util.data :refer [classnames]]
[app.common.geom.shapes :as gsh]
[app.common.geom.point :as gpt]
[app.common.math :as math]
[app.common.pages.spec :as spec]
[app.common.uuid :as uuid]
[app.main.data.workspace :as udw]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.changes :as dch]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.common.math :as math]
[app.util.i18n :refer [tr] :as i18n]))
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(def measure-attrs [:proportion-lock
:width :height
@ -88,7 +85,7 @@
on-proportion-lock-change
(mf/use-callback
(mf/deps ids)
(fn [event]
(fn [_]
(let [new-lock (if (= proportion-lock :multiple) true (not proportion-lock))]
(run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids))))
@ -114,7 +111,7 @@
on-switch-to-radius-1
(mf/use-callback
(mf/deps ids)
(fn [value]
(fn [_value]
(let [radius-update
(fn [shape]
(cond-> shape
@ -126,7 +123,7 @@
on-switch-to-radius-4
(mf/use-callback
(mf/deps ids)
(fn [value]
(fn [_value]
(let [radius-update
(fn [shape]
(cond-> shape
@ -180,164 +177,162 @@
on-constraint-button-clicked
(mf/use-callback
(mf/deps [ids values])
(fn [button]
(fn [event]
(let [constraints-h (get values :constraints-h :scale)
constraints-v (get values :constraints-v :scale)
(mf/deps [ids values])
(fn [button]
(fn [_]
(let [constraints-h (get values :constraints-h :scale)
constraints-v (get values :constraints-v :scale)
[constraint new-value]
(case button
:top (case constraints-v
:top [:constraints-v :scale]
:topbottom [:constraints-v :bottom]
:bottom [:constraints-v :topbottom]
[:constraints-v :top])
:bottom (case constraints-v
:bottom [:constraints-v :scale]
:topbottom [:constraints-v :top]
:top [:constraints-v :topbottom]
[:constraints-v :bottom])
:left (case constraints-h
:left [:constraints-h :scale]
:leftright [:constraints-h :right]
:right [:constraints-h :leftright]
[:constraints-h :left])
:right (case constraints-h
:right [:constraints-h :scale]
:leftright [:constraints-h :left]
:left [:constraints-h :leftright]
[:constraints-h :right])
:centerv (case constraints-v
[constraint new-value]
(case button
:top (case constraints-v
:top [:constraints-v :scale]
:topbottom [:constraints-v :bottom]
:bottom [:constraints-v :topbottom]
[:constraints-v :top])
:bottom (case constraints-v
:bottom [:constraints-v :scale]
:topbottom [:constraints-v :top]
:top [:constraints-v :topbottom]
[:constraints-v :bottom])
:left (case constraints-h
:left [:constraints-h :scale]
:leftright [:constraints-h :right]
:right [:constraints-h :leftright]
[:constraints-h :left])
:right (case constraints-h
:right [:constraints-h :scale]
:leftright [:constraints-h :left]
:left [:constraints-h :leftright]
[:constraints-h :right])
:centerv (case constraints-v
:center [:constraints-v :scale]
[:constraints-v :center])
:centerh (case constraints-h
:centerh (case constraints-h
:center [:constraints-h :scale]
[:constraints-h :center]))]
(st/emit! (dch/update-shapes
ids
#(assoc % constraint new-value)))))))
(st/emit! (dch/update-shapes
ids
#(assoc % constraint new-value)))))))
on-constraint-select-changed
(mf/use-callback
(mf/deps [ids values])
(fn [constraint]
(mf/deps [ids values])
(fn [constraint]
(fn [event]
(let [value (-> (dom/get-target-val event) (keyword))]
(when-not (str/empty? value)
(st/emit! (dch/update-shapes
ids
#(assoc % constraint value))))))))
ids
#(assoc % constraint value))))))))
on-fixed-scroll-clicked
(mf/use-callback
(mf/deps [ids values])
(fn [event]
(st/emit! (dch/update-shapes
ids
#(update % :fixed-scroll not)))))]
(mf/deps [ids values])
(fn [_]
(st/emit! (dch/update-shapes ids #(update % :fixed-scroll not)))))]
[:*
[:div.element-set
[:div.element-set-content
[:div.element-set
[:div.element-set-content
;; WIDTH & HEIGHT
(when (options :size)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.size")]
[:div.input-element.width
[:> numeric-input {:min 1
:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-width-change
:value (attr->string :width values)}]]
;; WIDTH & HEIGHT
(when (options :size)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.size")]
[:div.input-element.width
[:> numeric-input {:min 1
:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-width-change
:value (attr->string :width values)}]]
[:div.input-element.height
[:> numeric-input {:min 1
:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-height-change
:value (attr->string :height values)}]]
[:div.input-element.height
[:> numeric-input {:min 1
:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-height-change
:value (attr->string :height values)}]]
[:div.lock-size {:class (classnames
[:div.lock-size {:class (dom/classnames
:selected (true? proportion-lock)
:disabled (= proportion-lock :multiple))
:on-click on-proportion-lock-change}
(if proportion-lock
i/lock
i/unlock)]])
:on-click on-proportion-lock-change}
(if proportion-lock
i/lock
i/unlock)]])
;; POSITION
(when (options :position)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.position")]
[:div.input-element.Xaxis
[:> numeric-input {:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-pos-x-change
:value (attr->string :x values)}]]
[:div.input-element.Yaxis
[:> numeric-input {:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-pos-y-change
:value (attr->string :y values)}]]])
;; POSITION
(when (options :position)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.position")]
[:div.input-element.Xaxis
[:> numeric-input {:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-pos-x-change
:value (attr->string :x values)}]]
[:div.input-element.Yaxis
[:> numeric-input {:no-validate true
:placeholder "--"
:on-click select-all
:on-change on-pos-y-change
:value (attr->string :y values)}]]])
;; ROTATION
(when (options :rotation)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.rotation")]
[:div.input-element.degrees
[:> numeric-input
{:no-validate true
:min 0
:max 359
:data-wrap true
:placeholder "--"
:on-click select-all
:on-change on-rotation-change
:value (attr->string :rotation values)}]]
#_[:input.slidebar
{:type "range"
:min "0"
:max "359"
:step "10"
:no-validate true
:on-change on-rotation-change
:value (attr->string :rotation values)}]])
;; ROTATION
(when (options :rotation)
[:div.row-flex
[:span.element-set-subtitle (tr "workspace.options.rotation")]
[:div.input-element.degrees
[:> numeric-input
{:no-validate true
:min 0
:max 359
:data-wrap true
:placeholder "--"
:on-click select-all
:on-change on-rotation-change
:value (attr->string :rotation values)}]]
#_[:input.slidebar
{:type "range"
:min "0"
:max "359"
:step "10"
:no-validate true
:on-change on-rotation-change
:value (attr->string :rotation values)}]])
;; RADIUS
(let [radius-1? (some? (:rx values))
radius-4? (some? (:r1 values))]
(when (and (options :radius) (or radius-1? radius-4?))
[:div.row-flex
[:div.radius-options
;; RADIUS
(let [radius-1? (some? (:rx values))
radius-4? (some? (:r1 values))]
(when (and (options :radius) (or radius-1? radius-4?))
[:div.row-flex
[:div.radius-options
[:div.radius-icon.tooltip.tooltip-bottom
{:class (classnames
:selected
(and radius-1? (not radius-4?)))
{:class (dom/classnames
:selected
(and radius-1? (not radius-4?)))
:alt (tr "workspace.options.radius.all-corners")
:on-click on-switch-to-radius-1}
i/radius-1]
[:div.radius-icon.tooltip.tooltip-bottom
{:class (classnames
:selected
(and radius-4? (not radius-1?)))
{:class (dom/classnames
:selected
(and radius-4? (not radius-1?)))
:alt (tr "workspace.options.radius.single-corners")
:on-click on-switch-to-radius-4}
i/radius-4]]
(if radius-1?
[:div.input-element.mini
[:> numeric-input
{:placeholder "--"
:min 0
:on-click select-all
:on-change on-radius-1-change
:value (attr->string :rx values)}]]
(if radius-1?
[:div.input-element.mini
[:> numeric-input
{:placeholder "--"
:min 0
:on-click select-all
:on-change on-radius-1-change
:value (attr->string :rx values)}]]
[:*
[:*
[:div.input-element.mini
[:> numeric-input
{:placeholder "--"
@ -367,66 +362,66 @@
:on-change on-radius-r4-change
:value (attr->string :r4 values)}]]])]))]]
;; CONSTRAINTS
(when in-frame?
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.options.constraints")]]
;; CONSTRAINTS
(when in-frame?
[:div.element-set
[:div.element-set-title
[:span (tr "workspace.options.constraints")]]
[:div.element-set-content
[:div.row-flex.align-top
[:div.element-set-content
[:div.row-flex.align-top
[:div.constraints-widget
[:div.constraints-box]
[:div.constraint-button.top
{:class (classnames :active (or (= constraints-v :top)
(= constraints-v :topbottom)))
:on-click (on-constraint-button-clicked :top)}]
[:div.constraint-button.bottom
{:class (classnames :active (or (= constraints-v :bottom)
(= constraints-v :topbottom)))
:on-click (on-constraint-button-clicked :bottom)}]
[:div.constraint-button.left
{:class (classnames :active (or (= constraints-h :left)
(= constraints-h :leftright)))
:on-click (on-constraint-button-clicked :left)}]
[:div.constraint-button.right
{:class (classnames :active (or (= constraints-h :right)
(= constraints-h :leftright)))
:on-click (on-constraint-button-clicked :right)}]
[:div.constraint-button.centerv
{:class (classnames :active (= constraints-v :center))
:on-click (on-constraint-button-clicked :centerv)}]
[:div.constraint-button.centerh
{:class (classnames :active (= constraints-h :center))
:on-click (on-constraint-button-clicked :centerh)}]]
[:div.constraints-widget
[:div.constraints-box]
[:div.constraint-button.top
{:class (dom/classnames :active (or (= constraints-v :top)
(= constraints-v :topbottom)))
:on-click (on-constraint-button-clicked :top)}]
[:div.constraint-button.bottom
{:class (dom/classnames :active (or (= constraints-v :bottom)
(= constraints-v :topbottom)))
:on-click (on-constraint-button-clicked :bottom)}]
[:div.constraint-button.left
{:class (dom/classnames :active (or (= constraints-h :left)
(= constraints-h :leftright)))
:on-click (on-constraint-button-clicked :left)}]
[:div.constraint-button.right
{:class (dom/classnames :active (or (= constraints-h :right)
(= constraints-h :leftright)))
:on-click (on-constraint-button-clicked :right)}]
[:div.constraint-button.centerv
{:class (dom/classnames :active (= constraints-v :center))
:on-click (on-constraint-button-clicked :centerv)}]
[:div.constraint-button.centerh
{:class (dom/classnames :active (= constraints-h :center))
:on-click (on-constraint-button-clicked :centerh)}]]
[:div.constraints-form
[:div.row-flex
[:span.left-right i/full-screen]
[:select.input-select {:on-change (on-constraint-select-changed :constraints-h)
:value (d/name constraints-h "scale")}
(when (= constraints-h :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "left"} (tr "workspace.options.constraints.left")]
[:option {:value "right"} (tr "workspace.options.constraints.right")]
[:option {:value "leftright"} (tr "workspace.options.constraints.leftright")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
[:div.row-flex
[:span.top-bottom i/full-screen]
[:select.input-select {:on-change (on-constraint-select-changed :constraints-v)
:value (d/name constraints-v "scale")}
(when (= constraints-v :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "top"} (tr "workspace.options.constraints.top")]
[:option {:value "bottom"} (tr "workspace.options.constraints.bottom")]
[:option {:value "topbottom"} (tr "workspace.options.constraints.topbottom")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
(when first-level?
[:div.row-flex
[:div.fix-when {:class (classnames :active (:fixed-scroll values))
:on-click on-fixed-scroll-clicked}
i/pin
[:span (tr "workspace.options.constraints.fix-when-scrolling")]]])]]]])]))
[:div.constraints-form
[:div.row-flex
[:span.left-right i/full-screen]
[:select.input-select {:on-change (on-constraint-select-changed :constraints-h)
:value (d/name constraints-h "scale")}
(when (= constraints-h :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "left"} (tr "workspace.options.constraints.left")]
[:option {:value "right"} (tr "workspace.options.constraints.right")]
[:option {:value "leftright"} (tr "workspace.options.constraints.leftright")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
[:div.row-flex
[:span.top-bottom i/full-screen]
[:select.input-select {:on-change (on-constraint-select-changed :constraints-v)
:value (d/name constraints-v "scale")}
(when (= constraints-v :multiple)
[:option {:value ""} (tr "settings.multiple")])
[:option {:value "top"} (tr "workspace.options.constraints.top")]
[:option {:value "bottom"} (tr "workspace.options.constraints.bottom")]
[:option {:value "topbottom"} (tr "workspace.options.constraints.topbottom")]
[:option {:value "center"} (tr "workspace.options.constraints.center")]
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
(when first-level?
[:div.row-flex
[:div.fix-when {:class (dom/classnames :active (:fixed-scroll values))
:on-click on-fixed-scroll-clicked}
i/pin
[:span (tr "workspace.options.constraints.fix-when-scrolling")]]])]]]])]))

View file

@ -6,19 +6,18 @@
(ns app.main.ui.workspace.sidebar.options.menus.shadow
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.common.uuid :as uuid]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.undo :as dwu]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]))
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(def shadow-attrs [:shadow])
@ -38,8 +37,7 @@
(mf/defc shadow-entry
[{:keys [ids index value]}]
(let [locale (i18n/use-locale)
open-shadow (mf/use-state false)
(let [open-shadow (mf/use-state false)
basic-offset-x-ref (mf/use-ref nil)
basic-offset-y-ref (mf/use-ref nil)
@ -52,7 +50,7 @@
remove-shadow-by-index
(fn [values index] (->> (d/enumerate values)
(filterv (fn [[idx s]] (not= idx index)))
(filterv (fn [[idx _]] (not= idx index)))
(mapv second)))
on-remove-shadow
@ -61,7 +59,7 @@
(st/emit! (dch/update-shapes ids #(update % :shadow remove-shadow-by-index index) ))))
select-text
(fn [ref] (fn [event] (dom/select-text! (mf/ref-val ref))))
(fn [ref] (fn [_] (dom/select-text! (mf/ref-val ref))))
update-attr
(fn update-attr
@ -86,12 +84,12 @@
detach-color
(fn [index]
(fn [color opacity]
(if-not (string? (:color value))
(fn [_color _opacity]
(when-not (string? (:color value))
(st/emit! (dch/update-shapes
ids
#(assoc-in % [:shadow index :color]
(dissoc (:color value) :id :file-id)))))))
ids
#(assoc-in % [:shadow index :color]
(dissoc (:color value) :id :file-id)))))))
toggle-visibility
(fn [index]
@ -122,8 +120,8 @@
:on-change (fn [event]
(let [value (-> event dom/get-target dom/get-value d/read-string)]
(st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))}
[:option {:value ":drop-shadow"} (t locale "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"} (t locale "workspace.options.shadow-options.inner-shadow")]]
[:option {:value ":drop-shadow"} (tr "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"} (tr "workspace.options.shadow-options.inner-shadow")]]
[:div.element-set-actions
[:div.element-set-actions-button {:on-click (toggle-visibility index)}
@ -142,8 +140,8 @@
:on-change (fn [event]
(let [value (-> event dom/get-target dom/get-value d/read-string)]
(st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))}
[:option {:value ":drop-shadow"} (t locale "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"} (t locale "workspace.options.shadow-options.inner-shadow")]]]
[:option {:value ":drop-shadow"} (tr "workspace.options.shadow-options.drop-shadow")]
[:option {:value ":inner-shadow"} (tr "workspace.options.shadow-options.inner-shadow")]]]
[:div.row-grid-2
[:div.input-element
@ -153,7 +151,7 @@
:on-click (select-text adv-offset-x-ref)
:on-change (update-attr index :offset-x valid-number? basic-offset-x-ref)
:value (:offset-x value)}]
[:span.after (t locale "workspace.options.shadow-options.offsetx")]]
[:span.after (tr "workspace.options.shadow-options.offsetx")]]
[:div.input-element
[:> numeric-input {:ref adv-offset-y-ref
@ -162,7 +160,7 @@
:on-click (select-text adv-offset-y-ref)
:on-change (update-attr index :offset-y valid-number? basic-offset-y-ref)
:value (:offset-y value)}]
[:span.after (t locale "workspace.options.shadow-options.offsety")]]]
[:span.after (tr "workspace.options.shadow-options.offsety")]]]
[:div.row-grid-2
[:div.input-element
@ -173,7 +171,7 @@
:on-change (update-attr index :blur valid-number? basic-blur-ref)
:min 0
:value (:blur value)}]
[:span.after (t locale "workspace.options.shadow-options.blur")]]
[:span.after (tr "workspace.options.shadow-options.blur")]]
[:div.input-element
[:> numeric-input {:ref adv-spread-ref
@ -183,7 +181,7 @@
:on-change (update-attr index :spread valid-number?)
:min 0
:value (:spread value)}]
[:span.after (t locale "workspace.options.shadow-options.spread")]]]
[:span.after (tr "workspace.options.shadow-options.spread")]]]
[:div.color-row-wrap
[:& color-row {:color (if (string? (:color value))
@ -197,10 +195,8 @@
:on-close #(st/emit! (dwu/commit-undo-transaction))}]]]]))
(mf/defc shadow-menu
[{:keys [ids type values] :as props}]
(let [locale (i18n/use-locale)
on-remove-all-shadows
(fn [event]
(st/emit! (dch/update-shapes ids #(dissoc % :shadow) )))
(let [on-remove-all-shadows
(fn [_] (st/emit! (dch/update-shapes ids #(dissoc % :shadow))))
on-add-shadow
(fn []
@ -209,9 +205,9 @@
[:div.element-set-title
[:span
(case type
:multiple (t locale "workspace.options.shadow-options.title.multiple")
:group (t locale "workspace.options.shadow-options.title.group")
(t locale "workspace.options.shadow-options.title"))]
:multiple (tr "workspace.options.shadow-options.title.multiple")
:group (tr "workspace.options.shadow-options.title.group")
(tr "workspace.options.shadow-options.title"))]
(when-not (= :multiple (:shadow values))
[:div.add-page {:on-click on-add-shadow} i/close])]
@ -220,14 +216,14 @@
(= :multiple (:shadow values))
[:div.element-set-content
[:div.element-set-options-group
[:div.element-set-label (t locale "settings.multiple")]
[:div.element-set-label (tr "settings.multiple")]
[:div.element-set-actions
[:div.element-set-actions-button {:on-click on-remove-all-shadows}
i/minus]]]]
(not (empty? (:shadow values)))
(seq (:shadow values))
[:div.element-set-content
(for [[index {:keys [id] :as value}] (d/enumerate (:shadow values []))]
(for [[index value] (d/enumerate (:shadow values []))]
[:& shadow-entry {:key (str "shadow-" index)
:ids ids
:value value

View file

@ -6,21 +6,18 @@
(ns app.main.ui.workspace.sidebar.options.menus.stroke
(:require
[cuerdas.core :as str]
[rumext.alpha :as mf]
[app.common.data :as d]
[app.common.math :as math]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.undo :as dwu]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.undo :as dwu]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.util.data :refer [classnames]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr t]]
[app.util.object :as obj]))
[app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
(def stroke-attrs
[:stroke-style
@ -47,11 +44,10 @@
(mf/defc stroke-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type"]))]}
[{:keys [ids type values] :as props}]
(let [locale (i18n/use-locale)
label (case type
:multiple (t locale "workspace.options.selection-stroke")
:group (t locale "workspace.options.group-stroke")
(t locale "workspace.options.stroke"))
(let [label (case type
:multiple (tr "workspace.options.selection-stroke")
:group (tr "workspace.options.group-stroke")
(tr "workspace.options.stroke"))
show-options (not= (:stroke-style values :none) :none)
@ -65,7 +61,7 @@
(mf/use-callback
(mf/deps ids)
(fn [color]
(let [remove-multiple (fn [[key value]] (not= value :multiple))
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
color (into {} (filter remove-multiple) color)]
(st/emit! (dc/change-stroke ids color)))))
@ -99,7 +95,7 @@
(st/emit! (dch/update-shapes ids #(assoc % :stroke-width value))))))
on-add-stroke
(fn [event]
(fn [_]
(st/emit! (dch/update-shapes ids #(assoc %
:stroke-style :solid
:stroke-color "#000000"
@ -107,19 +103,19 @@
:stroke-width 1))))
on-del-stroke
(fn [event]
(fn [_]
(st/emit! (dch/update-shapes ids #(assoc % :stroke-style :none))))
on-open-picker
(mf/use-callback
(mf/deps ids)
(fn [value opacity id file-id]
(fn [_value _opacity _id _file-id]
(st/emit! (dwu/start-undo-transaction))))
on-close-picker
(mf/use-callback
(mf/deps ids)
(fn [value opacity id file-id]
(fn [_value _opacity _id _file-id]
(st/emit! (dwu/commit-undo-transaction))))]
(if show-options
@ -139,29 +135,29 @@
;; Stroke Width, Alignment & Style
[:div.row-flex
[:div.input-element
{:class (classnames :pixels (not= (:stroke-width values) :multiple))}
{:class (dom/classnames :pixels (not= (:stroke-width values) :multiple))}
[:input.input-text {:type "number"
:min "0"
:value (-> (:stroke-width values) width->string)
:placeholder (t locale "settings.multiple")
:placeholder (tr "settings.multiple")
:on-change on-stroke-width-change}]]
[:select#style.input-select {:value (enum->string (:stroke-alignment values))
:on-change on-stroke-alignment-change}
(when (= (:stroke-alignment values) :multiple)
[:option {:value ""} "--"])
[:option {:value ":center"} (t locale "workspace.options.stroke.center")]
[:option {:value ":inner"} (t locale "workspace.options.stroke.inner")]
[:option {:value ":outer"} (t locale "workspace.options.stroke.outer")]]
[:option {:value ":center"} (tr "workspace.options.stroke.center")]
[:option {:value ":inner"} (tr "workspace.options.stroke.inner")]
[:option {:value ":outer"} (tr "workspace.options.stroke.outer")]]
[:select#style.input-select {:value (enum->string (:stroke-style values))
:on-change on-stroke-style-change}
(when (= (:stroke-style values) :multiple)
[:option {:value ""} "--"])
[:option {:value ":solid"} (t locale "workspace.options.stroke.solid")]
[:option {:value ":dotted"} (t locale "workspace.options.stroke.dotted")]
[:option {:value ":dashed"} (t locale "workspace.options.stroke.dashed")]
[:option {:value ":mixed"} (t locale "workspace.options.stroke.mixed")]]]]]
[:option {:value ":solid"} (tr "workspace.options.stroke.solid")]
[:option {:value ":dotted"} (tr "workspace.options.stroke.dotted")]
[:option {:value ":dashed"} (tr "workspace.options.stroke.dashed")]
[:option {:value ":mixed"} (tr "workspace.options.stroke.mixed")]]]]]
;; NO STROKE
[:div.element-set

View file

@ -6,16 +6,14 @@
(ns app.main.ui.workspace.sidebar.options.menus.svg-attrs
(:require
[cuerdas.core :as str]
[app.common.data :as d]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.changes :as dch]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
[rumext.alpha :as mf]
[app.main.ui.icons :as i]))
[rumext.alpha :as mf]))
(mf/defc attribute-value [{:keys [attr value on-change on-delete] :as props}]
(let [handle-change
@ -55,7 +53,7 @@
:on-change on-change
:on-delete on-delete}])])]))
(mf/defc svg-attrs-menu [{:keys [ids type values]}]
(mf/defc svg-attrs-menu [{:keys [ids values]}]
(let [handle-change
(mf/use-callback
(mf/deps ids)
@ -86,7 +84,7 @@
[:div.element-set-title
[:span (tr "workspace.sidebar.options.svg-attrs.title")]]
(for [[index [attr-key attr-value]] (d/enumerate (:svg-attrs values))]
(for [[attr-key attr-value] (:svg-attrs values)]
[:& attribute-value {:key attr-key
:attr [attr-key]
:value attr-value

View file

@ -7,9 +7,8 @@
(ns app.main.ui.workspace.sidebar.options.menus.text
(:require
[app.common.data :as d]
[app.common.uuid :as uuid]
[app.common.text :as txt]
[app.main.data.workspace.common :as dwc]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.texts :as dwt]
@ -81,10 +80,10 @@
(def attrs (d/concat #{} shape-attrs root-attrs paragraph-attrs text-attrs))
(mf/defc text-align-options
[{:keys [ids values on-change] :as props}]
[{:keys [values on-change] :as props}]
(let [{:keys [text-align]} values
handle-change
(fn [event new-align]
(fn [_ new-align]
(on-change {:text-align new-align}))]
;; --- Align
@ -111,9 +110,9 @@
i/text-align-justify]]))
(mf/defc text-direction-options
[{:keys [ids values on-change] :as props}]
[{:keys [values on-change] :as props}]
(let [direction (:text-direction values)
handle-change (fn [event val]
handle-change (fn [_ val]
(on-change {:text-direction val}))]
;; --- Align
[:div.align-icons
@ -129,11 +128,11 @@
i/text-direction-rtl]]))
(mf/defc vertical-align
[{:keys [shapes ids values on-change] :as props}]
[{:keys [values on-change] :as props}]
(let [{:keys [vertical-align]} values
vertical-align (or vertical-align "top")
handle-change
(fn [event new-align]
(fn [_ new-align]
(on-change {:vertical-align new-align}))]
[:div.align-icons
@ -154,11 +153,10 @@
i/align-bottom]]))
(mf/defc grow-options
[{:keys [ids values on-change] :as props}]
(let [to-single-value (fn [coll] (if (> (count coll) 1) nil (first coll)))
grow-type (->> values :grow-type)
[{:keys [ids values] :as props}]
(let [grow-type (:grow-type values)
handle-change-grow
(fn [event grow-type]
(fn [_ grow-type]
(st/emit! (dch/update-shapes ids #(assoc % :grow-type grow-type))))]
[:div.align-icons
@ -179,13 +177,10 @@
i/auto-height]]))
(mf/defc text-decoration-options
[{:keys [ids values on-change] :as props}]
(let [{:keys [text-decoration]} values
text-decoration (or text-decoration "none")
[{:keys [values on-change] :as props}]
(let [text-decoration (or (:text-decoration values) "none")
handle-change
(fn [event type]
(fn [_ type]
(on-change {:text-decoration type}))]
[:div.align-icons
[:span.tooltip.tooltip-bottom
@ -262,18 +257,18 @@
(get typographies (:typography-ref-id values)))))
on-convert-to-typography
(fn [event]
(fn [_]
(let [setted-values (-> (d/without-nils values)
(select-keys
(d/concat text-font-attrs
text-spacing-attrs
text-transform-attrs)))
typography (merge txt/default-typography setted-values)
typography (generate-typography-name typography)]
(let [id (uuid/next)]
(st/emit! (dwl/add-typography (assoc typography :id id) false))
(run! #(emit-update! % {:typography-ref-id id
:typography-ref-file file-id}) ids))))
typography (generate-typography-name typography)
id (uuid/next)]
(st/emit! (dwl/add-typography (assoc typography :id id) false))
(run! #(emit-update! % {:typography-ref-id id
:typography-ref-file file-id}) ids)))
handle-detach-typography
(mf/use-callback

View file

@ -7,30 +7,24 @@
(ns app.main.ui.workspace.sidebar.options.menus.typography
(:require
["react-virtualized" :as rvt]
[app.common.exceptions :as ex]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.pages :as cp]
[app.common.text :as txt]
[app.main.data.workspace.texts :as dwt]
[app.main.data.shortcuts :as dsc]
[app.main.data.fonts :as df]
[app.main.data.workspace :as dw]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.util.dom :as dom]
[app.util.object :as obj]
[app.util.timers :as tm]
[app.util.keyboard :as kbd]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[app.util.router :as rt]
[app.util.timers :as ts]
[goog.events :as events]
[app.util.timers :as tm]
[cuerdas.core :as str]
[goog.events :as events]
[rumext.alpha :as mf]))
(defn- attr->string [value]
@ -88,11 +82,11 @@
(comp (filter #(contains? backends (:backend %)))))]
(into [] xform fonts)))
(defn- toggle-backend
[backends id]
(if (contains? backends id)
(disj backends id)
(conj backends id)))
;; (defn- toggle-backend
;; [backends id]
;; (if (contains? backends id)
;; (disj backends id)
;; (conj backends id)))
(mf/defc font-selector
[{:keys [on-select on-close current-font] :as props}]
@ -101,7 +95,6 @@
flist (mf/use-ref)
input (mf/use-ref)
ddown (mf/use-ref)
fonts (mf/use-memo (mf/deps @state) #(filter-fonts @state @fonts/fonts))
@ -237,7 +230,7 @@
:current? (= (:id font) (:id selected))}])))
(mf/defc font-options
[{:keys [editor ids values on-change] :as props}]
[{:keys [values on-change] :as props}]
(let [{:keys [font-id font-size font-variant-id]} values
font-id (or font-id (:font-id txt/default-text-attrs))
@ -261,15 +254,6 @@
:font-weight weight
:font-style style}))))
on-font-family-change
(mf/use-callback
(mf/deps fonts change-font)
(fn [event]
(let [new-font-id (dom/get-target-val event)]
(when-not (str/empty? new-font-id)
(let [font (get fonts new-font-id)]
(fonts/ensure-loaded! new-font-id (partial change-font new-font-id)))))))
on-font-size-change
(mf/use-callback
(mf/deps on-change)
@ -345,7 +329,7 @@
(mf/defc spacing-options
[{:keys [editor ids values on-change] :as props}]
[{:keys [values on-change] :as props}]
(let [{:keys [line-height
letter-spacing]} values
@ -385,13 +369,10 @@
:on-change #(handle-change % :letter-spacing)}]]]))
(mf/defc text-transform-options
[{:keys [editor ids values on-change] :as props}]
(let [{:keys [text-transform]} values
text-transform (or text-transform "none")
[{:keys [values on-change] :as props}]
(let [text-transform (or (:text-transform values) "none")
handle-change
(fn [event type]
(fn [_ type]
(on-change {:text-transform type}))]
[:div.align-icons
[:span.tooltip.tooltip-bottom
@ -461,7 +442,7 @@
(mf/deps focus-name?)
(fn []
(when focus-name?
(ts/schedule
(tm/schedule
#(when-let [node (mf/ref-val name-input-ref)]
(dom/focus! node)
(dom/select-text! node))))))
@ -539,7 +520,7 @@
:ref name-input-ref
:default-value (cp/merge-path-item (:path typography) (:name typography))
:on-blur on-name-blur}]
[:div.element-set-actions-button
{:on-click #(reset! open? false)}
i/actions]]]

View file

@ -6,12 +6,10 @@
(ns app.main.ui.workspace.sidebar.options.rows.input-row
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.main.ui.components.editable-select :refer [editable-select]]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.components.editable-select :refer [editable-select]]
[app.util.dom :as dom]))
[rumext.alpha :as mf]))
(mf/defc input-row [{:keys [label options value class min max on-change type placeholder]}]
[:div.row-flex.input-row

View file

@ -6,14 +6,14 @@
(ns app.main.ui.workspace.sidebar.options.shapes.circle
(:require
[rumext.alpha :as mf]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[rumext.alpha :as mf]))
(mf/defc options
[{:keys [shape] :as props}]

View file

@ -6,23 +6,22 @@
(ns app.main.ui.workspace.sidebar.options.shapes.frame
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.util.dom :as dom]
[app.common.geom.point :as gpt]
[app.util.i18n :refer [tr]]
[app.common.math :as math]
[app.main.store :as st]
[app.main.data.workspace :as udw]
[app.main.ui.icons :as i]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
[rumext.alpha :as mf]))
(declare +size-presets+)
@ -50,7 +49,7 @@
(st/emit! (udw/update-dimensions [(:id shape)] attr value)))
on-proportion-lock-change
(fn [event]
(fn [_]
(st/emit! (udw/set-shape-proportion-lock (:id shape) (not (:proportion-lock shape)))))
on-position-change
@ -82,8 +81,8 @@
:on-click #(on-preset-selected (:width size-preset) (:height size-preset))}
(:name size-preset)
[:span (:width size-preset) " x " (:height size-preset)]]))]]]
[:span.orientation-icon {on-click #(on-orientation-clicked :vert)} i/size-vert]
[:span.orientation-icon {on-click #(on-orientation-clicked :horiz)} i/size-horiz]]
[:span.orientation-icon {:on-click #(on-orientation-clicked :vert)} i/size-vert]
[:span.orientation-icon {:on-click #(on-orientation-clicked :horiz)} i/size-horiz]]
;; WIDTH & HEIGHT
[:div.row-flex

View file

@ -6,18 +6,18 @@
(ns app.main.ui.workspace.sidebar.options.shapes.group
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
[rumext.alpha :as mf]))
(mf/defc options
{::mf/wrap [mf/memo]

View file

@ -6,11 +6,11 @@
(ns app.main.ui.workspace.sidebar.options.shapes.image
(:require
[rumext.alpha :as mf]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[rumext.alpha :as mf]))
(mf/defc options
[{:keys [shape] :as props}]

View file

@ -147,7 +147,7 @@
:else (attrs/get-attrs-multi [v1 v2] attrs)))
extract-attrs
(fn [[ids values] {:keys [id type shapes content] :as shape}]
(fn [[ids values] {:keys [id type content] :as shape}]
(let [props (get-in type->props [type attr-type])]
(case props
:ignore [ids values]

View file

@ -6,15 +6,14 @@
(ns app.main.ui.workspace.sidebar.options.shapes.path
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[rumext.alpha :as mf]))
(mf/defc options
[{:keys [shape] :as props}]

View file

@ -6,14 +6,14 @@
(ns app.main.ui.workspace.sidebar.options.shapes.rect
(:require
[rumext.alpha :as mf]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
[rumext.alpha :as mf]))
(mf/defc options
{::mf/wrap [mf/memo]}

View file

@ -6,22 +6,23 @@
(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw
(:require
[rumext.alpha :as mf]
[cuerdas.core :as str]
[app.util.data :as d]
[app.util.color :as uc]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]))
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.util.color :as uc]
[app.util.data :as d]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
;; This is a list of svg tags that can be grouped in shape-container
;; this allows them to have gradients, shadows and masks
(def svg-elements #{:svg :g :circle :ellipse :image :line :path :polygon :polyline :rect :symbol :text :textPath})
(defn hex->number [hex] 1)
(defn hex->number [_] 1)
(defn shorthex->longhex [hex]
(let [[_ r g b] hex]
(str "#" r r g g b b)))
@ -45,10 +46,10 @@
(defn get-fill-values [shape]
(let [fill-values (or (select-keys shape fill-attrs))
color (-> (or (get-in shape [:content :attrs :fill])
(get-in shape [:content :attrs :style :fill]))
(parse-color))
(let [fill-values (select-keys shape fill-attrs)
color (-> (or (get-in shape [:content :attrs :fill])
(get-in shape [:content :attrs :style :fill]))
(parse-color))
fill-values (if (and (empty? fill-values) color)
{:fill-color (:color color)
@ -57,10 +58,10 @@
fill-values))
(defn get-stroke-values [shape]
(let [stroke-values (or (select-keys shape stroke-attrs))
color (-> (or (get-in shape [:content :attrs :stroke])
(get-in shape [:content :attrs :style :stroke]))
(parse-color))
(let [stroke-values (select-keys shape stroke-attrs)
color (-> (or (get-in shape [:content :attrs :stroke])
(get-in shape [:content :attrs :style :stroke]))
(parse-color))
stroke-color (:color color "#000000")
stroke-opacity (:opacity color 1)
@ -90,7 +91,7 @@
(let [ids [(:id shape)]
type (:type shape)
{:keys [tag attrs] :as content} (:content shape)
{:keys [tag] :as content} (:content shape)
measure-values (select-keys shape measure-attrs)
fill-values (get-fill-values shape)
stroke-values (get-stroke-values shape)]

View file

@ -18,8 +18,6 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.router :as rt]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.alpha :as mf]))
@ -86,12 +84,12 @@
on-drop
(mf/use-callback
(mf/deps id)
(fn [side {:keys [id name] :as data}]
(fn [side {:keys [id] :as data}]
(let [index (if (= :bot side) (inc index) index)]
(st/emit! (dw/relocate-page id index)))))
on-duplicate
(fn [event]
(fn [_]
(st/emit! (dw/duplicate-page id)))
[dprops dref]
@ -169,7 +167,7 @@
st/state =))
(mf/defc page-item-wrapper
[{:keys [file-id page-id index deletable? selected?] :as props}]
[{:keys [page-id index deletable? selected?] :as props}]
(let [page-ref (mf/use-memo (mf/deps page-id) #(make-page-ref page-id))
page (mf/deref page-ref)]
[:& page-item {:page page
@ -197,7 +195,7 @@
;; --- Sitemap Toolbox
(mf/defc sitemap
[{:keys [layout] :as props}]
[]
(let [file (mf/deref refs/workspace-file)
create (mf/use-callback
(mf/deps file)

View file

@ -7,11 +7,9 @@
(ns app.main.ui.workspace.viewport
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.main.refs :as refs]
[app.main.ui.context :as ctx]
[app.main.ui.context :as muc]
[app.main.ui.measurements :as msr]
[app.main.ui.shapes.embed :as embed]
[app.main.ui.shapes.export :as use]
@ -79,7 +77,6 @@
;; REFS
viewport-ref (mf/use-ref nil)
zoom-view-ref (mf/use-ref nil)
render-ref (mf/use-ref nil)
;; VARS
@ -139,7 +136,9 @@
show-presence? page-id
show-prototypes? (= options-mode :prototype)
show-selection-handlers? (seq selected)
show-snap-distance? (and (contains? layout :dynamic-alignment) (= transform :move) (not (empty? selected)))
show-snap-distance? (and (contains? layout :dynamic-alignment)
(= transform :move)
(seq selected))
show-snap-points? (and (or (contains? layout :dynamic-alignment)
(contains? layout :snap-grid))
(or drawing-obj transform))

View file

@ -12,10 +12,10 @@
[app.main.data.workspace :as dw]
[app.main.data.workspace.drawing :as dd]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.path :as dwdp]
[app.main.store :as st]
[app.main.streams :as ms]
[app.main.ui.workspace.viewport.utils :as utils]
[app.main.data.workspace.path :as dwdp]
[app.util.dom :as dom]
[app.util.dom.dnd :as dnd]
[app.util.keyboard :as kbd]
@ -290,8 +290,7 @@
(st/emit! (ms/->KeyboardEvent :up key shift? ctrl? alt? meta?))))))
(defn on-mouse-move [viewport-ref zoom]
(let [last-position (mf/use-var nil)
viewport (mf/ref-val viewport-ref)]
(let [last-position (mf/use-var nil)]
(mf/use-callback
(mf/deps zoom)
(fn [event]
@ -477,7 +476,7 @@
(defn on-resize [viewport-ref]
(mf/use-callback
(fn [event]
(fn [_]
(let [node (mf/ref-val viewport-ref)
prnt (dom/get-parent node)
size (dom/get-client-size prnt)]

View file

@ -7,17 +7,12 @@
(ns app.main.ui.workspace.viewport.drawarea
"Drawing components."
(:require
[rumext.alpha :as mf]
[app.main.data.workspace :as dw]
[app.main.data.workspace.drawing :as dd]
[app.main.store :as st]
[app.main.ui.workspace.shapes :as shapes]
[app.main.ui.shapes.path :refer [path-shape]]
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
[app.common.geom.shapes :as gsh]
[app.common.data :as d]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]))
[app.common.math :as mth]
[app.main.ui.shapes.path :refer [path-shape]]
[app.main.ui.workspace.shapes :as shapes]
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
[rumext.alpha :as mf]))
(declare generic-draw-area)
(declare path-draw-area)
@ -38,8 +33,8 @@
[{:keys [shape zoom]}]
(let [{:keys [x y width height]} (:selrect (gsh/transform-shape shape))]
(when (and x y
(not (d/nan? x))
(not (d/nan? y)))
(not (mth/nan? x))
(not (mth/nan? y)))
[:rect.main {:x x :y y
:width width

View file

@ -6,18 +6,17 @@
(ns app.main.ui.workspace.viewport.frame-grid
(:require
[rumext.alpha :as mf]
[okulary.core :as l]
[app.main.refs :as refs]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.uuid :as uuid]
[app.main.refs :as refs]
[app.util.geom.grid :as gg]
[app.common.uuid :as uuid]))
[okulary.core :as l]
[rumext.alpha :as mf]))
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]
(let [grid-id (mf/use-memo #(uuid/next))
{:keys [color size] :as params} (-> grid :params)
{:keys [size] :as params} (-> grid :params)
{color-value :color color-opacity :opacity} (-> grid :params :color)
;; Support for old color format
color-value (or color-value (:value (get-in grid [:params :color :value])))]
@ -43,7 +42,7 @@
:height (:height frame)
:fill (str "url(#" grid-id ")")}]]))
(mf/defc layout-grid [{:keys [key frame zoom grid]}]
(mf/defc layout-grid [{:keys [key frame grid]}]
(let [{color-value :color color-opacity :opacity} (-> grid :params :color)
;; Support for old color format
color-value (or color-value (:value (get-in grid [:params :color :value])))

View file

@ -7,21 +7,19 @@
(ns app.main.ui.workspace.viewport.gradients
"Gradients handlers and renders"
(:require
[rumext.alpha :as mf]
[cuerdas.core :as str]
[beicon.core :as rx]
[okulary.core :as l]
[app.common.math :as mth]
[app.common.geom.shapes :as gsh]
[app.common.geom.point :as gpt]
[app.common.geom.matrix :as gmt]
[app.util.dom :as dom]
[app.main.store :as st]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.main.data.workspace.colors :as dc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.streams :as ms]
[app.main.data.modal :as modal]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.colors :as dc]))
[app.util.dom :as dom]
[beicon.core :as rx]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.alpha :as mf]))
(def gradient-line-stroke-width 2)
(def gradient-line-stroke-color "white")
@ -94,7 +92,7 @@
on-click on-mouse-down on-mouse-up]}]
[:g {:filter (str/fmt "url(#%s)" filter-id)
:transform (gmt/rotate-matrix angle point)}
[:image {:href checkboard
:x (- (:x point) (/ gradient-square-width 2 zoom))
:y (- (:y point) (/ gradient-square-width 2 zoom))
@ -127,7 +125,7 @@
(mf/defc gradient-handler-transformed
[{:keys [from-p to-p width-p from-color to-color zoom editing
on-change-start on-change-finish on-change-width on-change-stop-color]}]
on-change-start on-change-finish on-change-width]}]
(let [moving-point (mf/use-var nil)
angle (+ 90 (gpt/angle from-p to-p))
@ -138,7 +136,7 @@
(st/emit! (dc/select-gradient-stop (case position
:from-p 0
:to-p 1)))))
on-mouse-down (fn [position event]
(dom/stop-propagation event)
(dom/prevent-default event)
@ -148,7 +146,7 @@
:from-p 0
:to-p 1)))))
on-mouse-up (fn [position event]
on-mouse-up (fn [_position event]
(dom/stop-propagation event)
(dom/prevent-default event)
(reset! moving-point nil))]

View file

@ -37,8 +37,6 @@
(mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-resize on-paste)
(fn []
(let [node (mf/ref-val viewport-ref)
prnt (dom/get-parent node)
keys [(events/listen js/document EventType.KEYDOWN on-key-down)
(events/listen js/document EventType.KEYUP on-key-up)
(events/listen node EventType.MOUSEMOVE on-mouse-move)
@ -90,7 +88,8 @@
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
(hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %)))
(defn setup-hover-shapes [page-id move-stream selected objects transform selected ctrl? hover hover-ids zoom]
;; TODO: revisit the arguments, looks like `selected` is not necessary here
(defn setup-hover-shapes [page-id move-stream _selected objects transform selected ctrl? hover hover-ids zoom]
(let [query-point
(mf/use-callback
(mf/deps page-id)
@ -111,12 +110,7 @@
;; When transforming shapes we stop querying the worker
(rx/filter #(not (some? (mf/ref-val transform-ref))))
(rx/switch-map query-point))
roots (mf/use-memo
(mf/deps selected objects)
(fn []
(let [roots-ids (cp/clean-loops objects selected)]
(->> roots-ids (mapv #(get objects %))))))]
]
(mf/use-effect
(mf/deps transform)

View file

@ -7,15 +7,11 @@
(ns app.main.ui.workspace.viewport.interactions
"Visually show shape interactions in workspace"
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.main.data.workspace :as dw]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.workspace.viewport.outline :refer [outline]]
[app.util.data :as dt]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[cuerdas.core :as str]
[rumext.alpha :as mf]
))
@ -24,14 +20,11 @@
[shape]
(first (filter #(= (:event-type %) :click) (:interactions shape))))
(defn- on-mouse-down
[event {:keys [id type] :as shape} selected]
(do
(dom/stop-propagation event)
(st/emit! (dw/select-shape id))
(st/emit! (dw/start-create-interaction))))
[event {:keys [id] :as shape}]
(dom/stop-propagation event)
(st/emit! (dw/select-shape id))
(st/emit! (dw/start-create-interaction)))
(defn connect-to-shape
"Calculate the best position to draw an interaction line
@ -118,7 +111,7 @@
(mf/defc interaction-path
[{:keys [orig-shape dest-shape dest-point selected selected? zoom] :as props}]
[{:keys [orig-shape dest-shape dest-point selected? zoom] :as props}]
(let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
(if dest-shape
(connect-to-shape orig-shape dest-shape)
@ -138,9 +131,9 @@
:pointer-events "visible"
:stroke-width (/ 2 zoom)
:d pdata
:on-mouse-down #(on-mouse-down % orig-shape selected)}]
:on-mouse-down #(on-mouse-down % orig-shape)}]
[:g {:on-mouse-down #(on-mouse-down % orig-shape selected)}
[:g {:on-mouse-down #(on-mouse-down % orig-shape)}
[:path {:stroke "#31EFB8"
:fill "none"
:pointer-events "visible"
@ -161,11 +154,11 @@
(mf/defc interaction-handle
[{:keys [shape selected zoom] :as props}]
[{:keys [shape zoom] :as props}]
(let [shape-rect (:selrect shape)
handle-x (+ (:x shape-rect) (:width shape-rect))
handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
[:g {:on-mouse-down #(on-mouse-down % shape selected)}
[:g {:on-mouse-down #(on-mouse-down % shape)}
[:& interaction-marker {:x handle-x
:y handle-y
:arrow-dir :right

View file

@ -9,8 +9,8 @@
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.main.refs :as refs]
[app.util.path.format :as upf]
[app.util.object :as obj]
[app.util.path.format :as upf]
[clojure.set :as set]
[rumext.alpha :as mf]
[rumext.util :refer [map->obj]]))
@ -29,7 +29,7 @@
(mf/deps shape)
#(when path? (upf/format-path (:content shape))))
{:keys [id x y width height selrect]} shape
{:keys [x y width height selrect]} shape
outline-type (case (:type shape)
:circle "ellipse"

View file

@ -7,9 +7,7 @@
(ns app.main.ui.workspace.viewport.path-actions
(:require
[app.main.data.workspace.path :as drp]
[app.main.data.workspace.path.helpers :as wph]
[app.main.data.workspace.path.shortcuts :as sc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.main.ui.workspace.shapes.path.common :as pc]
@ -20,8 +18,8 @@
(defn check-enabled [content selected-points]
(let [segments (upt/get-segments content selected-points)
num-points (count selected-points)
points-selected? (not (empty? selected-points))
segments-selected? (not (empty? segments))]
points-selected? (seq selected-points)
segments-selected? (seq segments)]
{:make-corner points-selected?
:make-curve points-selected?
:add-node segments-selected?
@ -31,8 +29,7 @@
:separate-nodes segments-selected?}))
(mf/defc path-actions [{:keys [shape]}]
(let [id (mf/deref refs/selected-edition)
{:keys [edit-mode selected-points snap-toggled] :as all} (mf/deref pc/current-edit-path-ref)
(let [{:keys [edit-mode selected-points snap-toggled] :as all} (mf/deref pc/current-edit-path-ref)
content (:content shape)
enabled-buttons
@ -42,66 +39,66 @@
on-select-draw-mode
(mf/use-callback
(fn [event]
(fn [_]
(st/emit! (drp/change-edit-mode :draw))))
on-select-edit-mode
(mf/use-callback
(fn [event]
(fn [_]
(st/emit! (drp/change-edit-mode :move))))
on-add-node
(mf/use-callback
(mf/deps (:add-node enabled-buttons))
(fn [event]
(fn [_]
(when (:add-node enabled-buttons)
(st/emit! (drp/add-node)))))
on-remove-node
(mf/use-callback
(mf/deps (:remove-node enabled-buttons))
(fn [event]
(fn [_]
(when (:remove-node enabled-buttons)
(st/emit! (drp/remove-node)))))
on-merge-nodes
(mf/use-callback
(mf/deps (:merge-nodes enabled-buttons))
(fn [event]
(fn [_]
(when (:merge-nodes enabled-buttons)
(st/emit! (drp/merge-nodes)))))
on-join-nodes
(mf/use-callback
(mf/deps (:join-nodes enabled-buttons))
(fn [event]
(fn [_]
(when (:join-nodes enabled-buttons)
(st/emit! (drp/join-nodes)))))
on-separate-nodes
(mf/use-callback
(mf/deps (:separate-nodes enabled-buttons))
(fn [event]
(fn [_]
(when (:separate-nodes enabled-buttons)
(st/emit! (drp/separate-nodes)))))
on-make-corner
(mf/use-callback
(mf/deps (:make-corner enabled-buttons))
(fn [event]
(fn [_]
(when (:make-corner enabled-buttons)
(st/emit! (drp/make-corner)))))
on-make-curve
(mf/use-callback
(mf/deps (:make-curve enabled-buttons))
(fn [event]
(fn [_]
(when (:make-curve enabled-buttons)
(st/emit! (drp/make-curve)))))
on-toggle-snap
(mf/use-callback
(fn [event]
(fn [_]
(st/emit! (drp/toggle-snap))))
]
@ -121,7 +118,7 @@
:alt (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:on-click on-select-edit-mode}
i/pointer-inner]]
[:div.viewport-actions-group
;; Add Node
[:div.viewport-actions-entry.tooltip.tooltip-bottom

View file

@ -7,21 +7,18 @@
(ns app.main.ui.workspace.viewport.pixel-overlay
(:require
[app.common.uuid :as uuid]
[app.main.data.workspace.colors :as dwc]
[app.main.data.modal :as modal]
[app.main.data.workspace.colors :as dwc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as muc]
[app.main.ui.cursors :as cur]
[app.main.ui.workspace.shapes :refer [shape-wrapper frame-wrapper]]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[app.util.timers :as timers]
[beicon.core :as rx]
[cuerdas.core :as str]
[goog.events :as events]
[okulary.core :as l]
[promesa.core :as p]
[rumext.alpha :as mf])
(:import goog.events.EventType))
@ -54,11 +51,8 @@
{::mf/wrap-props false}
[props]
(let [vport (unchecked-get props "vport")
vbox (unchecked-get props "vbox")
viewport-ref (unchecked-get props "viewport-ref")
viewport-node (mf/ref-val viewport-ref)
options (unchecked-get props "options")
svg-ref (mf/use-ref nil)
canvas-ref (mf/use-ref nil)
img-ref (mf/use-ref nil)
@ -67,11 +61,11 @@
handle-keydown
(mf/use-callback
(fn [event]
(when (and (kbd/esc? event))
(do (dom/stop-propagation event)
(dom/prevent-default event)
(st/emit! (dwc/stop-picker))
(modal/disallow-click-outside!)))))
(when (kbd/esc? event)
(dom/stop-propagation event)
(dom/prevent-default event)
(st/emit! (dwc/stop-picker))
(modal/disallow-click-outside!))))
handle-mouse-move-picker
(mf/use-callback

View file

@ -10,23 +10,15 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.math :as mth]
[app.common.uuid :as uuid]
[app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.streams :as ms]
[app.main.ui.cursors :as cur]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
[app.util.data :as d]
[app.util.debug :refer [debug?]]
[app.util.dom :as dom]
[app.util.object :as obj]
[beicon.core :as rx]
[cuerdas.core :as str]
[potok.core :as ptk]
[rumext.alpha :as mf]
[rumext.util :refer [map->obj]]))
@ -178,17 +170,12 @@
:cursor cursor}
:on-mouse-down #(on-resize {:x cx' :y cy'} %)}])
(let [rot-square (case position
:top-left 0
:top-right 90
:bottom-right 180
:bottom-left 270)]
[:circle {:on-mouse-down #(on-resize {:x cx' :y cy'} %)
:r (/ resize-point-circle-radius zoom)
:cx cx'
:cy cy'
:style {:fill (if (debug? :resize-handler) "red" "none")
:cursor cursor}}])
[:circle {:on-mouse-down #(on-resize {:x cx' :y cy'} %)
:r (/ resize-point-circle-radius zoom)
:cx cx'
:cy cy'
:style {:fill (if (debug? :resize-handler) "red" "none")
:cursor cursor}}]
)]))
(mf/defc resize-side-handler
@ -232,7 +219,7 @@
(mf/defc controls
{::mf/wrap-props false}
[props]
(let [{:keys [overflow-text type] :as shape} (obj/get props "shape")
(let [{:keys [overflow-text] :as shape} (obj/get props "shape")
zoom (obj/get props "zoom")
color (obj/get props "color")
on-move-selected (obj/get props "on-move-selected")
@ -275,7 +262,7 @@
;; TODO: add specs for clarity
(mf/defc text-edition-selection-handlers
[{:keys [shape zoom color] :as props}]
[{:keys [shape color] :as props}]
(let [{:keys [x y width height]} shape]
[:g.controls
[:rect.main {:x x :y y
@ -299,12 +286,6 @@
shape-center (geom/center-shape shape)
hover-id (-> (mf/deref refs/current-hover) first)
hover-id (when-not (d/seek #(= hover-id (:id %)) shapes) hover-id)
hover-shape (mf/deref (refs/object-by-id hover-id))
vbox (mf/deref refs/vbox)
on-resize (fn [current-position initial-position event]
(dom/stop-propagation event)
(st/emit! (dw/start-resize current-position initial-position selected shape)))
@ -329,14 +310,6 @@
(let [shape-id (:id shape)
shape (geom/transform-shape shape {:round-coords? false})
frame (mf/deref (refs/object-by-id (:frame-id shape)))
frame (when-not (= (:id frame) uuid/zero) frame)
vbox (mf/deref refs/vbox)
hover-id (-> (mf/deref refs/current-hover) first)
hover-id (when-not (= shape-id hover-id) hover-id)
hover-shape (mf/deref (refs/object-by-id hover-id))
shape' (if (debug? :simple-selection) (geom/setup {:type :rect} (geom/selection-rect [shape])) shape)
on-resize (fn [current-position initial-position event]
(dom/stop-propagation event)
@ -357,7 +330,7 @@
{::mf/wrap [mf/memo]}
[{:keys [shapes selected edition zoom disable-handlers on-move-selected] :as props}]
(let [num (count shapes)
{:keys [id type] :as shape} (first shapes)
{:keys [type] :as shape} (first shapes)
color (if (or (> num 1) (nil? (:shape-ref shape)))
selection-rect-color-normal

View file

@ -7,15 +7,11 @@
(ns app.main.ui.workspace.viewport.snap-distances
(:require
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.uuid :as uuid]
[app.main.refs :as refs]
[app.main.snap :as snap]
[app.main.worker :as uw]
[app.util.geom.snap-points :as sp]
[beicon.core :as rx]
[clojure.set :as set]
[cuerdas.core :as str]
@ -275,21 +271,20 @@
update-shape (fn [shape] (-> shape
(update :modifiers merge (:modifiers local))
gsh/transform-shape))]
(let [selrect (->> selected-shapes (map update-shape) gsh/selection-rect)
key (->> selected (map str) (str/join "-"))]
[:g.distance
[:& shape-distance
{:selrect selrect
:page-id page-id
:frame frame
:zoom zoom
:coord :x
:selected selected}]
[:& shape-distance
{:selrect selrect
:page-id page-id
:frame frame
:zoom zoom
:coord :y
:selected selected}]])))
gsh/transform-shape))
selrect (->> selected-shapes (map update-shape) gsh/selection-rect)]
[:g.distance
[:& shape-distance
{:selrect selrect
:page-id page-id
:frame frame
:zoom zoom
:coord :x
:selected selected}]
[:& shape-distance
{:selrect selrect
:page-id page-id
:frame frame
:zoom zoom
:coord :y
:selected selected}]]))

View file

@ -6,12 +6,10 @@
(ns app.main.ui.workspace.viewport.snap-points
(:require
[app.common.pages :as cp]
[app.common.math :as mth]
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.main.refs :as refs]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.main.snap :as snap]
[app.util.geom.snap-points :as sp]
[beicon.core :as rx]
@ -106,7 +104,7 @@
(hash-map coord fixedv (flip coord) maxv)]))))
(mf/defc snap-feedback
[{:keys [shapes page-id filter-shapes zoom modifiers] :as props}]
[{:keys [shapes filter-shapes zoom modifiers] :as props}]
(let [state (mf/use-state [])
subject (mf/use-memo #(rx/subject))

View file

@ -6,14 +6,14 @@
(ns app.main.ui.workspace.viewport.utils
(:require
[app.util.dom :as dom]
[app.common.geom.point :as gpt]
[cuerdas.core :as str]
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.main.ui.cursors :as cur]
))
[app.util.dom :as dom]
[cuerdas.core :as str]))
(defn update-transform [node shapes modifiers]
;; TODO: looks like first argument is not necessary.
(defn update-transform [_node shapes modifiers]
(doseq [{:keys [id type]} shapes]
(let [shape-node (dom/get-element (str "shape-" id))
@ -30,7 +30,8 @@
shape-node)]
(dom/set-attribute node "transform" (str (:displacement modifiers)))))))
(defn remove-transform [node shapes]
;; TODO: looks like first argument is not necessary.
(defn remove-transform [_node shapes]
(doseq [{:keys [id type]} shapes]
(when-let [node (dom/get-element (str "shape-" id))]
(let [node (if (= :frame type) (.-parentNode node) node)]

View file

@ -16,7 +16,6 @@
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
[app.util.dom :as dom]
[app.util.object :as obj]
[rumext.alpha :as mf]))
(mf/defc pixel-grid
@ -110,13 +109,13 @@
on-pointer-enter
(mf/use-callback
(mf/deps (:id frame) on-frame-enter)
(fn [event]
(fn [_]
(on-frame-enter (:id frame))))
on-pointer-leave
(mf/use-callback
(mf/deps (:id frame) on-frame-leave)
(fn [event]
(fn [_]
(on-frame-leave (:id frame))))]
[:text {:x 0

View file

@ -8,7 +8,6 @@
(:require
[app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.shapes :as gsh]
[app.common.geom.point :as gpt]
[app.common.uuid :as uuid]
[app.util.color :as uc]

View file

@ -7,7 +7,6 @@
(ns app.worker.impl
(:require
[app.common.pages.changes :as ch]
[app.common.transit :as t]
[okulary.core :as l]))
(enable-console-print!)

View file

@ -6,17 +6,14 @@
(ns app.worker.selection
(:require
[cljs.spec.alpha :as s]
[okulary.core :as l]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.spec :as us]
[app.common.uuid :as uuid]
[app.util.quadtree :as qdt]
[app.worker.impl :as impl]
[clojure.set :as set]))
[clojure.set :as set]
[okulary.core :as l]))
(defonce state (l/atom {}))
@ -66,8 +63,8 @@
changed-ids (into #{}
(comp (filter changes?)
(filter #(not= % uuid/zero)))
(set/union (keys old-objects)
(keys new-objects)))
(set/union (set (keys old-objects))
(set (keys new-objects))))
shapes (->> changed-ids (mapv #(get new-objects %)) (filterv (comp not nil?)))
parents-index (cp/generate-child-all-parents-index new-objects shapes)
@ -87,7 +84,7 @@
(create-index new-objects)))
(defn- query-index
[{index :index z-index :z-index} rect frame-id include-frames? include-groups? disabled-masks reverse?]
[{index :index z-index :z-index} rect frame-id include-frames? include-groups? reverse?]
(let [result (-> (qdt/search index (clj->js rect))
(es6-iterator-seq))
@ -137,7 +134,7 @@
(defmethod impl/handler :selection/initialize-index
[{:keys [file-id data] :as message}]
[{:keys [data] :as message}]
(letfn [(index-page [state page]
(let [id (:id page)
objects (:objects page)]
@ -154,10 +151,10 @@
nil)
(defmethod impl/handler :selection/query
[{:keys [page-id rect frame-id include-frames? include-groups? disabled-masks reverse?]
:or {include-groups? true disabled-masks #{} reverse? false} :as message}]
[{:keys [page-id rect frame-id include-frames? include-groups? reverse?]
:or {include-groups? true reverse? false} :as message}]
(when-let [index (get @state page-id)]
(query-index index rect frame-id include-frames? include-groups? disabled-masks reverse?)))
(query-index index rect frame-id include-frames? include-groups? reverse?)))
(defmethod impl/handler :selection/query-z-index
[{:keys [page-id objects ids]}]

View file

@ -7,7 +7,6 @@
(ns app.worker.snaps
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.uuid :as uuid]
[app.util.geom.grid :as gg]
[app.util.geom.snap-points :as snap]
@ -99,7 +98,8 @@
changed-ids (into #{}
(filter changed?)
(set/union (keys old-objects) (keys new-objects)))
(set/union (set (keys old-objects))
(set (keys new-objects))))
to-delete (aggregate-data old-objects changed-ids)
to-add (aggregate-data new-objects changed-ids)
@ -134,30 +134,25 @@
(reduce add-data $ to-add)
(reduce delete-frames $ frames-to-delete))))
(defn- log-state
"Helper function to print a friendly version of the snap tree. Debugging purposes"
[]
(let [process-frame-data #(d/mapm rt/as-map %)
process-page-data #(d/mapm process-frame-data %)]
(js/console.log "STATE" (clj->js (d/mapm process-page-data @state)))))
;; (defn- log-state
;; "Helper function to print a friendly version of the snap tree. Debugging purposes"
;; []
;; (let [process-frame-data #(d/mapm rt/as-map %)
;; process-page-data #(d/mapm process-frame-data %)]
;; (js/console.log "STATE" (clj->js (d/mapm process-page-data @state)))))
(defn- index-page [state page-id objects]
(let [snap-data (initialize-snap-data objects)]
(assoc state page-id snap-data)))
(defn- update-page [state page-id old-objects new-objects]
(let [changed? #(not= (get old-objects %) (get new-objects %))
changed-ids (into #{}
(filter changed?)
(set/union (keys old-objects) (keys new-objects)))
snap-data (get state page-id)
(let [snap-data (get state page-id)
snap-data (update-snap-data snap-data old-objects new-objects)]
(assoc state page-id snap-data)))
;; Public API
(defmethod impl/handler :snaps/initialize-index
[{:keys [file-id data] :as message}]
[{:keys [data] :as message}]
;; Create the index
(letfn [(process-page [state page]
(let [id (:id page)

View file

@ -6,14 +6,13 @@
(ns app.worker.thumbnails
(:require
[rumext.alpha :as mf]
[beicon.core :as rx]
[promesa.core :as p]
[app.main.fonts :as fonts]
["react-dom/server" :as rds]
[app.main.exports :as exports]
[app.worker.impl :as impl]
[app.main.fonts :as fonts]
[app.util.http :as http]
["react-dom/server" :as rds]))
[app.worker.impl :as impl]
[beicon.core :as rx]
[rumext.alpha :as mf]))
(defn- handle-response
[response]