From ea8bc687c048ff2c194718f65a0d3517e199ba05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Mon, 28 Jun 2021 16:00:50 +0200 Subject: [PATCH] :sparkles: Detach instance when syncing if the master component is gone --- .../app/main/data/workspace/libraries.cljs | 58 +------- .../data/workspace/libraries_helpers.cljs | 133 ++++++++++++------ 2 files changed, 97 insertions(+), 94 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 7996e492a..b267fb388 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -27,7 +27,7 @@ [beicon.core :as rx] [potok.core :as ptk])) -;; Change this to :info :debug or :trace to debug this module +;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default (log/set-level! :warn) (defn- log-changes @@ -450,57 +450,13 @@ (ptk/reify ::detach-component ptk/WatchEvent (watch [it state _] - (let [page-id (:current-page-id state) - objects (wsh/lookup-page-objects state page-id) - shapes (cp/get-object-with-children id objects) + (let [local-library (dwlh/get-local-file state) + container (cp/get-container (get state :current-page-id) + :page + local-library) - rchanges (mapv (fn [obj] - {:type :mod-obj - :page-id page-id - :id (:id obj) - :operations [{:type :set - :attr :component-id - :val nil} - {:type :set - :attr :component-file - :val nil} - {:type :set - :attr :component-root? - :val nil} - {:type :set - :attr :remote-synced? - :val nil} - {:type :set - :attr :shape-ref - :val nil} - {:type :set - :attr :touched - :val nil}]}) - shapes) - - uchanges (mapv (fn [obj] - {:type :mod-obj - :page-id page-id - :id (:id obj) - :operations [{:type :set - :attr :component-id - :val (:component-id obj)} - {:type :set - :attr :component-file - :val (:component-file obj)} - {:type :set - :attr :component-root? - :val (:component-root? obj)} - {:type :set - :attr :remote-synced? - :val (:remote-synced? obj)} - {:type :set - :attr :shape-ref - :val (:shape-ref obj)} - {:type :set - :attr :touched - :val (:touched obj)}]}) - shapes)] + [rchanges uchanges] + (dwlh/generate-detach-instance id container)] (rx/of (dch/commit-changes {:redo-changes rchanges :undo-changes uchanges diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 780b7b575..5c93525f4 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -17,7 +17,7 @@ [cljs.spec.alpha :as s] [clojure.set :as set])) -;; Change this to :info :debug or :trace to debug this module +;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default (log/set-level! :warn) (defonce empty-changes [[] []]) @@ -200,6 +200,63 @@ (get component :objects) identity))) +(defn generate-detach-instance + "Generate changes to remove the links between a shape and all its children + with a component." + [shape-id container] + (let [shapes (cp/get-object-with-children shape-id (:objects container)) + rchanges (mapv (fn [obj] + (make-change + container + {:type :mod-obj + :id (:id obj) + :operations [{:type :set + :attr :component-id + :val nil} + {:type :set + :attr :component-file + :val nil} + {:type :set + :attr :component-root? + :val nil} + {:type :set + :attr :remote-synced? + :val nil} + {:type :set + :attr :shape-ref + :val nil} + {:type :set + :attr :touched + :val nil}]})) + shapes) + + uchanges (mapv (fn [obj] + (make-change + container + {:type :mod-obj + :id (:id obj) + :operations [{:type :set + :attr :component-id + :val (:component-id obj)} + {:type :set + :attr :component-file + :val (:component-file obj)} + {:type :set + :attr :component-root? + :val (:component-root? obj)} + {:type :set + :attr :remote-synced? + :val (:remote-synced? obj)} + {:type :set + :attr :shape-ref + :val (:shape-ref obj)} + {:type :set + :attr :touched + :val (:touched obj)}]})) + shapes)] + + [rchanges uchanges])) + ;; ---- General library synchronization functions ---- @@ -216,26 +273,20 @@ :file (pretty-file file-id state) :library (pretty-file library-id state)) - (let [file (get-file state file-id) - library (get-file state library-id) - library-items (get library asset-type)] - - (if (empty? library-items) - empty-changes - - (loop [pages (vals (get file :pages-index)) - rchanges [] - uchanges []] - (if-let [page (first pages)] - (let [[page-rchanges page-uchanges] - (generate-sync-container asset-type - library-id - state - (cp/make-container page :page))] - (recur (next pages) - (d/concat rchanges page-rchanges) - (d/concat uchanges page-uchanges))) - [rchanges uchanges]))))) + (let [file (get-file state file-id)] + (loop [pages (vals (get file :pages-index)) + rchanges [] + uchanges []] + (if-let [page (first pages)] + (let [[page-rchanges page-uchanges] + (generate-sync-container asset-type + library-id + state + (cp/make-container page :page))] + (recur (next pages) + (d/concat rchanges page-rchanges) + (d/concat uchanges page-uchanges))) + [rchanges uchanges])))) (defn generate-sync-library "Generate changes to synchronize all shapes in all components of the @@ -248,27 +299,21 @@ :file (pretty-file file-id state) :library (pretty-file library-id state)) - (let [file (get-file state file-id) - library (get-file state library-id) - library-items (get library asset-type)] - - (if (empty? library-items) - empty-changes - - (loop [local-components (vals (get file :components)) - rchanges [] - uchanges []] - (if-let [local-component (first local-components)] - (let [[comp-rchanges comp-uchanges] - (generate-sync-container asset-type - library-id - state - (cp/make-container local-component - :component))] - (recur (next local-components) - (d/concat rchanges comp-rchanges) - (d/concat uchanges comp-uchanges))) - [rchanges uchanges]))))) + (let [file (get-file state file-id)] + (loop [local-components (vals (get file :components)) + rchanges [] + uchanges []] + (if-let [local-component (first local-components)] + (let [[comp-rchanges comp-uchanges] + (generate-sync-container asset-type + library-id + state + (cp/make-container local-component + :component))] + (recur (next local-components) + (d/concat rchanges comp-rchanges) + (d/concat uchanges comp-uchanges))) + [rchanges uchanges])))) (defn- generate-sync-container "Generate changes to synchronize all shapes in a particular container (a page @@ -568,7 +613,9 @@ root-main reset? initial-root?) - empty-changes))) + ; If the component is not found, because the master component has been + ; deleted or the library unlinked, detach the instance. + (generate-detach-instance shape-id container)))) (defn- generate-sync-shape-direct-recursive [container shape-inst component shape-main root-inst root-main reset? initial-root?]