0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-15 03:28:25 -05:00

🐛 Fix undo on page relocate/sorting.

This commit is contained in:
Andrey Antukh 2021-11-24 12:37:55 +01:00 committed by Andrés Moya
parent c4947d3737
commit e7b4010eba
9 changed files with 89 additions and 33 deletions

View file

@ -12,7 +12,8 @@
;; Auxiliary functions to help create a set of changes (undo + redo) ;; Auxiliary functions to help create a set of changes (undo + redo)
(defn empty-changes [origin page-id] (defn empty-changes
[origin page-id]
(let [changes {:redo-changes [] (let [changes {:redo-changes []
:undo-changes [] :undo-changes []
:origin origin}] :origin origin}]
@ -165,3 +166,11 @@
(update :undo-changes #(as-> % $ (update :undo-changes #(as-> % $
(reduce add-undo-change-parent $ ids) (reduce add-undo-change-parent $ ids)
(reduce add-undo-change-shape $ ids)))))) (reduce add-undo-change-shape $ ids))))))
(defn move-page
[chdata index prev-index]
(let [page-id (::page-id (meta chdata))]
(-> chdata
(update :redo-changes conj {:type :mov-page :id page-id :index index})
(update :undo-changes conj {:type :mov-page :id page-id :index prev-index}))))

View file

@ -213,11 +213,16 @@
(defn insert-at-index (defn insert-at-index
[objects index ids] [objects index ids]
(let [[before after] (split-at index objects) (let [[before after] (split-at index objects)
p? (set ids)] p? (complement (set ids))
(d/concat [] before' (filterv p? before)
(remove p? before) after' (filterv p? after)]
ids
(remove p? after)))) (if (and (not= (count before) (count before'))
(pos? (count after')))
(let [before' (conj before' (first after'))
after' (into [] (rest after'))]
(d/concat [] before' ids after'))
(d/concat [] before' ids after'))))
(defn append-at-the-end (defn append-at-the-end
[prev-ids ids] [prev-ids ids]

View file

@ -0,0 +1,50 @@
;; 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.common.pages-helpers-test
(:require
[clojure.test :as t]
[clojure.pprint :refer [pprint]]
[app.common.pages.helpers :as cph]))
(t/deftest insert-at-index
;; insert different object
(t/is (= (cph/insert-at-index [:a :b] 1 [:c :d])
[:a :c :d :b]))
;; insert on the start
(t/is (= (cph/insert-at-index [:a :b] 0 [:c])
[:c :a :b]))
;; insert on the end 1
(t/is (= (cph/insert-at-index [:a :b] 2 [:c])
[:a :b :c]))
;; insert on the end with not existing index
(t/is (= (cph/insert-at-index [:a :b] 10 [:c])
[:a :b :c]))
;; insert existing in a contiguos index
(t/is (= (cph/insert-at-index [:a :b] 1 [:a])
[:b :a]))
;; insert existing in the same index
(t/is (= (cph/insert-at-index [:a :b] 0 [:a])
[:a :b]))
;; insert existing in other index case 1
(t/is (= (cph/insert-at-index [:a :b :c] 2 [:a])
[:b :c :a]))
;; insert existing in other index case 2
(t/is (= (cph/insert-at-index [:a :b :c :d] 0 [:d])
[:d :a :b :c]))
;; insert existing in other index case 3
(t/is (= (cph/insert-at-index [:a :b :c :d] 1 [:a])
[:b :a :c :d]))
)

View file

@ -574,7 +574,7 @@
;; After ;; After
(t/is (= [shape-4-id shape-3-id group-1-id] (t/is (= [shape-4-id group-1-id shape-3-id]
(get-in res [:pages-index page-id :objects cp/root :shapes]))) (get-in res [:pages-index page-id :objects cp/root :shapes])))
;; (pprint (get-in data [:pages-index page-id :objects cp/root])) ;; (pprint (get-in data [:pages-index page-id :objects cp/root]))

View file

@ -81,8 +81,6 @@
(when-not (contains? ids ctid) (when-not (contains? ids ctid)
(swap! storage dissoc ::current-team-id))))))) (swap! storage dissoc ::current-team-id)))))))
(defn fetch-teams (defn fetch-teams
[] []
(ptk/reify ::fetch-teams (ptk/reify ::fetch-teams

View file

@ -14,6 +14,7 @@
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.pages.spec :as spec] [app.common.pages.spec :as spec]
[app.common.spec :as us] [app.common.spec :as us]
@ -350,16 +351,16 @@
;; TODO: properly handle positioning on undo. ;; TODO: properly handle positioning on undo.
;; TODO: for some reason, the page-id here in some circumstances is `nil`
(defn delete-page (defn delete-page
[id] [id]
(ptk/reify ::delete-page (ptk/reify ::delete-page
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [page (get-in state [:workspace-data :pages-index id]) (let [page (get-in state [:workspace-data :pages-index id])
rchg {:type :del-page rchg {:type :del-page :id id}
:id id} uchg {:type :add-page :page page}]
uchg {:type :add-page
:page page}]
(rx/of (dch/commit-changes {:redo-changes [rchg] (rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg] :undo-changes [uchg]
:origin it}) :origin it})
@ -1114,17 +1115,11 @@
(ptk/reify ::relocate-pages (ptk/reify ::relocate-pages
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [cidx (-> (get-in state [:workspace-data :pages]) (let [prev-index (-> (get-in state [:workspace-data :pages])
(d/index-of id)) (d/index-of id))
rchg {:type :mov-page changes (-> (pcb/empty-changes it id)
:id id (pcb/move-page index prev-index))]
:index index} (rx/of (dch/commit-changes changes))))))
uchg {:type :mov-page
:id id
:index cidx}]
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it}))))))
;; --- Shape / Selection Alignment and Distribution ;; --- Shape / Selection Alignment and Distribution

View file

@ -114,20 +114,20 @@
:changes changes})))) :changes changes}))))
(defn commit-changes (defn commit-changes
[{:keys [redo-changes undo-changes origin save-undo? file-id] [{:keys [redo-changes undo-changes origin save-undo? file-id] :or {save-undo? true}}]
:or {save-undo? true}}]
(log/debug :msg "commit-changes" (log/debug :msg "commit-changes"
:js/redo-changes redo-changes :js/redo-changes redo-changes
:js/undo-changes undo-changes) :js/undo-changes undo-changes)
(let [error (volatile! nil)
strace (.-stack (ex-info "" {}))]
(let [error (volatile! nil)]
(ptk/reify ::commit-changes (ptk/reify ::commit-changes
cljs.core/IDeref cljs.core/IDeref
(-deref [_] (-deref [_]
{:file-id file-id {:file-id file-id
:hint-events @st/last-events :hint-events @st/last-events
:hint-origin (ptk/type origin) :hint-origin (ptk/type origin)
:hint-strace strace
:changes redo-changes}) :changes redo-changes})
ptk/UpdateEvent ptk/UpdateEvent
@ -135,7 +135,6 @@
(let [current-file-id (get state :current-file-id) (let [current-file-id (get state :current-file-id)
file-id (or file-id current-file-id) file-id (or file-id current-file-id)
path (if (= file-id current-file-id) path (if (= file-id current-file-id)
[:workspace-data] [:workspace-data]
[:workspace-libraries file-id :data])] [:workspace-libraries file-id :data])]
(try (try

View file

@ -70,7 +70,8 @@
(accumulate-undo-entry state entry) (accumulate-undo-entry state entry)
(add-undo-entry state entry))))) (add-undo-entry state entry)))))
(defonce empty-tx {:undo-changes [] :redo-changes []}) (def empty-tx
{:undo-changes [] :redo-changes []})
(defn start-undo-transaction [] (defn start-undo-transaction []
(ptk/reify ::start-undo-transaction (ptk/reify ::start-undo-transaction

View file

@ -82,10 +82,9 @@
on-drop on-drop
(mf/use-callback (mf/use-callback
(mf/deps id) (mf/deps id index)
(fn [side {:keys [id] :as data}] (fn [side {:keys [id] :as data}]
(let [index (if (= :bot side) (inc index) index)] (st/emit! (dw/relocate-page id index))))
(st/emit! (dw/relocate-page id index)))))
on-duplicate on-duplicate
(fn [_] (fn [_]