From 57c93f80e28b6cdf6b6b8e025cfec2fee2cdf4ff Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 16 Oct 2020 11:40:49 +0200 Subject: [PATCH] :sparkles: Reusable shape container refactor --- frontend/src/app/main/exports.cljs | 46 +++++------- frontend/src/app/main/ui/shapes/shape.cljs | 30 +++++++- frontend/src/app/main/ui/viewer/shapes.cljs | 45 +++++------ .../app/main/ui/workspace/shapes/common.cljs | 22 ++---- .../app/main/ui/workspace/shapes/frame.cljs | 23 ++---- .../app/main/ui/workspace/shapes/path.cljs | 38 ++++------ .../app/main/ui/workspace/shapes/text.cljs | 74 +++++++++---------- 7 files changed, 123 insertions(+), 155 deletions(-) diff --git a/frontend/src/app/main/exports.cljs b/frontend/src/app/main/exports.cljs index c495b3766..7146814df 100644 --- a/frontend/src/app/main/exports.cljs +++ b/frontend/src/app/main/exports.cljs @@ -27,8 +27,7 @@ [app.main.ui.shapes.rect :as rect] [app.main.ui.shapes.text :as text] [app.main.ui.shapes.group :as group] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.context :as muc])) + [app.main.ui.shapes.shape :refer [shape-container]])) (def ^:private default-color "#E8E9EA") ;; $color-canvas @@ -57,14 +56,9 @@ (mf/fnc frame-wrapper [{:keys [shape] :as props}] (let [childs (mapv #(get objects %) (:shapes shape)) - shape (geom/transform-shape shape) - render-id (mf/use-memo #(str (uuid/next)))] - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.frame - [:defs - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - [:& frame-shape {:shape shape :childs childs}]]])))) + shape (geom/transform-shape shape)] + [:> shape-container {:shape shape} + [:& frame-shape {:shape shape :childs childs}]])))) (defn group-wrapper-factory [objects] @@ -86,25 +80,19 @@ frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))] (when (and shape (not (:hidden shape))) (let [shape (geom/transform-shape frame shape) - opts #js {:shape shape} - render-id (mf/use-memo #(str (uuid/next)))] - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g {:filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - (case (:type shape) - :curve [:> path/path-shape opts] - :text [:> text/text-shape opts] - :icon [:> icon/icon-shape opts] - :rect [:> rect/rect-shape opts] - :path [:> path/path-shape opts] - :image [:> image/image-shape opts] - :circle [:> circle/circle-shape opts] - :frame [:> frame-wrapper {:shape shape}] - :group [:> group-wrapper {:shape shape :frame frame}] - nil)]]))))) + opts #js {:shape shape}] + [:> shape-container {:shape shape} + (case (:type shape) + :curve [:> path/path-shape opts] + :text [:> text/text-shape opts] + :icon [:> icon/icon-shape opts] + :rect [:> rect/rect-shape opts] + :path [:> path/path-shape opts] + :image [:> image/image-shape opts] + :circle [:> circle/circle-shape opts] + :frame [:> frame-wrapper {:shape shape}] + :group [:> group-wrapper {:shape shape :frame frame}] + nil)]))))) (mf/defc page-svg {::mf/wrap [mf/memo]} diff --git a/frontend/src/app/main/ui/shapes/shape.cljs b/frontend/src/app/main/ui/shapes/shape.cljs index a4202b844..0567c1074 100644 --- a/frontend/src/app/main/ui/shapes/shape.cljs +++ b/frontend/src/app/main/ui/shapes/shape.cljs @@ -7,5 +7,33 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.shapes.shape) +(ns app.main.ui.shapes.shape + (:require + [rumext.alpha :as mf] + [app.util.object :as obj] + [app.common.uuid :as uuid] + [app.main.ui.shapes.filters :as filters] + [app.main.ui.shapes.gradients :as grad] + [app.main.ui.context :as muc])) +(mf/defc shape-container + {::mf/wrap-props false} + [props] + + (let [shape (unchecked-get props "shape") + children (unchecked-get props "children") + render-id (mf/use-memo #(str (uuid/next))) + filter-id (str "filter_" render-id) + group-props (-> props + (obj/clone) + (obj/without ["shape" "children"]) + (obj/set! "className" "shape") + (obj/set! "filter" (filters/filter-str filter-id shape)))] + [:& (mf/provider muc/render-ctx) {:value render-id} + [:> :g group-props + [:defs + [:& filters/filters {:shape shape :filter-id filter-id}] + [:& grad/gradient {:shape shape :attr :fill-color-gradient}] + [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] + + children]])) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index ceaa0f7b1..7ceb6166c 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -30,9 +30,7 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as geom] - [app.common.uuid :as uuid] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.context :as muc])) + [app.main.ui.shapes.shape :refer [shape-container]])) (defn on-mouse-down [event {:keys [interactions] :as shape}] @@ -57,31 +55,24 @@ on-mouse-down (mf/use-callback (mf/deps shape) - #(on-mouse-down % shape)) + #(on-mouse-down % shape))] - render-id (mf/use-memo #(str (uuid/next)))] - - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.shape {:on-mouse-down on-mouse-down - :cursor (when (:interactions shape) "pointer") - :filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - [:& component {:shape shape - :frame frame - :childs childs - :is-child-selected? true}] - (when (and (:interactions shape) show-interactions?) - [:rect {:x (- x 1) - :y (- y 1) - :width (+ width 2) - :height (+ height 2) - :fill "#31EFB8" - :stroke "#31EFB8" - :stroke-width 1 - :fill-opacity 0.2}])]]))) + [:> shape-container {:shape shape + :on-mouse-down on-mouse-down + :cursor (when (:interactions shape) "pointer")} + [:& component {:shape shape + :frame frame + :childs childs + :is-child-selected? true}] + (when (and (:interactions shape) show-interactions?) + [:rect {:x (- x 1) + :y (- y 1) + :width (+ width 2) + :height (+ height 2) + :fill "#31EFB8" + :stroke "#31EFB8" + :stroke-width 1 + :fill-opacity 0.2}])]))) (defn frame-wrapper [shape-container show-interactions?] diff --git a/frontend/src/app/main/ui/workspace/shapes/common.cljs b/frontend/src/app/main/ui/workspace/shapes/common.cljs index 698b4a642..302c0cf48 100644 --- a/frontend/src/app/main/ui/workspace/shapes/common.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/common.cljs @@ -14,14 +14,11 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.keyboard :as kbd] - [app.main.ui.shapes.filters :as filters] - [app.main.ui.shapes.gradients :as grad] [app.util.dom :as dom] - [app.common.uuid :as uuid] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as geom] - [app.main.ui.context :as muc])) + [app.main.ui.shapes.shape :refer [shape-container]])) (defn- on-mouse-down [event {:keys [id type] :as shape}] @@ -73,18 +70,11 @@ #(on-mouse-down % shape)) on-context-menu (mf/use-callback (mf/deps shape) - #(on-context-menu % shape)) - render-id (mf/use-memo #(str (uuid/next)))] + #(on-context-menu % shape))] - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.shape {:on-mouse-down on-mouse-down - :on-context-menu on-context-menu - :filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - - [:& component {:shape shape}]]]))) + [:> shape-container {:shape shape + :on-mouse-down on-mouse-down + :on-context-menu on-context-menu} + [:& component {:shape shape}]]))) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index 18086d3ad..d72bc71ca 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -19,16 +19,13 @@ [app.main.ui.workspace.shapes.common :as common] [app.main.data.workspace.selection :as dws] [app.main.ui.shapes.frame :as frame] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.shapes.filters :as filters] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as geom] [app.util.dom :as dom] [app.main.streams :as ms] [app.util.timers :as ts] - [app.main.ui.context :as muc] - [app.common.uuid :as uuid])) + [app.main.ui.shapes.shape :refer [shape-container]])) (defn- frame-wrapper-factory-equals? [np op] @@ -115,9 +112,7 @@ (mf/use-callback (mf/deps (:id shape)) (fn [] - (st/emit! (dws/change-hover-state (:id shape) false)))) - - render-id (mf/use-memo #(str (uuid/next)))] + (st/emit! (dws/change-hover-state (:id shape) false))))] (when-not (:hidden shape) [:g {:class (when selected? "selected") @@ -130,14 +125,8 @@ :on-double-click on-double-click :on-mouse-down on-mouse-down}] - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.frame {:filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - - [:& frame-shape - {:shape shape - :childs children}]]]]))))) + [:> shape-container {:shape shape} + [:& frame-shape + {:shape shape + :childs children}]]]))))) diff --git a/frontend/src/app/main/ui/workspace/shapes/path.cljs b/frontend/src/app/main/ui/workspace/shapes/path.cljs index 125b9f237..81fd43816 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path.cljs @@ -11,22 +11,19 @@ (:require [rumext.alpha :as mf] [app.common.data :as d] + [app.util.dom :as dom] + [app.util.timers :as ts] + [app.main.streams :as ms] [app.main.constants :as c] - [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] + [app.main.data.workspace :as dw] + [app.main.data.workspace.drawing :as dr] [app.main.ui.keyboard :as kbd] [app.main.ui.shapes.path :as path] [app.main.ui.shapes.filters :as filters] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.workspace.shapes.common :as common] - [app.main.data.workspace.drawing :as dr] - [app.util.dom :as dom] - [app.main.streams :as ms] - [app.util.timers :as ts] - [app.common.uuid :as uuid] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.context :as muc])) + [app.main.ui.shapes.shape :refer [shape-container]] + [app.main.ui.workspace.shapes.common :as common])) (mf/defc path-wrapper {::mf/wrap-props false} @@ -46,20 +43,13 @@ (do (dom/stop-propagation event) (dom/prevent-default event) - (st/emit! (dw/start-edition-mode (:id shape))))))) + (st/emit! (dw/start-edition-mode (:id shape)))))))] - render-id (mf/use-memo #(str (uuid/next)))] + [:> shape-container {:shape shape + :on-double-click on-double-click + :on-mouse-down on-mouse-down + :on-context-menu on-context-menu} - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.shape {:on-double-click on-double-click - :on-mouse-down on-mouse-down - :on-context-menu on-context-menu - :filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - - [:& path/path-shape {:shape shape - :background? true}]]])) + [:& path/path-shape {:shape shape + :background? true}]])) diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index f93dae4b7..1fccaefdd 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -9,35 +9,34 @@ (ns app.main.ui.workspace.shapes.text (:require - [cuerdas.core :as str] + ["slate" :as slate] + ["slate-react" :as rslate] [goog.events :as events] [goog.object :as gobj] + [cuerdas.core :as str] [rumext.alpha :as mf] + [beicon.core :as rx] + [app.util.color :as color] + [app.util.dom :as dom] + [app.util.text :as ut] + [app.util.object :as obj] + [app.util.color :as uc] + [app.util.timers :as timers] [app.common.data :as d] + [app.common.geom.shapes :as geom] + [app.main.refs :as refs] + [app.main.store :as st] + [app.main.fonts :as fonts] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.texts :as dwt] - [app.main.refs :as refs] - [app.main.store :as st] [app.main.ui.cursors :as cur] [app.main.ui.workspace.shapes.common :as common] [app.main.ui.shapes.text :as text] [app.main.ui.keyboard :as kbd] [app.main.ui.context :as muc] [app.main.ui.shapes.filters :as filters] - [app.main.fonts :as fonts] - [app.util.color :as color] - [app.util.dom :as dom] - [app.util.text :as ut] - [app.common.geom.shapes :as geom] - [app.util.object :as obj] - [app.util.color :as uc] - [app.util.timers :as timers] - ["slate" :as slate] - ["slate-react" :as rslate] - [app.common.uuid :as uuid] - [app.main.ui.shapes.gradients :as grad] - [app.main.ui.context :as muc]) + [app.main.ui.shapes.shape :refer [shape-container]]) (:import goog.events.EventType goog.events.KeyCodes)) @@ -81,9 +80,7 @@ (dom/stop-propagation event) (dom/prevent-default event) (when selected? - (st/emit! (dw/start-edition-mode (:id shape))))) - - render-id (mf/use-memo #(str (uuid/next)))] + (st/emit! (dw/start-edition-mode (:id shape)))))] (mf/use-effect (mf/deps shape edition selected? current-transform) @@ -91,30 +88,25 @@ selected? (not edition?) (not embed-resources?) - (nil? current-transform))] - (timers/schedule #(reset! render-editor check?))))) + (nil? current-transform)) + result (timers/schedule #(reset! render-editor check?))] + #(rx/dispose! result)))) - [:& (mf/provider muc/render-ctx) {:value render-id} - [:g.shape {:on-double-click on-double-click - :on-mouse-down on-mouse-down - :on-context-menu on-context-menu - :filter (filters/filter-str (str "filter_" render-id) shape)} - [:defs - [:& filters/filters {:shape shape}] - [:& grad/gradient {:shape shape :attr :fill-color-gradient}] - [:& grad/gradient {:shape shape :attr :stroke-color-gradient}]] - [:* - (when @render-editor - [:g {:opacity 0 - :style {:pointer-events "none"}} - ;; We only render the component for its side-effect - [:& text-shape-edit {:shape shape - :read-only? true}]]) + [:> shape-container {:shape shape + :on-double-click on-double-click + :on-mouse-down on-mouse-down + :on-context-menu on-context-menu} + (when @render-editor + [:g {:opacity 0 + :style {:pointer-events "none"}} + ;; We only render the component for its side-effect + [:& text-shape-edit {:shape shape + :read-only? true}]]) - (if edition? - [:& text-shape-edit {:shape shape}] - [:& text/text-shape {:shape shape - :selected? selected?}])]]])) + (if edition? + [:& text-shape-edit {:shape shape}] + [:& text/text-shape {:shape shape + :selected? selected?}])])) ;; --- Text Editor Rendering