mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 23:16:38 +02:00
♻️ Enable again undo/redo functionality.
This commit is contained in:
parent
0c7fd793be
commit
fdc3a93a75
5 changed files with 78 additions and 108 deletions
|
@ -88,6 +88,12 @@
|
||||||
"A marker protocol for mark events that alters the
|
"A marker protocol for mark events that alters the
|
||||||
page and is subject to perform a backend synchronization.")
|
page and is subject to perform a backend synchronization.")
|
||||||
|
|
||||||
|
(defn page-update?
|
||||||
|
[o]
|
||||||
|
(or (satisfies? IPageUpdate o)
|
||||||
|
(satisfies? IMetadataUpdate o)
|
||||||
|
(= ::page-update o)))
|
||||||
|
|
||||||
;; --- Helpers
|
;; --- Helpers
|
||||||
|
|
||||||
(defn pack-page
|
(defn pack-page
|
||||||
|
|
|
@ -2,13 +2,18 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; 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/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.data.undo
|
(ns uxbox.main.data.undo
|
||||||
(:require [beicon.core :as rx]
|
(:require
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[cljs.spec.alpha :as s]
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[uxbox.main.data.pages :as udp]
|
[uxbox.main.data.pages :as udp]
|
||||||
[uxbox.main.store :as st]))
|
[uxbox.main.store :as st]
|
||||||
|
[uxbox.util.spec :as us]))
|
||||||
|
|
||||||
|
(def MAX-STACK-SIZE 50)
|
||||||
|
|
||||||
;; --- Watch Page Changes
|
;; --- Watch Page Changes
|
||||||
|
|
||||||
|
@ -16,88 +21,57 @@
|
||||||
(declare save-undo-entry?)
|
(declare save-undo-entry?)
|
||||||
(declare undo?)
|
(declare undo?)
|
||||||
(declare redo?)
|
(declare redo?)
|
||||||
(declare initialize-undo-for-page)
|
|
||||||
|
|
||||||
(deftype WatchPageChanges [id]
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state stream]
|
|
||||||
nil
|
|
||||||
#_(let [stopper (->> stream
|
|
||||||
(rx/filter #(= % ::udp/stop-page-watcher))
|
|
||||||
(rx/take 1))]
|
|
||||||
(->> stream
|
|
||||||
(rx/take-until stopper)
|
|
||||||
(rx/filter #(or (satisfies? udp/IPageUpdate %)
|
|
||||||
(satisfies? udp/IMetadataUpdate %)))
|
|
||||||
(rx/filter #(not (undo? %)))
|
|
||||||
(rx/filter #(not (redo? %)))
|
|
||||||
(rx/map #(save-undo-entry id))))))
|
|
||||||
|
|
||||||
(defn watch-page-changes
|
(defn watch-page-changes
|
||||||
[id]
|
[id]
|
||||||
(WatchPageChanges. id))
|
(s/assert ::us/uuid id)
|
||||||
|
(ptk/reify ::watch-page-changes
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
|
(let [stopper (rx/filter #(= % ::udp/stop-page-watcher) stream)]
|
||||||
|
(->> stream
|
||||||
|
(rx/filter udp/page-update?)
|
||||||
|
(rx/filter #(not (undo? %)))
|
||||||
|
(rx/filter #(not (redo? %)))
|
||||||
|
(rx/map #(save-undo-entry id))
|
||||||
|
(rx/take-until stopper))))))
|
||||||
|
|
||||||
;; -- Save Undo Entry
|
;; -- Save Undo Entry
|
||||||
|
|
||||||
(defrecord SaveUndoEntry [id]
|
(defn save-undo-entry
|
||||||
|
[id]
|
||||||
|
(s/assert ::us/uuid id)
|
||||||
|
(letfn [(cons-entry [stack entry]
|
||||||
|
(let [stack (cons entry stack)]
|
||||||
|
(if (> (count stack) MAX-STACK-SIZE)
|
||||||
|
(take MAX-STACK-SIZE stack)
|
||||||
|
stack)))]
|
||||||
|
(ptk/reify ::save-undo-entry
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
state
|
(let [page (udp/pack-page state id)
|
||||||
#_(let [page (udp/pack-page state id)
|
|
||||||
undo {:data (:data page)
|
undo {:data (:data page)
|
||||||
:metadata (:metadata page)}]
|
:metadata (:metadata page)}]
|
||||||
(-> state
|
(-> state
|
||||||
(update-in [:undo id :stack] #(cons undo %))
|
(update-in [:undo id :stack] cons-entry undo)
|
||||||
(assoc-in [:undo id :selected] 0)))))
|
(assoc-in [:undo id :selected] 0)))))))
|
||||||
|
|
||||||
|
|
||||||
(defn save-undo-entry
|
|
||||||
[id]
|
|
||||||
{:pre [(uuid? id)]}
|
|
||||||
(SaveUndoEntry. id))
|
|
||||||
|
|
||||||
(defn save-undo-entry?
|
(defn save-undo-entry?
|
||||||
[v]
|
[v]
|
||||||
(instance? SaveUndoEntry v))
|
(= (ptk/type v) ::save-undo-entry))
|
||||||
|
|
||||||
;; --- Initialize Undo (For page)
|
|
||||||
|
|
||||||
(defrecord InitializeUndoForPage [id]
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state stream]
|
|
||||||
(let [initialized? (get-in state [:undo id])
|
|
||||||
page-loaded? (get-in state [:pages id])]
|
|
||||||
(cond
|
|
||||||
(and page-loaded? initialized?)
|
|
||||||
(rx/empty)
|
|
||||||
|
|
||||||
page-loaded?
|
|
||||||
(rx/of (save-undo-entry id))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(->> stream
|
|
||||||
(rx/filter udp/pages-fetched?)
|
|
||||||
(rx/take 1)
|
|
||||||
(rx/map #(initialize-undo-for-page id)))))))
|
|
||||||
|
|
||||||
(defn- initialize-undo-for-page
|
|
||||||
[id]
|
|
||||||
(InitializeUndoForPage. id))
|
|
||||||
|
|
||||||
;; --- Select Previous Entry
|
;; --- Select Previous Entry
|
||||||
|
|
||||||
(defrecord Undo []
|
(def undo
|
||||||
udp/IPageUpdate
|
(ptk/reify ::undo
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
#_(let [page-id (get-in state [:workspace :page])
|
(let [pid (get-in state [:workspace :current])
|
||||||
undo-state (get-in state [:undo page-id])
|
{:keys [stack selected] :as ustate} (get-in state [:undo pid])]
|
||||||
stack (:stack undo-state)
|
|
||||||
selected (:selected undo-state 0)]
|
|
||||||
(if (>= selected (dec (count stack)))
|
(if (>= selected (dec (count stack)))
|
||||||
state
|
state
|
||||||
(let [pointer (inc selected)
|
(let [pointer (inc selected)
|
||||||
page (get-in state [:pages page-id])
|
page (get-in state [:pages pid])
|
||||||
undo (nth stack pointer)
|
undo (nth stack pointer)
|
||||||
data (:data undo)
|
data (:data undo)
|
||||||
metadata (:metadata undo)
|
metadata (:metadata undo)
|
||||||
|
@ -108,25 +82,21 @@
|
||||||
;; (pp/pprint packed)
|
;; (pp/pprint packed)
|
||||||
|
|
||||||
(-> state
|
(-> state
|
||||||
(udp/assoc-page packed)
|
(udp/unpack-page packed)
|
||||||
(assoc-in [:undo page-id :selected] pointer)))))))
|
(assoc-in [:undo pid :selected] pointer))))))))
|
||||||
|
|
||||||
(defn undo
|
|
||||||
[]
|
|
||||||
(Undo.))
|
|
||||||
|
|
||||||
(defn undo?
|
(defn undo?
|
||||||
[v]
|
[v]
|
||||||
(instance? Undo v))
|
(= (ptk/type v) ::undo))
|
||||||
|
|
||||||
;; --- Select Next Entry
|
;; --- Select Next Entry
|
||||||
|
|
||||||
(defrecord Redo []
|
(def redo
|
||||||
udp/IPageUpdate
|
(ptk/reify ::redo
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
#_(let [page-id (get-in state [:workspace :page])
|
(let [pid (get-in state [:workspace :current])
|
||||||
undo-state (get-in state [:undo page-id])
|
undo-state (get-in state [:undo pid])
|
||||||
stack (:stack undo-state)
|
stack (:stack undo-state)
|
||||||
selected (:selected undo-state)]
|
selected (:selected undo-state)]
|
||||||
(if (or (nil? selected) (zero? selected))
|
(if (or (nil? selected) (zero? selected))
|
||||||
|
@ -135,7 +105,7 @@
|
||||||
undo (nth stack pointer)
|
undo (nth stack pointer)
|
||||||
data (:data undo)
|
data (:data undo)
|
||||||
metadata (:metadata undo)
|
metadata (:metadata undo)
|
||||||
page (get-in state [:pages page-id])
|
page (get-in state [:pages pid])
|
||||||
packed (assoc page :data data :metadata metadata)]
|
packed (assoc page :data data :metadata metadata)]
|
||||||
|
|
||||||
;; (println "Redo: pointer=" pointer)
|
;; (println "Redo: pointer=" pointer)
|
||||||
|
@ -143,13 +113,9 @@
|
||||||
;; (pp/pprint packed)
|
;; (pp/pprint packed)
|
||||||
|
|
||||||
(-> state
|
(-> state
|
||||||
(udp/assoc-page packed)
|
(udp/unpack-page packed)
|
||||||
(assoc-in [:undo page-id :selected] pointer)))))))
|
(assoc-in [:undo pid :selected] pointer))))))))
|
||||||
|
|
||||||
(defn redo
|
|
||||||
[]
|
|
||||||
(Redo.))
|
|
||||||
|
|
||||||
(defn redo?
|
(defn redo?
|
||||||
[v]
|
[v]
|
||||||
(instance? Redo v))
|
(= (ptk/type v) ::redo))
|
||||||
|
|
|
@ -994,7 +994,6 @@
|
||||||
url (str cfg/viewurl "?v=" rval "#/preview/" (:share-token project) "/" page-id)]
|
url (str cfg/viewurl "?v=" rval "#/preview/" (:share-token project) "/" page-id)]
|
||||||
(js/open url "new tab" ""))))
|
(js/open url "new tab" ""))))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Page Changes Reactions
|
;; Page Changes Reactions
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
[uxbox.main.data.undo :as du])
|
[uxbox.main.data.undo :as du])
|
||||||
(:import goog.events.EventType
|
(:import goog.events.EventType
|
||||||
goog.events.KeyCodes
|
goog.events.KeyCodes
|
||||||
goog.ui.KeyboardShortcutHandler
|
|
||||||
goog.ui.KeyboardShortcutHandler))
|
goog.ui.KeyboardShortcutHandler))
|
||||||
|
|
||||||
(declare move-selected)
|
(declare move-selected)
|
||||||
|
@ -34,9 +33,9 @@
|
||||||
:ctrl+c #(st/emit! (dw/copy-to-clipboard))
|
:ctrl+c #(st/emit! (dw/copy-to-clipboard))
|
||||||
:ctrl+v #(st/emit! (dw/paste-from-clipboard))
|
:ctrl+v #(st/emit! (dw/paste-from-clipboard))
|
||||||
:ctrl+shift+v #(dl/open! :clipboard)
|
:ctrl+shift+v #(dl/open! :clipboard)
|
||||||
:ctrl+z #(st/emit! (du/undo))
|
:ctrl+z #(st/emit! du/undo)
|
||||||
:ctrl+shift+z #(st/emit! (du/redo))
|
:ctrl+shift+z #(st/emit! du/redo)
|
||||||
:ctrl+y #(st/emit! (du/redo))
|
:ctrl+y #(st/emit! du/redo)
|
||||||
:ctrl+b #(st/emit! (dw/select-for-drawing :rect))
|
:ctrl+b #(st/emit! (dw/select-for-drawing :rect))
|
||||||
:ctrl+e #(st/emit! (dw/select-for-drawing :circle))
|
:ctrl+e #(st/emit! (dw/select-for-drawing :circle))
|
||||||
:ctrl+t #(st/emit! (dw/select-for-drawing :text))
|
:ctrl+t #(st/emit! (dw/select-for-drawing :text))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue