diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index dbd7eca00..0cdcf64de 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -7,7 +7,6 @@ (ns app.main.data.workspace (:require [app.common.data :as d] - [app.common.exceptions :as ex] [app.common.geom.align :as gal] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] @@ -19,37 +18,31 @@ [app.common.spec :as us] [app.common.uuid :as uuid] [app.config :as cfg] - [app.main.constants :as c] - [app.main.data.workspace.colors :as mdc] [app.main.data.messages :as dm] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.drawing :as dwd] - [app.main.data.workspace.path :as dwdp] [app.main.data.workspace.groups :as dwg] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.notifications :as dwn] + [app.main.data.workspace.path :as dwdp] [app.main.data.workspace.persistence :as dwp] [app.main.data.workspace.selection :as dws] - [app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.svg-upload :as svg] + [app.main.data.workspace.transforms :as dwt] + [app.main.data.workspace.undo :as dwu] [app.main.repo :as rp] - [app.main.store :as st] [app.main.streams :as ms] - [app.main.worker :as uw] - [app.util.dom :as dom] [app.util.http :as http] - [app.util.i18n :refer [tr] :as i18n] + [app.util.i18n :as i18n] [app.util.logging :as log] - [app.util.object :as obj] [app.util.router :as rt] - [app.util.timers :as ts] [app.util.transit :as t] [app.util.webapi :as wapi] [beicon.core :as rx] [cljs.spec.alpha :as s] [clojure.set :as set] [cuerdas.core :as str] - [goog.string.path :as path] [potok.core :as ptk])) ;; (log/set-level! :trace) @@ -269,7 +262,7 @@ :name name} uchange {:type :del-page :id id}] - (rx/of (dwc/commit-changes [rchange] [uchange] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchange] [uchange] {:commit-local? true})))))) (defn duplicate-page [page-id] (ptk/reify ::duplicate-page @@ -287,7 +280,7 @@ :page page} uchange {:type :del-page :id id}] - (rx/of (dwc/commit-changes [rchange] [uchange] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchange] [uchange] {:commit-local? true})))))) (s/def ::rename-page (s/keys :req-un [::id ::name])) @@ -306,7 +299,7 @@ uchg {:type :mod-page :id id :name (:name page)}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) (declare purge-page) (declare go-to-file) @@ -323,7 +316,7 @@ :id id} uchg {:type :add-page :page page}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}) (when (= id (:current-page-id state)) go-to-file)))))) @@ -604,7 +597,7 @@ (ptk/reify ::update-shape ptk/WatchEvent (watch [_ state stream] - (rx/of (dwc/update-shapes [id] #(merge % attrs)))))) + (rx/of (dch/update-shapes [id] #(merge % attrs)))))) (defn start-rename-shape [id] @@ -712,7 +705,7 @@ :index (cp/position-on-parent id objects)})) selected)] ;; TODO: maybe missing the :reg-objects event? - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) ;; --- Change Shape Order (D&D Ordering) @@ -986,7 +979,7 @@ shapes-to-detach shapes-to-reroot shapes-to-deroot)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/expand-collapse parent-id)))))) (defn relocate-selected-shapes @@ -1039,7 +1032,7 @@ uchg {:type :mov-page :id id :index cidx}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) ;; --- Shape / Selection Alignment and Distribution @@ -1141,7 +1134,7 @@ (assoc shape :proportion-lock false) (-> (assoc shape :proportion-lock true) (gpr/assign-proportions))))] - (rx/of (dwc/update-shapes [id] assign-proportions)))))) + (rx/of (dch/update-shapes [id] assign-proportions)))))) ;; --- Update Shape Position @@ -1183,7 +1176,7 @@ (cond-> obj (boolean? blocked) (assoc :blocked blocked) (boolean? hidden) (assoc :hidden hidden)))] - (rx/of (dwc/update-shapes-recursive [id] update-fn)))))) + (rx/of (dch/update-shapes-recursive [id] update-fn)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1410,7 +1403,7 @@ (catch :default e (let [data (ex-data e)] (if (:not-implemented data) - (rx/of (dm/warn (tr "errors.clipboard-not-implemented"))) + (rx/of (dm/warn (i18n/tr "errors.clipboard-not-implemented"))) (js/console.error "ERROR" e)))))))) (defn paste-from-event @@ -1582,7 +1575,7 @@ (map #(get-in % [:obj :id])) (into (d/ordered-set)))] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes selected))))] (ptk/reify ::paste-shape ptk/WatchEvent @@ -1629,10 +1622,10 @@ :height height :grow-type (if (> (count text) 100) :auto-height :auto-width) :content (as-content text)})] - (rx/of (dwc/start-undo-transaction) + (rx/of (dwu/start-undo-transaction) (dws/deselect-all) (dwc/add-shape shape) - (dwc/commit-undo-transaction)))))) + (dwu/commit-undo-transaction)))))) (defn- paste-svg [text] @@ -1743,7 +1736,7 @@ (let [page-id (get state :current-page-id) options (dwc/lookup-page-options state page-id) previus-color (:background options)] - (rx/of (dwc/commit-changes + (rx/of (dch/commit-changes [{:type :set-option :page-id page-id :option :background diff --git a/frontend/src/app/main/data/workspace/changes.cljs b/frontend/src/app/main/data/workspace/changes.cljs new file mode 100644 index 000000000..49ae693c5 --- /dev/null +++ b/frontend/src/app/main/data/workspace/changes.cljs @@ -0,0 +1,219 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.main.data.workspace.changes + (:require + [app.common.data :as d] + [app.common.pages :as cp] + [app.common.pages.spec :as spec] + [app.common.spec :as us] + [app.main.data.workspace.undo :as dwu] + [app.main.worker :as uw] + [app.util.logging :as log] + [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 ::coll-of-uuid + (s/every ::us/uuid)) + +(defonce page-change? #{:add-page :mod-page :del-page :mov-page}) + +(declare commit-changes) + +(def commit-changes? (ptk/type? ::commit-changes)) + +(defn- generate-operations + ([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 update-shapes + ([ids f] (update-shapes ids f nil)) + ([ids f {:keys [reg-objects?] :or {reg-objects? false}}] + (us/assert ::coll-of-uuid ids) + (us/assert fn? f) + (ptk/reify ::update-shapes + ptk/WatchEvent + (watch [_ state stream] + (let [page-id (:current-page-id state) + objects (get-in state [:workspace-data :pages-index page-id :objects])] + (loop [ids (seq ids) + rch [] + uch []] + (if (nil? ids) + (rx/of (commit-changes + (cond-> rch reg-objects? (conj {:type :reg-objects :page-id page-id :shapes (vec ids)})) + (cond-> uch reg-objects? (conj {:type :reg-objects :page-id page-id :shapes (vec ids)})) + {:commit-local? true})) + + (let [id (first ids) + obj1 (get objects id) + obj2 (f obj1) + rch-operations (generate-operations obj1 obj2) + uch-operations (generate-operations obj2 obj1 true) + rchg {:type :mod-obj + :page-id page-id + :operations rch-operations + :id id} + uchg {:type :mod-obj + :page-id page-id + :operations uch-operations + :id id}] + (recur (next ids) + (if (empty? rch-operations) rch (conj rch rchg)) + (if (empty? uch-operations) uch (conj uch uchg))))))))))) + +(defn update-shapes-recursive + [ids f] + (us/assert ::coll-of-uuid ids) + (us/assert fn? f) + (letfn [(impl-get-children [objects id] + (cons id (cp/get-children id objects))) + + (impl-gen-changes [objects page-id ids] + (loop [sids (seq ids) + cids (seq (impl-get-children objects (first sids))) + rchanges [] + uchanges []] + (cond + (nil? sids) + [rchanges uchanges] + + (nil? cids) + (recur (next sids) + (seq (impl-get-children objects (first (next sids)))) + rchanges + uchanges) + + :else + (let [id (first cids) + obj1 (get objects id) + obj2 (f obj1) + rops (generate-operations obj1 obj2) + uops (generate-operations obj2 obj1 true) + rchg {:type :mod-obj + :page-id page-id + :operations rops + :id id} + uchg {:type :mod-obj + :page-id page-id + :operations uops + :id id}] + (recur sids + (next cids) + (conj rchanges rchg) + (conj uchanges uchg))))))] + (ptk/reify ::update-shapes-recursive + ptk/WatchEvent + (watch [_ state stream] + (let [page-id (:current-page-id state) + objects (get-in state [:workspace-data :pages-index page-id :objects]) + [rchanges uchanges] (impl-gen-changes objects page-id (seq ids))] + (rx/of (commit-changes rchanges uchanges {:commit-local? true}))))))) + +(defn update-indices + [page-id changes] + (ptk/reify ::update-indices + ptk/EffectEvent + (effect [_ state stream] + (uw/ask! {:cmd :update-page-indices + :page-id page-id + :changes changes})))) + +(defn commit-changes + ([changes undo-changes] + (commit-changes changes undo-changes {})) + ([changes undo-changes {:keys [save-undo? + commit-local? + file-id] + :or {save-undo? true + commit-local? false} + :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 + cljs.core/IDeref + (-deref [_] {:file-id file-id :changes changes}) + + ptk/UpdateEvent + (update [_ state] + (let [current-file-id (get state :current-file-id) + file-id (or file-id current-file-id) + path1 (if (= file-id current-file-id) + [:workspace-file :data] + [:workspace-libraries file-id :data]) + path2 (if (= file-id current-file-id) + [:workspace-data] + [:workspace-libraries file-id :data])] + (try + (us/verify ::spec/changes changes) + (let [state (update-in state path1 cp/process-changes changes false)] + (cond-> state + commit-local? (update-in path2 cp/process-changes changes false))) + (catch :default e + (vreset! error e) + state)))) + + ptk/WatchEvent + (watch [_ state stream] + (when-not @error + (let [;; adds page-id to page changes (that have the `id` field instead) + add-page-id + (fn [{:keys [id type page] :as change}] + (cond-> change + (page-change? type) + (assoc :page-id (or id (:id page))))) + + changes-by-pages + (->> changes + (map add-page-id) + (remove #(nil? (:page-id %))) + (group-by :page-id)) + + process-page-changes + (fn [[page-id changes]] + (update-indices page-id changes))] + (rx/concat + (rx/from (map process-page-changes changes-by-pages)) + + (when (and save-undo? (seq undo-changes)) + (let [entry {:undo-changes undo-changes + :redo-changes changes}] + (rx/of (dwu/append-undo entry)))))))))))) diff --git a/frontend/src/app/main/data/workspace/colors.cljs b/frontend/src/app/main/data/workspace/colors.cljs index 6a27b8f92..d43d36905 100644 --- a/frontend/src/app/main/data/workspace/colors.cljs +++ b/frontend/src/app/main/data/workspace/colors.cljs @@ -13,6 +13,7 @@ [app.main.data.modal :as md] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.texts :as dwt] + [app.main.data.workspace.changes :as dch] [app.main.repo :as rp] [app.main.store :as st] [app.main.streams :as ms] @@ -150,7 +151,7 @@ (rx/concat (rx/from (map #(dwt/update-text-attrs {:id % :attrs attrs}) text-ids)) - (rx/of (dwc/update-shapes shape-ids (fn [shape] (d/merge shape attrs))))))))) + (rx/of (dch/update-shapes shape-ids (fn [shape] (d/merge shape attrs))))))))) (defn change-stroke [ids color] @@ -176,7 +177,7 @@ (contains? color :opacity) (assoc :stroke-opacity (:opacity color)))] - (rx/of (dwc/update-shapes ids (fn [shape] + (rx/of (dch/update-shapes ids (fn [shape] (cond-> (d/merge shape attrs) (= (:stroke-style shape) :none) (assoc :stroke-style :solid diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index c8f4c3393..b5d8ced0d 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -10,17 +10,15 @@ [app.common.geom.proportions :as gpr] [app.common.geom.shapes :as gsh] [app.common.pages :as cp] - [app.common.pages.spec :as spec] [app.common.spec :as us] [app.common.uuid :as uuid] - [app.main.worker :as uw] + [app.main.data.workspace.changes :as dch] + [app.main.data.workspace.undo :as dwu] [app.main.streams :as ms] + [app.main.worker :as uw] [app.util.logging :as log] - [app.util.timers :as ts] [beicon.core :as rx] [cljs.spec.alpha :as s] - [clojure.set :as set] - [cuerdas.core :as str] [potok.core :as ptk])) ;; Change this to :info :debug or :trace to debug this module @@ -58,121 +56,6 @@ (get-in state [:workspace-data :components component-id :objects]))) -;; --- Changes Handling - -(defonce page-change? #{:add-page :mod-page :del-page :mov-page}) - -(defn commit-changes - ([changes undo-changes] - (commit-changes changes undo-changes {})) - ([changes undo-changes {:keys [save-undo? - commit-local? - file-id] - :or {save-undo? true - commit-local? false} - :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 - cljs.core/IDeref - (-deref [_] {:file-id file-id :changes changes}) - - ptk/UpdateEvent - (update [_ state] - (let [current-file-id (get state :current-file-id) - file-id (or file-id current-file-id) - path1 (if (= file-id current-file-id) - [:workspace-file :data] - [:workspace-libraries file-id :data]) - path2 (if (= file-id current-file-id) - [:workspace-data] - [:workspace-libraries file-id :data])] - (try - (us/verify ::spec/changes changes) - (let [state (update-in state path1 cp/process-changes changes false)] - (cond-> state - commit-local? (update-in path2 cp/process-changes changes false))) - (catch :default e - (vreset! error e) - state)))) - - ptk/WatchEvent - (watch [_ state stream] - (when-not @error - (let [;; adds page-id to page changes (that have the `id` field instead) - add-page-id - (fn [{:keys [id type page] :as change}] - (cond-> change - (page-change? type) - (assoc :page-id (or id (:id page))))) - - changes-by-pages - (->> changes - (map add-page-id) - (remove #(nil? (:page-id %))) - (group-by :page-id)) - - process-page-changes - (fn [[page-id changes]] - (update-indices page-id changes))] - (rx/concat - (rx/from (map process-page-changes changes-by-pages)) - - (when (and save-undo? (seq undo-changes)) - (let [entry {:undo-changes undo-changes - :redo-changes changes}] - (rx/of (append-undo entry)))))))))))) - -(defn generate-operations - ([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] - (letfn [(impl-diff [res id] - (let [obj1 (get objects1 id) - obj2 (get objects2 id) - ops (generate-operations (dissoc obj1 :shapes :frame-id) - (dissoc obj2 :shapes :frame-id))] - (if (empty? ops) - res - (conj res {:type :mod-obj - :page-id page-id - :operations ops - :id id}))))] - (reduce impl-diff [] (set/union (set (keys objects1)) - (set (keys objects2)))))) - ;; --- Selection Index Handling (defn initialize-indices @@ -186,14 +69,7 @@ (->> (uw/ask! msg) (rx/map (constantly ::index-initialized))))))) -(defn update-indices - [page-id changes] - (ptk/reify ::update-indices - ptk/EffectEvent - (effect [_ state stream] - (uw/ask! {:cmd :update-page-indices - :page-id page-id - :changes changes})))) + ;; --- Common Helpers & Events @@ -253,110 +129,8 @@ (update state :workspace-local dissoc :expanded)))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Undo / Redo -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(s/def ::undo-changes ::cp/changes) -(s/def ::redo-changes ::cp/changes) -(s/def ::undo-entry - (s/keys :req-un [::undo-changes ::redo-changes])) - -(def MAX-UNDO-SIZE 50) - -(defn- conj-undo-entry - [undo data] - (let [undo (conj undo data) - cnt (count undo)] - (if (> cnt MAX-UNDO-SIZE) - (subvec undo (- cnt MAX-UNDO-SIZE)) - undo))) - -(defn- materialize-undo - [changes index] - (ptk/reify ::materialize-undo - ptk/UpdateEvent - (update [_ state] - (-> state - (update :workspace-data cp/process-changes changes) - (assoc-in [:workspace-undo :index] index))))) - -(defn- reset-undo - [index] - (ptk/reify ::reset-undo - ptk/UpdateEvent - (update [_ state] - (-> state - (update :workspace-undo dissoc :undo-index) - (update-in [:workspace-undo :items] (fn [queue] (into [] (take (inc index) queue)))))))) - -(defn- add-undo-entry - [state entry] - (if (and entry - (not-empty (:undo-changes entry)) - (not-empty (:redo-changes entry))) - (let [index (get-in state [:workspace-undo :index] -1) - items (get-in state [:workspace-undo :items] []) - items (->> items (take (inc index)) (into [])) - items (conj-undo-entry items entry)] - (-> state - (update :workspace-undo assoc :items items - :index (min (inc index) - (dec MAX-UNDO-SIZE))))) - state)) - -(defn- accumulate-undo-entry - [state {:keys [undo-changes redo-changes]}] - (-> state - (update-in [:workspace-undo :transaction :undo-changes] #(into undo-changes %)) - (update-in [:workspace-undo :transaction :redo-changes] #(into % redo-changes)))) - -(defn- append-undo - [entry] - (us/verify ::undo-entry entry) - (ptk/reify ::append-undo - ptk/UpdateEvent - (update [_ state] - (if (get-in state [:workspace-undo :transaction]) - (accumulate-undo-entry state entry) - (add-undo-entry state entry))))) - -(defonce empty-tx {:undo-changes [] :redo-changes []}) - -(defn start-undo-transaction [] - (ptk/reify ::start-undo-transaction - ptk/UpdateEvent - (update [_ state] - ;; We commit the old transaction before starting the new one - (let [current-tx (get-in state [:workspace-undo :transaction])] - (cond-> state - (nil? current-tx) (assoc-in [:workspace-undo :transaction] empty-tx)))))) - -(defn discard-undo-transaction [] - (ptk/reify ::discard-undo-transaction - ptk/UpdateEvent - (update [_ state] - (update state :workspace-undo dissoc :transaction)))) - -(defn commit-undo-transaction [] - (ptk/reify ::commit-undo-transaction - ptk/UpdateEvent - (update [_ state] - (-> state - (add-undo-entry (get-in state [:workspace-undo :transaction])) - (update :workspace-undo dissoc :transaction))))) - -(def pop-undo-into-transaction - (ptk/reify ::last-undo-into-transaction - ptk/UpdateEvent - (update [_ state] - (let [index (get-in state [:workspace-undo :index] -1)] - - (cond-> state - (>= index 0) (accumulate-undo-entry (get-in state [:workspace-undo :items index])) - (>= index 0) (update-in [:workspace-undo :index] dec)))))) - -;; If these functions change modules review /src/app/main/data/workspace/path/undo.cljs +;; These functions should've been in `src/app/main/data/workspace/undo.cljs` but doing that causes +;; a circular dependency with `src/app/main/data/workspace/changes.cljs` (def undo (ptk/reify ::undo ptk/WatchEvent @@ -370,8 +144,8 @@ index (or (:index undo) (dec (count items)))] (when-not (or (empty? items) (= index -1)) (let [changes (get-in items [index :undo-changes])] - (rx/of (materialize-undo changes (dec index)) - (commit-changes changes [] {:save-undo? false})))))))))) + (rx/of (dwu/materialize-undo changes (dec index)) + (dch/commit-changes changes [] {:save-undo? false})))))))))) (def redo (ptk/reify ::redo @@ -385,16 +159,8 @@ index (or (:index undo) (dec (count items)))] (when-not (or (empty? items) (= index (dec (count items)))) (let [changes (get-in items [(inc index) :redo-changes])] - (rx/of (materialize-undo changes (inc index)) - (commit-changes changes [] {:save-undo? false})))))))))) - -(def reinitialize-undo - (ptk/reify ::reset-undo - ptk/UpdateEvent - (update [_ state] - (assoc state :workspace-undo {})))) - - + (rx/of (dwu/materialize-undo changes (inc index)) + (dch/commit-changes changes [] {:save-undo? false})))))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Shapes @@ -420,93 +186,6 @@ ;; NOTE: This is a generic implementation for update multiple shapes ;; in one single commit/undo entry. -(s/def ::coll-of-uuid - (s/every ::us/uuid)) - -(defn update-shapes - ([ids f] (update-shapes ids f nil)) - ([ids f {:keys [reg-objects?] :or {reg-objects? false}}] - (us/assert ::coll-of-uuid ids) - (us/assert fn? f) - (ptk/reify ::update-shapes - ptk/WatchEvent - (watch [_ state stream] - (let [page-id (:current-page-id state) - objects (lookup-page-objects state page-id)] - (loop [ids (seq ids) - rch [] - uch []] - (if (nil? ids) - (rx/of (commit-changes - (cond-> rch reg-objects? (conj {:type :reg-objects :page-id page-id :shapes (vec ids)})) - (cond-> uch reg-objects? (conj {:type :reg-objects :page-id page-id :shapes (vec ids)})) - {:commit-local? true})) - - (let [id (first ids) - obj1 (get objects id) - obj2 (f obj1) - rch-operations (generate-operations obj1 obj2) - uch-operations (generate-operations obj2 obj1 true) - rchg {:type :mod-obj - :page-id page-id - :operations rch-operations - :id id} - uchg {:type :mod-obj - :page-id page-id - :operations uch-operations - :id id}] - (recur (next ids) - (if (empty? rch-operations) rch (conj rch rchg)) - (if (empty? uch-operations) uch (conj uch uchg))))))))))) - -(defn update-shapes-recursive - [ids f] - (us/assert ::coll-of-uuid ids) - (us/assert fn? f) - (letfn [(impl-get-children [objects id] - (cons id (cp/get-children id objects))) - - (impl-gen-changes [objects page-id ids] - (loop [sids (seq ids) - cids (seq (impl-get-children objects (first sids))) - rchanges [] - uchanges []] - (cond - (nil? sids) - [rchanges uchanges] - - (nil? cids) - (recur (next sids) - (seq (impl-get-children objects (first (next sids)))) - rchanges - uchanges) - - :else - (let [id (first cids) - obj1 (get objects id) - obj2 (f obj1) - rops (generate-operations obj1 obj2) - uops (generate-operations obj2 obj1 true) - rchg {:type :mod-obj - :page-id page-id - :operations rops - :id id} - uchg {:type :mod-obj - :page-id page-id - :operations uops - :id id}] - (recur sids - (next cids) - (conj rchanges rchg) - (conj uchanges uchg))))))] - (ptk/reify ::update-shapes-recursive - ptk/WatchEvent - (watch [_ state stream] - (let [page-id (:current-page-id state) - objects (lookup-page-objects state page-id) - [rchanges uchanges] (impl-gen-changes objects page-id (seq ids))] - (rx/of (commit-changes rchanges uchanges {:commit-local? true}))))))) - (defn select-shapes [ids] @@ -639,7 +318,7 @@ (assoc :name name)))] (rx/concat - (rx/of (commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (select-shapes (d/ordered-set id))) (when (= :text (:type attrs)) (->> (rx/of (start-edition-mode id)) @@ -672,7 +351,7 @@ :page-id page-id :index index :shapes [shape-id]})))] - (rx/of (commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn delete-shapes @@ -779,7 +458,7 @@ ;; (cljs.pprint/pprint rchanges) ;; (println "================ uchanges") ;; (cljs.pprint/pprint uchanges) - (rx/of (commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) ;; --- Add shape to Workspace diff --git a/frontend/src/app/main/data/workspace/drawing/common.cljs b/frontend/src/app/main/data/workspace/drawing/common.cljs index 922c796af..f31d5be14 100644 --- a/frontend/src/app/main/data/workspace/drawing/common.cljs +++ b/frontend/src/app/main/data/workspace/drawing/common.cljs @@ -12,6 +12,7 @@ [app.common.geom.shapes :as gsh] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.selection :as dws] + [app.main.data.workspace.undo :as dwu] [app.main.streams :as ms] [app.main.worker :as uw])) @@ -54,7 +55,7 @@ ;; Add & select the created shape to the workspace (rx/concat (if (= :text (:type shape)) - (rx/of (dwc/start-undo-transaction)) + (rx/of (dwu/start-undo-transaction)) (rx/empty)) (rx/of (dwc/add-shape shape)) diff --git a/frontend/src/app/main/data/workspace/grid.cljs b/frontend/src/app/main/data/workspace/grid.cljs index fe4e439e2..13a327103 100644 --- a/frontend/src/app/main/data/workspace/grid.cljs +++ b/frontend/src/app/main/data/workspace/grid.cljs @@ -10,7 +10,7 @@ [potok.core :as ptk] [app.common.data :as d] [app.common.spec :as us] - [app.main.data.workspace.common :as dwc])) + [app.main.data.workspace.changes :as dch])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Grid @@ -48,7 +48,7 @@ grid {:type :square :params params :display true}] - (rx/of (dwc/update-shapes [frame-id] + (rx/of (dch/update-shapes [frame-id] (fn [obj] (update obj :grids (fnil #(conj % grid) []))))))))) @@ -57,14 +57,14 @@ (ptk/reify ::set-frame-grid ptk/WatchEvent (watch [_ state stream] - (rx/of (dwc/update-shapes [frame-id] (fn [o] (update o :grids (fnil #(d/remove-at-index % index) [])))))))) + (rx/of (dch/update-shapes [frame-id] (fn [o] (update o :grids (fnil #(d/remove-at-index % index) [])))))))) (defn set-frame-grid [frame-id index data] (ptk/reify ::set-frame-grid ptk/WatchEvent (watch [_ state stream] - (rx/of (dwc/update-shapes [frame-id] #(assoc-in % [:grids index] data)))))) + (rx/of (dch/update-shapes [frame-id] #(assoc-in % [:grids index] data)))))) (defn set-default-grid [type params] @@ -73,7 +73,7 @@ (watch [_ state stream] (let [pid (:current-page-id state) prev-value (get-in state [:workspace-data :pages-index pid :options :saved-grids type])] - (rx/of (dwc/commit-changes [{:type :set-option + (rx/of (dch/commit-changes [{:type :set-option :page-id pid :option [:saved-grids type] :value params}] diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index 4bb6736a0..886ff2fbd 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -4,6 +4,7 @@ [app.common.geom.shapes :as gsh] [app.common.pages :as cp] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.selection :as dws] [beicon.core :as rx] [potok.core :as ptk])) @@ -106,7 +107,7 @@ shapes (shapes-for-grouping objects selected)] (when-not (empty? shapes) (let [[group rchanges uchanges] (prepare-create-group page-id shapes "Group-" false)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set (:id group)))))))))) (def ungroup-selected @@ -122,7 +123,7 @@ (= (:type group) :group)) (let [[rchanges uchanges] (prepare-remove-group page-id group objects)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))))) (def mask-group (ptk/reify ::mask-group @@ -176,7 +177,7 @@ :page-id page-id :shapes [(:id group)]})] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set (:id group)))))))))) (def unmask-group @@ -209,7 +210,7 @@ :page-id page-id :shapes [(:id group)]}]] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set (:id group)))))))))) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index fa9d3b279..1d120c9a9 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -14,6 +14,7 @@ [app.common.geom.shapes :as geom] [app.main.data.messages :as dm] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.libraries-helpers :as dwlh] [app.common.pages :as cp] [app.main.repo :as rp] @@ -90,7 +91,7 @@ uchg {:type :del-color :id id}] (rx/of #(assoc-in % [:workspace-local :color-for-rename] id) - (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))) + (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))) (defn add-recent-color [color] @@ -100,7 +101,7 @@ (watch [_ state s] (let [rchg {:type :add-recent-color :color color}] - (rx/of (dwc/commit-changes [rchg] [] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [] {:commit-local? true})))))) (def clear-color-for-rename (ptk/reify ::clear-color-for-rename @@ -120,7 +121,7 @@ :color color} uchg {:type :mod-color :color prev}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}) (sync-file (:current-file-id state) file-id)))))) (defn delete-color @@ -134,7 +135,7 @@ :id id} uchg {:type :add-color :color prev}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) (defn add-media [{:keys [id] :as media}] @@ -147,7 +148,7 @@ :object obj} uchg {:type :del-media :id id}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) (defn rename-media [id new-name] @@ -169,7 +170,7 @@ :name (:name object) :path (:path object)}}]] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn delete-media [{:keys [id] :as params}] @@ -182,7 +183,7 @@ :id id} uchg {:type :add-media :object prev}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) (defn add-typography ([typography] (add-typography typography true)) @@ -196,7 +197,7 @@ :typography typography} uchg {:type :del-typography :id (:id typography)}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}) #(cond-> % edit? (assoc-in [:workspace-local :rename-typography] (:id typography)))))))))) @@ -213,7 +214,7 @@ :typography typography} uchg {:type :mod-typography :typography prev}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}) (sync-file (:current-file-id state) file-id)))))) (defn delete-typography @@ -227,7 +228,7 @@ :id id} uchg {:type :add-typography :typography prev}] - (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})))))) + (rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})))))) (def add-component "Add a new component to current file library, from the currently selected shapes." @@ -242,7 +243,7 @@ (let [[group rchanges uchanges] (dwlh/generate-add-component selected objects page-id file-id)] (when-not (empty? rchanges) - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set (:id group)))))))))) (defn rename-component @@ -273,7 +274,7 @@ :path (:path component) :objects objects}]] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn duplicate-component "Create a new component copied from the one with the given id." @@ -301,7 +302,7 @@ uchanges [{:type :del-component :id (:id new-shape)}]] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn delete-component "Delete the component with the given id, from the current file library." @@ -321,7 +322,7 @@ :path (:path component) :shapes (vals (:objects component))}]] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn instantiate-component "Create a new shape in the current page, from the component with the given id @@ -398,7 +399,7 @@ :ignore-touched true}) new-shapes)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set (:id new-shape)))))))) (defn detach-component @@ -461,7 +462,7 @@ :val (:touched obj)}]}) shapes)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn nav-to-component-file [file-id] @@ -514,7 +515,7 @@ rchanges local-library)) - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})))))) (defn update-component "Modify the component linked to the shape with the given id, in the @@ -569,11 +570,11 @@ file)) (rx/of (when (seq local-rchanges) - (dwc/commit-changes local-rchanges local-uchanges + (dch/commit-changes local-rchanges local-uchanges {:commit-local? true :file-id (:id local-library)})) (when (seq rchanges) - (dwc/commit-changes rchanges uchanges + (dch/commit-changes rchanges uchanges {:commit-local? true :file-id file-id}))))))) @@ -623,7 +624,7 @@ (rx/concat (rx/of (dm/hide-tag :sync-dialog)) (when rchanges - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true :file-id file-id}))) (when (not= file-id library-id) ;; When we have just updated the library file, give some time for the @@ -666,7 +667,7 @@ (log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes rchanges file)) - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true :file-id file-id}))))))) (def ignore-sync diff --git a/frontend/src/app/main/data/workspace/path/changes.cljs b/frontend/src/app/main/data/workspace/path/changes.cljs index 2d046fe6d..0df544a4f 100644 --- a/frontend/src/app/main/data/workspace/path/changes.cljs +++ b/frontend/src/app/main/data/workspace/path/changes.cljs @@ -7,7 +7,7 @@ (ns app.main.data.workspace.path.changes (:require [app.common.spec :as us] - [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.path.helpers :as helpers] [app.main.data.workspace.path.spec :as spec] [app.main.data.workspace.path.state :as st] @@ -67,7 +67,7 @@ (let [shape (get-in state (st/get-path state)) page-id (:current-page-id state) [rch uch] (generate-path-changes page-id shape old-content (:content shape))] - (rx/of (dwc/commit-changes rch uch {:commit-local? true}))) + (rx/of (dch/commit-changes rch uch {:commit-local? true}))) (rx/empty))))))) diff --git a/frontend/src/app/main/data/workspace/path/edition.cljs b/frontend/src/app/main/data/workspace/path/edition.cljs index cace090c2..9911a4b98 100644 --- a/frontend/src/app/main/data/workspace/path/edition.cljs +++ b/frontend/src/app/main/data/workspace/path/edition.cljs @@ -9,7 +9,7 @@ [app.common.data :as d] [app.common.geom.point :as gpt] [app.common.math :as mth] - [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.path.changes :as changes] [app.main.data.workspace.path.common :as common] [app.main.data.workspace.path.helpers :as helpers] @@ -60,7 +60,7 @@ [rch uch] (changes/generate-path-changes page-id shape (:content shape) new-content)] - (rx/of (dwc/commit-changes rch uch {:commit-local? true}) + (rx/of (dch/commit-changes rch uch {:commit-local? true}) (selection/update-selection point-change) (fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler))))))) diff --git a/frontend/src/app/main/data/workspace/path/tools.cljs b/frontend/src/app/main/data/workspace/path/tools.cljs index 303e50428..c7cb1cd4e 100644 --- a/frontend/src/app/main/data/workspace/path/tools.cljs +++ b/frontend/src/app/main/data/workspace/path/tools.cljs @@ -6,7 +6,7 @@ (ns app.main.data.workspace.path.tools (:require - [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.path.changes :as changes] [app.main.data.workspace.path.common :as common] [app.main.data.workspace.path.state :as st] @@ -32,7 +32,7 @@ new-content (-> (tool-fn (:content shape) points) (ups/close-subpaths)) [rch uch] (changes/generate-path-changes page-id shape (:content shape) new-content)] - (rx/of (dwc/commit-changes rch uch {:commit-local? true}))))))) + (rx/of (dch/commit-changes rch uch {:commit-local? true}))))))) (defn make-corner ([] diff --git a/frontend/src/app/main/data/workspace/persistence.cljs b/frontend/src/app/main/data/workspace/persistence.cljs index 5d4add00b..7b5d4433b 100644 --- a/frontend/src/app/main/data/workspace/persistence.cljs +++ b/frontend/src/app/main/data/workspace/persistence.cljs @@ -17,6 +17,7 @@ [app.main.data.media :as di] [app.main.data.messages :as dm] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.svg-upload :as svg] @@ -51,7 +52,7 @@ (let [stoper (rx/filter #(= ::finalize %) stream) forcer (rx/filter #(= ::force-persist %) stream) notifier (->> stream - (rx/filter (ptk/type? ::dwc/commit-changes)) + (rx/filter dch/commit-changes?) (rx/debounce 2000) (rx/merge stoper forcer)) @@ -79,7 +80,7 @@ (st/emit! (update-persistence-status {:status :saved})))] (->> (rx/merge (->> stream - (rx/filter (ptk/type? ::dwc/commit-changes)) + (rx/filter dch/commit-changes?) (rx/map deref) (rx/filter local-file?) (rx/tap on-dirty) @@ -91,7 +92,7 @@ (rx/tap on-saving) (rx/take-until (rx/delay 100 stoper))) (->> stream - (rx/filter (ptk/type? ::dwc/commit-changes)) + (rx/filter dch/commit-changes?) (rx/map deref) (rx/filter library-file?) (rx/filter (complement #(empty? (:changes %)))) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 6812a5a9f..5db6c36e6 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -18,6 +18,7 @@ [app.common.spec :as us] [app.common.uuid :as uuid] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.modal :as md] [app.main.streams :as ms] [app.main.worker :as uw])) @@ -395,7 +396,7 @@ (map #(get-in % [:obj :id])) (into (d/ordered-set)))] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (select-shapes selected)))))) (defn change-hover-state diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index f10934f16..2ca3c32cc 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -10,6 +10,7 @@ [app.main.data.workspace :as dw] [app.main.data.workspace.colors :as mdc] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.drawing :as dwd] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.texts :as dwtxt] @@ -123,7 +124,7 @@ :clear-undo {:tooltip (ds/meta "Q") :command (ds/c-mod "q") - :fn #(st/emit! dwc/reinitialize-undo)} + :fn #(st/emit! dwu/reinitialize-undo)} :draw-frame {:tooltip "A" :command "a" diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 1b3a479bf..a3950b64b 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -14,6 +14,7 @@ [app.common.pages :as cp] [app.common.uuid :as uuid] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.repo :as rp] [app.util.color :as uc] [app.util.path.parser :as upp] @@ -462,7 +463,7 @@ rchanges (conj rchanges reg-objects-action)] - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}) + (rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}) (dwc/select-shapes (d/ordered-set root-id)))) (catch :default e diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index 154930a99..955344a8e 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -15,6 +15,8 @@ [app.main.data.workspace.selection :as dws] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.transforms :as dwt] + [app.main.data.workspace.changes :as dch] + [app.main.data.workspace.undo :as dwu] [app.main.fonts :as fonts] [app.util.object :as obj] [app.util.text-editor :as ted] @@ -77,8 +79,8 @@ (when (and (not= content (:content shape)) (some? (:current-page-id state))) (rx/of - (dwc/update-shapes [id] #(assoc % :content content)) - (dwc/commit-undo-transaction))))) + (dch/update-shapes [id] #(assoc % :content content)) + (dwu/commit-undo-transaction))))) (rx/of (dws/deselect-shape id) (dwc/delete-shapes [id]))))))) @@ -141,7 +143,7 @@ shape-ids (cond (= (:type shape) :text) [id] (= (:type shape) :group) (cp/get-children id objects))] - (rx/of (dwc/update-shapes shape-ids update-fn)))))) + (rx/of (dch/update-shapes shape-ids update-fn)))))) (defn update-paragraph-attrs [{:keys [id attrs]}] @@ -169,7 +171,7 @@ shape-ids (cond (= (:type shape) :text) [id] (= (:type shape) :group) (cp/get-children id objects))] - (rx/of (dwc/update-shapes shape-ids update-fn)))))))) + (rx/of (dch/update-shapes shape-ids update-fn)))))))) (defn update-text-attrs [{:keys [id attrs]}] @@ -187,7 +189,7 @@ update-fn #(update-shape % txt/is-text-node? attrs/merge attrs) shape-ids (cond (= (:type shape) :text) [id] (= (:type shape) :group) (cp/get-children id objects))] - (rx/of (dwc/update-shapes shape-ids update-fn))))))) + (rx/of (dch/update-shapes shape-ids update-fn))))))) ;; --- RESIZE UTILS diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 12143a43c..a9cb1c3be 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -14,7 +14,9 @@ [app.common.pages :as cp] [app.common.spec :as us] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.selection :as dws] + [app.main.data.workspace.undo :as dwu] [app.main.refs :as refs] [app.main.snap :as snap] [app.main.store :as st] @@ -140,7 +142,7 @@ (filter #(= :text (:type %))) (map :id))] (rx/concat - (rx/of (dwc/update-shapes text-shapes-ids #(assoc % :grow-type :fixed))) + (rx/of (dch/update-shapes text-shapes-ids #(assoc % :grow-type :fixed))) (->> ms/mouse-position (rx/with-latest vector ms/mouse-position-shift) (rx/map normalize-proportion-lock) @@ -259,9 +261,9 @@ :shapes [(:id shape)]})))] (when-not (empty? rch) - (rx/of dwc/pop-undo-into-transaction - (dwc/commit-changes rch uch {:commit-local? true}) - (dwc/commit-undo-transaction) + (rx/of dwu/pop-undo-into-transaction + (dch/commit-changes rch uch {:commit-local? true}) + (dwu/commit-undo-transaction) (dwc/expand-collapse frame-id))))))) (defn start-move diff --git a/frontend/src/app/main/data/workspace/undo.cljs b/frontend/src/app/main/data/workspace/undo.cljs new file mode 100644 index 000000000..a1f5fcaf3 --- /dev/null +++ b/frontend/src/app/main/data/workspace/undo.cljs @@ -0,0 +1,134 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.main.data.workspace.undo + (:require + [app.common.data :as d] + [app.common.geom.proportions :as gpr] + [app.common.geom.shapes :as gsh] + [app.common.pages :as cp] + [app.common.pages.spec :as spec] + [app.common.spec :as us] + [app.common.uuid :as uuid] + [app.main.worker :as uw] + [app.main.streams :as ms] + [app.util.logging :as log] + [app.util.timers :as ts] + [beicon.core :as rx] + [cljs.spec.alpha :as s] + [clojure.set :as set] + [cuerdas.core :as str] + [potok.core :as ptk])) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Undo / Redo +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(s/def ::undo-changes ::cp/changes) +(s/def ::redo-changes ::cp/changes) +(s/def ::undo-entry + (s/keys :req-un [::undo-changes ::redo-changes])) + +(def MAX-UNDO-SIZE 50) + +(defn- conj-undo-entry + [undo data] + (let [undo (conj undo data) + cnt (count undo)] + (if (> cnt MAX-UNDO-SIZE) + (subvec undo (- cnt MAX-UNDO-SIZE)) + undo))) + +(defn- materialize-undo + [changes index] + (ptk/reify ::materialize-undo + ptk/UpdateEvent + (update [_ state] + (-> state + (update :workspace-data cp/process-changes changes) + (assoc-in [:workspace-undo :index] index))))) + +(defn- reset-undo + [index] + (ptk/reify ::reset-undo + ptk/UpdateEvent + (update [_ state] + (-> state + (update :workspace-undo dissoc :undo-index) + (update-in [:workspace-undo :items] (fn [queue] (into [] (take (inc index) queue)))))))) + +(defn- add-undo-entry + [state entry] + (if (and entry + (not-empty (:undo-changes entry)) + (not-empty (:redo-changes entry))) + (let [index (get-in state [:workspace-undo :index] -1) + items (get-in state [:workspace-undo :items] []) + items (->> items (take (inc index)) (into [])) + items (conj-undo-entry items entry)] + (-> state + (update :workspace-undo assoc :items items + :index (min (inc index) + (dec MAX-UNDO-SIZE))))) + state)) + +(defn- accumulate-undo-entry + [state {:keys [undo-changes redo-changes]}] + (-> state + (update-in [:workspace-undo :transaction :undo-changes] #(into undo-changes %)) + (update-in [:workspace-undo :transaction :redo-changes] #(into % redo-changes)))) + +(defn- append-undo + [entry] + (us/verify ::undo-entry entry) + (ptk/reify ::append-undo + ptk/UpdateEvent + (update [_ state] + (if (get-in state [:workspace-undo :transaction]) + (accumulate-undo-entry state entry) + (add-undo-entry state entry))))) + +(defonce empty-tx {:undo-changes [] :redo-changes []}) + +(defn start-undo-transaction [] + (ptk/reify ::start-undo-transaction + ptk/UpdateEvent + (update [_ state] + ;; We commit the old transaction before starting the new one + (let [current-tx (get-in state [:workspace-undo :transaction])] + (cond-> state + (nil? current-tx) (assoc-in [:workspace-undo :transaction] empty-tx)))))) + +(defn discard-undo-transaction [] + (ptk/reify ::discard-undo-transaction + ptk/UpdateEvent + (update [_ state] + (update state :workspace-undo dissoc :transaction)))) + +(defn commit-undo-transaction [] + (ptk/reify ::commit-undo-transaction + ptk/UpdateEvent + (update [_ state] + (-> state + (add-undo-entry (get-in state [:workspace-undo :transaction])) + (update :workspace-undo dissoc :transaction))))) + +(def pop-undo-into-transaction + (ptk/reify ::last-undo-into-transaction + ptk/UpdateEvent + (update [_ state] + (let [index (get-in state [:workspace-undo :index] -1)] + + (cond-> state + (>= index 0) (accumulate-undo-entry (get-in state [:workspace-undo :items index])) + (>= index 0) (update-in [:workspace-undo :index] dec)))))) + +(def reinitialize-undo + (ptk/reify ::reset-undo + ptk/UpdateEvent + (update [_ state] + (assoc state :workspace-undo {})))) + diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 3d39ac33e..5720cd50b 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -10,6 +10,7 @@ [app.main.data.modal :as modal] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.shortcuts :as sc] [app.main.refs :as refs] @@ -83,10 +84,10 @@ ;; We defer the execution so the mouse event won't close the editor (timers/schedule #(st/emit! (dw/start-editing-selected)))) do-update-component (st/emitf - (dwc/start-undo-transaction) + (dwu/start-undo-transaction) (dwl/update-component id) (dwl/sync-file current-file-id (:component-file shape)) - (dwc/commit-undo-transaction)) + (dwu/commit-undo-transaction)) confirm-update-remote-component (st/emitf (dwl/update-component id) (dwl/sync-file current-file-id diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 4830282d8..059c816bb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -19,6 +19,7 @@ [app.main.data.modal :as modal] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.texts :as dwt] [app.main.exports :as exports] @@ -142,9 +143,9 @@ (if (empty? selected-components) (st/emit! (dwl/duplicate-component {:id (:component-id @state)})) (do - (st/emit! (dwc/start-undo-transaction)) + (st/emit! (dwu/start-undo-transaction)) (apply st/emit! (map #(dwl/duplicate-component {:id %}) selected-components)) - (st/emit! (dwc/commit-undo-transaction)))))) + (st/emit! (dwu/commit-undo-transaction)))))) on-delete (mf/use-callback @@ -195,7 +196,7 @@ (mf/deps components selected-components on-clear-selection) (fn [name] (on-clear-selection) - (st/emit! (dwc/start-undo-transaction)) + (st/emit! (dwu/start-undo-transaction)) (apply st/emit! (->> components (filter #(contains? selected-components (:id %))) @@ -203,7 +204,7 @@ (:id %) (str name " / " (cp/merge-path-item (:path %) (:name %))))))) - (st/emit! (dwc/commit-undo-transaction)))) + (st/emit! (dwu/commit-undo-transaction)))) on-fold-group (mf/use-callback @@ -383,7 +384,7 @@ (mf/deps objects selected-objects on-clear-selection) (fn [name] (on-clear-selection) - (st/emit! (dwc/start-undo-transaction)) + (st/emit! (dwu/start-undo-transaction)) (apply st/emit! (->> objects (filter #(contains? selected-objects (:id %))) @@ -391,7 +392,7 @@ (:id %) (str name " / " (cp/merge-path-item (:path %) (:name %))))))) - (st/emit! (dwc/commit-undo-transaction)))) + (st/emit! (dwu/commit-undo-transaction)))) on-fold-group (mf/use-callback @@ -975,7 +976,7 @@ (mf/deps @selected-assets) (fn [] (do - (st/emit! (dwc/start-undo-transaction)) + (st/emit! (dwu/start-undo-transaction)) (apply st/emit! (map #(dwl/delete-component {:id %}) (:components @selected-assets))) (apply st/emit! (map #(dwl/delete-media {:id %}) @@ -984,7 +985,7 @@ (:colors @selected-assets))) (apply st/emit! (map #(dwl/delete-typography %) (:typographies @selected-assets))) - (st/emit! (dwc/commit-undo-transaction)))))] + (st/emit! (dwu/commit-undo-transaction)))))] [:div.tool-window {:on-context-menu #(dom/prevent-default %) :on-click unselect-all} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index 10556bff9..f6c8698ca 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.uuid :as uuid] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.store :as st] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.options.common :refer [advanced-options]] @@ -32,7 +33,7 @@ has-value? (not (nil? blur)) multiple? (= blur :multiple) - change! (fn [update-fn] (st/emit! (dwc/update-shapes ids update-fn))) + change! (fn [update-fn] (st/emit! (dch/update-shapes ids update-fn))) handle-add (fn [] 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 8044aa721..bc7c39384 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 @@ -16,6 +16,7 @@ [app.main.ui.components.context-menu :refer [context-menu]] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.libraries :as dwl] [app.util.i18n :as i18n :refer [t]] [app.util.dom :as dom])) @@ -50,10 +51,10 @@ do-detach-component (st/emitf (dwl/detach-component id)) do-reset-component (st/emitf (dwl/reset-component id)) do-update-component (st/emitf - (dwc/start-undo-transaction) + (dwu/start-undo-transaction) (dwl/update-component id) (dwl/sync-file current-file-id current-file-id) - (dwc/commit-undo-transaction)) + (dwu/commit-undo-transaction)) confirm-update-remote-component (st/emitf (dwl/update-component id) (dwl/sync-file current-file-id diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index b70447603..47112a3f2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -9,6 +9,7 @@ [app.common.pages :as cp] [app.main.data.workspace.colors :as dc] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.main.data.workspace.texts :as dwt] [app.main.refs :as refs] [app.main.store :as st] @@ -78,13 +79,13 @@ (mf/use-callback (mf/deps ids) (fn [value opacity id file-id] - (st/emit! (dwc/start-undo-transaction)))) + (st/emit! (dwu/start-undo-transaction)))) on-close-picker (mf/use-callback (mf/deps ids) (fn [value opacity id file-id] - (st/emit! (dwc/commit-undo-transaction))))] + (st/emit! (dwu/commit-undo-transaction))))] (if show? [:div.element-set diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs index 2149367cb..46fa46660 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs @@ -9,6 +9,7 @@ [app.common.data :as d] [app.common.math :as mth] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.store :as st] [app.main.ui.components.numeric-input :refer [numeric-input]] [app.main.ui.icons :as i] @@ -34,7 +35,7 @@ (mf/use-callback (mf/deps ids) (fn [prop value] - (st/emit! (dwc/update-shapes ids #(assoc % prop value))))) + (st/emit! (dch/update-shapes ids #(assoc % prop value))))) handle-change-blend-mode (mf/use-callback diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index f9fa9df7e..0d02a5419 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -17,6 +17,7 @@ [app.common.geom.point :as gpt] [app.main.data.workspace :as udw] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.ui.components.numeric-input :refer [numeric-input]] [app.common.math :as math] [app.util.i18n :refer [t] :as i18n])) @@ -106,7 +107,7 @@ (:r1 shape) (-> (assoc :rx 0 :ry 0) (dissoc :r1 :r2 :r3 :r4))))] - (st/emit! (dwc/update-shapes ids-with-children radius-update))))) + (st/emit! (dch/update-shapes ids-with-children radius-update))))) on-switch-to-radius-4 (mf/use-callback @@ -118,7 +119,7 @@ (:rx shape) (-> (assoc :r1 0 :r2 0 :r3 0 :r4 0) (dissoc :rx :ry))))] - (st/emit! (dwc/update-shapes ids-with-children radius-update))))) + (st/emit! (dch/update-shapes ids-with-children radius-update))))) on-radius-1-change (mf/use-callback @@ -134,7 +135,7 @@ (or (:rx shape) (:r1 shape)) (assoc :rx value :ry value)))] - (st/emit! (dwc/update-shapes ids-with-children radius-update))))) + (st/emit! (dch/update-shapes ids-with-children radius-update))))) on-radius-4-change (mf/use-callback @@ -150,7 +151,7 @@ (attr shape) (assoc attr value)))] - (st/emit! (dwc/update-shapes ids-with-children radius-update))))) + (st/emit! (dch/update-shapes ids-with-children radius-update))))) on-width-change #(on-size-change % :width) on-height-change #(on-size-change % :height) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs index 01dda5963..0f84e67c6 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs @@ -10,6 +10,8 @@ [app.common.data :as d] [app.common.uuid :as uuid] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] + [app.main.data.workspace.undo :as dwu] [app.main.store :as st] [app.main.ui.icons :as i] [app.main.ui.components.numeric-input :refer [numeric-input]] @@ -56,7 +58,7 @@ on-remove-shadow (fn [index] (fn [] - (st/emit! (dwc/update-shapes ids #(update % :shadow remove-shadow-by-index index) )))) + (st/emit! (dch/update-shapes ids #(update % :shadow remove-shadow-by-index index) )))) select-text (fn [ref] (fn [event] (dom/select-text! (mf/ref-val ref)))) @@ -69,14 +71,14 @@ ([index attr valid? update-ref] (fn [value] (when (or (not valid?) (valid? value)) - (do (st/emit! (dwc/update-shapes ids #(assoc-in % [:shadow index attr] value))) + (do (st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index attr] value))) (when update-ref (dom/set-value! (mf/ref-val update-ref) value))))))) update-color (fn [index] (fn [color opacity] (let [color (d/without-keys color [:id :file-id :gradient])] - (st/emit! (dwc/update-shapes + (st/emit! (dch/update-shapes ids #(-> % (assoc-in [:shadow index :color] color) @@ -86,7 +88,7 @@ (fn [index] (fn [color opacity] (if-not (string? (:color value)) - (st/emit! (dwc/update-shapes + (st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :color] (dissoc (:color value) :id :file-id))))))) @@ -94,7 +96,7 @@ toggle-visibility (fn [index] (fn [] - (st/emit! (dwc/update-shapes ids #(update-in % [:shadow index :hidden] not)))))] + (st/emit! (dch/update-shapes ids #(update-in % [:shadow index :hidden] not)))))] [:* [:div.element-set-options-group @@ -129,7 +131,7 @@ {:default-value (str (:style value)) :on-change (fn [event] (let [value (-> event dom/get-target dom/get-value d/read-string)] - (st/emit! (dwc/update-shapes ids #(assoc-in % [:shadow index :style] value)))))} + (st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))} [:option {:value ":drop-shadow"} (t locale "workspace.options.shadow-options.drop-shadow")] [:option {:value ":inner-shadow"} (t locale "workspace.options.shadow-options.inner-shadow")]]] @@ -181,18 +183,18 @@ :disable-gradient true :on-change (update-color index) :on-detach (detach-color index) - :on-open #(st/emit! (dwc/start-undo-transaction)) - :on-close #(st/emit! (dwc/commit-undo-transaction))}]]]])) + :on-open #(st/emit! (dwu/start-undo-transaction)) + :on-close #(st/emit! (dwu/commit-undo-transaction))}]]]])) (mf/defc shadow-menu [{:keys [ids type values] :as props}] (let [locale (i18n/use-locale) on-remove-all-shadows (fn [event] - (st/emit! (dwc/update-shapes ids #(dissoc % :shadow) ))) + (st/emit! (dch/update-shapes ids #(dissoc % :shadow) ))) on-add-shadow (fn [] - (st/emit! (dwc/update-shapes ids #(update % :shadow (fnil conj []) (create-shadow)) )))] + (st/emit! (dch/update-shapes ids #(update % :shadow (fnil conj []) (create-shadow)) )))] [:div.element-set.shadow-options [:div.element-set-title [:span diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index 002a6a7bc..14ae0a784 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -11,6 +11,8 @@ [app.common.data :as d] [app.common.math :as math] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.colors :as dc] [app.main.store :as st] [app.main.ui.icons :as i] @@ -78,7 +80,7 @@ (let [value (-> (dom/get-target event) (dom/get-value) (d/read-string))] - (st/emit! (dwc/update-shapes ids #(assoc % :stroke-style value))))) + (st/emit! (dch/update-shapes ids #(assoc % :stroke-style value))))) on-stroke-alignment-change (fn [event] @@ -86,7 +88,7 @@ (dom/get-value) (d/read-string))] (when-not (str/empty? value) - (st/emit! (dwc/update-shapes ids #(assoc % :stroke-alignment value)))))) + (st/emit! (dch/update-shapes ids #(assoc % :stroke-alignment value)))))) on-stroke-width-change (fn [event] @@ -94,11 +96,11 @@ (dom/get-value) (d/parse-integer 0))] (when-not (str/empty? value) - (st/emit! (dwc/update-shapes ids #(assoc % :stroke-width value)))))) + (st/emit! (dch/update-shapes ids #(assoc % :stroke-width value)))))) on-add-stroke (fn [event] - (st/emit! (dwc/update-shapes ids #(assoc % + (st/emit! (dch/update-shapes ids #(assoc % :stroke-style :solid :stroke-color "#000000" :stroke-opacity 1 @@ -106,19 +108,19 @@ on-del-stroke (fn [event] - (st/emit! (dwc/update-shapes ids #(assoc % :stroke-style :none)))) + (st/emit! (dch/update-shapes ids #(assoc % :stroke-style :none)))) on-open-picker (mf/use-callback (mf/deps ids) (fn [value opacity id file-id] - (st/emit! (dwc/start-undo-transaction)))) + (st/emit! (dwu/start-undo-transaction)))) on-close-picker (mf/use-callback (mf/deps ids) (fn [value opacity id file-id] - (st/emit! (dwc/commit-undo-transaction))))] + (st/emit! (dwu/commit-undo-transaction))))] (if show-options [:div.element-set diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs index 3675d3b86..bd6dc955a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs @@ -9,6 +9,7 @@ [cuerdas.core :as str] [app.common.data :as d] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.store :as st] [app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]] [app.util.dom :as dom] @@ -61,7 +62,7 @@ (fn [attr value] (let [update-fn (fn [shape] (assoc-in shape (concat [:svg-attrs] attr) value))] - (st/emit! (dwc/update-shapes ids update-fn))))) + (st/emit! (dch/update-shapes ids update-fn))))) handle-delete (mf/use-callback @@ -76,7 +77,7 @@ (empty? (get-in shape [:svg-attrs :style])) (update :svg-attrs dissoc :style))] shape))] - (st/emit! (dwc/update-shapes ids update-fn))))) + (st/emit! (dch/update-shapes ids update-fn))))) ] 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 031dc1d3c..5c83e42cc 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 @@ -10,6 +10,7 @@ [app.common.uuid :as uuid] [app.common.text :as txt] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.changes :as dch] [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.texts :as dwt] [app.main.fonts :as fonts] @@ -159,7 +160,7 @@ grow-type (->> values :grow-type) handle-change-grow (fn [event grow-type] - (st/emit! (dwc/update-shapes ids #(assoc % :grow-type grow-type))))] + (st/emit! (dch/update-shapes ids #(assoc % :grow-type grow-type))))] [:div.align-icons [:span.tooltip.tooltip-bottom diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs index c6cbc40f2..ef96fe0db 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs @@ -13,6 +13,7 @@ [app.main.store :as st] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] + [app.main.data.workspace.undo :as dwu] [app.util.i18n :as i18n :refer [t]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]])) @@ -31,12 +32,12 @@ on-open (mf/use-callback (mf/deps page-id) - #(st/emit! (dwc/start-undo-transaction))) + #(st/emit! (dwu/start-undo-transaction))) on-close (mf/use-callback (mf/deps page-id) - #(st/emit! (dwc/commit-undo-transaction)))] + #(st/emit! (dwu/commit-undo-transaction)))] [:div.element-set [:div.element-set-title (t locale "workspace.options.canvas-background")]