Skip to content

Commit

Permalink
feat: limit the scope of undo/redo to page only
Browse files Browse the repository at this point in the history
  • Loading branch information
tiensonqin committed Apr 12, 2023
1 parent 593526f commit 6869146
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 4 deletions.
75 changes: 72 additions & 3 deletions src/main/frontend/modules/editor/undo_redo.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
[frontend.db.conn :as conn]
[frontend.modules.datascript-report.core :as db-report]
[frontend.state :as state]
[clojure.set :as set]))
[clojure.set :as set]
[medley.core :as medley]))

;;;; APIs

Expand All @@ -30,6 +31,21 @@
[]
(-> (get-state) :redo-stack))

(defn- get-page-from-block
[stack]
(let [last-blocks (:blocks (last stack))]
(or (:db/id (some #(when (:block/name %) %) last-blocks))
(:db/id (some :block/page last-blocks)))))

(defn- get-history-page
[action]
(or
(:history/page @state/state)
(when-let [id (if (= :undo action)
(get-page-from-block @(get-undo-stack))
(get-page-from-block @(get-redo-stack)))]
(swap! state/state assoc :history/page id))))

(defn push-undo
[txs]
(let [undo-stack (get-undo-stack)]
Expand Down Expand Up @@ -74,6 +90,33 @@
(swap! redo-stack pop)
removed-e)))

(defn page-pop-redo
[page-id]
(prn "[debug] redo: " (:block/original-name (db/pull page-id)))
(when-let [redo-stack (get-redo-stack)]
(when-let [stack @redo-stack]
(when (seq stack)
(let [reversed-stack (medley/indexed (reverse stack))
idx (some (fn [[idx item]]
(some #(when (or (= (:db/id %) page-id)
(= (:db/id (:block/page %)) page-id)) idx) (:blocks item))) reversed-stack)]
(when idx
(let [idx' (- (count stack) idx 1)
before (subvec stack 0 idx')
after (subvec stack (inc idx'))
others (vec (concat before after))]
(reset! redo-stack others)
(prn "[debug] redo remove: " (nth stack idx'))
(nth stack idx'))))))))

(defn- smart-pop-redo
[]
(if (:history/page-only-mode? @state/state)
(if-let [page-id (get-history-page :redo)]
(page-pop-redo page-id)
(pop-redo))
(pop-redo)))

(defn reset-redo
[]
(let [redo-stack (get-redo-stack)]
Expand All @@ -98,9 +141,35 @@
(let [conn (conn/get-db false)]
(d/transact! conn txs tx-meta)))

(defn page-pop-undo
[page-id]
(let [undo-stack (get-undo-stack)]
(when-let [stack @undo-stack]
(when (seq stack)
(let [reversed-stack (medley/indexed (reverse stack))
idx (some (fn [[idx item]]
(some #(when (or (= (:db/id %) page-id)
(= (:db/id (:block/page %)) page-id)) idx) (:blocks item))) reversed-stack)]
(when idx
(let [idx' (- (count stack) idx 1)
before (subvec stack 0 idx')
after (subvec stack (inc idx'))
others (vec (concat before after))]
(reset! undo-stack others)
(prn "[debug] undo remove: " (nth stack idx'))
[(nth stack idx') others])))))))

(defn- smart-pop-undo
[]
(if (:history/page-only-mode? @state/state)
(if-let [page-id (get-history-page :undo)]
(page-pop-undo page-id)
(pop-undo))
(pop-undo)))

(defn undo
[]
(let [[e prev-e] (pop-undo)]
(let [[e prev-e] (smart-pop-undo)]
(when e
(let [{:keys [txs tx-meta]} e
new-txs (get-txs false txs)
Expand Down Expand Up @@ -139,7 +208,7 @@

(defn redo
[]
(when-let [{:keys [txs tx-meta] :as e} (pop-redo)]
(when-let [{:keys [txs tx-meta] :as e} (smart-pop-redo)]
(let [new-txs (get-txs true txs)]
(push-undo e)
(transact! new-txs (merge {:redo? true}
Expand Down
5 changes: 5 additions & 0 deletions src/main/frontend/modules/shortcut/config.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@
:editor/zoom-out {:binding (if mac? "mod+," "alt+left")
:fn editor-handler/zoom-out!}

:editor/toggle-undo-redo-mode {:binding "t u"
:fn state/toggle-undo-redo-mode!}

:ui/toggle-brackets {:binding "mod+c mod+b"
:fn config-handler/toggle-ui-show-brackets!}

Expand Down Expand Up @@ -586,6 +589,7 @@
:editor/select-all-blocks
:editor/zoom-in
:editor/zoom-out
:editor/toggle-undo-redo-mode
:editor/undo
:editor/redo
:ui/toggle-brackets
Expand Down Expand Up @@ -743,6 +747,7 @@
:shortcut.category/toggle
[:ui/toggle-help
:editor/toggle-open-blocks
:editor/toggle-undo-redo-mode
:ui/toggle-wide-mode
:ui/toggle-cards
:ui/toggle-document-mode
Expand Down
1 change: 1 addition & 0 deletions src/main/frontend/modules/shortcut/dicts.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
:editor/select-parent "Select parent block"
:editor/zoom-in "Zoom in editing block / Forwards otherwise"
:editor/zoom-out "Zoom out editing block / Backwards otherwise"
:editor/toggle-undo-redo-mode "Toggle undo redo mode (global or page only)"
:ui/toggle-brackets "Toggle whether to display brackets"
:go/search-in-page "Search blocks in the current page"
:go/electron-find-in-page "Find text in page"
Expand Down
14 changes: 13 additions & 1 deletion src/main/frontend/state.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@
:whiteboard/onboarding-whiteboard? (or (storage/get :ls-onboarding-whiteboard?) false)
:whiteboard/onboarding-tour? (or (storage/get :whiteboard-onboarding-tour?) false)
:whiteboard/last-persisted-at {}
:whiteboard/pending-tx-data {}})))
:whiteboard/pending-tx-data {}
:history/page-only-mode? false
:history/page nil})))

;; Block ast state
;; ===============
Expand Down Expand Up @@ -2093,3 +2095,13 @@ Similar to re-frame subscriptions"
(defn clear-user-info!
[]
(storage/remove :user-groups))

(defn toggle-undo-redo-mode!
[]
(if (:history/page-only-mode? @state)
(swap! state assoc
:history/page-only-mode? false
:history/page nil)
(swap! state assoc
:history/page-only-mode? true
:history/page nil)))

0 comments on commit 6869146

Please sign in to comment.