From e7b0e253d486cde6cf67b86608a39735ff535c02 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 12:52:49 +0100 Subject: [PATCH 01/13] :sparkles: Use new convention for components for workspace right and left sidebar --- common/src/app/common/logic/libraries.cljc | 1 - frontend/src/app/main/ui/workspace.cljs | 16 ++++++++-------- frontend/src/app/main/ui/workspace/sidebar.cljs | 7 +++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 7faf88d1f..e610eef24 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -79,7 +79,6 @@ [component new-component-id library-data] (let [components-v2 (dm/get-in library-data [:options :components-v2])] (if components-v2 - (let [main-instance-page (ctf/get-component-page library-data component) main-instance-shape (ctf/get-component-root library-data component) delta (gpt/point (+ (:width main-instance-shape) 50) 0) diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index c05a86229..a169ae616 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -29,7 +29,7 @@ [app.main.ui.workspace.nudge] [app.main.ui.workspace.palette :refer [palette]] [app.main.ui.workspace.plugins] - [app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] + [app.main.ui.workspace.sidebar :refer [left-sidebar* right-sidebar*]] [app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button]] [app.main.ui.workspace.sidebar.history :refer [history-toolbox*]] [app.main.ui.workspace.tokens.modals] @@ -111,14 +111,14 @@ [:* (if (:collapse-left-sidebar layout) [:& collapsed-button] - [:& left-sidebar {:layout layout + [:> left-sidebar* {:layout layout + :file file + :page-id page-id}]) + [:> right-sidebar* {:section options-mode + :selected selected + :layout layout :file file - :page-id page-id}]) - [:& right-sidebar {:section options-mode - :selected selected - :layout layout - :file file - :page-id page-id}]])])) + :page-id page-id}]])])) (mf/defc workspace-loader* {::mf/private true} diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index ac00afe8f..3a9584351 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -48,7 +48,7 @@ :size "s" :aria-label (tr "workspace.sidebar.collapse")}]]) -(mf/defc left-sidebar +(mf/defc left-sidebar* {::mf/wrap [mf/memo] ::mf/props :obj} [{:keys [layout file page-id] :as props}] @@ -179,9 +179,8 @@ ;; --- Right Sidebar (Component) -(mf/defc right-sidebar - {::mf/wrap-props false - ::mf/wrap [mf/memo]} +(mf/defc right-sidebar* + {::mf/wrap [mf/memo]} [{:keys [layout section file page-id] :as props}] (let [drawing-tool (:tool (mf/deref refs/workspace-drawing)) From 12fa4fdef54c753970a0c3ba0eb2fafea89142c5 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 13:19:27 +0100 Subject: [PATCH 02/13] :lipstick: Add cosmetic changes to common libraries logic ns --- common/src/app/common/logic/libraries.cljc | 37 ++++++++++++---------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index e610eef24..e5c3e506a 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -204,21 +204,23 @@ (cond-> {} force-frame? (assoc :force-frame-id frame-id))) - first-shape (cond-> (first new-shapes) - (not (nil? parent-id)) - (assoc :parent-id parent-id) - (and (not (nil? parent)) (= :frame (:type parent))) - (assoc :frame-id (:id parent)) - (and (not (nil? parent)) (not= :frame (:type parent))) - (assoc :frame-id (:frame-id parent)) - (and (not (nil? parent)) (ctn/in-any-component? objects parent)) - (dissoc :component-root) - (and (nil? parent) (not (nil? frame-id))) - (assoc :frame-id frame-id)) + first-shape + (cond-> (first new-shapes) + (not (nil? parent-id)) + (assoc :parent-id parent-id) + (and (not (nil? parent)) (= :frame (:type parent))) + (assoc :frame-id (:id parent)) + (and (not (nil? parent)) (not= :frame (:type parent))) + (assoc :frame-id (:frame-id parent)) + (and (not (nil? parent)) (ctn/in-any-component? objects parent)) + (dissoc :component-root) + (and (nil? parent) (not (nil? frame-id))) + (assoc :frame-id frame-id)) ;; on copy/paste old id is used later to reorder the paster layers - changes (cond-> (pcb/add-object changes first-shape {:ignore-touched true}) - (some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id))) + changes + (cond-> (pcb/add-object changes first-shape {:ignore-touched true}) + (some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id))) changes (if (ctl/grid-layout? objects (:parent-id first-shape)) @@ -239,9 +241,10 @@ (pcb/reorder-grid-children [(:parent-id first-shape)]))) changes) - changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true}) - changes - (rest new-shapes))] + changes + (reduce #(pcb/add-object %1 %2 {:ignore-touched true}) + changes + (rest new-shapes))] [new-shape changes]))) @@ -1487,7 +1490,7 @@ (defn- update-tokens "Token synchronization algorithm. Copy the applied tokens that have changed in the origin shape to the dest shape (applying or removing as necessary). - + Only the given token attributes are synced." [changes container dest-shape orig-shape token-attrs] (let [orig-tokens (get orig-shape :applied-tokens {}) From 9b2315d39d9a5e659628910876ef9193779a953f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 13:20:00 +0100 Subject: [PATCH 03/13] :zap: Remove props conversion overhead on shape-options component With using new rumext call convention with :> handler and * on the component name. --- .../main/ui/workspace/sidebar/options.cljs | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index f8fd19e1a..719587374 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -42,14 +42,19 @@ ;; --- Options -(mf/defc shape-options +(mf/defc shape-options* {::mf/wrap [#(mf/throttle % 60)]} [{:keys [shape shapes-with-children page-id file-id shared-libs]}] - (let [workspace-modifiers (mf/deref refs/workspace-modifiers) - modifiers (get-in workspace-modifiers [(:id shape) :modifiers]) - shape (gsh/transform-shape shape modifiers)] + (let [shape-type (dm/get-prop shape :type) + shape-id (dm/get-prop shape :id) + + modifiers (mf/deref refs/workspace-modifiers) + modifiers (dm/get-in modifiers [shape-id :modifiers]) + + shape (gsh/transform-shape shape modifiers)] + [:* - (case (:type shape) + (case shape-type :frame [:& frame/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}] @@ -73,7 +78,7 @@ (when (= (:type panel) :component-swap) [:& component-menu {:shapes (:shapes panel) :swap-opened? true}])) -(mf/defc design-menu +(mf/defc design-menu* {::mf/wrap [mf/memo]} [{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}] (let [sp-panel (mf/deref refs/specialized-panel) @@ -104,7 +109,7 @@ [:& specialized-panel {:panel sp-panel}] (d/not-empty? drawing) - [:& shape-options + [:> shape-options* {:shape (:object drawing) :page-id page-id :file-id file-id @@ -114,7 +119,7 @@ [:& page/options] (= 1 (count selected)) - [:& shape-options + [:> shape-options* {:shape (first selected-shapes) :page-id page-id :file-id file-id @@ -151,12 +156,13 @@ (st/emit! :interrupt (dwc/set-workspace-read-only false))))) design-content - (mf/html [:& design-menu {:selected selected - :objects objects - :page-id page-id - :file-id file-id - :selected-shapes selected-shapes - :shapes-with-children shapes-with-children}]) + (mf/html [:> design-menu* + {:selected selected + :objects objects + :page-id page-id + :file-id file-id + :selected-shapes selected-shapes + :shapes-with-children shapes-with-children}]) inspect-content (mf/html [:div {:class (stl/css :element-options :inspect-options)} From 0b18177925d64e9db881df63aaae4e1779fe465d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 13:50:12 +0100 Subject: [PATCH 04/13] :zap: Add efficiency optimizations to frame options component --- .../main/ui/workspace/sidebar/options.cljs | 4 +- .../sidebar/options/shapes/frame.cljs | 82 +++++++++++-------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 719587374..c5ce31810 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -44,7 +44,7 @@ (mf/defc shape-options* {::mf/wrap [#(mf/throttle % 60)]} - [{:keys [shape shapes-with-children page-id file-id shared-libs]}] + [{:keys [shape shapes-with-children page-id file-id shared-libs] :as props}] (let [shape-type (dm/get-prop shape :type) shape-id (dm/get-prop shape :id) @@ -55,7 +55,7 @@ [:* (case shape-type - :frame [:& frame/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] + :frame [:> frame/options* props] :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}] :rect [:& rect/options {:shape shape}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index 96ba853b6..47c764a9f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -6,10 +6,9 @@ (ns app.main.ui.workspace.sidebar.options.shapes.frame (:require - [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] - [app.main.ui.hooks :as hooks] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]] [app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]] @@ -25,50 +24,63 @@ [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [rumext.v2 :as mf])) -(mf/defc options - [{:keys [shape file-id shape-with-children shared-libs] :as props}] - (let [ids [(:id shape)] - type (:type shape) - objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v)))) - stroke-values (select-keys shape stroke-attrs) - layer-values (select-keys shape layer-attrs) - measure-values (select-measure-keys shape) - constraint-values (select-keys shape constraint-attrs) +(mf/defc options* + [{:keys [shape file-id shapes-with-children shared-libs] :as props}] + (let [shape-id (dm/get-prop shape :id) + shape-type (dm/get-prop shape :type) + + ids (mf/with-memo [shape-id] + [shape-id]) + + stroke-values (select-keys shape stroke-attrs) + layer-values (select-keys shape layer-attrs) + measure-values (select-measure-keys shape) + constraint-values (select-keys shape constraint-attrs) layout-container-values (select-keys shape layout-container-flex-attrs) - layout-item-values (select-keys shape layout-item-attrs) + layout-item-values (select-keys shape layout-item-attrs) - ids (hooks/use-equal-memo ids) + is-layout-child-ref + (mf/with-memo [ids] + (refs/is-layout-child? ids)) + is-layout-child? + (mf/deref is-layout-child-ref) - is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) - is-layout-child? (mf/deref is-layout-child-ref) + is-flex-parent-ref + (mf/with-memo [ids] + (refs/flex-layout-child? ids)) + is-flex-parent? + (mf/deref is-flex-parent-ref) - is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids)) - is-flex-parent? (mf/deref is-flex-parent-ref) + is-grid-parent-ref + (mf/with-memo [ids] + (refs/grid-layout-child? ids)) + is-grid-parent? + (mf/deref is-grid-parent-ref) - is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids)) - is-grid-parent? (mf/deref is-grid-parent-ref) + parents-by-ids-ref + (mf/with-memo [ids] + (refs/parents-by-ids ids)) + parents + (mf/deref parents-by-ids-ref) - is-layout-container? (ctl/any-layout? shape) - is-flex-layout? (ctl/flex-layout? shape) - is-grid-layout? (ctl/grid-layout? shape) - is-layout-child-absolute? (ctl/item-absolute? shape) + is-layout-container? (ctl/any-layout? shape) + is-flex-layout? (ctl/flex-layout? shape) + is-grid-layout? (ctl/grid-layout? shape) + is-layout-child-absolute? (ctl/item-absolute? shape)] - ids (hooks/use-equal-memo ids) - parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids)) - parents (mf/deref parents-by-ids-ref)] [:* [:& layer-menu {:ids ids - :type type + :type shape-type :values layer-values}] - [:& measures-menu {:ids [(:id shape)] + [:& measures-menu {:ids ids :values measure-values - :type type + :type shape-type :shape shape}] [:& component-menu {:shapes [shape]}] [:& layout-container-menu - {:type type + {:type shape-type :ids [(:id shape)] :values layout-container-values :multiple false}] @@ -81,7 +93,7 @@ (when (or is-layout-child? is-layout-container?) [:& layout-item-menu {:ids ids - :type type + :type shape-type :values layout-item-values :is-flex-parent? is-flex-parent? :is-grid-parent? is-grid-parent? @@ -96,13 +108,13 @@ :values constraint-values}]) [:& fill-menu {:ids ids - :type type + :type shape-type :values (select-keys shape fill-attrs-shape)}] [:& stroke-menu {:ids ids - :type type + :type shape-type :values stroke-values}] - [:& color-selection-menu {:type type - :shapes (vals objects) + [:& color-selection-menu {:type shape-type + :shapes shapes-with-children :file-id file-id :shared-libs shared-libs}] [:& shadow-menu {:ids ids From ef7fbc09b0833cec1147a6e7395c951d3ae06297 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 14:35:53 +0100 Subject: [PATCH 05/13] :sparkles: Add minor optimization to type->options resolution on measures-menu --- .../sidebar/options/menus/measures.cljs | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index c23bc4307..2e00b5bf9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -33,7 +33,7 @@ [app.main.ui.workspace.tokens.token-types :as wtty] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] - [clojure.set :refer [rename-keys union]] + [clojure.set :as set] [rumext.v2 :as mf])) (def measure-attrs @@ -48,16 +48,27 @@ :show-content :hide-in-viewer]) -(def ^:private type->options - {:bool #{:size :position :rotation} - :circle #{:size :position :rotation} - :frame #{:presets :size :position :rotation :radius :clip-content :show-in-viewer} - :group #{:size :position :rotation} - :image #{:size :position :rotation :radius} - :path #{:size :position :rotation} - :rect #{:size :position :rotation :radius} - :svg-raw #{:size :position :rotation} - :text #{:size :position :rotation}}) +(def ^:private generic-options + #{:size :position :rotation}) + +(def ^:private rect-options + #{:size :position :rotation :radius}) + +(def ^:private frame-options + #{:presets :size :position :rotation :radius :clip-content :show-in-viewer}) + +(defn- type->options + [type] + (case type + :bool generic-options + :circle generic-options + :frame frame-options + :group generic-options + :image rect-options + :path generic-options + :rect rect-options + :svg-raw generic-options + :text generic-options)) (def ^:private clip-content-icon (i/icon-xref :clip-content (stl/css :checkbox-button))) (def ^:private play-icon (i/icon-xref :play (stl/css :checkbox-button))) @@ -67,37 +78,45 @@ (defn select-measure-keys "Consider some shapes can be drawn from bottom to top or from left to right" [shape] - (let [shape (cond - (and (:flip-x shape) (:flip-y shape)) - (rename-keys shape {:r1 :r3 :r2 :r4 :r3 :r1 :r4 :r2}) + (let [flip-x (get shape :flip-x) + flip-y (get shape :flip-y) - (:flip-x shape) - (rename-keys shape {:r1 :r2 :r2 :r1 :r3 :r4 :r4 :r3}) + shape (cond + (and flip-x flip-y) + (set/rename-keys shape {:r1 :r3 :r2 :r4 :r3 :r1 :r4 :r2}) - (:flip-y shape) - (rename-keys shape {:r1 :r4 :r2 :r3 :r3 :r2 :r4 :r1}) + flip-x + (set/rename-keys shape {:r1 :r2 :r2 :r1 :r3 :r4 :r4 :r3}) - :else - shape)] + flip-y + (set/rename-keys shape {:r1 :r4 :r2 :r3 :r3 :r2 :r4 :r1}) + + :else + shape)] (select-keys shape measure-attrs))) -;; -- User/drawing coords (mf/defc measures-menu - {::mf/wrap-props false + {::mf/props :obj ::mf/wrap [mf/memo]} [{:keys [ids ids-with-children values type all-types shape]}] - (let [options (if (= type :multiple) - (reduce #(union %1 %2) (map #(get type->options %) all-types)) - (get type->options type)) + (let [design-tokens? (mf/use-ctx muc/design-tokens) - design-tokens? (mf/use-ctx muc/design-tokens) + options + (mf/with-memo [type all-types] + (if (= type :multiple) + (into #{} (mapcat type->options) all-types) + (type->options type))) - ids-with-children (or ids-with-children ids) + ids-with-children + (or ids-with-children ids) - old-shapes (if (= type :multiple) - (deref (refs/objects-by-id ids)) - [shape]) - frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes) + old-shapes + (if (= type :multiple) + (deref (refs/objects-by-id ids)) + [shape]) + + frames + (map #(deref (refs/object-by-id (:frame-id %))) old-shapes) ids (hooks/use-equal-memo ids) From 6b3f70e94b4b8e900c0d41b893f5ed7581db3925 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 14:52:09 +0100 Subject: [PATCH 06/13] :zap: Remove props conversion overhead from measures-menu component --- .../ui/workspace/sidebar/options/menus/measures.cljs | 2 +- .../main/ui/workspace/sidebar/options/shapes/bool.cljs | 10 +++++----- .../ui/workspace/sidebar/options/shapes/circle.cljs | 10 +++++----- .../ui/workspace/sidebar/options/shapes/frame.cljs | 10 +++++----- .../ui/workspace/sidebar/options/shapes/group.cljs | 4 ++-- .../ui/workspace/sidebar/options/shapes/image.cljs | 10 +++++----- .../ui/workspace/sidebar/options/shapes/multiple.cljs | 4 ++-- .../main/ui/workspace/sidebar/options/shapes/path.cljs | 10 +++++----- .../main/ui/workspace/sidebar/options/shapes/rect.cljs | 10 +++++----- .../ui/workspace/sidebar/options/shapes/svg_raw.cljs | 10 +++++----- .../main/ui/workspace/sidebar/options/shapes/text.cljs | 4 ++-- 11 files changed, 42 insertions(+), 42 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 2e00b5bf9..2326b30e2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -95,7 +95,7 @@ shape)] (select-keys shape measure-attrs))) -(mf/defc measures-menu +(mf/defc measures-menu* {::mf/props :obj ::mf/wrap [mf/memo]} [{:keys [ids ids-with-children values type all-types shape]}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs index 4cf2ef29f..dba8089ca 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs @@ -16,7 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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]] [rumext.v2 :as mf])) @@ -51,10 +51,10 @@ :type type :values layer-values}] - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs index 6bc6394b4..450cc5dae 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs @@ -16,7 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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]] @@ -53,10 +53,10 @@ :type type :values layer-values}] - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index 47c764a9f..a675d1ec9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -19,7 +19,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys 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]] [rumext.v2 :as mf])) @@ -72,10 +72,10 @@ [:& layer-menu {:ids ids :type shape-type :values layer-values}] - [:& measures-menu {:ids ids - :values measure-values - :type shape-type - :shape shape}] + [:> measures-menu* {:ids ids + :values measure-values + :type shape-type + :shape shape}] [:& component-menu {:shapes [shape]}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs index f605ac544..b95408270 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs @@ -20,7 +20,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-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.svg-attrs :refer [svg-attrs-menu]] @@ -69,7 +69,7 @@ [:div {:class (stl/css :options)} [:& layer-menu {:type type :ids layer-ids :values layer-values}] - [:& measures-menu {:type type :ids measure-ids :values measure-values :shape shape}] + [:> measures-menu* {:type type :ids measure-ids :values measure-values :shape shape}] [:& component-menu {:shapes [shape]}] ;;remove this in components-v2 [:& layout-container-menu diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs index a05e46575..8f506ab21 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs @@ -16,7 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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]] [rumext.v2 :as mf])) @@ -53,10 +53,10 @@ :type type :values layer-values}] - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index b96c8b454..c57025a71 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -25,7 +25,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu*]] [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.text :as ot] @@ -359,7 +359,7 @@ [:& layer-menu {:type type :ids layer-ids :values layer-values}]) (when-not (empty? measure-ids) - [:& measures-menu {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}]) + [:> measures-menu* {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}]) (when-not (empty? components) [:& component-menu {:shapes components}]) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs index db0aba009..78c708277 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs @@ -16,7 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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]] @@ -52,10 +52,10 @@ [:& layer-menu {:ids ids :type type :values layer-values}] - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs index b7406ddca..d543291db 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs @@ -16,7 +16,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys 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]] @@ -55,10 +55,10 @@ [:& layer-menu {:ids ids :type type :values layer-values}] - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs index bf13cf76c..d540cb2d5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs @@ -17,7 +17,7 @@ [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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]] @@ -124,10 +124,10 @@ (when (contains? svg-elements tag) [:* - [:& measures-menu {:ids ids - :type type - :values measure-values - :shape shape}] + [:> measures-menu* {:ids ids + :type type + :values measure-values + :shape shape}] [:& layout-container-menu {:type type diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs index 7fdcc2c96..ba0f15069 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -22,7 +22,7 @@ [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]] [app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]] - [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-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.text :refer [text-menu]] @@ -98,7 +98,7 @@ [:& layer-menu {:ids ids :type type :values layer-values}] - [:& measures-menu + [:> measures-menu* {:ids ids :type type :values (select-keys shape measure-attrs) From 42acdbd135df83b69ddefd2fe0583d60204e6deb Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 17:55:28 +0100 Subject: [PATCH 07/13] :recycle: Reorganize common types tests --- common/test/common_tests/helpers_test.cljc | 65 +++++++++++++++++++ common/test/common_tests/runner.cljc | 16 ++--- ...ries_test.cljc => absorb_assets_test.cljc} | 56 ++-------------- ...mponent_test.cljc => components_test.cljc} | 2 +- .../modifiers_test.cljc} | 4 +- .../shape_interactions_test.cljc} | 3 +- 6 files changed, 81 insertions(+), 65 deletions(-) create mode 100644 common/test/common_tests/helpers_test.cljc rename common/test/common_tests/types/{types_libraries_test.cljc => absorb_assets_test.cljc} (76%) rename common/test/common_tests/types/{types_component_test.cljc => components_test.cljc} (97%) rename common/test/common_tests/{types_modifiers_test.cljc => types/modifiers_test.cljc} (92%) rename common/test/common_tests/{types_shape_interactions_test.cljc => types/shape_interactions_test.cljc} (99%) diff --git a/common/test/common_tests/helpers_test.cljc b/common/test/common_tests/helpers_test.cljc new file mode 100644 index 000000000..7f478207d --- /dev/null +++ b/common/test/common_tests/helpers_test.cljc @@ -0,0 +1,65 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns common-tests.helpers-test + (:require + [app.common.data :as d] + [app.common.test-helpers.components :as thc] + [app.common.test-helpers.compositions :as tho] + [app.common.test-helpers.files :as thf] + [app.common.test-helpers.ids-map :as thi] + [app.common.test-helpers.shapes :as ths] + [clojure.test :as t])) + +(t/use-fixtures :each thi/test-fixture) + +(t/deftest create-file + (let [f1 (thf/sample-file :file1) + f2 (thf/sample-file :file2 :page-label :page1) + f3 (thf/sample-file :file3 :name "testing file") + f4 (-> (thf/sample-file :file4 :page-label :page2) + (thf/add-sample-page :page3 :name "testing page") + (ths/add-sample-shape :shape1)) + f5 (-> f4 + (ths/add-sample-shape :shape2) + (thf/switch-to-page :page2) + (ths/add-sample-shape :shape3 :name "testing shape" :width 100)) + s1 (ths/get-shape f4 :shape1) + s2 (ths/get-shape f5 :shape2 :page-label :page3) + s3 (ths/get-shape f5 :shape3)] + + ;; (thf/pprint-file f4) + + (t/is (= (:name f1) "Test file")) + (t/is (= (:name f3) "testing file")) + (t/is (= (:id f2) (thi/id :file2))) + (t/is (= (:id f4) (thi/id :file4))) + (t/is (= (-> f4 :data :pages-index vals first :id) (thi/id :page2))) + (t/is (= (-> f4 :data :pages-index vals first :name) "Page 1")) + (t/is (= (-> f4 :data :pages-index vals second :id) (thi/id :page3))) + (t/is (= (-> f4 :data :pages-index vals second :name) "testing page")) + + (t/is (= (:id (thf/current-page f2)) (thi/id :page1))) + (t/is (= (:id (thf/current-page f4)) (thi/id :page3))) + (t/is (= (:id (thf/current-page f5)) (thi/id :page2))) + + (t/is (= (:id s1) (thi/id :shape1))) + (t/is (= (:name s1) "Rectangle")) + (t/is (= (:id s2) (thi/id :shape2))) + (t/is (= (:name s2) "Rectangle")) + (t/is (= (:id s3) (thi/id :shape3))) + (t/is (= (:name s3) "testing shape")) + (t/is (= (:width s3) 100)) + (t/is (= (:width (:selrect s3)) 100)))) + +(t/deftest create-components + (let [f1 (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 :main-root :main-child :copy-root))] + + #_(thf/dump-file f1) + #_(thf/pprint-file f4) + + (t/is (= (:name f1) "Test file")))) diff --git a/common/test/common_tests/runner.cljc b/common/test/common_tests/runner.cljc index 443bce779..6b30a8886 100644 --- a/common/test/common_tests/runner.cljc +++ b/common/test/common_tests/runner.cljc @@ -35,12 +35,12 @@ [common-tests.svg-test] [common-tests.text-test] [common-tests.time-test] - [common-tests.types-modifiers-test] - [common-tests.types-shape-interactions-test] + [common-tests.types.absorb-assets-test] + [common-tests.types.components-test] + [common-tests.types.modifiers-test] [common-tests.types.shape-decode-encode-test] + [common-tests.types.shape-interactions-test] [common-tests.types.tokens-lib-test] - [common-tests.types.types-component-test] - [common-tests.types.types-libraries-test] [common-tests.uuid-test])) #?(:cljs (enable-console-print!)) @@ -82,10 +82,10 @@ 'common-tests.svg-test 'common-tests.text-test 'common-tests.time-test - 'common-tests.types-modifiers-test - 'common-tests.types-shape-interactions-test + 'common-tests.types.modifiers-test + 'common-tests.types.shape-interactions-test 'common-tests.types.shape-decode-encode-test 'common-tests.types.tokens-lib-test - 'common-tests.types.types-component-test - 'common-tests.types.types-libraries-test + 'common-tests.types.components-test + 'common-tests.types.absorb-assets-test 'common-tests.uuid-test)) diff --git a/common/test/common_tests/types/types_libraries_test.cljc b/common/test/common_tests/types/absorb_assets_test.cljc similarity index 76% rename from common/test/common_tests/types/types_libraries_test.cljc rename to common/test/common_tests/types/absorb_assets_test.cljc index ab13cf868..790d029b0 100644 --- a/common/test/common_tests/types/types_libraries_test.cljc +++ b/common/test/common_tests/types/absorb_assets_test.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns common-tests.types.types-libraries-test +(ns common-tests.types.absorb-assets-test (:require [app.common.data :as d] [app.common.test-helpers.components :as thc] @@ -23,55 +23,7 @@ (t/use-fixtures :each thi/test-fixture) -(t/deftest test-create-file - (let [f1 (thf/sample-file :file1) - f2 (thf/sample-file :file2 :page-label :page1) - f3 (thf/sample-file :file3 :name "testing file") - f4 (-> (thf/sample-file :file4 :page-label :page2) - (thf/add-sample-page :page3 :name "testing page") - (ths/add-sample-shape :shape1)) - f5 (-> f4 - (ths/add-sample-shape :shape2) - (thf/switch-to-page :page2) - (ths/add-sample-shape :shape3 :name "testing shape" :width 100)) - s1 (ths/get-shape f4 :shape1) - s2 (ths/get-shape f5 :shape2 :page-label :page3) - s3 (ths/get-shape f5 :shape3)] - - ;; (thf/pprint-file f4) - - (t/is (= (:name f1) "Test file")) - (t/is (= (:name f3) "testing file")) - (t/is (= (:id f2) (thi/id :file2))) - (t/is (= (:id f4) (thi/id :file4))) - (t/is (= (-> f4 :data :pages-index vals first :id) (thi/id :page2))) - (t/is (= (-> f4 :data :pages-index vals first :name) "Page 1")) - (t/is (= (-> f4 :data :pages-index vals second :id) (thi/id :page3))) - (t/is (= (-> f4 :data :pages-index vals second :name) "testing page")) - - (t/is (= (:id (thf/current-page f2)) (thi/id :page1))) - (t/is (= (:id (thf/current-page f4)) (thi/id :page3))) - (t/is (= (:id (thf/current-page f5)) (thi/id :page2))) - - (t/is (= (:id s1) (thi/id :shape1))) - (t/is (= (:name s1) "Rectangle")) - (t/is (= (:id s2) (thi/id :shape2))) - (t/is (= (:name s2) "Rectangle")) - (t/is (= (:id s3) (thi/id :shape3))) - (t/is (= (:name s3) "testing shape")) - (t/is (= (:width s3) 100)) - (t/is (= (:width (:selrect s3)) 100)))) - -(t/deftest test-create-components - (let [f1 (-> (thf/sample-file :file1) - (tho/add-simple-component-with-copy :component1 :main-root :main-child :copy-root))] - - #_(thf/dump-file f1) - #_(thf/pprint-file f4) - - (t/is (= (:name f1) "Test file")))) - -(t/deftest test-absorb-components +(t/deftest absorb-components (let [;; Setup library (-> (thf/sample-file :library :is-shared true) (tho/add-simple-component :component1 :main-root :rect1)) @@ -105,7 +57,7 @@ (t/is (ctk/is-main-of? main-root' copy-root' true)) (t/is (ctk/main-instance-of? (:id main-root') (:id (second pages')) component')))) -(t/deftest test-absorb-colors +(t/deftest absorb-colors (let [;; Setup library (-> (thf/sample-file :library :is-shared true) (ths/add-sample-library-color :color1 {:name "Test color" @@ -142,7 +94,7 @@ (t/is (= (:fill-color-ref-id fill') (thi/id :color1))) (t/is (= (:fill-color-ref-file fill') (:id file'))))) -(t/deftest test-absorb-typographies +(t/deftest absorb-typographies (let [;; Setup library (-> (thf/sample-file :library :is-shared true) (ths/add-sample-typography :typography1 {:name "Test typography"})) diff --git a/common/test/common_tests/types/types_component_test.cljc b/common/test/common_tests/types/components_test.cljc similarity index 97% rename from common/test/common_tests/types/types_component_test.cljc rename to common/test/common_tests/types/components_test.cljc index d46480bf7..36394f29a 100644 --- a/common/test/common_tests/types/types_component_test.cljc +++ b/common/test/common_tests/types/components_test.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns common-tests.types.types-component-test +(ns common-tests.types.components-test (:require [app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.shapes :as ths] diff --git a/common/test/common_tests/types_modifiers_test.cljc b/common/test/common_tests/types/modifiers_test.cljc similarity index 92% rename from common/test/common_tests/types_modifiers_test.cljc rename to common/test/common_tests/types/modifiers_test.cljc index 740d49628..264b3e71e 100644 --- a/common/test/common_tests/types_modifiers_test.cljc +++ b/common/test/common_tests/types/modifiers_test.cljc @@ -4,14 +4,14 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns common-tests.types-modifiers-test +(ns common-tests.types.modifiers-test (:require [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.types.modifiers :as ctm] [clojure.test :as t])) -(t/deftest test-modifiers->transform +(t/deftest modifiers->transform (let [modifiers (-> (ctm/empty) (ctm/move (gpt/point 100 200)) diff --git a/common/test/common_tests/types_shape_interactions_test.cljc b/common/test/common_tests/types/shape_interactions_test.cljc similarity index 99% rename from common/test/common_tests/types_shape_interactions_test.cljc rename to common/test/common_tests/types/shape_interactions_test.cljc index 5a699278d..853a68ba8 100644 --- a/common/test/common_tests/types_shape_interactions_test.cljc +++ b/common/test/common_tests/types/shape_interactions_test.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns common-tests.types-shape-interactions-test +(ns common-tests.types.shape-interactions-test (:require [app.common.exceptions :as ex] [app.common.geom.point :as gpt] @@ -50,7 +50,6 @@ (t/is (= :after-delay (:event-type new-interaction))) (t/is (= 300 (:delay new-interaction))))))) - (t/deftest set-action-type (let [interaction ctsi/default-interaction] From 99d7b7ebf8d7d0f44ae653f5f14472541612becb Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 17:58:04 +0100 Subject: [PATCH 08/13] :recycle: Use correct function for color transformation Regression introduced in previous refactor PR --- common/src/app/common/types/color.cljc | 11 ----------- .../main/ui/workspace/sidebar/options/menus/fill.cljs | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index 3f309096b..ab50f4be0 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -143,7 +143,6 @@ ;; --- fill -;; FIXME: revisit, this generates invalid colors (defn fill->shape-color [fill] (d/without-nils @@ -154,16 +153,6 @@ :ref-id (:fill-color-ref-id fill) :ref-file (:fill-color-ref-file fill)})) -(defn fill->color - [fill] - (d/without-nils - {:color (:fill-color fill) - :opacity (:fill-opacity fill) - :gradient (:fill-color-gradient fill) - :image (:fill-image fill) - :id (:fill-color-ref-id fill) - :file-id (:fill-color-ref-file fill)})) - (defn set-fill-color [shape position color opacity gradient image] (update-in shape [:fills position] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index f4c3971ec..047d26346 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -168,7 +168,7 @@ (seq fills) [:& h/sortable-container {} (for [[index value] (d/enumerate (:fills values []))] - [:& color-row {:color (ctc/fill->color value) + [:& color-row {:color (ctc/fill->shape-color value) :key index :index index :title (tr "workspace.options.fill") From f32531b39fc8b8eb91a2f572f37f9b729477d1b0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 17:58:59 +0100 Subject: [PATCH 09/13] :recycle: Refactor how click is handled on assets panel Remove deep partial application with simple return value signal if default click handler is intercepted or not. --- common/src/app/common/types/file.cljc | 4 +- .../ui/workspace/sidebar/assets/colors.cljs | 28 +++++------- .../workspace/sidebar/assets/components.cljs | 8 +--- .../sidebar/assets/file_library.cljs | 12 +++--- .../ui/workspace/sidebar/assets/graphics.cljs | 4 +- .../sidebar/assets/typographies.cljs | 43 ++++++------------- 6 files changed, 35 insertions(+), 64 deletions(-) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index fa52b75ac..5deaa52c9 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -464,8 +464,8 @@ Returns a list ((asset ((container shapes) (container shapes)...))...)" [file-data library-data asset-type] (let [assets-seq (case asset-type - :component (ctkl/components-seq library-data) - :color (ctcl/colors-seq library-data) + :component (ctkl/components-seq library-data) + :color (ctcl/colors-seq library-data) :typography (ctyl/typographies-seq library-data)) find-usages-in-container diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs index 0738bd690..fa8d87363 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs @@ -64,19 +64,6 @@ (:color color) (:color color) :else (:value color)) - apply-color - (mf/use-fn - (mf/deps color) - (fn [event] - (st/emit! - (dwl/add-recent-color color) - (dc/apply-color-from-palette color (kbd/alt? event)) - (ptk/event - ::ev/event - {::ev/name "use-library-color" - ::ev/origin "sidebar" - :external-library (not local?)})))) - rename-color (mf/use-fn (mf/deps file-id color-id) @@ -189,10 +176,17 @@ on-click (mf/use-fn - (mf/deps color-id apply-color on-asset-click read-only?) - (when-not read-only? - (dwl/add-recent-color color) - (partial on-asset-click color-id apply-color)))] + (mf/deps color on-asset-click read-only?) + (fn [event] + (when-not read-only? + (st/emit! (ptk/data-event ::ev/event + {::ev/name "use-library-color" + ::ev/origin "sidebar" + :external-library (not local?)})) + + (when-not (on-asset-click event (:id color)) + (st/emit! (dwl/add-recent-color color) + (dc/apply-color-from-palette color (kbd/alt? event)))))))] (mf/with-effect [editing?] (when editing? diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs index dd2c00737..bef71e37e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -71,17 +71,13 @@ [root-shape container] (get-component-root-and-container file-id component) - unselect-all - (mf/use-fn - (fn [] - (st/emit! (dw/unselect-all-assets)))) - on-component-click (mf/use-fn (mf/deps component-id on-asset-click) (fn [event] (dom/stop-propagation event) - (on-asset-click component-id unselect-all event))) + (when-not (on-asset-click event component-id) + (st/emit! (dw/unselect-all-assets))))) on-component-double-click (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs index d707cd053..34098b2cb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs @@ -196,21 +196,19 @@ on-asset-click (mf/use-fn (mf/deps file-id selected) - (fn [asset-type asset-groups asset-id default-click event] + (fn [asset-type asset-groups event asset-id] (cond (kbd/mod? event) (do (dom/stop-propagation event) - (st/emit! (dw/toggle-selected-assets file-id asset-id asset-type))) + (st/emit! (dw/toggle-selected-assets file-id asset-id asset-type)) + true) (kbd/shift? event) (do (dom/stop-propagation event) - (extend-selected selected asset-type asset-groups asset-id file-id)) - - :else - (when default-click - (default-click event))))) + (extend-selected selected asset-type asset-groups asset-id file-id) + true)))) on-component-click (mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :components)) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/graphics.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/graphics.cljs index fe49a5fa3..15d4a79db 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/graphics.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/graphics.cljs @@ -82,7 +82,9 @@ on-asset-click (mf/use-fn (mf/deps object-id on-asset-click) - (partial on-asset-click object-id nil))] + (fn [event] + (on-asset-click event object-id)))] + [:div {:ref item-ref :class-name (stl/css-case :selected (contains? selected-objects object-id) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs index bfbf3092e..0ed537853 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs @@ -39,7 +39,7 @@ (mf/defc typography-item {::mf/wrap-props false} - [{:keys [typography file-id local? handle-change selected apply-typography editing-id renaming-id on-asset-click + [{:keys [typography file-id local? handle-change selected editing-id renaming-id on-asset-click on-context-menu selected-full selected-paths move-typography rename?]}] (let [item-ref (mf/use-ref) typography-id (:id typography) @@ -91,26 +91,17 @@ (mf/deps typography) (partial handle-change typography)) - apply-typography - (mf/use-fn - (mf/deps typography) - (partial apply-typography typography)) - on-asset-click (mf/use-fn - (mf/deps typography apply-typography on-asset-click) - (partial on-asset-click typography-id apply-typography)) - - on-click - (mf/use-fn - (mf/deps typography apply-typography on-asset-click) - (fn [ev] - (st/emit! (ptk/event - ::ev/event - {::ev/name "use-library-typography" - ::ev/origin "sidebar" - :external-library (not local?)})) - (on-asset-click ev)))] + (mf/deps typography on-asset-click read-only? local?) + (fn [event] + (when-not read-only? + (st/emit! (ptk/data-event ::ev/event + {::ev/name "use-library-typography" + ::ev/origin "sidebar" + :external-library (not local?)})) + (when-not (on-asset-click event (:id typography)) + (st/emit! (dwt/apply-typography typography file-id))))))] [:div {:class (stl/css :typography-item) :ref item-ref @@ -126,7 +117,7 @@ :typography typography :local? local? :selected? (contains? selected typography-id) - :on-click on-click + :on-click on-asset-click :on-change handle-change :on-context-menu on-context-menu :editing? editing? @@ -139,7 +130,7 @@ (mf/defc typographies-group {::mf/wrap-props false} [{:keys [file-id prefix groups open-groups force-open? file local? selected local-data - editing-id renaming-id on-asset-click handle-change apply-typography on-rename-group + editing-id renaming-id on-asset-click handle-change on-rename-group on-ungroup on-context-menu selected-full]}] (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that false @@ -208,7 +199,6 @@ :local? local? :handle-change handle-change :selected selected - :apply-typography apply-typography :editing-id editing-id :renaming-id renaming-id :rename? (= (:rename-typography local-data) id) @@ -234,7 +224,6 @@ :local-data local-data :on-asset-click on-asset-click :handle-change handle-change - :apply-typography apply-typography :on-rename-group on-rename-group :on-ungroup on-ungroup :on-context-menu on-context-menu @@ -284,13 +273,6 @@ (fn [typography changes] (st/emit! (dwl/update-typography (merge typography changes) file-id)))) - apply-typography - (mf/use-fn - (mf/deps file-id read-only?) - (fn [typography _event] - (when-not read-only? - (st/emit! (dwt/apply-typography typography file-id))))) - create-group (mf/use-fn (mf/deps typographies selected on-clear-selection file-id (:id @state)) @@ -438,7 +420,6 @@ :local-data local-data :on-asset-click on-asset-click :handle-change handle-change - :apply-typography apply-typography :on-rename-group on-rename-group :on-ungroup on-ungroup :on-context-menu on-context-menu From 6d666c49263856c13f50f2702edb41fa7c0e040e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 18:14:54 +0100 Subject: [PATCH 10/13] :bug: Fix not properly display library color --- .../sidebar/options/rows/color_row.cljs | 32 ++++++++----------- .../sidebar/options/rows/stroke_row.cljs | 8 ++--- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs index 04dfdb89b..3766cbb52 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs @@ -50,21 +50,18 @@ on-reorder on-detach on-open on-close on-remove disable-drag on-focus on-blur select-only select-on-focus]}] (let [current-file-id (mf/use-ctx ctx/current-file-id) - file-colors (mf/deref refs/workspace-file-colors) shared-libs (mf/deref refs/libraries) hover-detach (mf/use-state false) on-change (h/use-ref-callback on-change) - src-colors (if (= (:file-id color) current-file-id) - file-colors - (dm/get-in shared-libs [(:file-id color) :data :colors])) - color-name (dm/get-in src-colors [(:id color) :name]) + src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors]) + color-name (dm/get-in src-colors [(:ref-id color) :name]) multiple-colors? (uc/multiple? color) - library-color? (and (:id color) color-name (not multiple-colors?)) - gradient-color? (and (not multiple-colors?) - (:gradient color) - (get-in color [:gradient :type])) + library-color? (and (:ref-id color) color-name (not multiple-colors?)) + gradient-color? (and (not multiple-colors?) + (:gradient color) + (dm/get-in color [:gradient :type])) image-color? (and (not multiple-colors?) (:image color)) @@ -124,10 +121,9 @@ (mf/use-fn (mf/deps color on-change) (fn [value] - (let [color (assoc color - :opacity (/ value 100) - :id nil - :file-id nil)] + (let [color (-> color + (assoc :opacity (/ value 100)) + (dissoc :ref-id :ref-file))] (st/emit! (dwl/add-recent-color color) (on-change color))))) @@ -209,13 +205,11 @@ :gradient-name-wrapper gradient-color?)} [:div {:class (stl/css :color-bullet-wrapper)} [:& cb/color-bullet {:color (cond-> color - (nil? color-name) (assoc - :id nil - :file-id nil)) + (nil? color-name) (dissoc :ref-id :ref-file)) :mini true :on-click handle-click-color}]] (cond - ;; Rendering a color with ID + ;; Rendering a color with ID library-color? [:* [:div {:class (stl/css :color-name) @@ -235,7 +229,7 @@ gradient-color? [:* [:div {:class (stl/css :color-name)} - (uc/gradient-type->string (get-in color [:gradient :type]))]] + (uc/gradient-type->string (dm/get-in color [:gradient :type]))]] ;; Rendering an image image-color? @@ -250,7 +244,7 @@ "" (-> color :color cc/remove-hash)) :placeholder (tr "settings.multiple") - :className (stl/css :color-input) + :class (stl/css :color-input) :on-focus on-focus :on-blur on-blur :on-change handle-value-change}]])] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs index 9545c380b..22cf9d567 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs @@ -8,6 +8,7 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] + [app.common.types.color :as ctc] [app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.reorder-handler :refer [reorder-handler]] [app.main.ui.components.select :refer [select]] @@ -147,12 +148,7 @@ [:& reorder-handler {:ref dref}]) ;; Stroke Color - [:& color-row {:color {:color (:stroke-color stroke) - :opacity (:stroke-opacity stroke) - :id (:stroke-color-ref-id stroke) - :file-id (:stroke-color-ref-file stroke) - :gradient (:stroke-color-gradient stroke) - :image (:stroke-image stroke)} + [:& color-row {:color (ctc/stroke->shape-color stroke) :index index :title title :on-change on-color-change-refactor From 068dd5f4bc2c4366d106e7d09be4c5fcff39a109 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 21:04:49 +0100 Subject: [PATCH 11/13] :zap: Add performance oriented refactor for color palette components --- common/src/app/common/types/color.cljc | 3 + .../src/app/main/data/workspace/colors.cljs | 5 +- .../app/main/ui/workspace/color_palette.cljs | 117 ++++++++++-------- .../app/main/ui/workspace/color_palette.scss | 2 + .../src/app/main/ui/workspace/palette.cljs | 17 +-- .../sidebar/options/rows/color_row.cljs | 20 ++- 6 files changed, 93 insertions(+), 71 deletions(-) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index ab50f4be0..c5cbb888b 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -115,6 +115,9 @@ (sm/register! ::recent-color schema:recent-color) (sm/register! ::color-attrs schema:color-attrs) +(def valid-color? + (sm/lazy-validator schema:color)) + (def check-color! (sm/check-fn schema:color :hint "expected valid color struct")) diff --git a/frontend/src/app/main/data/workspace/colors.cljs b/frontend/src/app/main/data/workspace/colors.cljs index 85c096a46..cdcc683a7 100644 --- a/frontend/src/app/main/data/workspace/colors.cljs +++ b/frontend/src/app/main/data/workspace/colors.cljs @@ -89,7 +89,7 @@ text-ids (filter is-text? ids) shape-ids (remove is-text? ids) - undo-id (js/Symbol) + undo-id (js/Symbol) attrs (cond-> {} @@ -146,7 +146,8 @@ (rx/of (dwsh/update-shapes shape-ids transform-attrs))))))) (defn change-fill - ([ids color position] (change-fill ids color position nil)) + ([ids color position] + (change-fill ids color position nil)) ([ids color position options] (ptk/reify ::change-fill ptk/WatchEvent diff --git a/frontend/src/app/main/ui/workspace/color_palette.cljs b/frontend/src/app/main/ui/workspace/color_palette.cljs index 6d4c2c9c9..37a9bf4be 100644 --- a/frontend/src/app/main/ui/workspace/color_palette.cljs +++ b/frontend/src/app/main/ui/workspace/color_palette.cljs @@ -8,19 +8,21 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.data.macros :as dm] + [app.common.types.color :as ctc] [app.main.data.event :as ev] [app.main.data.workspace.colors :as mdc] [app.main.data.workspace.libraries :as dwl] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.color-bullet :as cb] - [app.main.ui.hooks :as h] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.color :as uc] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.keyboard :as kbd] [app.util.object :as obj] + [okulary.core :as l] [potok.v2.core :as ptk] [rumext.v2 :as mf])) @@ -48,25 +50,23 @@ [:& cb/color-name {:color color :size size :origin :palette}]])) (mf/defc palette* - [{:keys [current-colors size width selected]}] - (let [;; We had to do this due to a bug that leave some bugged colors - current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors)) - state (mf/use-state {:show-menu false}) - offset-step (cond - (<= size 64) 40 - (<= size 80) 72 - :else 72) + [{:keys [colors size width selected]}] + (let [state (mf/use-state #(do {:show-menu false})) + offset-step (cond + (<= size 64) 40 + (<= size 80) 72 + :else 72) buttons-size (cond (<= size 64) 164 :else 132) width (- width buttons-size) visible (int (/ width offset-step)) - show-arrows? (> (count current-colors) visible) + show-arrows? (> (count colors) visible) visible (if show-arrows? (int (/ (- width 48) offset-step)) visible) offset (:offset @state 0) - max-offset (- (count current-colors) + max-offset (- (count colors) visible) container (mf/use-ref nil) bullet-size (cond @@ -79,7 +79,7 @@ :else 64) on-left-arrow-click - (mf/use-callback + (mf/use-fn (mf/deps max-offset visible) (fn [_] (swap! state update :offset @@ -89,7 +89,7 @@ offset))))) on-right-arrow-click - (mf/use-callback + (mf/use-fn (mf/deps max-offset visible) (fn [_] (swap! state update :offset @@ -99,7 +99,7 @@ offset))))) on-scroll - (mf/use-callback + (mf/use-fn (mf/deps max-offset) (fn [event] (let [event (dom/event->native-event event) @@ -109,12 +109,12 @@ (on-right-arrow-click event) (on-left-arrow-click event)))))] - (mf/use-layout-effect - #(let [dom (mf/ref-val container) + (mf/with-layout-effect [] + (let [dom (mf/ref-val container) width (obj/get dom "clientWidth")] (swap! state assoc :width width))) - (mf/with-effect [width current-colors] + (mf/with-effect [width colors] (when (not= 0 (:offset @state)) (swap! state assoc :offset 0))) @@ -126,10 +126,10 @@ [:button {:class (stl/css :left-arrow) :disabled (= offset 0) :on-click on-left-arrow-click} i/arrow]) - [:div {:class (stl/css :color-palette-content) + [:div {:class (stl/css :color-palette-content) :ref container :on-wheel on-scroll} - (if (empty? current-colors) + (if (empty? colors) [:div {:class (stl/css :color-palette-empty) :style {:position "absolute" :left "50%" @@ -140,44 +140,61 @@ :style {:position "relative" :max-width (str width "px") :right (str (* offset-step offset) "px")}} - (for [[idx item] (map-indexed vector current-colors)] + (for [[idx item] (map-indexed vector colors)] [:> palette-item* {:color item :key idx :size size :selected selected}])])] + (when show-arrows? [:button {:class (stl/css :right-arrow) :disabled (= offset max-offset) :on-click on-right-arrow-click} i/arrow])])) -(defn library->colors [shared-libs selected] - (map #(merge % {:file-id selected}) - (-> shared-libs - (get-in [selected :data :colors]) - (vals)))) +(mf/defc recent-colors-palette* + {::mf/private true} + [props] + (let [colors (mf/deref refs/recent-colors) -(mf/defc color-palette + colors (mf/with-memo [colors] + (->> (reverse colors) + (filter ctc/valid-color?) + (vec))) + + props (mf/spread-props props {:colors colors})] + [:> palette* props])) + +(defn- make-library-colors-ref + [file-id] + (l/derived (fn [libraries] + (dm/get-in libraries [file-id :data :colors])) + refs/libraries)) + +(mf/defc file-color-palette* + {::mf/private true} + [{:keys [file-id] :as props}] + (let [colors-ref (mf/with-memo [file-id] + (make-library-colors-ref file-id)) + colors (mf/deref colors-ref) + colors (mf/with-memo [colors file-id] + (->> (vals colors) + (filter ctc/valid-color?) + (map #(assoc % :file-id file-id)) + (sort-by :name) + (vec))) + props (mf/spread-props props {:colors colors})] + + [:> palette* props])) + +(mf/defc color-palette* {::mf/wrap [mf/memo]} - [{:keys [size width selected] :as props}] - (let [recent-colors (mf/deref refs/recent-colors) - file-colors (mf/deref refs/workspace-file-colors) - shared-libs (mf/deref refs/libraries) - colors (mf/use-state [])] + [{:keys [selected] :as props}] + (let [file-id (mf/use-ctx ctx/current-file-id)] + (cond + (= selected :recent) + [:> recent-colors-palette* props] - (mf/with-effect [selected shared-libs] - (let [colors' (cond - (= selected :recent) (reverse recent-colors) - (= selected :file) (->> (vals file-colors) (sort-by :name)) - :else (->> (library->colors shared-libs selected) (sort-by :name)))] - (reset! colors (into [] colors')))) + (= selected :file) + (let [props (mf/spread-props props {:file-id file-id})] + [:> file-color-palette* props]) - (mf/with-effect [recent-colors selected] - (when (= selected :recent) - (reset! colors (reverse recent-colors)))) - - (mf/with-effect [file-colors selected] - (when (= selected :file) - (reset! colors (into [] (->> (vals file-colors) - (sort-by :name)))))) - - [:> palette* {:current-colors @colors - :size size - :width width - :selected selected}])) + :else + (let [props (mf/spread-props props {:file-id selected})] + [:> file-color-palette* props])))) diff --git a/frontend/src/app/main/ui/workspace/color_palette.scss b/frontend/src/app/main/ui/workspace/color_palette.scss index 396245369..f8f3ed244 100644 --- a/frontend/src/app/main/ui/workspace/color_palette.scss +++ b/frontend/src/app/main/ui/workspace/color_palette.scss @@ -74,6 +74,8 @@ .color-palette-content { overflow: hidden; + display: flex; + align-items: center; } .color-palette-inside { diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index 37085382c..5fc91d538 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -19,7 +19,7 @@ [app.main.ui.hooks :as h] [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] - [app.main.ui.workspace.color-palette :refer [color-palette]] + [app.main.ui.workspace.color-palette :refer [color-palette*]] [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu]] [app.main.ui.workspace.text-palette :refer [text-palette]] [app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]] @@ -195,13 +195,14 @@ :selected selected-text :width vport-width}]]) (when color-palette? - [:* [:& color-palette-ctx-menu {:show-menu? show-menu? - :close-menu on-close-menu - :on-select-palette on-select-palette - :selected @selected}] - [:& color-palette {:size size - :selected @selected - :width vport-width}]])]] + [:* + [:& color-palette-ctx-menu {:show-menu? show-menu? + :close-menu on-close-menu + :on-select-palette on-select-palette + :selected @selected}] + [:> color-palette* {:size size + :selected @selected + :width vport-width}]])]] [:div {:class (stl/css :handler) :on-click toggle-palettes :data-testid "toggle-palettes-visibility"} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs index 3766cbb52..a6beaa797 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs @@ -19,7 +19,6 @@ [app.main.ui.components.color-input :refer [color-input*]] [app.main.ui.components.numeric-input :refer [numeric-input*]] [app.main.ui.components.reorder-handler :refer [reorder-handler]] - [app.main.ui.context :as ctx] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.formats :as fmt] [app.main.ui.hooks :as h] @@ -49,24 +48,23 @@ [{:keys [index color disable-gradient disable-opacity disable-image disable-picker on-change on-reorder on-detach on-open on-close on-remove disable-drag on-focus on-blur select-only select-on-focus]}] - (let [current-file-id (mf/use-ctx ctx/current-file-id) - shared-libs (mf/deref refs/libraries) - hover-detach (mf/use-state false) - on-change (h/use-ref-callback on-change) + (let [shared-libs (mf/deref refs/libraries) + hover-detach (mf/use-state false) + on-change (h/use-ref-callback on-change) - src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors]) - color-name (dm/get-in src-colors [(:ref-id color) :name]) + src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors]) + color-name (dm/get-in src-colors [(:ref-id color) :name]) multiple-colors? (uc/multiple? color) library-color? (and (:ref-id color) color-name (not multiple-colors?)) gradient-color? (and (not multiple-colors?) (:gradient color) (dm/get-in color [:gradient :type])) - image-color? (and (not multiple-colors?) - (:image color)) + image-color? (and (not multiple-colors?) + (:image color)) - editing-text* (mf/use-state false) - editing-text? (deref editing-text*) + editing-text* (mf/use-state false) + editing-text? (deref editing-text*) opacity? (and (not multiple-colors?) From de2475cca614b8a494e3bf78f3a595b8653aa31f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 21:04:57 +0100 Subject: [PATCH 12/13] :zap: Add performance oriented refactor to color palette context menu --- .../ui/workspace/color_palette_ctx_menu.cljs | 118 +++++++++++------- .../src/app/main/ui/workspace/palette.cljs | 10 +- 2 files changed, 79 insertions(+), 49 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/color_palette_ctx_menu.cljs b/frontend/src/app/main/ui/workspace/color_palette_ctx_menu.cljs index 32f745165..4159c0663 100644 --- a/frontend/src/app/main/ui/workspace/color_palette_ctx_menu.cljs +++ b/frontend/src/app/main/ui/workspace/color_palette_ctx_menu.cljs @@ -11,45 +11,73 @@ [app.main.refs :as refs] [app.main.ui.components.color-bullet :as cb] [app.main.ui.components.dropdown :refer [dropdown]] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.i18n :refer [tr]] [rumext.v2 :as mf])) -(mf/defc color-palette-ctx-menu - [{:keys [show-menu? close-menu on-select-palette selected]}] - (let [recent-colors (mf/deref refs/recent-colors) - file-colors (mf/deref refs/workspace-file-colors) - shared-libs (mf/deref refs/libraries)] - [:& dropdown {:show show-menu? - :on-close close-menu} - [:ul {:class (stl/css :palette-menu)} - (for [{:keys [data id] :as library} (vals shared-libs)] - (let [colors (-> data :colors vals)] - [:li {:class (stl/css-case :palette-library true - :selected (= selected id)) - :key (dm/str "library-" id) - :on-click on-select-palette - :data-palette (dm/str id)} - [:div {:class (stl/css :option-wrapper)} - [:div {:class (stl/css :library-name)} - [:div {:class (stl/css :lib-name-wrapper)} - [:span {:class (stl/css :lib-name)} - (dm/str (:name library))] - [:span {:class (stl/css :lib-num)} - (dm/str "(" (count colors) ")")]] - (when (= selected id) - [:span {:class (stl/css :icon-wrapper)} - i/tick])] - [:div {:class (stl/css :color-sample) - :style #js {"--bullet-size" "20px"}} - (for [[i {:keys [color id gradient]}] (map-indexed vector (take 7 colors))] - [:& cb/color-bullet {:key (dm/str "color-" i) - :mini true - :color {:color color :id id :gradient gradient}}])]]])) +(def ^:private xf:sample-colors + (comp (map val) + (take 7))) - [:li {:class (stl/css-case :file-library true - :selected (= selected :file)) - :on-click on-select-palette +(defn- extract-colors + [{:keys [data] :as file}] + (let [colors (into [] xf:sample-colors (:colors data))] + (-> file + (assoc :colors colors) + (dissoc :data)))) + +(mf/defc color-palette-ctx-menu* + [{:keys [show on-close on-select selected]}] + (let [recent-colors (mf/deref refs/recent-colors) + libraries (mf/deref refs/libraries) + + file-id (mf/use-ctx ctx/current-file-id) + local-colors (mf/with-memo [libraries file-id] + (let [colors (dm/get-in libraries [file-id :data :colors])] + (into [] xf:sample-colors colors))) + + libraries (mf/with-memo [libraries file-id] + (->> (dissoc libraries file-id) + (vals) + (mapv extract-colors))) + + recent-colors (mf/with-memo [recent-colors] + (->> (reverse recent-colors) + (take 7) + (map-indexed (fn [index color] + (assoc color ::id (dm/str index)))) + (vec)))] + + [:& dropdown {:show show :on-close on-close} + [:ul {:class (stl/css :palette-menu)} + (for [{:keys [id colors] :as library} libraries] + [:li {:class (stl/css-case :palette-library true + :selected (= selected id)) + :key (dm/str "library-" id) + :on-click on-select + :data-palette (dm/str id)} + [:div {:class (stl/css :option-wrapper)} + [:div {:class (stl/css :library-name)} + [:div {:class (stl/css :lib-name-wrapper)} + [:span {:class (stl/css :lib-name)} + (dm/str (:name library))] + [:span {:class (stl/css :lib-num)} + (dm/str "(" (count colors) ")")]] + (when (= selected id) + [:span {:class (stl/css :icon-wrapper)} + i/tick])] + [:div {:class (stl/css :color-sample) + :style {:--bullet-size "20px"}} + (for [color colors] + [:& cb/color-bullet {:key (dm/str (:id color)) + :mini true + :color color}])]]]) + + [:li {:class (stl/css-case + :file-library true + :selected (= selected :file)) + :on-click on-select :data-palette "file"} [:div {:class (stl/css :option-wrapper)} @@ -59,21 +87,22 @@ [:span {:class (stl/css :lib-name)} (dm/str (tr "workspace.libraries.colors.file-library"))] [:span {:class (stl/css :lib-num)} - (dm/str "(" (count file-colors) ")")]] + (dm/str "(" (count local-colors) ")")]] (when (= selected :file) [:span {:class (stl/css :icon-wrapper)} i/tick])] [:div {:class (stl/css :color-sample) - :style #js {"--bullet-size" "20px"}} - (for [[i color] (map-indexed vector (take 7 (vals file-colors)))] - [:& cb/color-bullet {:key (dm/str "color-" i) + :style {:--bullet-size "20px"}} + (for [color local-colors] + [:& cb/color-bullet {:key (dm/str (:id color)) :mini true :color color}])]]] - [:li {:class (stl/css :recent-colors true - :selected (= selected :recent)) - :on-click on-select-palette + [:li {:class (stl/css + :recent-colors true + :selected (= selected :recent)) + :on-click on-select :data-palette "recent"} [:div {:class (stl/css :option-wrapper)} [:div {:class (stl/css :library-name)} @@ -87,8 +116,9 @@ [:span {:class (stl/css :icon-wrapper)} i/tick])] [:div {:class (stl/css :color-sample) - :style #js {"--bullet-size" "20px"}} - (for [[idx color] (map-indexed vector (take 7 (reverse recent-colors)))] - [:& cb/color-bullet {:key (str "color-" idx) + :style {:--bullet-size "20px"}} + + (for [color recent-colors] + [:& cb/color-bullet {:key (dm/str (::id color)) :mini true :color color}])]]]]])) diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index 5fc91d538..431f97935 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -20,7 +20,7 @@ [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] [app.main.ui.workspace.color-palette :refer [color-palette*]] - [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu]] + [app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]] [app.main.ui.workspace.text-palette :refer [text-palette]] [app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]] [app.util.dom :as dom] @@ -196,10 +196,10 @@ :width vport-width}]]) (when color-palette? [:* - [:& color-palette-ctx-menu {:show-menu? show-menu? - :close-menu on-close-menu - :on-select-palette on-select-palette - :selected @selected}] + [:> color-palette-ctx-menu* {:show show-menu? + :on-close on-close-menu + :on-select on-select-palette + :selected @selected}] [:> color-palette* {:size size :selected @selected :width vport-width}]])]] From 2a63f8e96654f30c8b56eb6db1397719a0134ecf Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 21:33:11 +0100 Subject: [PATCH 13/13] :zap: Add performance oriented refactor on colorpicker libraries component --- .../ui/workspace/colorpicker/libraries.cljs | 112 +++++++++--------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs index 4ce65154d..788d354db 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs @@ -10,6 +10,7 @@ [app.common.colors :as c] [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.types.color :as ctc] [app.main.data.event :as ev] [app.main.data.workspace :as dw] [app.main.data.workspace.colors :as mdc] @@ -17,6 +18,7 @@ [app.main.store :as st] [app.main.ui.components.color-bullet :as cb] [app.main.ui.components.select :refer [select]] + [app.main.ui.context :as ctx] [app.main.ui.hooks :as h] [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] @@ -27,103 +29,107 @@ (mf/defc libraries [{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity disable-image]}] - (let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent) - current-colors (mf/use-state []) + (let [selected* (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent) + selected (deref selected*) - shared-libs (mf/deref refs/libraries) - file-colors (mf/deref refs/workspace-file-colors) + file-id (mf/use-ctx ctx/current-file-id) + + current-colors* (mf/use-state []) + current-colors (deref current-colors*) + + libraries (mf/deref refs/libraries) recent-colors (mf/deref refs/recent-colors) - recent-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) recent-colors)) + recent-colors (mf/with-memo [recent-colors] + (filterv ctc/valid-color? recent-colors)) + + library-options + (mf/with-memo [] + [{:value "recent" :label (tr "workspace.libraries.colors.recent-colors")} + {:value "file" :label (tr "workspace.libraries.colors.file-library")}]) + + options + (mf/with-memo [library-options file-id] + (into library-options + (comp + (map val) + (map (fn [lib] {:value (d/name (:id lib)) :label (:name lib)}))) + (dissoc libraries file-id))) on-library-change (mf/use-fn (fn [event] - (reset! selected + (reset! selected* (if (or (= event "recent") (= event "file")) (keyword event) (parse-uuid event))))) - check-valid-color? + valid-color? (mf/use-fn + (mf/deps disable-gradient disable-opacity disable-image) (fn [color] (and (or (not disable-gradient) (not (:gradient color))) (or (not disable-opacity) (= 1 (:opacity color))) (or (not disable-image) (not (:image color)))))) - ;; Sort colors by hue and lightness - get-sorted-colors - (mf/use-fn - (fn [colors] - (sort c/sort-colors (into [] (filter check-valid-color?) colors)))) - toggle-palette (mf/use-fn - (mf/deps @selected) + (mf/deps selected) (fn [] (r/set-resize-type! :bottom) (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") (st/emit! (dw/remove-layout-flag :textpalette) - (-> (mdc/show-palette @selected) + (-> (mdc/show-palette selected) (vary-meta assoc ::ev/origin "workspace-colorpicker"))))) - shared-libs-options (mapv (fn [lib] {:value (d/name (:id lib)) :label (:name lib)}) (vals shared-libs)) - - - library-options [{:value "recent" :label (tr "workspace.libraries.colors.recent-colors")} - {:value "file" :label (tr "workspace.libraries.colors.file-library")}] - - options (concat library-options shared-libs-options) - on-color-click (mf/use-fn - (mf/deps state @selected) + (mf/deps state selected on-select-color) (fn [event] - (when-not (= :recent @selected) + (when-not (= :recent selected) (st/emit! (ptk/event ::ev/event {::ev/name "use-library-color" ::ev/origin "colorpicker" - :external-library (not= :file @selected)}))) + :external-library (not= :file selected)}))) (on-select-color state event)))] ;; Load library colors when the select is changed - (mf/with-effect [@selected recent-colors file-colors] - (let [colors (cond - (= @selected :recent) - ;; The `map?` check is to keep backwards compatibility. We transform from string to map - (map #(if (map? %) % {:color %}) (reverse (or recent-colors []))) + (mf/with-effect [selected recent-colors libraries file-id valid-color?] + (let [file-id (if (= selected :file) + file-id + selected) - (= @selected :file) - (->> (vals file-colors) (sort-by :name)) + colors (if (= selected :recent) + ;; NOTE: The `map?` check is to keep backwards + ;; compatibility We transform from string to map + (->> (reverse recent-colors) + (filter valid-color?) + (map-indexed (fn [index color] + (let [color (if (map? color) color {:color color})] + (assoc color ::id (dm/str index))))) + (sort c/sort-colors)) + (->> (dm/get-in libraries [file-id :data :colors]) + (vals) + (filter valid-color?) + (map-indexed (fn [index color] + (-> color + (assoc :file-id file-id) + (assoc ::id (dm/str index))))) + (sort-by :name)))] - :else ;; Library UUID - (as-> @selected file-id - (->> (get-in shared-libs [file-id :data :colors]) - (vals) - (sort-by :name) - (map #(assoc % :file-id file-id)))))] - - (if (not= @selected :recent) - (reset! current-colors (get-sorted-colors colors)) - (reset! current-colors (into [] (filter check-valid-color? colors)))))) - - ;; If the file colors change and the file option is selected updates the state - (mf/with-effect [file-colors] - (when (= @selected :file) - (let [colors (vals file-colors)] - (reset! current-colors (get-sorted-colors colors))))) + (reset! current-colors* colors))) [:div {:class (stl/css :libraries)} [:div {:class (stl/css :select-wrapper)} [:& select {:class (stl/css :shadow-type-select) - :default-value (or (name @selected) "recent") + :default-value (or (d/name selected) "recent") :options options :on-change on-library-change}]] [:div {:class (stl/css :selected-colors)} - (when (= @selected :file) + (when (= selected :file) [:button {:class (stl/css :add-color-btn) :on-click on-add-library-color} i/add]) @@ -132,8 +138,8 @@ :on-click toggle-palette} i/swatches] - (for [[idx color] (map-indexed vector @current-colors)] + (for [color current-colors] [:& cb/color-bullet - {:key (dm/str "color-" idx) + {:key (dm/str "color-" (::id color)) :color color :on-click on-color-click}])]]))