diff --git a/backend/src/app/cli/fixtures.clj b/backend/src/app/cli/fixtures.clj index 9c1997581a..d60c61b44e 100644 --- a/backend/src/app/cli/fixtures.clj +++ b/backend/src/app/cli/fixtures.clj @@ -112,7 +112,7 @@ (create-file [conn owner-id project-id index] (let [id (mk-uuid "file" project-id index) name (str "file" index) - data (cp/make-file-data)] + data (cp/make-file-data id)] (log/info "create file" id) (db/insert! conn :file {:id id @@ -186,7 +186,7 @@ id (mk-uuid "file" "draft" owner-id index) name (str "file" index) project-id (:default-project-id owner) - data (cp/make-file-data)] + data (cp/make-file-data id)] (log/info "create draft file" id) (db/insert! conn :file diff --git a/backend/src/app/services/mutations/files.clj b/backend/src/app/services/mutations/files.clj index 17742805d4..b428daa9f8 100644 --- a/backend/src/app/services/mutations/files.clj +++ b/backend/src/app/services/mutations/files.clj @@ -63,7 +63,7 @@ :or {is-shared false} :as params}] (let [id (or id (uuid/next)) - data (cp/make-file-data) + data (cp/make-file-data id) file (db/insert! conn :file {:id id :project-id project-id @@ -276,6 +276,7 @@ changes (:changes params) file (-> file (update :data blob/decode) + (update :data assoc :id (:id file)) (update :data pmg/migrate-data) (update :data cp/process-changes changes) (update :data blob/encode) diff --git a/backend/src/app/tasks/trim_file.clj b/backend/src/app/tasks/trim_file.clj index 56e81777cd..6ff2146e52 100644 --- a/backend/src/app/tasks/trim_file.clj +++ b/backend/src/app/tasks/trim_file.clj @@ -67,6 +67,7 @@ (db/with-atomic [conn db/pool] (let [mobjs (map :id (db/query conn :media-object {:file-id id})) data (-> (blob/decode data) + (assoc :id id) (pmg/migrate-data)) used (collect-used-media data) diff --git a/backend/tests/app/tests/test_common_pages.clj b/backend/tests/app/tests/test_common_pages.clj index 9a265e998c..b8a220d484 100644 --- a/backend/tests/app/tests/test_common_pages.clj +++ b/backend/tests/app/tests/test_common_pages.clj @@ -18,8 +18,9 @@ [app.tests.helpers :as th])) (t/deftest process-change-set-option - (let [page-id (uuid/custom 1 1) - data (cp/make-file-data page-id)] + (let [file-id (uuid/custom 2 2) + page-id (uuid/custom 1 1) + data (cp/make-file-data file-id page-id)] (t/testing "Sets option single" (let [chg {:type :set-option :page-id page-id @@ -83,8 +84,9 @@ )) (t/deftest process-change-add-obj - (let [page-id (uuid/custom 1 1) - data (cp/make-file-data page-id) + (let [file-id (uuid/custom 2 2) + page-id (uuid/custom 1 1) + data (cp/make-file-data file-id page-id) id-a (uuid/custom 2 1) id-b (uuid/custom 2 2) id-c (uuid/custom 2 3)] @@ -136,8 +138,9 @@ )) (t/deftest process-change-mod-obj - (let [page-id (uuid/custom 1 1) - data (cp/make-file-data page-id)] + (let [file-id (uuid/custom 2 2) + page-id (uuid/custom 1 1) + data (cp/make-file-data file-id page-id)] (t/testing "simple mod-obj" (let [chg {:type :mod-obj :page-id page-id @@ -161,9 +164,10 @@ (t/deftest process-change-del-obj - (let [page-id (uuid/custom 1 1) + (let [file-id (uuid/custom 2 2) + page-id (uuid/custom 1 1) id (uuid/custom 2 1) - data (cp/make-file-data page-id) + data (cp/make-file-data file-id page-id) data (-> data (assoc-in [:pages-index page-id :objects uuid/zero :shapes] [id]) (assoc-in [:pages-index page-id :objects id] @@ -205,8 +209,9 @@ rect-d-id (uuid/custom 0 8) rect-e-id (uuid/custom 0 9) + file-id (uuid/custom 2 2) page-id (uuid/custom 1 1) - data (cp/make-file-data page-id) + data (cp/make-file-data file-id page-id) data (update-in data [:pages-index page-id :objects] #(-> % @@ -417,6 +422,7 @@ shape-2-id (uuid/custom 2 2) shape-3-id (uuid/custom 2 3) frame-id (uuid/custom 1 1) + file-id (uuid/custom 4 4) page-id (uuid/custom 0 1) changes [{:type :add-obj @@ -449,7 +455,7 @@ :obj {:type :rect :name "Shape 3"}} ] - data (cp/make-file-data page-id) + data (cp/make-file-data file-id page-id) data (cp/process-changes data changes)] (t/testing "preserve order on multiple shape mov 1" @@ -513,6 +519,7 @@ shape-3-id (uuid/custom 1 3) shape-4-id (uuid/custom 1 4) group-1-id (uuid/custom 1 5) + file-id (uuid/custom 1 6) page-id (uuid/custom 0 1) changes [{:type :add-obj @@ -555,7 +562,7 @@ :parent-id group-1-id :shapes [shape-1-id shape-2-id]}] - data (cp/make-file-data page-id) + data (cp/make-file-data file-id page-id) data (cp/process-changes data changes)] (t/testing "case 1" diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index c2ad88592a..1e83700a91 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -80,3 +80,4 @@ (s/def ::recent-color ::spec/recent-color) (s/def ::shape-attrs ::spec/shape-attrs) (s/def ::typography ::spec/typography) + diff --git a/common/app/common/pages/common.cljc b/common/app/common/pages/common.cljc index 2d58b6bbe3..bfd1de4961 100644 --- a/common/app/common/pages/common.cljc +++ b/common/app/common/pages/common.cljc @@ -11,7 +11,7 @@ (:require [app.common.uuid :as uuid])) -(def file-version 4) +(def file-version 5) (def default-color "#b1b2b5") ;; $color-gray-20 (def root uuid/zero) diff --git a/common/app/common/pages/helpers.cljc b/common/app/common/pages/helpers.cljc index b3edf29fd6..b0cc1b468f 100644 --- a/common/app/common/pages/helpers.cljc +++ b/common/app/common/pages/helpers.cljc @@ -58,6 +58,7 @@ (defn get-container [id type local-file] + (assert (some? type)) (-> (if (= type :page) (get-in local-file [:pages-index id]) (get-in local-file [:components id])) @@ -68,10 +69,11 @@ (get-in container [:objects shape-id])) (defn get-component - [component-id file-id local-library libraries] - (let [file (if (nil? file-id) + [component-id library-id local-library libraries] + (assert (some? (:id local-library))) + (let [file (if (= library-id (:id local-library)) local-library - (get-in libraries [file-id :data]))] + (get-in libraries [library-id :data]))] (get-in file [:components component-id]))) (defn is-master-of diff --git a/common/app/common/pages/init.cljc b/common/app/common/pages/init.cljc index d39ecf1fe3..0eab6ae862 100644 --- a/common/app/common/pages/init.cljc +++ b/common/app/common/pages/init.cljc @@ -132,12 +132,13 @@ :height (:height selection-rect)}) (defn make-file-data - ([] (make-file-data (uuid/next))) - ([id] + ([file-id] (make-file-data file-id(uuid/next))) + ([file-id page-id] (let [ pd (assoc empty-page-data - :id id + :id page-id :name "Page-1")] (-> empty-file-data - (update :pages conj id) - (update :pages-index assoc id pd))))) + (assoc :id file-id) + (update :pages conj page-id) + (update :pages-index assoc page-id pd))))) diff --git a/common/app/common/pages/migrations.cljc b/common/app/common/pages/migrations.cljc index 5c65aa9ed2..c2f170a01f 100644 --- a/common/app/common/pages/migrations.cljc +++ b/common/app/common/pages/migrations.cljc @@ -35,7 +35,9 @@ (defn migrate-file [file] - (update file :data migrate-data)) + (-> file + (update :data assoc :id (:id file)) + (update :data migrate-data))) ;; Default handler, noop (defmethod migrate :default [data] data) @@ -120,3 +122,18 @@ ;; We did rollback version 4 migration. ;; Keep this in order to remember the next version to be 5 (defmethod migrate 4 [data] data) + +;; Put the id of the local file in :component-file in instances of local components +(defmethod migrate 5 + [data] + (letfn [(update-object [_ object] + (if (and (some? (:component-id object)) + (nil? (:component-file object))) + (assoc object :component-file (:id data)) + object)) + + (update-page [_ page] + (update page :objects #(d/mapm update-object %)))] + + (update data :pages-index #(d/mapm update-page %)))) + diff --git a/frontend/src/app/config.cljs b/frontend/src/app/config.cljs index 0d06269958..2ea07e3229 100644 --- a/frontend/src/app/config.cljs +++ b/frontend/src/app/config.cljs @@ -69,7 +69,7 @@ (def platform (parse-platform)) (js/console.log - (str/format "Welcome to pentpot! Version: '%s'" (:full version))) + (str/format "Welcome to penpot! Version: '%s'" (:full version))) ;; --- Helper Functions diff --git a/frontend/src/app/main/data/colors.cljs b/frontend/src/app/main/data/colors.cljs index c84529a2b8..a063fe787d 100644 --- a/frontend/src/app/main/data/colors.cljs +++ b/frontend/src/app/main/data/colors.cljs @@ -119,11 +119,11 @@ text-ids (filter is-text? ids) shape-ids (filter (comp not is-text?) ids) - attrs (cond-> {:fill-color (:color color) - :fill-color-ref-id (:id color) - :fill-color-ref-file (:file-id color) - :fill-color-gradient (:gradient color) - :fill-opacity (:opacity color)}) + attrs {:fill-color (:color color) + :fill-color-ref-id (:id color) + :fill-color-ref-file (:file-id color) + :fill-color-gradient (:gradient color) + :fill-opacity (:opacity color)} update-fn (fn [shape] (merge shape attrs)) editors (get-in state [:workspace-local :editors]) diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index 037fa483e4..278255c526 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -9,18 +9,22 @@ (ns app.main.data.workspace.common (:require - [beicon.core :as rx] - [cljs.spec.alpha :as s] - [clojure.set :as set] - [potok.core :as ptk] [app.common.data :as d] + [app.common.geom.proportions :as gpr] + [app.common.geom.shapes :as gsh] [app.common.pages :as cp] [app.common.spec :as us] [app.common.uuid :as uuid] [app.main.worker :as uw] + [app.util.logging :as log] [app.util.timers :as ts] - [app.common.geom.proportions :as gpr] - [app.common.geom.shapes :as gsh])) + [beicon.core :as rx] + [cljs.spec.alpha :as s] + [clojure.set :as set] + [potok.core :as ptk])) + +;; Change this to :info :debug or :trace to debug this module +(log/set-level! :warn) (s/def ::shape-attrs ::cp/shape-attrs) (s/def ::set-of-string (s/every string? :kind set?)) @@ -66,6 +70,9 @@ :as opts}] (us/verify ::cp/changes changes) ;; (us/verify ::cp/changes undo-changes) + (log/debug :msg "commit-changes" + :js/changes changes + :js/undo-changes undo-changes) (let [error (volatile! nil)] (ptk/reify ::commit-changes diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 8551541365..a2276906cb 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -76,8 +76,9 @@ (assoc-in state [:workspace-local :color-for-rename] nil)))) (defn update-color - [{:keys [id] :as color}] + [{:keys [id] :as color} file-id] (us/assert ::cp/color color) + (us/assert ::us/uuid file-id) (ptk/reify ::update-color ptk/WatchEvent (watch [_ state stream] @@ -87,7 +88,7 @@ uchg {:type :mod-color :color prev}] (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) - (sync-file nil)))))) + (sync-file file-id)))))) (defn delete-color [{:keys [id] :as params}] @@ -164,9 +165,9 @@ (assoc-in [:workspace-local :rename-typography] (:id typography)))))))))) (defn update-typography - [typography] + [typography file-id] (us/assert ::cp/typography typography) - + (us/assert ::us/uuid file-id) (ptk/reify ::update-typography ptk/WatchEvent (watch [_ state stream] @@ -176,7 +177,7 @@ uchg {:type :mod-typography :typography prev}] (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) - (sync-file nil)))))) + (sync-file file-id)))))) (defn delete-typography [id] @@ -196,7 +197,8 @@ (ptk/reify ::add-component ptk/WatchEvent (watch [_ state stream] - (let [page-id (:current-page-id state) + (let [file-id (:current-file-id state) + page-id (:current-page-id state) objects (dwc/lookup-page-objects state page-id) selected (get-in state [:workspace-local :selected]) shapes (dwg/shapes-for-grouping objects selected)] @@ -210,7 +212,7 @@ (dwg/prepare-create-group page-id shapes "Component-" true)) [new-shape new-shapes updated-shapes] - (dwlh/make-component-shape group objects) + (dwlh/make-component-shape group objects file-id) rchanges (conj rchanges {:type :add-component @@ -303,8 +305,8 @@ ptk/WatchEvent (watch [_ state stream] (let [component (cp/get-component id - nil - (get state :workspace-data) + (:current-file-id state) + (dwlh/get-local-library state) nil) all-components (vals (get-in state [:workspace-data :components])) unames (set (map :name all-components)) @@ -344,18 +346,18 @@ (defn instantiate-component "Create a new shape in the current page, from the component with the given id - in the given file library (if file-id is nil, take it from the current file library)." + in the given file library / current file library." [file-id component-id position] - (us/assert (s/nilable ::us/uuid) file-id) + (us/assert ::us/uuid file-id) (us/assert ::us/uuid component-id) (us/assert ::us/point position) (ptk/reify ::instantiate-component ptk/WatchEvent (watch [_ state stream] - (let [component (if (nil? file-id) - (get-in state [:workspace-data :components component-id]) - (get-in state [:workspace-libraries file-id :data :components component-id])) - component-shape (get-in component [:objects (:id component)]) + (let [local-library (dwlh/get-local-library state) + libraries (get state :workspace-libraries) + component (cp/get-component component-id file-id local-library libraries) + component-shape (cp/get-shape component component-id) orig-pos (gpt/point (:x component-shape) (:y component-shape)) delta (gpt/subtract position orig-pos) @@ -387,19 +389,9 @@ (nil? (:parent-id original-shape)) (assoc :component-id (:id original-shape) + :component-file file-id :component-root? true) - (and (nil? (:parent-id original-shape)) (some? file-id)) - (assoc :component-file file-id) - - (and (nil? (:parent-id original-shape)) (nil? file-id)) - (dissoc :component-file) - - (and (some? (:component-id original-shape)) - (nil? (:component-file original-shape)) - (some? file-id)) - (assoc :component-file file-id) - (some? (:parent-id original-shape)) (dissoc :component-root?)))) @@ -514,15 +506,15 @@ ptk/WatchEvent (watch [_ state stream] (log/info :msg "RESET-COMPONENT of shape" :id (str id)) - (let [local-file (get state :workspace-data) - libraries (get state :workspace-libraries) - container (cp/get-container (get state :current-page-id) - :page - local-file) + (let [local-library (dwlh/get-local-library state) + libraries (dwlh/get-libraries state) + container (cp/get-container (get state :current-page-id) + :page + local-library) [rchanges uchanges] (dwlh/generate-sync-shape-direct container id - local-file + local-library libraries true)] (log/debug :msg "RESET-COMPONENT finished" :js/rchanges rchanges) @@ -539,16 +531,11 @@ ptk/WatchEvent (watch [_ state stream] (log/info :msg "UPDATE-COMPONENT of shape" :id (str id)) - (let [page-id (:current-page-id state) - objects (dwc/lookup-page-objects state page-id) - shape (get objects id) - file-id (get shape :component-file) - - [rchanges uchanges] + (let [[rchanges uchanges] (dwlh/generate-sync-shape-inverse (get state :current-page-id) id - (get state :workspace-data) - (get state :workspace-libraries))] + (dwlh/get-local-library state) + (dwlh/get-libraries state))] (log/debug :msg "UPDATE-COMPONENT finished" :js/rchanges rchanges) @@ -562,17 +549,17 @@ component of the library file, and copy the new values to the shapes. Do it also for shapes inside components of the local file library." [file-id] - (us/assert (s/nilable ::us/uuid) file-id) + (us/assert ::us/uuid file-id) (ptk/reify ::sync-file ptk/UpdateEvent (update [_ state] - (if file-id + (if (not= file-id (:current-file-id state)) (assoc-in state [:workspace-libraries file-id :synced-at] (dt/now)) state)) ptk/WatchEvent (watch [_ state stream] - (log/info :msg "SYNC-FILE" :file (str (or file-id "local"))) + (log/info :msg "SYNC-FILE" :file (if (= file-id (:current-file-id state)) "local" (str file-id))) (let [library-changes [(dwlh/generate-sync-library :components file-id state) (dwlh/generate-sync-library :colors file-id state) (dwlh/generate-sync-library :typographies file-id state)] @@ -590,7 +577,7 @@ (rx/of (dm/hide-tag :sync-dialog)) (when rchanges (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))) - (when file-id + (when (not= file-id (:current-file-id state)) (rp/mutation :update-sync {:file-id (get-in state [:workspace-file :id]) :library-id file-id})) @@ -607,12 +594,12 @@ ;; implement updated-at at component level, to detect what components have ;; not changed, and then not to apply sync and terminate the loop. [file-id] - (us/assert (s/nilable ::us/uuid) file-id) + (us/assert ::us/uuid file-id) (ptk/reify ::sync-file-2nd-stage ptk/WatchEvent (watch [_ state stream] - (log/info :msg "SYNC-FILE (2nd stage)" :file (str (or file-id "local"))) - (let [[rchanges1 uchanges1] (dwlh/generate-sync-file :components nil state) + (log/info :msg "SYNC-FILE (2nd stage)" :file (if (= file-id (:current-file-id state)) "local" (str file-id))) + (let [[rchanges1 uchanges1] (dwlh/generate-sync-file :components file-id state) [rchanges2 uchanges2] (dwlh/generate-sync-library :components file-id state) rchanges (d/concat rchanges1 rchanges2) uchanges (d/concat uchanges1 uchanges2)] @@ -621,7 +608,7 @@ (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))) (def ignore-sync - (ptk/reify ::sync-file + (ptk/reify ::ignore-sync ptk/UpdateEvent (update [_ state] (assoc-in state [:workspace-file :ignore-sync-until] (dt/now))) diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 1cd2461e4b..205c2df165 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -12,7 +12,6 @@ [cljs.spec.alpha :as s] [app.common.spec :as us] [app.common.data :as d] - [app.common.pages :as cph] ;; TODO: remove this namespace [app.common.geom.point :as gpt] [app.common.geom.shapes :as geom] [app.common.pages :as cp] @@ -44,7 +43,6 @@ (declare generate-sync-shape-inverse-recursive) (declare compare-children) -(declare concat-changes) (declare add-shape-to-instance) (declare add-shape-to-master) (declare remove-shape) @@ -53,6 +51,19 @@ (declare update-attrs) (declare reposition-shape) +(defn concat-changes + [[rchanges1 uchanges1] [rchanges2 uchanges2]] + [(d/concat rchanges1 rchanges2) + (d/concat uchanges1 uchanges2)]) + +(defn get-local-library + [state] + (get state :workspace-data)) + +(defn get-libraries + [state] + (get state :workspace-libraries)) + ;; ---- Create a new component ---- @@ -60,7 +71,7 @@ "Clone the shape and all children. Generate new ids and detach from parent and frame. Update the original shapes to have links to the new ones." - [shape objects] + [shape objects file-id] (assert (nil? (:component-id shape))) (assert (nil? (:component-file shape))) (assert (nil? (:shape-ref shape))) @@ -88,23 +99,23 @@ (nil? (:parent-id new-shape)) (assoc :component-id (:id new-shape) - :component-file nil + :component-file file-id :component-root? true) (some? (:parent-id new-shape)) (dissoc :component-root?)))] - (cph/clone-object shape nil objects update-new-shape update-original-shape))) + (cp/clone-object shape nil objects update-new-shape update-original-shape))) (defn duplicate-component "Clone the root shape of the component and all children. Generate new ids from all of them." [component] - (let [component-root (cph/get-component-root component)] - (cph/clone-object component-root - nil - (get component :objects) - identity))) + (let [component-root (cp/get-component-root component)] + (cp/clone-object component-root + nil + (get component :objects) + identity))) ;; ---- General library synchronization functions ---- @@ -114,14 +125,14 @@ with the given asset of the given library." [asset-type library-id state] (s/assert #{:colors :components :typographies} asset-type) - (s/assert (s/nilable ::us/uuid) library-id) + (s/assert ::us/uuid library-id) (log/info :msg "Sync local file with library" :asset-type asset-type :library (str (or library-id "local"))) (let [library-items - (if (nil? library-id) + (if (= library-id (:current-file-id state)) (get-in state [:workspace-data asset-type]) (get-in state [:workspace-libraries library-id :data asset-type]))] @@ -136,7 +147,7 @@ (generate-sync-container asset-type library-id state - (cph/make-container page :page))] + (cp/make-container page :page))] (recur (next pages) (d/concat rchanges page-rchanges) (d/concat uchanges page-uchanges))) @@ -149,10 +160,10 @@ (log/info :msg "Sync local components with library" :asset-type asset-type - :library (str (or library-id "local"))) + :library (str library-id)) (let [library-items - (if (nil? library-id) + (if (= library-id (:current-file-id state)) (get-in state [:workspace-data asset-type]) (get-in state [:workspace-libraries library-id :data asset-type]))] (if (empty? library-items) @@ -166,8 +177,8 @@ (generate-sync-container asset-type library-id state - (cph/make-container local-component - :component))] + (cp/make-container local-component + :component))] (recur (next local-components) (d/concat rchanges comp-rchanges) (d/concat uchanges comp-uchanges))) @@ -178,12 +189,12 @@ (a page or a component) that are linked to the given library." [asset-type library-id state container] - (if (cph/page? container) + (if (cp/page? container) (log/debug :msg "Sync page in local file" :page-id (:id container)) (log/debug :msg "Sync component in local library" :component-id (:id container))) (let [has-asset-reference? (has-asset-reference-fn asset-type library-id) - linked-shapes (cph/select-objects has-asset-reference? container)] + linked-shapes (cp/select-objects has-asset-reference? container)] (loop [shapes (seq linked-shapes) rchanges [] uchanges []] @@ -209,22 +220,23 @@ (= (:component-file shape) library-id))) :colors - (fn [shape] (if (= (:type shape) :text) - (->> shape - :content - ;; Check if any node in the content has a reference for the library - (ut/some-node - #(or (and (some? (:stroke-color-ref-id %)) - (= library-id (:stroke-color-ref-file %))) - (and (some? (:fill-color-ref-id %)) - (= library-id (:fill-color-ref-file %)))))) - (some - #(let [attr (name %) - attr-ref-id (keyword (str attr "-ref-id")) - attr-ref-file (keyword (str attr "-ref-file"))] - (and (get shape attr-ref-id) - (= library-id (get shape attr-ref-file)))) - (map #(nth % 2) color-sync-attrs)))) + (fn [shape] + (if (= (:type shape) :text) + (->> shape + :content + ;; Check if any node in the content has a reference for the library + (ut/some-node + #(or (and (some? (:stroke-color-ref-id %)) + (= library-id (:stroke-color-ref-file %))) + (and (some? (:fill-color-ref-id %)) + (= library-id (:fill-color-ref-file %)))))) + (some + #(let [attr (name %) + attr-ref-id (keyword (str attr "-ref-id")) + attr-ref-file (keyword (str attr "-ref-file"))] + (and (get shape attr-ref-id) + (= library-id (get shape attr-ref-file)))) + (map #(nth % 2) color-sync-attrs)))) :typographies (fn [shape] @@ -233,8 +245,8 @@ :content ;; Check if any node in the content has a reference for the library (ut/some-node - #(and (some? (:typography-ref-id %)) - (= library-id (:typography-ref-file %))))))))) + #(and (some? (:typography-ref-id %)) + (= library-id (:typography-ref-file %))))))))) (defmulti generate-sync-shape "Generate changes to synchronize one shape, that use the given type @@ -245,11 +257,12 @@ [_ library-id state container shape] (generate-sync-shape-direct container (:id shape) - (get state :workspace-data) - (get state :workspace-libraries) + (get-local-library state) + (get-libraries state) false)) -(defn- generate-sync-text-shape [shape container update-node] +(defn- generate-sync-text-shape + [shape container update-node] (let [old-content (:content shape) new-content (ut/map-node update-node old-content) rchanges [(as-> {:type :mod-obj @@ -257,7 +270,7 @@ :operations [{:type :set :attr :content :val new-content}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] uchanges [(as-> {:type :mod-obj @@ -265,7 +278,7 @@ :operations [{:type :set :attr :content :val old-content}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] @@ -275,10 +288,11 @@ (defmethod generate-sync-shape :colors [_ library-id state container shape] + (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 [colors (get-assets library-id :colors state)] + (let [colors (get-assets library-id :colors state)] (if (= :text (:type shape)) (let [update-node (fn [node] (if-let [color (get colors (:fill-color-ref-id node))] @@ -298,13 +312,13 @@ (let [rchanges [(as-> {:type :mod-obj :id (:id shape) :operations roperations} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] uchanges [(as-> {:type :mod-obj :id (:id shape) :operations uoperations} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] [rchanges uchanges])) @@ -327,6 +341,7 @@ (defmethod generate-sync-shape :typographies [_ library-id state container shape] + (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." @@ -342,7 +357,7 @@ (defn- get-assets [library-id asset-type state] - (if (nil? library-id) + (if (= library-id (:current-file-id state)) (get-in state [:workspace-data asset-type]) (get-in state [:workspace-libraries library-id :data asset-type]))) @@ -354,17 +369,17 @@ be copied to this one. If reset? is true, all changed attributes will be copied and the 'touched' flags in the instance shape will be cleared." - [container shape-id local-file libraries reset?] + [container shape-id local-library libraries reset?] (log/debug :msg "Sync shape direct" :shape (str shape-id) :reset? reset?) - (let [shape-inst (cph/get-shape container shape-id) - component (cph/get-component (:component-id shape-inst) - (:component-file shape-inst) - local-file - libraries) - shape-master (cph/get-shape component (:shape-ref shape-inst)) + (let [shape-inst (cp/get-shape container shape-id) + component (cp/get-component (:component-id shape-inst) + (:component-file shape-inst) + local-library + libraries) + shape-master (cp/get-shape component (:shape-ref shape-inst)) root-inst shape-inst - root-master (cph/get-component-root component)] + root-master (cp/get-component-root component)] (generate-sync-shape-direct-recursive container shape-inst @@ -407,9 +422,9 @@ container options)) - children-inst (mapv #(cph/get-shape container %) + children-inst (mapv #(cp/get-shape container %) (:shapes shape-inst)) - children-master (mapv #(cph/get-shape component %) + children-master (mapv #(cp/get-shape component %) (:shapes shape-master)) only-inst (fn [shape-inst] @@ -468,18 +483,18 @@ shapes. And if the component shapes are, in turn, instances of a second component, their 'touched' flags will be set accordingly." - [page-id shape-id local-file libraries] + [page-id shape-id local-library libraries] (log/debug :msg "Sync shape inverse" :shape (str shape-id)) - (let [container (cph/get-container page-id :page local-file) - shape-inst (cph/get-shape container shape-id) - component (cph/get-component (:component-id shape-inst) - (:component-file shape-inst) - local-file - libraries) - shape-master (cph/get-shape component (:shape-ref shape-inst)) + (let [container (cp/get-container page-id :page local-library) + shape-inst (cp/get-shape container shape-id) + component (cp/get-component (:component-id shape-inst) + (:component-file shape-inst) + local-library + libraries) + shape-master (cp/get-shape component (:shape-ref shape-inst)) root-inst shape-inst - root-master (cph/get-component-root component)] + root-master (cp/get-component-root component)] (generate-sync-shape-inverse-recursive container shape-inst @@ -509,7 +524,7 @@ shape-master root-master) - component-container (cph/make-container component :component) + component-container (cp/make-container component :component) [rchanges uchanges] (concat-changes @@ -528,9 +543,9 @@ (change-touched shape-inst nil container {:reset-touched? true}) empty-changes))) - children-inst (mapv #(cph/get-shape container %) + children-inst (mapv #(cp/get-shape container %) (:shapes shape-inst)) - children-master (mapv #(cph/get-shape component %) + children-master (mapv #(cp/get-shape component %) (:shapes shape-master)) only-inst (fn [shape-inst] @@ -544,7 +559,7 @@ (remove-shape shape-master component-container false)) - + both (fn [shape-inst shape-master] (let [options (if-not (:component-id shape-inst) options @@ -607,15 +622,15 @@ children-inst) :else - (if (cph/is-master-of child-master child-inst) + (if (cp/is-master-of child-master child-inst) (recur (next children-inst) (next children-master) (concat-changes [rchanges uchanges] (both-cb child-inst child-master))) - (let [child-inst' (d/seek #(cph/is-master-of child-master %) + (let [child-inst' (d/seek #(cp/is-master-of child-master %) children-inst) - child-master' (d/seek #(cph/is-master-of % child-inst) + child-master' (d/seek #(cp/is-master-of % child-inst) children-master)] (cond (nil? child-inst') @@ -643,20 +658,15 @@ (concat-changes (both-cb child-inst child-master')) (concat-changes (moved-cb child-inst' child-master)))))))))))) -(defn concat-changes - [[rchanges1 uchanges1] [rchanges2 uchanges2]] - [(d/concat rchanges1 rchanges2) - (d/concat uchanges1 uchanges2)]) - (defn- add-shape-to-instance [component-shape component container root-instance root-master omit-touched?] (log/info :msg (str "ADD [P] " (:name component-shape))) - (let [component-parent-shape (cph/get-shape component (:parent-id component-shape)) - parent-shape (d/seek #(cph/is-master-of component-parent-shape %) - (cph/get-object-with-children (:id root-instance) - (:objects container))) + (let [component-parent-shape (cp/get-shape component (:parent-id component-shape)) + parent-shape (d/seek #(cp/is-master-of component-parent-shape %) + (cp/get-object-with-children (:id root-instance) + (:objects container))) all-parents (vec (cons (:id parent-shape) - (cph/get-parents parent-shape (:objects container)))) + (cp/get-parents parent-shape (:objects container)))) update-new-shape (fn [new-shape original-shape] (let [new-shape (reposition-shape new-shape @@ -667,32 +677,17 @@ (assoc :frame-id (:frame-id parent-shape)) (nil? (:shape-ref original-shape)) - (assoc :shape-ref (:id original-shape)) - - (some? (:shape-ref original-shape)) - (assoc :shape-ref (:shape-ref original-shape)) - - (:component-id original-shape) - (assoc :component-id (:component-id original-shape)) - - (:component-file original-shape) - (assoc :component-file (:component-file original-shape)) - - (:component-root original-shape) - (assoc :component-root (:component-root original-shape)) - - (:touched original-shape) - (assoc :touched (:touched original-shape))))) + (assoc :shape-ref (:id original-shape))))) update-original-shape (fn [original-shape new-shape] original-shape) [new-shape new-shapes _] - (cph/clone-object component-shape - (:id parent-shape) - (get component :objects) - update-new-shape - update-original-shape) + (cp/clone-object component-shape + (:id parent-shape) + (get component :objects) + update-new-shape + update-original-shape) rchanges (d/concat (mapv (fn [shape'] @@ -704,13 +699,13 @@ (cond-> $ (:frame-id shape') (assoc :frame-id (:frame-id shape'))) - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))) new-shapes) [(as-> {:type :reg-objects :shapes all-parents} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]) @@ -719,24 +714,24 @@ (as-> {:type :del-obj :id (:id shape') :ignore-touched true} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))) new-shapes))] - (if (and (cph/touched-group? parent-shape :shapes-group) omit-touched?) + (if (and (cp/touched-group? parent-shape :shapes-group) omit-touched?) empty-changes [rchanges uchanges]))) (defn- add-shape-to-master [shape component page root-instance root-master] (log/info :msg (str "ADD [C] " (:name shape))) - (let [parent-shape (cph/get-shape page (:parent-id shape)) - component-parent-shape (d/seek #(cph/is-master-of % parent-shape) - (cph/get-object-with-children (:id root-master) - (:objects component))) + (let [parent-shape (cp/get-shape page (:parent-id shape)) + component-parent-shape (d/seek #(cp/is-master-of % parent-shape) + (cp/get-object-with-children (:id root-master) + (:objects component))) all-parents (vec (cons (:id component-parent-shape) - (cph/get-parents component-parent-shape (:objects component)))) + (cp/get-parents component-parent-shape (:objects component)))) update-new-shape (fn [new-shape original-shape] (reposition-shape new-shape @@ -750,11 +745,11 @@ original-shape)) [new-shape new-shapes updated-shapes] - (cph/clone-object shape - (:id component-parent-shape) - (get page :objects) - update-new-shape - update-original-shape) + (cp/clone-object shape + (:id component-parent-shape) + (get page :objects) + update-new-shape + update-original-shape) rchanges (d/concat (mapv (fn [shape'] @@ -802,17 +797,17 @@ (defn- remove-shape [shape container omit-touched?] (log/info :msg (str "REMOVE-SHAPE " - (if (cph/page? container) "[P] " "[C] ") + (if (cp/page? container) "[P] " "[C] ") (:name shape))) (let [objects (get container :objects) - parents (cph/get-parents (:id shape) objects) + parents (cp/get-parents (:id shape) objects) parent (first parents) - children (cph/get-children (:id shape) objects) + children (cp/get-children (:id shape) objects) rchanges [(as-> {:type :del-obj :id (:id shape) :ignore-touched true} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] @@ -820,14 +815,14 @@ (let [shape' (get objects id)] (as-> {:type :add-obj :id id - :index (cph/position-on-parent id objects) + :index (cp/position-on-parent id objects) :parent-id (:parent-id shape') :ignore-touched true :obj shape'} $ (cond-> $ (:frame-id shape') (assoc :frame-id (:frame-id shape'))) - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container)))))) @@ -836,31 +831,31 @@ (map add-change children) [(as-> {:type :reg-objects :shapes (vec parents)} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))])] - (if (and (cph/touched-group? parent :shapes-group) omit-touched?) + (if (and (cp/touched-group? parent :shapes-group) omit-touched?) empty-changes [rchanges uchanges]))) (defn- move-shape [shape index-before index-after container omit-touched?] (log/info :msg (str "MOVE " - (if (cph/page? container) "[P] " "[C] ") + (if (cp/page? container) "[P] " "[C] ") (:name shape) " " index-before " -> " index-after)) - (let [parent (cph/get-shape container (:parent-id shape)) + (let [parent (cp/get-shape container (:parent-id shape)) rchanges [(as-> {:type :mov-objects :parent-id (:parent-id shape) :shapes [(:id shape)] :index index-after :ignore-touched true} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] uchanges [(as-> {:type :mov-objects @@ -868,11 +863,11 @@ :shapes [(:id shape)] :index index-before :ignore-touched true} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] - (if (and (cph/touched-group? parent :shapes-group) omit-touched?) + (if (and (cp/touched-group? parent :shapes-group) omit-touched?) empty-changes [rchanges uchanges]))) @@ -886,7 +881,7 @@ empty-changes (do (log/info :msg (str "CHANGE-TOUCHED " - (if (cph/page? container) "[P] " "[C] ") + (if (cp/page? container) "[P] " "[C] ") (:name dest-shape)) :options options) (let [rchanges [(as-> {:type :mod-obj @@ -898,7 +893,7 @@ nil copy-touched? (:touched orig-shape))}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] @@ -907,7 +902,7 @@ :operations [{:type :set-touched :touched (:touched dest-shape)}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] [rchanges uchanges])))) @@ -918,16 +913,16 @@ empty-changes (do (log/info :msg (str "SET-TOUCHED-SHAPES-GROUP " - (if (cph/page? container) "[P] " "[C] ") + (if (cp/page? container) "[P] " "[C] ") (:name shape))) (let [rchanges [(as-> {:type :mod-obj :id (:id shape) :operations [{:type :set-touched - :touched (cph/set-touched-group + :touched (cp/set-touched-group (:touched shape) :shapes-group)}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] @@ -936,7 +931,7 @@ :operations [{:type :set-touched :touched (:touched shape)}]} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] [rchanges uchanges])))) @@ -962,7 +957,7 @@ (log/info :msg (str "SYNC " (:name origin-shape) " -> " - (if (cph/page? container) "[P] " "[C] ") + (if (cp/page? container) "[P] " "[C] ") (:name dest-shape))) (let [; To synchronize geometry attributes we need to make a prior @@ -1002,13 +997,13 @@ rchanges [(as-> {:type :mod-obj :id (:id dest-shape) :operations roperations} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))] uchanges [(as-> {:type :mod-obj :id (:id dest-shape) :operations uoperations} $ - (if (cph/page? container) + (if (cp/page? container) (assoc $ :page-id (:id container)) (assoc $ :component-id (:id container))))]] [rchanges uchanges]) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index e2b13677f6..6ac073904f 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -112,7 +112,8 @@ (def workspace-local-library (l/derived (fn [state] (select-keys (get state :workspace-data) - [:colors + [:id + :colors :media :typographies :components])) diff --git a/frontend/src/app/main/store.cljs b/frontend/src/app/main/store.cljs index 333756e36e..db46995ad5 100644 --- a/frontend/src/app/main/store.cljs +++ b/frontend/src/app/main/store.cljs @@ -122,7 +122,7 @@ (let [root-shape (cp/get-root-shape shape objects) component-id (when root-shape (:component-id root-shape)) component-file-id (when root-shape (:component-file root-shape)) - component-file (when component-file-id (get libraries component-file-id)) + component-file (when component-file-id (get libraries component-file-id nil)) component (when component-id (if component-file (get-in component-file [:data :components component-id]) @@ -141,7 +141,7 @@ "" (let [component-id (:component-id shape) component-file-id (:component-file shape) - component-file (when component-file-id (get libraries component-file-id)) + component-file (when component-file-id (get libraries component-file-id nil)) component (if component-file (get-in component-file [:data :components component-id]) (get components component-id))] diff --git a/frontend/src/app/main/ui/handoff/attributes/text.cljs b/frontend/src/app/main/ui/handoff/attributes/text.cljs index 81c75388a4..e61c1922fd 100644 --- a/frontend/src/app/main/ui/handoff/attributes/text.cljs +++ b/frontend/src/app/main/ui/handoff/attributes/text.cljs @@ -36,7 +36,6 @@ (get-in state [:viewer-libraries file-id :data :typographies]))] #(l/derived get-library st/state))) - (def properties [:fill-color :fill-color-gradient :font-family diff --git a/frontend/src/app/main/ui/shapes/text/styles.cljs b/frontend/src/app/main/ui/shapes/text/styles.cljs index fa230f1af5..0ace637395 100644 --- a/frontend/src/app/main/ui/shapes/text/styles.cljs +++ b/frontend/src/app/main/ui/shapes/text/styles.cljs @@ -80,9 +80,6 @@ (-> (js->clj fill-color-gradient :keywordize-keys true) (update :type keyword))) - fill-color-ref-id (obj/get data "fill-color-ref-id") - fill-color-ref-file (obj/get data "fill-color-ref-file") - ;; Uncomment this to allow to remove text colors. This could break the texts that already exist ;;[r g b a] (if (nil? fill-color) ;; [0 0 0 0] ;; Transparent color diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index de51809668..026da3504c 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -16,6 +16,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.streams :as ms] + [app.main.ui.context :as ctx] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.hooks :refer [use-rxsub]] [app.main.ui.icons :as i] @@ -50,6 +51,8 @@ {:keys [id] :as shape} (:shape mdata) selected (:selected mdata) + current-file-id (mf/use-ctx ctx/current-file-id) + do-duplicate #(st/emit! dw/duplicate-selected) do-delete #(st/emit! dw/delete-selected) do-copy #(st/emit! dw/copy-selected) @@ -73,7 +76,7 @@ do-update-component #(do (st/emit! (dwc/start-undo-transaction)) (st/emit! (dwl/update-component id)) - (st/emit! (dwl/sync-file nil)) + (st/emit! (dwl/sync-file current-file-id)) (st/emit! (dwc/commit-undo-transaction))) do-show-component #(st/emit! (dw/go-to-layout :assets)) do-navigate-component-file #(st/emit! (dwl/nav-to-component-file @@ -154,7 +157,7 @@ ;; WARNING: this menu is the same as the context menu at the sidebar. ;; If you change it, you must change equally the file ;; app/main/ui/workspace/sidebar/options/component.cljs - (if (nil? (:component-file shape)) + (if (= (:component-file shape) current-file-id) [:* [:& menu-separator] [:& menu-entry {:title (t locale "workspace.shape.menu.detach-instance") diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 3b28d8daab..c02577c875 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -51,6 +51,7 @@ :top nil :left nil :component-id nil}) + on-duplicate (mf/use-callback (mf/deps state) @@ -61,7 +62,7 @@ (mf/deps state) (fn [] (st/emit! (dwl/delete-component {:id (:component-id @state)})) - (st/emit! (dwl/sync-file nil)))) + (st/emit! (dwl/sync-file file-id)))) on-rename (mf/use-callback @@ -99,7 +100,7 @@ on-drag-start (mf/use-callback (fn [component event] - (dnd/set-data! event "app/component" {:file-id (if local? nil file-id) + (dnd/set-data! event "app/component" {:file-id file-id :component component}) (dnd/set-allowed-effect! event "move")))] @@ -260,7 +261,7 @@ [(tr "workspace.assets.delete") on-delete]]}])])])) (mf/defc color-item - [{:keys [color local? locale] :as props}] + [{:keys [color local? file-id locale] :as props}] (let [rename? (= (:color-for-rename @refs/workspace-local) (:id color)) id (:id color) input-ref (mf/use-ref) @@ -283,12 +284,12 @@ rename-color (fn [name] - (st/emit! (dwl/update-color (assoc color :name name)))) + (st/emit! (dwl/update-color (assoc color :name name) file-id))) edit-color (fn [new-color] (let [updated-color (merge new-color (select-keys color [:id :file-id :name]))] - (st/emit! (dwl/update-color updated-color)))) + (st/emit! (dwl/update-color updated-color file-id)))) delete-color (fn [] @@ -406,9 +407,10 @@ (let [color (cond-> color (:value color) (assoc :color (:value color) :opacity 1) (:value color) (dissoc :value) - true (assoc :file-id (when (not local?) file-id)))] + true (assoc :file-id file-id))] [:& color-item {:key (:id color) :color color + :file-id file-id :local? local? :locale locale}]))])])) @@ -433,12 +435,12 @@ (mf/use-callback (mf/deps file-id) (fn [typography changes] - (st/emit! (dwl/update-typography (merge typography changes))))) + (st/emit! (dwl/update-typography (merge typography changes) file-id)))) handle-typography-selection (fn [typography] (let [attrs (merge - {:typography-ref-file (when-not local? file-id) + {:typography-ref-file file-id :typography-ref-id (:id typography)} (d/without-keys typography [:id :name]))] (run! #(st/emit! (dwt/update-text-attrs {:id % :editor (get-in local [:editors %]) :attrs attrs})) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs index 0d4a125b7f..a6f0a29dba 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs @@ -13,6 +13,7 @@ [app.common.pages :as cp] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.main.ui.components.context-menu :refer [context-menu]] [app.main.data.workspace :as dw] @@ -25,7 +26,9 @@ (mf/defc component-menu [{:keys [ids values] :as props}] - (let [id (first ids) + (let [current-file-id (mf/use-ctx ctx/current-file-id) + + id (first ids) locale (mf/deref i18n/locale) local (mf/use-state {:menu-open false}) @@ -51,7 +54,7 @@ do-update-component #(do (st/emit! (dwc/start-undo-transaction)) (st/emit! (dwl/update-component id)) - (st/emit! (dwl/sync-file nil)) + (st/emit! (dwl/sync-file current-file-id)) (st/emit! (dwc/commit-undo-transaction))) do-show-component #(st/emit! (dw/go-to-layout :assets)) do-navigate-component-file #(st/emit! (dwl/nav-to-component-file @@ -72,7 +75,7 @@ ;; app/main/ui/workspace/context_menu.cljs [:& context-menu {:on-close on-menu-close :show (:menu-open @local) - :options (if (nil? (:component-file values)) + :options (if (= (:component-file values) current-file-id) [[(t locale "workspace.shape.menu.detach-instance") do-detach-component] [(t locale "workspace.shape.menu.reset-overrides") do-reset-component] [(t locale "workspace.shape.menu.update-master") do-update-component] 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 c9fbbce617..f5b771dcef 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 @@ -21,6 +21,7 @@ [app.main.refs :as refs] [app.main.data.modal :as modal] [app.main.ui.hooks :as h] + [app.main.ui.context :as ctx] [app.main.ui.components.color-bullet :as cb] [app.main.ui.components.numeric-input :refer [numeric-input]])) @@ -64,11 +65,14 @@ (mf/defc color-row [{:keys [color disable-gradient disable-opacity on-change on-open on-close]}] - (let [file-colors (mf/deref refs/workspace-file-colors) - shared-libs (mf/deref refs/workspace-libraries) + (let [current-file-id (mf/use-ctx ctx/current-file-id) + file-colors (mf/deref refs/workspace-file-colors) + shared-libs (mf/deref refs/workspace-libraries) get-color-name (fn [{:keys [id file-id]}] - (let [src-colors (if file-id (get-in shared-libs [file-id :data :colors]) file-colors)] + (let [src-colors (if (= file-id current-file-id) + file-colors + (get-in shared-libs [file-id :data :colors]))] (get-in src-colors [id :name]))) parse-color (fn [color] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs index 25644aee75..2e51bde042 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs @@ -12,6 +12,7 @@ [rumext.alpha :as mf] [cuerdas.core :as str] [okulary.core :as l] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.common.data :as d] [app.common.uuid :as uuid] @@ -177,6 +178,7 @@ shapes] :as props}] (let [locale (mf/deref i18n/locale) + current-file-id (mf/use-ctx ctx/current-file-id) typographies (mf/deref refs/workspace-file-typography) shared-libs (mf/deref refs/workspace-libraries) label (case type @@ -201,16 +203,16 @@ typography (cond (and (:typography-ref-id values) (not= (:typography-ref-id values) :multiple) - (:typography-ref-file values)) + (not= (:typography-ref-file values) current-file-id)) (-> shared-libs (get-in [(:typography-ref-file values) :data :typographies (:typography-ref-id values)]) (assoc :file-id (:typography-ref-file values))) (and (:typography-ref-id values) - (not= (:typography-ref-id values) :multiple)) + (not= (:typography-ref-id values) :multiple) + (= (:typography-ref-file values) current-file-id)) (get typographies (:typography-ref-id values))) - on-convert-to-typography (mf/use-callback (mf/deps values) @@ -234,7 +236,7 @@ handle-change-typography (fn [changes] - (st/emit! (dwl/update-typography (merge typography changes)))) + (st/emit! (dwl/update-typography (merge typography changes) current-file-id))) opts #js {:editor editor :ids ids @@ -253,7 +255,7 @@ (cond typography [:& typography-entry {:typography typography - :read-only? (some? (:typography-ref-file values)) + :read-only? (not= (:typography-ref-file values) current-file-id) :file (get shared-libs (:typography-ref-file values)) :on-deattach handle-deattach-typography :on-change handle-change-typography}] diff --git a/frontend/src/app/util/code_gen.cljs b/frontend/src/app/util/code_gen.cljs index f40a4f3722..ab6dc65642 100644 --- a/frontend/src/app/util/code_gen.cljs +++ b/frontend/src/app/util/code_gen.cljs @@ -25,9 +25,7 @@ (defn format-fill-color [_ shape] (let [color {:color (:fill-color shape) :opacity (:fill-opacity shape) - :gradient (:fill-color-gradient shape) - :id (:fill-ref-id shape) - :file-id (:fill-ref-file-id shape)}] + :gradient (:fill-color-gradient shape)}] (uc/color->background color))) (defn format-stroke [_ shape] @@ -35,9 +33,7 @@ style (name (:stroke-style shape)) color {:color (:stroke-color shape) :opacity (:stroke-opacity shape) - :gradient (:stroke-color-gradient shape) - :id (:stroke-ref-id shape) - :file-id (:stroke-ref-file-id shape)}] + :gradient (:stroke-color-gradient shape)}] (str/format "%spx %s %s" width style (uc/color->background color)))) (def styles-data