From 880091a4f76b151488d726af008f411e811eea86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Wed, 23 Sep 2020 14:27:35 +0200 Subject: [PATCH] :tada: Update components leaving touched attrs --- common/app/common/pages.cljc | 60 +++++++- common/app/common/pages_helpers.cljc | 2 +- frontend/src/app/main/data/workspace.cljs | 4 +- .../src/app/main/data/workspace/common.cljs | 53 +++---- .../app/main/data/workspace/libraries.cljs | 130 +++++++++++------- .../main/ui/workspace/sidebar/history.cljs | 4 +- 6 files changed, 167 insertions(+), 86 deletions(-) diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index 6aa325c36..71e1fe887 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -213,6 +213,33 @@ :internal.shape/selrect :internal.shape/points])) +(def sync-attrs {:fill-color :fill-group + :fill-color-ref-file :fill-group + :fill-color-ref-id :fill-group + :fill-opacity :fill-group + :content :text-content-group + :font-family :text-font-group + :font-size :text-font-group + :font-style :text-font-group + :font-weight :text-font-group + :letter-spacing :text-display-group + :line-height :text-display-group + :text-align :text-display-group + :stroke-color :stroke-group + :stroke-color-ref-file :stroke-group + :stroke-color-ref-id :stroke-group + :stroke-opacity :stroke-group + :stroke-style :stroke-group + :stroke-width :stroke-group + :stroke-alignment :stroke-group + :width :size-group + :height :size-group + :proportion :size-group + :rx :radius-group + :ry :radius-group + :points :points-group + :transform :transform-group}) + (s/def ::minimal-shape (s/keys :req-un [::type ::name] :opt-un [::id])) @@ -286,11 +313,16 @@ (s/def :internal.operations.set/attr keyword?) (s/def :internal.operations.set/val any?) +(s/def :internal.operations.set/touched + (s/nilable (s/every keyword? :kind set?))) (defmethod operation-spec :set [_] (s/keys :req-un [:internal.operations.set/attr :internal.operations.set/val])) +(defmethod operation-spec :set-touched [_] + (s/keys :req-un [:internal.operations.set/touched])) + (defmulti change-spec :type) (s/def :internal.changes.set-option/option any?) @@ -795,11 +827,29 @@ (defmethod process-operation :set [shape op] - (let [attr (:attr op) - val (:val op)] - (if (nil? val) - (dissoc shape attr) - (assoc shape attr val)))) + (let [attr (:attr op) + val (:val op) + ignore (:ignore-touched op) + shape-ref (:shape-ref shape) + group (get sync-attrs attr)] + + (cond-> shape + (nil? val) + (dissoc attr) + + (some? val) + (assoc attr val) + + (and shape-ref group (not ignore)) + (update :touched #(conj (or % #{}) group))))) + +(defmethod process-operation :set-touched + [shape op] + (let [touched (:touched op) + shape-ref (:shape-ref shape)] + (if (or (nil? shape-ref) (nil? touched) (empty? touched)) + (dissoc shape :touched) + (assoc shape :touched touched)))) (defmethod process-operation :default [shape op] diff --git a/common/app/common/pages_helpers.cljc b/common/app/common/pages_helpers.cljc index 53be7402a..08a0c4bed 100644 --- a/common/app/common/pages_helpers.cljc +++ b/common/app/common/pages_helpers.cljc @@ -186,7 +186,7 @@ updated-object (update-original-object object new-object) - updated-objects (if (= object updated-object) + updated-objects (if (identical? object updated-object) updated-children (concat [updated-object] updated-children))] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 48a73d2b5..e809a4c0b 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -895,7 +895,7 @@ (let [curr (first moved) prev (get objects (:id curr)) ops1 (dwc/generate-operations prev curr) - ops2 (dwc/generate-operations curr prev)] + ops2 (dwc/generate-operations curr prev true)] (recur (next moved) (conj rchanges {:type :mod-obj :page-id page-id @@ -942,7 +942,7 @@ (let [curr (first moved) prev (get objects (:id curr)) ops1 (dwc/generate-operations prev curr) - ops2 (dwc/generate-operations curr prev)] + ops2 (dwc/generate-operations curr prev true)] (recur (next moved) (conj rchanges {:type :mod-obj :page-id page-id diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index 422b4a379..7b079dea3 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -86,28 +86,33 @@ (rx/of (append-undo entry)))))))))) (defn generate-operations - [ma mb] - (let [ma-keys (set (keys ma)) - mb-keys (set (keys mb)) - added (set/difference mb-keys ma-keys) - removed (set/difference ma-keys mb-keys) - both (set/intersection ma-keys mb-keys)] - (d/concat - (mapv #(array-map :type :set :attr % :val (get mb %)) added) - (mapv #(array-map :type :set :attr % :val nil) removed) - (loop [items (seq both) - result []] - (if items - (let [k (first items) - vma (get ma k) - vmb (get mb k)] - (if (= vma vmb) - (recur (next items) result) - (recur (next items) - (conj result {:type :set - :attr k - :val vmb})))) - result))))) + ([ma mb] (generate-operations ma mb false)) + ([ma mb undo?] + (let [ops (let [ma-keys (set (keys ma)) + mb-keys (set (keys mb)) + added (set/difference mb-keys ma-keys) + removed (set/difference ma-keys mb-keys) + both (set/intersection ma-keys mb-keys)] + (d/concat + (mapv #(array-map :type :set :attr % :val (get mb %)) added) + (mapv #(array-map :type :set :attr % :val nil) removed) + (loop [items (seq both) + result []] + (if items + (let [k (first items) + vma (get ma k) + vmb (get mb k)] + (if (= vma vmb) + (recur (next items) result) + (recur (next items) + (conj result {:type :set + :attr k + :val vmb + :ignore-touched undo?})))) + result))))] + (if undo? + (conj ops {:type :set-touched :touched (:touched mb)}) + ops)))) (defn generate-changes [page-id objects1 objects2] @@ -415,7 +420,7 @@ obj1 (get objects id) obj2 (f obj1) rch-operations (generate-operations obj1 obj2) - uch-operations (generate-operations obj2 obj1) + uch-operations (generate-operations obj2 obj1 true) rchg {:type :mod-obj :page-id page-id :operations rch-operations @@ -456,7 +461,7 @@ obj1 (get objects id) obj2 (f obj1) rops (generate-operations obj1 obj2) - uops (generate-operations obj2 obj1) + uops (generate-operations obj2 obj1 true) rchg {:type :mod-obj :page-id page-id :operations rops diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 7e1c0b189..685bbf7e6 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -366,7 +366,6 @@ (declare remove-component-and-ref) (declare remove-ref) (declare update-attrs) -(declare sync-attrs) (declare calc-new-pos) (defn reset-component @@ -388,7 +387,7 @@ (get-in state [:workspace-libraries file-id :data :components])) [rchanges uchanges] - (generate-sync-shape-and-children root-shape page components)] + (generate-sync-shape-and-children root-shape page components true)] (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) @@ -418,18 +417,37 @@ (some? (:shape-ref original-shape)) (assoc :id (:shape-ref original-shape)))) - [new-shape new-shapes _] - (cph/clone-object root-shape nil objects update-new-shape) + touch-shape (fn [original-shape _] + (into {} original-shape)) - rchanges [{:type :mod-component + [new-shape new-shapes original-shapes] + (cph/clone-object root-shape nil objects update-new-shape touch-shape) + + rchanges (concat + [{:type :mod-component :id component-id :name (:name new-shape) :shapes new-shapes}] + (map (fn [shape] + {:type :mod-obj + :page-id page-id + :id (:id shape) + :operations [{:type :set-touched + :touched nil}]}) + original-shapes)) - uchanges [{:type :mod-component - :id component-id - :name (:name component-obj) - :shapes (vals component-objs)}]] + uchanges (concat + [{:type :mod-component + :id component-id + :name (:name component-obj) + :shapes (vals component-objs)}] + (map (fn [shape] + {:type :mod-obj + :page-id page-id + :id (:id shape) + :operations [{:type :set-touched + :touched (:touched shape)}]}) + original-shapes))] (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) @@ -520,13 +538,13 @@ (if (nil? shape) [rchanges uchanges] (let [[shape-rchanges shape-uchanges] - (generate-sync-shape-and-children shape page components)] + (generate-sync-shape-and-children shape page components false)] (recur (next shapes) (concat rchanges shape-rchanges) (concat uchanges shape-uchanges)))))))) (defn- generate-sync-shape-and-children - [root-shape page components] + [root-shape page components reset-touched?] (let [objects (get page :objects) all-shapes (cph/get-object-with-children (:id root-shape) objects) component (get components (:component-id root-shape)) @@ -538,19 +556,24 @@ (if (nil? shape) [rchanges uchanges] (let [[shape-rchanges shape-uchanges] - (generate-sync-shape shape root-shape root-component page component)] + (generate-sync-shape shape root-shape root-component page component reset-touched?)] (recur (next shapes) (concat rchanges shape-rchanges) (concat uchanges shape-uchanges)))))))) (defn- generate-sync-shape - [shape root-shape root-component page component] + [shape root-shape root-component page component reset-touched?] (if (nil? component) (remove-component-and-ref shape page) (let [component-shape (get (:objects component) (:shape-ref shape))] (if (nil? component-shape) (remove-ref shape page) - (update-attrs shape component-shape root-shape root-component page))))) + (update-attrs shape + component-shape + root-shape + root-component + page + reset-touched?))))) (defn- remove-component-and-ref [shape page] @@ -565,7 +588,9 @@ :val nil} {:type :set :attr :shape-ref - :val nil}]}] + :val nil} + {:type :set-touched + :touched nil}]}] [{:type :mod-obj :page-id (:id page) :id (:id shape) @@ -577,7 +602,9 @@ :val (:component-file shape)} {:type :set :attr :shape-ref - :val (:shape-ref shape)}]}]]) + :val (:shape-ref shape)} + {:type :set-touched + :touched (:touched shape)}]}]]) (defn- remove-ref [shape page] @@ -586,18 +613,22 @@ :id (:id shape) :operations [{:type :set :attr :shape-ref - :val nil}]}] + :val nil} + {:type :set-touched + :touched nil}]}] [{:type :mod-obj :page-id (:id page) :id (:id shape) :operations [{:type :set :attr :shape-ref - :val (:shape-ref shape)}]}]]) + :val (:shape-ref shape)} + {:type :set-touched + :touched (:touched shape)}]}]]) (defn- update-attrs - [shape component-shape root-shape root-component page] + [shape component-shape root-shape root-component page reset-touched?] (let [new-pos (calc-new-pos shape component-shape root-shape root-component)] - (loop [attrs (seq sync-attrs) + (loop [attrs (seq (keys cp/sync-attrs)) roperations [{:type :set :attr :x :val (:x new-pos)} @@ -613,7 +644,19 @@ (let [attr (first attrs)] (if (nil? attr) - (let [rchanges [{:type :mod-obj + (let [roperations (if reset-touched? + (conj roperations + {:type :set-touched + :touched nil}) + roperations) + + uoperations (if reset-touched? + (conj uoperations + {:type :set-touched + :touched (:touched shape)}) + uoperations) + + rchanges [{:type :mod-obj :page-id (:id page) :id (:id shape) :operations roperations}] @@ -628,41 +671,22 @@ uoperations) (let [roperation {:type :set :attr attr - :val (get component-shape attr)} + :val (get component-shape attr) + :ignore-touched true} uoperation {:type :set :attr attr - :val (get shape attr)}] - (recur (next attrs) - (conj roperations roperation) - (conj uoperations uoperation))))))))) + :val (get shape attr) + :ignore-touched true} -(def sync-attrs [:content - :fill-color - :fill-color-ref-file - :fill-color-ref-id - :fill-opacity - :font-family - :font-size - :font-style - :font-weight - :letter-spacing - :line-height - :proportion - :rx - :ry - :stroke-color - :stroke-color-ref-file - :stroke-color-ref-id - :stroke-opacity - :stroke-style - :stroke-width - :stroke-alignment - :text-align - :width - :height - :interactions - :points - :transform]) + attr-group (get cp/sync-attrs attr) + touched (get shape :touched #{})] + (if (or (not (touched attr-group)) reset-touched?) + (recur (next attrs) + (conj roperations roperation) + (conj uoperations uoperation)) + (recur (next attrs) + roperations + uoperations))))))))) (defn- calc-new-pos [shape component-shape root-shape root-component] diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.cljs b/frontend/src/app/main/ui/workspace/sidebar/history.cljs index 369daf8cb..5cc931dcf 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/history.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/history.cljs @@ -34,7 +34,9 @@ [:div.undo-entry-change {:key (str "change-" idx-change)} [:div.undo-entry-change-data (when type (str type)) " " (when id (str (get-in objects [id :name] (subs (str id) 0 8))))] (when operations - [:div.undo-entry-change-data (str/join ", " (map (comp name :attr) operations))])])])) + [:div.undo-entry-change-data (str/join ", " + (map (comp name :attr) + (filter #(= (:type %) :set) operations)))])])])) (mf/defc history-toolbox [] (let [locale (mf/deref i18n/locale)