mirror of
https://github.com/penpot/penpot.git
synced 2025-02-12 18:18:24 -05:00
🐛 Fix undo on page relocate/sorting.
This commit is contained in:
parent
c4947d3737
commit
e7b4010eba
9 changed files with 89 additions and 33 deletions
|
@ -12,7 +12,8 @@
|
|||
|
||||
;; 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 []
|
||||
:undo-changes []
|
||||
:origin origin}]
|
||||
|
@ -165,3 +166,11 @@
|
|||
(update :undo-changes #(as-> % $
|
||||
(reduce add-undo-change-parent $ 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}))))
|
||||
|
|
|
@ -213,11 +213,16 @@
|
|||
(defn insert-at-index
|
||||
[objects index ids]
|
||||
(let [[before after] (split-at index objects)
|
||||
p? (set ids)]
|
||||
(d/concat []
|
||||
(remove p? before)
|
||||
ids
|
||||
(remove p? after))))
|
||||
p? (complement (set ids))
|
||||
before' (filterv p? before)
|
||||
after' (filterv 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
|
||||
[prev-ids ids]
|
||||
|
|
50
common/test/app/common/pages_helpers_test.cljc
Normal file
50
common/test/app/common/pages_helpers_test.cljc
Normal 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]))
|
||||
|
||||
)
|
|
@ -574,7 +574,7 @@
|
|||
|
||||
;; 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])))
|
||||
|
||||
;; (pprint (get-in data [:pages-index page-id :objects cp/root]))
|
||||
|
|
|
@ -81,8 +81,6 @@
|
|||
(when-not (contains? ids ctid)
|
||||
(swap! storage dissoc ::current-team-id)))))))
|
||||
|
||||
|
||||
|
||||
(defn fetch-teams
|
||||
[]
|
||||
(ptk/reify ::fetch-teams
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.pages.spec :as spec]
|
||||
[app.common.spec :as us]
|
||||
|
@ -350,16 +351,16 @@
|
|||
|
||||
;; TODO: properly handle positioning on undo.
|
||||
|
||||
;; TODO: for some reason, the page-id here in some circumstances is `nil`
|
||||
(defn delete-page
|
||||
[id]
|
||||
(ptk/reify ::delete-page
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [page (get-in state [:workspace-data :pages-index id])
|
||||
rchg {:type :del-page
|
||||
:id id}
|
||||
uchg {:type :add-page
|
||||
:page page}]
|
||||
rchg {:type :del-page :id id}
|
||||
uchg {:type :add-page :page page}]
|
||||
|
||||
(rx/of (dch/commit-changes {:redo-changes [rchg]
|
||||
:undo-changes [uchg]
|
||||
:origin it})
|
||||
|
@ -1114,17 +1115,11 @@
|
|||
(ptk/reify ::relocate-pages
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [cidx (-> (get-in state [:workspace-data :pages])
|
||||
(d/index-of id))
|
||||
rchg {:type :mov-page
|
||||
:id id
|
||||
:index index}
|
||||
uchg {:type :mov-page
|
||||
:id id
|
||||
:index cidx}]
|
||||
(rx/of (dch/commit-changes {:redo-changes [rchg]
|
||||
:undo-changes [uchg]
|
||||
:origin it}))))))
|
||||
(let [prev-index (-> (get-in state [:workspace-data :pages])
|
||||
(d/index-of id))
|
||||
changes (-> (pcb/empty-changes it id)
|
||||
(pcb/move-page index prev-index))]
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
;; --- Shape / Selection Alignment and Distribution
|
||||
|
||||
|
|
|
@ -114,20 +114,20 @@
|
|||
:changes changes}))))
|
||||
|
||||
(defn commit-changes
|
||||
[{:keys [redo-changes undo-changes origin save-undo? file-id]
|
||||
:or {save-undo? true}}]
|
||||
|
||||
[{:keys [redo-changes undo-changes origin save-undo? file-id] :or {save-undo? true}}]
|
||||
(log/debug :msg "commit-changes"
|
||||
:js/redo-changes redo-changes
|
||||
:js/undo-changes undo-changes)
|
||||
(let [error (volatile! nil)
|
||||
strace (.-stack (ex-info "" {}))]
|
||||
|
||||
(let [error (volatile! nil)]
|
||||
(ptk/reify ::commit-changes
|
||||
cljs.core/IDeref
|
||||
(-deref [_]
|
||||
{:file-id file-id
|
||||
:hint-events @st/last-events
|
||||
:hint-origin (ptk/type origin)
|
||||
:hint-strace strace
|
||||
:changes redo-changes})
|
||||
|
||||
ptk/UpdateEvent
|
||||
|
@ -135,7 +135,6 @@
|
|||
(let [current-file-id (get state :current-file-id)
|
||||
file-id (or file-id current-file-id)
|
||||
path (if (= file-id current-file-id)
|
||||
|
||||
[:workspace-data]
|
||||
[:workspace-libraries file-id :data])]
|
||||
(try
|
||||
|
|
|
@ -70,7 +70,8 @@
|
|||
(accumulate-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 []
|
||||
(ptk/reify ::start-undo-transaction
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
|
||||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(mf/deps id index)
|
||||
(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
|
||||
(fn [_]
|
||||
|
|
Loading…
Add table
Reference in a new issue