diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index 726f03786..d73b48956 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -75,15 +75,11 @@ ptk/WatchEvent (watch [_ state stream] - (let [page-id (:current-page-id state) - uidx (get-in state [:workspace-undo :index] ::not-found)] + (let [page-id (:current-page-id state)] (rx/concat (when (some :page-id changes) (rx/of (update-indices page-id))) - (when (and save-undo? (not= uidx ::not-found)) - (rx/of (reset-undo uidx))) - (when (and save-undo? (seq undo-changes)) (let [entry {:undo-changes undo-changes :redo-changes changes}] @@ -273,9 +269,16 @@ (defn- add-undo-entry [state entry] - (if entry - (let [state (update-in state [:workspace-undo :items] (fnil conj-undo-entry []) entry)] - (assoc-in state [:workspace-undo :index] (dec (count (get-in state [:workspace-undo :items]))))) + (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 (inc index)))) state)) (defn- accumulate-undo-entry @@ -317,6 +320,16 @@ (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 undo (ptk/reify ::undo ptk/WatchEvent @@ -399,17 +412,19 @@ (let [id (first ids) obj1 (get objects id) obj2 (f obj1) + rch-operations (generate-operations obj1 obj2) + uch-operations (generate-operations obj2 obj1) rchg {:type :mod-obj :page-id page-id - :operations (generate-operations obj1 obj2) + :operations rch-operations :id id} uchg {:type :mod-obj :page-id page-id - :operations (generate-operations obj2 obj1) + :operations uch-operations :id id}] (recur (next ids) - (conj rch rchg) - (conj uch uchg)))))))))) + (if (empty? rch-operations) rch (conj rch rchg)) + (if (empty? uch-operations) uch (conj uch uchg))))))))))) (defn update-shapes-recursive diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index 4b11c8e31..d8f13b9aa 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -357,24 +357,29 @@ #(let [self-node (mf/ref-val self-ref) paragraph-node (when self-node (dom/query self-node ".paragraph-set"))] (when paragraph-node - (let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)] - (cond - (and (:overflow-text shape) (not= :fixed (:grow-type shape))) - (st/emit! (dwt/update-overflow-text id false)) + (let [{:keys [width height]} (dom/get-bounding-rect paragraph-node) + undo-transaction (get-in @st/state [:workspaceundo :transaction])] + (when (not undo-transaction) (st/emit! dwc/start-undo-transaction)) + (when (or (not= (:width shape) width) + (not= (:height shape) height)) + (cond + (and (:overflow-text shape) (not= :fixed (:grow-type shape))) + (st/emit! (dwt/update-overflow-text id false)) - (and (= :fixed (:grow-type shape)) (not (:overflow-text shape)) (> height (:height shape))) - (st/emit! (dwt/update-overflow-text id true)) + (and (= :fixed (:grow-type shape)) (not (:overflow-text shape)) (> height (:height shape))) + (st/emit! (dwt/update-overflow-text id true)) - (and (= :fixed (:grow-type shape)) (:overflow-text shape) (<= height (:height shape))) - (st/emit! (dwt/update-overflow-text id false)) + (and (= :fixed (:grow-type shape)) (:overflow-text shape) (<= height (:height shape))) + (st/emit! (dwt/update-overflow-text id false)) - (= grow-type :auto-width) - (st/emit! (dw/update-dimensions [id] :width width) - (dw/update-dimensions [id] :height height)) + (= grow-type :auto-width) + (st/emit! (dw/update-dimensions [id] :width width) + (dw/update-dimensions [id] :height height)) - (= grow-type :auto-height) - (st/emit! (dw/update-dimensions [id] :height height)) - ))))))) + (= grow-type :auto-height) + (st/emit! (dw/update-dimensions [id] :height height)) + )) + (when (not undo-transaction) (st/emit! dwc/discard-undo-transaction)))))))) [:foreignObject {:ref self-ref :transform (geom/transform-matrix shape) diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.cljs b/frontend/src/app/main/ui/workspace/sidebar/history.cljs index c3797afae..369daf8cb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/history.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/history.cljs @@ -31,7 +31,7 @@ (let [{:keys [redo-changes]} entry] [:li.undo-entry {:class (when is-transaction? "transaction")} (for [[idx-change {:keys [type id operations]}] (map-indexed vector redo-changes)] - [:div.undo-entry-change + [: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))])])]))