mirror of
https://github.com/logseq/logseq.git
synced 2026-04-27 23:54:55 +00:00
enhance(perf): insert and delete blocks (#9142)
* enhance(perf): improve performance for both insert and delete * fix: remember cursor pos before executing the body in a transaction Otherwise, the edit-block and position could be changed * fix: disable delete-concat when there's no child or right sibling --------- Co-authored-by: Gabriel Horner <97210743+logseq-cldwalker@users.noreply.github.com> Co-authored-by: Gabriel Horner <gabriel@logseq.com>
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
[txs]
|
||||
(filterv (fn [[_ a & y]]
|
||||
(= :block/content a))
|
||||
txs))
|
||||
txs))
|
||||
|
||||
(defn get-content-from-stack
|
||||
"For test."
|
||||
@@ -60,22 +60,21 @@
|
||||
(when-let [stack @undo-stack]
|
||||
(when (seq stack)
|
||||
(let [removed-e (peek stack)
|
||||
popped-stack (pop stack)
|
||||
prev-e (peek popped-stack)]
|
||||
popped-stack (pop stack)]
|
||||
(reset! undo-stack popped-stack)
|
||||
[removed-e prev-e])))))
|
||||
removed-e)))))
|
||||
|
||||
(defn push-redo
|
||||
[txs]
|
||||
(let [redo-stack (get-redo-stack)]
|
||||
(swap! redo-stack conj txs)))
|
||||
(swap! redo-stack conj txs)))
|
||||
|
||||
(defn pop-redo
|
||||
[]
|
||||
(let [redo-stack (get-redo-stack)]
|
||||
(when-let [removed-e (peek @redo-stack)]
|
||||
(swap! redo-stack pop)
|
||||
removed-e)))
|
||||
(when-let [removed-e (peek @redo-stack)]
|
||||
(swap! redo-stack pop)
|
||||
removed-e)))
|
||||
|
||||
(defn page-pop-redo
|
||||
[page-id]
|
||||
@@ -119,7 +118,7 @@
|
||||
(and redo? (not add?)) :db/retract
|
||||
(and (not redo?) (not add?)) :db/add)]
|
||||
[op id attr value tx]))
|
||||
txs)))
|
||||
txs)))
|
||||
|
||||
;;;; Invokes
|
||||
|
||||
@@ -128,7 +127,7 @@
|
||||
(let [conn (conn/get-db false)]
|
||||
(d/transact! conn txs tx-meta)))
|
||||
|
||||
(defn page-pop-undo
|
||||
(defn- page-pop-undo
|
||||
[page-id]
|
||||
(let [undo-stack (get-undo-stack)]
|
||||
(when-let [stack @undo-stack]
|
||||
@@ -144,7 +143,7 @@
|
||||
others (vec (concat before after))]
|
||||
(reset! undo-stack others)
|
||||
(prn "[debug] undo remove: " (nth stack idx'))
|
||||
[(nth stack idx') others])))))))
|
||||
(nth stack idx'))))))))
|
||||
|
||||
(defn- smart-pop-undo
|
||||
[]
|
||||
@@ -154,56 +153,77 @@
|
||||
(pop-undo))
|
||||
(pop-undo)))
|
||||
|
||||
(defn- set-editor-content!
|
||||
"Prevent block auto-save during undo/redo."
|
||||
[]
|
||||
(when-let [block (state/get-edit-block)]
|
||||
(state/set-edit-content! (state/get-edit-input-id)
|
||||
(:block/content (db/entity (:db/id block))))))
|
||||
|
||||
(defn- get-next-tx-editor-cursor
|
||||
[tx-id]
|
||||
(let [result (->> (sort (keys (:history/tx->editor-cursor @state/state)))
|
||||
(split-with #(not= % tx-id))
|
||||
second)]
|
||||
(when (> (count result) 1)
|
||||
(when-let [next-tx-id (nth result 1)]
|
||||
(get-in @state/state [:history/tx->editor-cursor next-tx-id])))))
|
||||
|
||||
(defn- get-previous-tx-id
|
||||
[tx-id]
|
||||
(let [result (->> (sort (keys (:history/tx->editor-cursor @state/state)))
|
||||
(split-with #(not= % tx-id))
|
||||
first)]
|
||||
(when (>= (count result) 1)
|
||||
(last result))))
|
||||
|
||||
(defn- get-previous-tx-editor-cursor
|
||||
[tx-id]
|
||||
(when-let [prev-tx-id (get-previous-tx-id tx-id)]
|
||||
(get-in @state/state [:history/tx->editor-cursor prev-tx-id])))
|
||||
|
||||
(defn undo
|
||||
[]
|
||||
(let [[e prev-e] (smart-pop-undo)]
|
||||
(when e
|
||||
(let [{:keys [txs tx-meta]} e
|
||||
new-txs (get-txs false txs)
|
||||
undo-delete-concat-block? (and (= :delete-block (:outliner-op tx-meta))
|
||||
(seq (:concat-data tx-meta)))
|
||||
editor-cursor (cond
|
||||
undo-delete-concat-block?
|
||||
(let [data (:concat-data tx-meta)]
|
||||
(assoc (:editor-cursor e)
|
||||
:last-edit-block {:block/uuid (:last-edit-block data)}
|
||||
:pos (if (:end? data) :max 0)))
|
||||
|
||||
;; same block
|
||||
(= (get-in e [:editor-cursor :last-edit-block :block/uuid])
|
||||
(get-in prev-e [:editor-cursor :last-edit-block :block/uuid]))
|
||||
(:editor-cursor prev-e)
|
||||
|
||||
:else
|
||||
(:editor-cursor e))]
|
||||
|
||||
(push-redo e)
|
||||
(transact! new-txs (merge {:undo? true}
|
||||
tx-meta
|
||||
(select-keys e [:pagination-blocks-range])))
|
||||
|
||||
(when undo-delete-concat-block?
|
||||
(when-let [block (state/get-edit-block)]
|
||||
(state/set-edit-content! (state/get-edit-input-id)
|
||||
(:block/content (db/entity (:db/id block))))))
|
||||
|
||||
(when (:whiteboard/transact? tx-meta)
|
||||
(state/pub-event! [:whiteboard/undo e]))
|
||||
(assoc e
|
||||
:txs-op new-txs
|
||||
:editor-cursor editor-cursor)))))
|
||||
(when-let [e (smart-pop-undo)]
|
||||
(let [{:keys [txs tx-meta tx-id]} e
|
||||
new-txs (get-txs false txs)
|
||||
current-editor-cursor (get-in @state/state [:history/tx->editor-cursor tx-id])
|
||||
save-block? (= (:outliner-op tx-meta) :save-block)
|
||||
prev-editor-cursor (get-previous-tx-editor-cursor tx-id)
|
||||
editor-cursor (if (and save-block?
|
||||
(= (:block/uuid (:last-edit-block prev-editor-cursor))
|
||||
(:block/uuid (state/get-edit-block))))
|
||||
prev-editor-cursor
|
||||
current-editor-cursor)]
|
||||
(push-redo e)
|
||||
(transact! new-txs (merge {:undo? true}
|
||||
tx-meta
|
||||
(select-keys e [:pagination-blocks-range])))
|
||||
(set-editor-content!)
|
||||
(when (:whiteboard/transact? tx-meta)
|
||||
(state/pub-event! [:whiteboard/undo e]))
|
||||
(assoc e
|
||||
:txs-op new-txs
|
||||
:editor-cursor editor-cursor))))
|
||||
|
||||
(defn redo
|
||||
[]
|
||||
(when-let [{:keys [txs tx-meta] :as e} (smart-pop-redo)]
|
||||
(let [new-txs (get-txs true txs)]
|
||||
(when-let [{:keys [txs tx-meta tx-id] :as e} (smart-pop-redo)]
|
||||
(let [new-txs (get-txs true txs)
|
||||
current-editor-cursor (get-in @state/state [:history/tx->editor-cursor tx-id])
|
||||
editor-cursor (if (= (:outliner-op tx-meta) :save-block)
|
||||
current-editor-cursor
|
||||
(get-next-tx-editor-cursor tx-id))]
|
||||
(push-undo e)
|
||||
(transact! new-txs (merge {:redo? true}
|
||||
tx-meta
|
||||
(select-keys e [:pagination-blocks-range])))
|
||||
(set-editor-content!)
|
||||
(when (:whiteboard/transact? tx-meta)
|
||||
(state/pub-event! [:whiteboard/redo e]))
|
||||
(assoc e :txs-op new-txs))))
|
||||
(assoc e
|
||||
:txs-op new-txs
|
||||
:editor-cursor editor-cursor))))
|
||||
|
||||
(defn toggle-undo-redo-mode!
|
||||
[]
|
||||
@@ -231,14 +251,14 @@
|
||||
#{:block/created-at :block/updated-at})))
|
||||
(reset-redo)
|
||||
(if (:replace? tx-meta)
|
||||
(let [[removed-e _prev-e] (pop-undo)
|
||||
(let [removed-e (pop-undo)
|
||||
entity (update removed-e :txs concat tx-data)]
|
||||
(push-undo entity))
|
||||
(let [updated-blocks (db-report/get-blocks tx-report)
|
||||
entity {:blocks updated-blocks
|
||||
entity {:tx-id (get-in tx-report [:tempids :db/current-tx])
|
||||
:blocks updated-blocks
|
||||
:txs tx-data
|
||||
:tx-meta tx-meta
|
||||
:editor-cursor (:editor-cursor tx-meta)
|
||||
:pagination-blocks-range (get-in [:ui/pagination-blocks-range (get-in tx-report [:db-after :max-tx])] @state/state)
|
||||
:app-state (select-keys @state/state
|
||||
[:route-match
|
||||
|
||||
Reference in New Issue
Block a user