diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/common/src/app/common/files/libraries_helpers.cljc similarity index 97% rename from frontend/src/app/main/data/workspace/libraries_helpers.cljs rename to common/src/app/common/files/libraries_helpers.cljc index ff03da46e..0be04e5d6 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/common/src/app/common/files/libraries_helpers.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns app.main.data.workspace.libraries-helpers +(ns app.common.files.libraries-helpers (:require [app.common.data :as d] [app.common.data.macros :as dm] @@ -25,7 +25,6 @@ [app.common.types.shape-tree :as ctst] [app.common.types.shape.layout :as ctl] [app.common.types.typography :as cty] - [app.main.data.workspace.state-helpers :as wsh] [cljs.spec.alpha :as s] [clojure.set :as set])) @@ -37,7 +36,6 @@ (declare generate-sync-text-shape) (declare uses-assets?) -(declare get-assets) (declare generate-sync-shape-direct) (declare generate-sync-shape-direct-recursive) (declare generate-sync-shape-inverse) @@ -59,10 +57,10 @@ (declare make-change) (defn pretty-file - [file-id state] - (if (= file-id (:current-file-id state)) + [file-id libraries current-file-id] + (if (= file-id current-file-id) "" - (str "<" (get-in state [:workspace-libraries file-id :name]) ">"))) + (str "<" (get-in libraries [file-id :name]) ">"))) (defn pretty-uuid [uuid] @@ -304,7 +302,7 @@ If an asset id is given, only shapes linked to this particular asset will be synchronized." - [it file-id asset-type asset-id library-id state] + [it file-id asset-type asset-id library-id libraries current-file-id] (s/assert #{:colors :components :typographies} asset-type) (s/assert (s/nilable ::us/uuid) asset-id) (s/assert ::us/uuid file-id) @@ -313,10 +311,10 @@ (log/info :msg "Sync file with library" :asset-type asset-type :asset-id asset-id - :file (pretty-file file-id state) - :library (pretty-file library-id state)) + :file (pretty-file file-id libraries current-file-id) + :library (pretty-file library-id libraries current-file-id)) - (let [file (wsh/get-file state file-id) + (let [file (get-in libraries [file-id :data]) components-v2 (get-in file [:options :components-v2])] (loop [containers (ctf/object-containers-seq file) changes (pcb/empty-changes it)] @@ -329,9 +327,10 @@ asset-type asset-id library-id - state container - components-v2)))) + components-v2 + libraries + current-file-id)))) changes)))) (defn generate-sync-library @@ -341,7 +340,7 @@ If an asset id is given, only shapes linked to this particular asset will be synchronized." - [it file-id asset-type asset-id library-id state] + [it file-id asset-type asset-id library-id libraries current-file-id] (s/assert #{:colors :components :typographies} asset-type) (s/assert (s/nilable ::us/uuid) asset-id) (s/assert ::us/uuid file-id) @@ -350,10 +349,10 @@ (log/info :msg "Sync local components with library" :asset-type asset-type :asset-id asset-id - :file (pretty-file file-id state) - :library (pretty-file library-id state)) + :file (pretty-file file-id libraries current-file-id) + :library (pretty-file library-id libraries current-file-id)) - (let [file (wsh/get-file state file-id) + (let [file (get-in libraries [file-id :data]) components-v2 (get-in file [:options :components-v2])] (loop [local-components (ctkl/components-seq file) changes (pcb/empty-changes it)] @@ -365,15 +364,16 @@ asset-type asset-id library-id - state (cfh/make-container local-component :component) - components-v2))) + components-v2 + libraries + current-file-id))) changes)))) (defn- generate-sync-container "Generate changes to synchronize all shapes in a particular container (a page or a component) that use assets of the given type in the given library." - [it asset-type asset-id library-id state container components-v2] + [it asset-type asset-id library-id container components-v2 libraries current-file-id] (if (cfh/page? container) (log/debug :msg "Sync page in local file" :page-id (:id container)) @@ -390,10 +390,11 @@ (generate-sync-shape asset-type changes library-id - state container shape - components-v2)) + components-v2 + libraries + current-file-id)) changes)))) (defmulti uses-assets? @@ -421,33 +422,32 @@ (defmulti generate-sync-shape "Generate changes to synchronize one shape from all assets of the given type that is using, in the given library." - (fn [asset-type _changes _library-id _state _container _shape _components-v2] asset-type)) + (fn [asset-type _changes _library-id _container _shape _components-v2 _libraries _current-file-id] asset-type)) (defmethod generate-sync-shape :components - [_ changes _library-id state container shape components-v2] + [_ changes _library-id container shape components-v2 libraries current-file-id] (let [shape-id (:id shape) - file (wsh/get-local-file-full state) - libraries (wsh/get-libraries state)] + file (get current-file-id libraries)] (generate-sync-shape-direct changes file libraries container shape-id false components-v2))) (defmethod generate-sync-shape :colors - [_ changes library-id state _ shape _] + [_ changes library-id _ shape _ libraries _] (log/debug :msg "Sync colors of shape" :shape (:name shape)) ;; Synchronize a shape that uses some colors of the library. The value of the ;; color in the library is copied to the shape. - (let [library-colors (get-assets library-id :colors state)] + (let [library-colors (get-in libraries [library-id :data :colors])] (pcb/update-shapes changes [(:id shape)] #(ctc/sync-shape-colors % library-id library-colors)))) (defmethod generate-sync-shape :typographies - [_ changes library-id state container shape _] + [_ changes library-id container shape _ libraries _] (log/debug :msg "Sync typographies of shape" :shape (:name shape)) ;; Synchronize a shape that uses some typographies of the library. The attributes ;; of the typography are copied to the shape." - (let [typographies (get-assets library-id :typographies state) + (let [typographies (get-in libraries [library-id :data :typographies]) update-node (fn [node] (if-let [typography (get typographies (:typography-ref-id node))] (merge node (dissoc typography :name :id)) @@ -455,12 +455,6 @@ :typography-ref-file)))] (generate-sync-text-shape changes shape container update-node))) -(defn- get-assets - [library-id asset-type state] - (if (= library-id (:current-file-id state)) - (get-in state [:workspace-data asset-type]) - (get-in state [:workspace-libraries library-id :data asset-type]))) - (defn- generate-sync-text-shape [changes shape container update-node] (let [old-content (:content shape) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 75d662313..8ad2a90be 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -12,6 +12,7 @@ [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cfh] [app.common.files.libraries-common-helpers :as cflch] + [app.common.files.libraries-helpers :as cflh] [app.common.files.shapes-helpers :as cfsh] [app.common.geom.point :as gpt] [app.common.logging :as log] @@ -29,7 +30,6 @@ [app.main.data.workspace :as-alias dw] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.groups :as dwg] - [app.main.data.workspace.libraries-helpers :as dwlh] [app.main.data.workspace.notifications :as-alias dwn] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.shapes :as dwsh] @@ -54,6 +54,13 @@ ;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default (log/set-level! :warn) + +(defn- pretty-file + [file-id state] + (if (= file-id (:current-file-id state)) + "" + (str "<" (get-in state [:workspace-libraries file-id :name]) ">"))) + (defn- log-changes [changes file] (let [extract-change @@ -472,7 +479,7 @@ [new-component-shape new-component-shapes ; <- null in components-v2 new-main-instance-shape new-main-instance-shapes] - (dwlh/duplicate-component component new-component-id (:data library)) + (cflh/duplicate-component component new-component-id (:data library)) changes (-> (pcb/empty-changes it nil) (pcb/with-page main-instance-page) @@ -525,7 +532,7 @@ current-page (dm/get-in state [:workspace-data :pages-index page-id]) objects (wsh/lookup-page-objects state page-id) library-data (wsh/get-file state library-id) - {:keys [changes shape]} (dwlh/prepare-restore-component library-data component-id current-page it) + {:keys [changes shape]} (cflh/prepare-restore-component library-data component-id current-page it) parent-id (:parent-id shape) objects (cond-> (assoc objects (:id shape) shape) (not (nil? parent-id)) @@ -574,7 +581,7 @@ (pcb/with-objects objects)) [new-shape changes] - (dwlh/generate-instantiate-component changes + (cflh/generate-instantiate-component changes objects file-id component-id @@ -606,7 +613,7 @@ changes (-> (pcb/empty-changes it) (pcb/with-container container) (pcb/with-objects (:objects container)) - (dwlh/generate-detach-instance container libraries id))] + (cflh/generate-detach-instance container libraries id))] (rx/of (dch/commit-changes changes)))))) @@ -642,7 +649,7 @@ changes (when can-detach? (reduce (fn [changes id] - (dwlh/generate-detach-instance changes container libraries id)) + (cflh/generate-detach-instance changes container libraries id)) (-> (pcb/empty-changes it) (pcb/with-container container) (pcb/with-objects objects)) @@ -731,7 +738,7 @@ (-> (pcb/empty-changes it) (pcb/with-container container) (pcb/with-objects (:objects container)) - (dwlh/generate-sync-shape-direct file-full libraries container (:id head) false components-v2))] + (cflh/generate-sync-shape-direct file-full libraries container (:id head) false components-v2))] (log/debug :msg "SYNC-head finished" :js/rchanges (log-changes (:redo-changes changes) @@ -767,7 +774,7 @@ (-> (pcb/empty-changes it) (pcb/with-container container) (pcb/with-objects (:objects container)) - (dwlh/generate-sync-shape-direct file-full libraries container id true components-v2))] + (cflh/generate-sync-shape-direct file-full libraries container id true components-v2))] (log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes (:redo-changes changes) @@ -823,7 +830,7 @@ (-> (pcb/empty-changes it) (pcb/set-undo-group undo-group) (pcb/with-container container) - (dwlh/generate-sync-shape-inverse full-file libraries container id components-v2)) + (cflh/generate-sync-shape-inverse full-file libraries container id components-v2)) file-id (:component-file shape) file (wsh/get-file state file-id) @@ -947,7 +954,7 @@ inside-comp? (ctn/in-any-component? objects parent) [new-shape changes] - (dwlh/generate-instantiate-component changes + (cflh/generate-instantiate-component changes objects (:id file) id-new-component @@ -978,7 +985,7 @@ ;; We need to set the same index as the original shape (pcb/change-parent (:parent-id shape) [new-shape] index {:component-swap true :ignore-touched true}) - (dwlh/change-touched new-shape + (cflh/change-touched new-shape shape (ctn/make-container page :page) {}))] @@ -1039,7 +1046,7 @@ (watch [_ state _] (let [undo-id (js/Symbol)] (log/info :msg "COMPONENT-SWAP" - :file (dwlh/pretty-file file-id state) + :file (pretty-file file-id state) :id-new-component id-new-component :undo-id undo-id) (rx/concat @@ -1092,12 +1099,15 @@ (watch [it state _] (when (and (some? file-id) (some? library-id)) ; Prevent race conditions while navigating out of the file (log/info :msg "SYNC-FILE" - :file (dwlh/pretty-file file-id state) - :library (dwlh/pretty-file library-id state) + :file (pretty-file file-id state) + :library (pretty-file library-id state) :asset-type asset-type :asset-id asset-id :undo-group undo-group) (let [file (wsh/get-file state file-id) + libraries (wsh/get-libraries state) + current-file-id (:current-file-id state) + sync-components? (or (nil? asset-type) (= asset-type :components)) sync-colors? (or (nil? asset-type) (= asset-type :colors)) @@ -1108,22 +1118,22 @@ (-> (pcb/empty-changes it) (pcb/set-undo-group undo-group)) [(when sync-components? - (dwlh/generate-sync-library it file-id :components asset-id library-id state)) + (cflh/generate-sync-library it file-id :components asset-id library-id libraries current-file-id)) (when sync-colors? - (dwlh/generate-sync-library it file-id :colors asset-id library-id state)) + (cflh/generate-sync-library it file-id :colors asset-id library-id libraries current-file-id)) (when sync-typographies? - (dwlh/generate-sync-library it file-id :typographies asset-id library-id state))]) + (cflh/generate-sync-library it file-id :typographies asset-id library-id libraries current-file-id))]) file-changes (reduce pcb/concat-changes (-> (pcb/empty-changes it) (pcb/set-undo-group undo-group)) [(when sync-components? - (dwlh/generate-sync-file it file-id :components asset-id library-id state)) + (cflh/generate-sync-file it file-id :components asset-id library-id libraries current-file-id)) (when sync-colors? - (dwlh/generate-sync-file it file-id :colors asset-id library-id state)) + (cflh/generate-sync-file it file-id :colors asset-id library-id libraries current-file-id)) (when sync-typographies? - (dwlh/generate-sync-file it file-id :typographies asset-id library-id state))]) + (cflh/generate-sync-file it file-id :typographies asset-id library-id libraries current-file-id))]) changes (pcb/concat-changes library-changes file-changes) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index b5b3d3a0d..38e1ec51a 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -12,6 +12,7 @@ [app.common.files.focus :as cpf] [app.common.files.helpers :as cfh] [app.common.files.libraries-common-helpers :as cflch] + [app.common.files.libraries-helpers :as cflh] [app.common.geom.point :as gpt] [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] @@ -28,7 +29,6 @@ [app.main.data.modal :as md] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.collapse :as dwc] - [app.main.data.workspace.libraries-helpers :as dwlh] [app.main.data.workspace.specialized-panel :as-alias dwsp] [app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.undo :as dwu] @@ -435,7 +435,7 @@ (gpt/subtract (-> origin-frame :selrect gpt/point))) instantiate-component - #(dwlh/generate-instantiate-component changes + #(cflh/generate-instantiate-component changes objects file-id (:component-id component-root) @@ -448,7 +448,7 @@ {}) restore-component - #(let [restore (dwlh/prepare-restore-component changes library-data (:component-id component-root) it page delta (:id component-root) parent-id frame-id)] + #(let [restore (cflh/prepare-restore-component changes library-data (:component-id component-root) it page delta (:id component-root) parent-id frame-id)] [(:shape restore) (:changes restore)]) [_shape changes] diff --git a/frontend/src/app/main/data/workspace/state_helpers.cljs b/frontend/src/app/main/data/workspace/state_helpers.cljs index b04fa88f6..7249a1f3f 100644 --- a/frontend/src/app/main/data/workspace/state_helpers.cljs +++ b/frontend/src/app/main/data/workspace/state_helpers.cljs @@ -123,6 +123,15 @@ (get state :workspace-data) (dm/get-in state [:workspace-libraries file-id :data]))) +(defn get-file-full + "Get the data content of the given file (it may be the current file + or one library)." + [state file-id] + (if (= file-id (:current-file-id state)) + (-> (get state :workspace-file) + (assoc :data (get state :workspace-data))) + (dm/get-in state [:workspace-libraries file-id :data]))) + (defn get-libraries "Retrieve all libraries, including the local file." [state]