From 2a63f8e96654f30c8b56eb6db1397719a0134ecf Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 16 Jan 2025 21:33:11 +0100 Subject: [PATCH] :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}])]]))