diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 141dd25e11..d6bffce4b0 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -168,11 +168,13 @@ (assoc file :data (d/removem (comp t/pointer? val) data)))))))))) (defn- libraries-fetched - [libraries] + [file-id libraries] (ptk/reify ::libraries-fetched ptk/UpdateEvent (update [_ state] - (let [libraries (d/index-by :id libraries)] + (let [libraries (->> libraries + (map (fn [l] (assoc l :library-of file-id))) + (d/index-by :id))] (update state :files merge libraries))) ptk/WatchEvent @@ -208,7 +210,7 @@ (rx/map #(assoc % :synced-at synced-at))))) (rx/merge-map resolve-file) (rx/reduce conj []) - (rx/map libraries-fetched)) + (rx/map (partial libraries-fetched file-id))) (->> (rx/from libraries) (rx/map :id) (rx/mapcat (fn [file-id] diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 34cf12d4f7..d4a57d21e4 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -1201,7 +1201,7 @@ (vals (get state :files))) do-more-info - #(modal/show! :libraries-dialog {:starting-tab "updates"}) + #(modal/show! :libraries-dialog {:starting-tab "updates" :file-id file-id}) do-update #(do (apply st/emit! (map (fn [library] @@ -1388,7 +1388,10 @@ (let [libraries (:workspace-shared-files state) library (d/seek #(= (:id %) library-id) libraries)] (if library - (update state :files assoc library-id (dissoc library :library-summary)) + (update state :files assoc library-id + (-> library + (dissoc :library-summary) + (assoc :library-of file-id))) state))) ptk/WatchEvent @@ -1401,6 +1404,8 @@ (->> (rp/cmd! :get-file {:id library-id :features features}) (rx/merge-map fpmap/resolve-file) ;; FIXME: this should call the libraries-fetched event instead of ad-hoc assoc event + (rx/map (fn [file] + (assoc file :library-of file-id))) (rx/map (fn [file] (fn [state] (assoc-in state [:files library-id] file))))) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index deb64480c3..f9e46b272a 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -83,10 +83,32 @@ files (without the content, only summary)" (l/derived :shared-files st/state)) +(defn select-libraries + [files file-id] + (persistent! + (reduce-kv (fn [result id file] + (if (or (= id file-id) + (= (:library-of file) file-id)) + (assoc! result id file) + result)) + (transient {}) + files))) + +;; NOTE: for performance reasons, prefer derefing refs/files and then +;; use with-memo mechanism with `select-libraries` this will avoid +;; executing the select-libraries reduce-kv on each state change and +;; only execute it when files are changed. This ref exists for +;; backward compatibility with the code, but it is considered +;; DEPRECATED and all new code should not use it and old code should +;; be gradually migrated to more efficient approach (def libraries - "A derived state that contanins the currently loaded shared libraries - with all its content; including the current file" - (l/derived :files st/state)) + "A derived state that contanins the currently loaded shared + libraries with all its content; including the current file" + (l/derived (fn [state] + (let [files (get state :files) + file-id (get state :current-file-id)] + (select-libraries files file-id))) + st/state)) (defn extract-selected-files [files selected] diff --git a/frontend/src/app/main/ui/inspect/attributes/text.cljs b/frontend/src/app/main/ui/inspect/attributes/text.cljs index e478b93a57..e1828710a7 100644 --- a/frontend/src/app/main/ui/inspect/attributes/text.cljs +++ b/frontend/src/app/main/ui/inspect/attributes/text.cljs @@ -56,10 +56,12 @@ (make-typographies-library-ref (:typography-ref-file style))) typography-library (mf/deref typography-library-ref) + + ;; FIXME: too many duplicate operations file-typographies-viewer (mf/deref file-typographies-ref) file-typographies-workspace (mf/deref refs/workspace-file-typography) - file-library-workspace (get (mf/deref refs/libraries) (:typography-ref-file style)) + file-library-workspace (get (mf/deref refs/files) (:typography-ref-file style)) typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)]) color-format (mf/use-state :hex) diff --git a/frontend/src/app/main/ui/inspect/right_sidebar.cljs b/frontend/src/app/main/ui/inspect/right_sidebar.cljs index 27ca93817b..990b3a2281 100644 --- a/frontend/src/app/main/ui/inspect/right_sidebar.cljs +++ b/frontend/src/app/main/ui/inspect/right_sidebar.cljs @@ -26,16 +26,11 @@ "Retrieve all libraries, including the local file, on workspace or viewer" [from] (if (= from :workspace) - (let [workspace-data (deref refs/workspace-data) - {:keys [id] :as local} workspace-data - libraries (deref refs/libraries)] - (-> libraries - (assoc id {:id id - :data local}))) - (let [viewer-data (deref refs/viewer-data) - local (get-in viewer-data [:file :data]) - id (get local :id) - libraries (:libraries viewer-data)] + (deref refs/libraries) + (let [viewer-data (deref refs/viewer-data) + local (get-in viewer-data [:file :data]) + id (get local :id) + libraries (:libraries viewer-data)] (-> libraries (assoc id {:id id :data local}))))) diff --git a/frontend/src/app/main/ui/workspace/color_palette.cljs b/frontend/src/app/main/ui/workspace/color_palette.cljs index 4f3e507e48..fd93b321d8 100644 --- a/frontend/src/app/main/ui/workspace/color_palette.cljs +++ b/frontend/src/app/main/ui/workspace/color_palette.cljs @@ -166,9 +166,9 @@ (defn- make-library-colors-ref [file-id] - (l/derived (fn [libraries] - (dm/get-in libraries [file-id :data :colors])) - refs/libraries)) + (l/derived (fn [files] + (dm/get-in files [file-id :data :colors])) + refs/files)) (mf/defc file-color-palette* {::mf/private true} diff --git a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs index 788d354db0..6814a9a7c6 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs @@ -48,7 +48,7 @@ {:value "file" :label (tr "workspace.libraries.colors.file-library")}]) options - (mf/with-memo [library-options file-id] + (mf/with-memo [library-options libraries file-id] (into library-options (comp (map val) diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index 963385602f..90d9111b25 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -248,10 +248,12 @@ (mf/use-fn (mf/deps file-id) #(st/emit! (dwl/set-file-shared file-id false) - (modal/show :libraries-dialog {}))) + (modal/show :libraries-dialog {:file-id file-id}))) on-delete-cancel - (mf/use-fn #(st/emit! (modal/show :libraries-dialog {}))) + (mf/use-fn + (mf/deps file-id) + #(st/emit! (modal/show :libraries-dialog {:file-id file-id}))) publish (mf/use-fn @@ -259,7 +261,7 @@ (fn [event] (let [input-node (dom/get-target event) publish-library #(st/emit! (dwl/set-file-shared file-id true)) - cancel-publish #(st/emit! (modal/show :libraries-dialog {}))] + cancel-publish #(st/emit! (modal/show :libraries-dialog {:file-id file-id}))] (if empty-library? (st/emit! (modal/show {:type :confirm @@ -563,17 +565,15 @@ (mf/defc libraries-dialog {::mf/register modal/components ::mf/register-as :libraries-dialog} - [{:keys [starting-tab] :as props :or {starting-tab :libraries}}] - (let [;; NOTE: we don't want to react on file changes, we just want - ;; a snapshot of file on the momento of open the dialog - file (deref refs/file) - - file-id (:id file) - team-id (:team-id file) - shared? (:is-shared file) + [{:keys [starting-tab file-id] :as props :or {starting-tab :libraries}}] + (let [files (mf/deref refs/files) + file (get files file-id) + team-id (:team-id file) + shared? (:is-shared file) linked-libraries - (mf/deref refs/files) + (mf/with-memo [files file-id] + (refs/select-libraries files file-id)) linked-libraries (mf/with-memo [linked-libraries file-id] diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index 21e639f255..a556b664eb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -56,6 +56,7 @@ [{:keys [layout file page-id] :as props}] (let [options-mode (mf/deref refs/options-mode-global) project (mf/deref refs/project) + file-id (get file :id) design-tokens? (features/use-feature "design-tokens/v1") mode-inspect? (= options-mode :inspect) @@ -116,7 +117,7 @@ assets-tab - (mf/html [:& assets-toolbox {:size (- size 58) :file-id file}]) + (mf/html [:& assets-toolbox {:size (- size 58) :file-id file-id}]) tokens-tab (when design-tokens? diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 7f240d7343..d0d8ca8be9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -33,10 +33,10 @@ ::mf/private true} [{:keys [filters]}] (let [file-id (mf/use-ctx ctx/current-file-id) - - libraries (mf/deref refs/libraries) - libraries (mf/with-memo [libraries file-id] - (->> (vals libraries) + files (mf/deref refs/files) + libraries (mf/with-memo [files file-id] + (->> (refs/select-libraries files file-id) + (vals) (remove :is-indirect) (remove #(= file-id (:id %))) (map (fn [file] @@ -129,8 +129,9 @@ show-libraries-dialog (mf/use-fn + (mf/deps file-id) (fn [] - (modal/show! :libraries-dialog {}) + (modal/show! :libraries-dialog {:file-id file-id}) (modal/allow-click-outside!))) on-open-menu diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs index 371cfc624d..405ca5f264 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs @@ -321,7 +321,7 @@ current-file-id (mf/use-ctx ctx/current-file-id) current-page-id (mf/use-ctx ctx/current-page-id) - libraries (deref refs/libraries) + libraries (deref refs/files) current-file (get libraries current-file-id) objects (-> (dsh/get-page (:data current-file) current-page-id) 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 15f81726c6..bc4b6bc76c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -44,7 +44,7 @@ (defn- get-component-root-and-container [file-id component] - (let [data (dm/get-in @refs/libraries [file-id :data]) + (let [data (dm/get-in @refs/files [file-id :data]) root-shape (ctf/get-component-root data component) container (ctf/get-component-page data component)] [root-shape container])) @@ -453,7 +453,7 @@ (fn [component event] (let [file-data - (dm/get-in @refs/libraries [file-id :data]) + (dm/get-in @refs/files [file-id :data]) shape-main (ctf/get-component-root file-data component)] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 56a8023a07..1d59834b66 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] :as props}] + [{:keys [shape shapes-with-children page-id file-id libraries] :as props}] (let [shape-type (dm/get-prop shape :type) shape-id (dm/get-prop shape :id) @@ -56,8 +56,8 @@ [:* (case shape-type :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}] + :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :libraries libraries}] + :text [:& text/options {:shape shape :file-id file-id :libraries libraries}] :rect [:& rect/options {:shape shape}] :circle [:& circle/options {:shape shape}] :path [:& path/options {:shape shape}] @@ -83,7 +83,7 @@ [{:keys [selected objects page-id file-id selected-shapes shapes-with-children]}] (let [sp-panel (mf/deref refs/specialized-panel) drawing (mf/deref refs/workspace-drawing) - shared-libs (mf/deref refs/libraries) + libraries (mf/deref refs/libraries) edition (mf/deref refs/selected-edition) edit-grid? (ctl/grid-layout? objects edition) grid-edition (mf/deref refs/workspace-grid-edition) @@ -113,7 +113,7 @@ {:shape (:object drawing) :page-id page-id :file-id file-id - :shared-libs shared-libs}] + :libraries libraries}] (= 0 (count selected)) [:> page/options*] @@ -123,7 +123,7 @@ {:shape (first selected-shapes) :page-id page-id :file-id file-id - :shared-libs shared-libs + :libraries libraries :shapes-with-children shapes-with-children}] :else @@ -132,7 +132,7 @@ :shapes selected-shapes :page-id page-id :file-id file-id - :shared-libs shared-libs}])])) + :libraries libraries}])])) (mf/defc options-content* {::mf/memo true diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs index f6b753ba1b..bd8579138b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs @@ -19,8 +19,8 @@ [rumext.v2 :as mf])) (defn- prepare-colors - [shapes file-id shared-libs] - (let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id shared-libs))) + [shapes file-id libraries] + (let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id libraries))) groups (d/group-by :attrs #(dissoc % :attrs) data) all-colors (distinct (mapv :attrs data)) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 86fb956a2c..56e1f15333 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -295,7 +295,8 @@ (let [single? (= 1 (count shapes)) shape (first shapes) current-file-id (mf/use-ctx ctx/current-file-id) - libraries (mf/deref refs/files) + + libraries (mf/deref refs/libraries) objects (mf/deref refs/workspace-page-objects) ^boolean @@ -513,7 +514,7 @@ [{:keys [shapes swap-opened?]}] (let [current-file-id (mf/use-ctx ctx/current-file-id) - libraries (deref refs/libraries) + libraries (deref refs/files) current-file (get libraries current-file-id) state* (mf/use-state diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index e2363c52aa..74e645737b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -184,7 +184,7 @@ (let [file-id (mf/use-ctx ctx/current-file-id) typographies (mf/deref refs/workspace-file-typography) - shared-libs (mf/deref refs/libraries) + libraries (mf/deref refs/files) label (case type :multiple (tr "workspace.options.text-options.title-selection") :group (tr "workspace.options.text-options.title-group") @@ -224,21 +224,19 @@ (emit-update! ids attrs))) typography - (mf/use-memo - (mf/deps values file-id shared-libs) - (fn [] - (cond - (and typography-id - (not= typography-id :multiple) - (not= typography-file-id file-id)) - (-> shared-libs - (get-in [typography-file-id :data :typographies typography-id]) - (assoc :file-id typography-file-id)) + (mf/with-memo [values file-id libraries] + (cond + (and typography-id + (not= typography-id :multiple) + (not= typography-file-id file-id)) + (-> libraries + (get-in [typography-file-id :data :typographies typography-id]) + (assoc :file-id typography-file-id)) - (and typography-id - (not= typography-id :multiple) - (= typography-file-id file-id)) - (get typographies typography-id)))) + (and typography-id + (not= typography-id :multiple) + (= typography-file-id file-id)) + (get typographies typography-id))) on-convert-to-typography (fn [_] 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 7e7cdb17ec..b86a972dfb 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 @@ -48,13 +48,13 @@ [{:keys [index color disable-gradient disable-opacity disable-image disable-picker hidden on-change on-reorder on-detach on-open on-close on-remove disable-drag on-focus on-blur select-only select-on-focus]}] - (let [shared-libs (mf/deref refs/libraries) + (let [libraries (mf/deref refs/files) hover-detach (mf/use-state false) on-change (h/use-ref-callback on-change) file-id (or (:ref-file color) (:file-id color)) color-id (or (:ref-id color) (:id color)) - src-colors (dm/get-in shared-libs [file-id :data :colors]) + src-colors (dm/get-in libraries [file-id :data :colors]) color-name (dm/get-in src-colors [color-id :name]) multiple-colors? (uc/multiple? color) 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 e39a3aff60..1401741307 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 @@ -34,7 +34,7 @@ [props] (let [shape (unchecked-get props "shape") shape-with-children (unchecked-get props "shape-with-children") - shared-libs (unchecked-get props "shared-libs") + libraries (unchecked-get props "libraries") objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v)))) file-id (unchecked-get props "file-id") layout-container-values (select-keys shape layout-container-flex-attrs) @@ -106,7 +106,7 @@ {:type type :shapes (vals objects) :file-id file-id - :libraries shared-libs}] + :libraries libraries}] (when-not (empty? shadow-ids) [:> shadow-menu* {:ids ids :values (get shape :shadow) :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 61d06a07d3..5f13076323 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 @@ -29,7 +29,7 @@ [rumext.v2 :as mf])) (mf/defc options - [{:keys [shape file-id] :as props}] + [{:keys [shape file-id libraries] :as props}] (let [ids [(:id shape)] type (:type shape) @@ -53,8 +53,6 @@ (mf/deref refs/workspace-v2-editor-state) (mf/deref refs/workspace-editor-state)) - shared-libs (mf/deref refs/libraries) - editor-state (when (not (features/active-feature? @st/state "text-editor/v2")) (get state-map (:id shape))) @@ -150,7 +148,7 @@ {:type type :shapes [shape] :file-id file-id - :libraries shared-libs}]) + :libraries libraries}]) [:> shadow-menu* {:ids ids :values (get shape :shadow)}] diff --git a/frontend/src/app/main/ui/workspace/text_palette.cljs b/frontend/src/app/main/ui/workspace/text_palette.cljs index 7c92895dc0..4becd5a546 100644 --- a/frontend/src/app/main/ui/workspace/text_palette.cljs +++ b/frontend/src/app/main/ui/workspace/text_palette.cljs @@ -68,7 +68,7 @@ (str (:font-size typography) "px | " (:name variant-data))]])])) (mf/defc palette - [{:keys [selected selected-ids current-file-id file-typographies shared-libs size width]}] + [{:keys [selected selected-ids current-file-id file-typographies libraries size width]}] (let [file-id (case selected :recent nil @@ -79,7 +79,7 @@ (case selected :recent [] :file (sort-by #(str/lower (:name %)) (vals file-typographies)) - (sort-by #(str/lower (:name %)) (vals (get-in shared-libs [selected :data :typographies])))) + (sort-by #(str/lower (:name %)) (vals (get-in libraries [selected :data :typographies])))) state (mf/use-state {:offset 0}) offset-step 144 buttons-size (cond @@ -182,13 +182,17 @@ {::mf/wrap [mf/memo]} [{:keys [size width selected] :as props}] (let [selected-ids (mf/deref refs/selected-shapes) + + ;; FIXME: we have duplicate operations, if we already have the + ;; libraries, so we already have file-typographies so we don't + ;; need two separate lens/refs for that file-typographies (mf/deref refs/workspace-file-typography) - shared-libs (mf/deref refs/libraries) + libraries (mf/deref refs/files) current-file-id (mf/use-ctx ctx/current-file-id)] [:& palette {:current-file-id current-file-id :selected-ids selected-ids :file-typographies file-typographies - :shared-libs shared-libs + :libraries libraries :width width :selected selected :size size}])) diff --git a/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs b/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs index 568e6a84e8..8034780e58 100644 --- a/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs +++ b/frontend/src/app/main/ui/workspace/text_palette_ctx_menu.cljs @@ -17,11 +17,11 @@ (mf/defc text-palette-ctx-menu [{:keys [show-menu? close-menu on-select-palette selected]}] (let [typographies (mf/deref refs/workspace-file-typography) - shared-libs (mf/deref refs/libraries)] + libraries (mf/deref refs/libraries)] [:& dropdown {:show show-menu? :on-close close-menu} [:ul {:class (stl/css :text-context-menu)} - (for [[idx cur-library] (map-indexed vector (vals shared-libs))] + (for [[idx cur-library] (map-indexed vector (vals libraries))] (let [typographies (-> cur-library (get-in [:data :typographies]) vals)] [:li {:class (stl/css-case :palette-library true