Skip to content

Commit

Permalink
enhance(perf): insert and delete blocks (logseq#9142)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Co-authored-by: Gabriel Horner <[email protected]>
  • Loading branch information
3 people authored May 9, 2023
1 parent 4be6715 commit 01479ef
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 131 deletions.
2 changes: 2 additions & 0 deletions .carve/ignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ logseq.graph-parser.nbb-test-runner/run-tests
;; For debugging
frontend.fs.sync/debug-print-sync-events-loop
frontend.fs.sync/stop-debug-print-sync-events-loop
;; Used in macro
frontend.state/get-current-edit-block-and-position
2 changes: 1 addition & 1 deletion e2e-tests/editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ test('undo and redo after starting an action should not destroy text #6267', asy

// And it should keep what was undone as a redo action
await page.keyboard.press(modKey + '+Shift+z')
await expect(page.locator('text="text2"')).toHaveCount(1)
await expect(page.locator('text="text1 text2 [[]]"')).toHaveCount(1)
})

test('undo after starting an action should close the action menu #6269', async ({ page, block }) => {
Expand Down
3 changes: 1 addition & 2 deletions src/main/frontend/components/block.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,7 @@
[:span.warning.mr-1 {:title "Block ref invalid"}
(block-ref/->block-ref id)]))
[:span.warning.mr-1 {:title "Block ref invalid"}
(block-ref/->block-ref id)]
))
(block-ref/->block-ref id)]))

(defn inline-text
([format v]
Expand Down
11 changes: 2 additions & 9 deletions src/main/frontend/db/model.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -957,15 +957,8 @@ independent of format as format specific heading characters are stripped"
"Doesn't include nested children."
[repo block-uuid]
(when-let [db (conn/get-db repo)]
(-> (d/q
'[:find [(pull ?b [*]) ...]
:in $ ?parent-id
:where
[?parent :block/uuid ?parent-id]
[?b :block/parent ?parent]]
db
block-uuid)
(sort-by-left (db-utils/entity [:block/uuid block-uuid])))))
(when-let [parent (db-utils/entity repo [:block/uuid block-uuid])]
(sort-by-left (:block/_parent parent) parent))))

(defn get-block-children
"Including nested children."
Expand Down
2 changes: 1 addition & 1 deletion src/main/frontend/db/react.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
;;; keywords specs for reactive query, used by `react/q` calls
;; ::block
;; pull-block react-query
(s/def ::block (s/tuple #(= ::block %) uuid?))
(s/def ::block (s/tuple #(= ::block %) int?))
;; ::page-blocks
;; get page-blocks react-query
(s/def ::page-blocks (s/tuple #(= ::page-blocks %) int?))
Expand Down
10 changes: 2 additions & 8 deletions src/main/frontend/handler/block.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
[frontend.db :as db]
[frontend.db.model :as db-model]
[frontend.db.react :as react]
[frontend.db.utils :as db-utils]
[frontend.mobile.haptics :as haptics]
[frontend.modules.outliner.core :as outliner-core]
[frontend.modules.outliner.transaction :as outliner-tx]
Expand Down Expand Up @@ -70,14 +69,9 @@
(util/distinct-by :db/id))))))

(defn indentable?
[{:block/keys [parent] :as block}]
[{:block/keys [parent left]}]
(when parent
(let [parent-block (db-utils/pull (:db/id parent))
first-child (first
(db-model/get-block-immediate-children
(state/get-current-repo)
(:block/uuid parent-block)))]
(not= (:db/id block) (:db/id first-child)))))
(not= parent left)))

(defn outdentable?
[{:block/keys [level] :as _block}]
Expand Down
70 changes: 37 additions & 33 deletions src/main/frontend/handler/editor.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -753,30 +753,28 @@
(outliner-core/delete-blocks! [block] {:children? children?})))))

(defn- move-to-prev-block
([repo sibling-block format id value]
(move-to-prev-block repo sibling-block format id value true))
([repo sibling-block format id value edit?]
(when (and repo sibling-block)
(when-let [sibling-block-id (dom/attr sibling-block "blockid")]
(when-let [block (db/pull repo '[*] [:block/uuid (uuid sibling-block-id)])]
(let [original-content (util/trim-safe (:block/content block))
value' (-> (property/remove-built-in-properties format original-content)
(drawer/remove-logbook))
new-value (str value' value)
tail-len (count value)
pos (max
(if original-content
(gobj/get (utf8/encode original-content) "length")
0)
0)]
(when edit?
(edit-block! block pos id
{:custom-content new-value
:tail-len tail-len
:move-cursor? false}))
{:prev-block block
:new-content new-value
:pos pos}))))))
[repo sibling-block format id value move?]
(when (and repo sibling-block)
(when-let [sibling-block-id (dom/attr sibling-block "blockid")]
(when-let [block (db/pull repo '[*] [:block/uuid (uuid sibling-block-id)])]
(let [original-content (util/trim-safe (:block/content block))
value' (-> (property/remove-built-in-properties format original-content)
(drawer/remove-logbook))
new-value (str value' value)
tail-len (count value)
pos (max
(if original-content
(gobj/get (utf8/encode original-content) "length")
0)
0)
f (fn [] (edit-block! block pos id
{:custom-content new-value
:tail-len tail-len
:move-cursor? false}))]
(when move? (f))
{:prev-block block
:new-content new-value
:move-fn f})))))

(declare save-block!)

Expand All @@ -802,7 +800,7 @@
(when block-parent-id
(let [block-parent (gdom/getElement block-parent-id)
sibling-block (util/get-prev-block-non-collapsed-non-embed block-parent)
{:keys [prev-block new-content]} (move-to-prev-block repo sibling-block format id value)
{:keys [prev-block new-content move-fn]} (move-to-prev-block repo sibling-block format id value false)
concat-prev-block? (boolean (and prev-block new-content))
transact-opts (cond->
{:outliner-op :delete-block}
Expand All @@ -812,7 +810,8 @@
(outliner-tx/transact! transact-opts
(when concat-prev-block?
(save-block! repo prev-block new-content))
(delete-block-aux! block delete-children?))))))))))
(delete-block-aux! block delete-children?))
(move-fn)))))))))
(state/set-editor-op! nil)))

(defn delete-blocks!
Expand All @@ -829,7 +828,8 @@
(move-to-prev-block repo sibling-block
(:block/format block)
(dom/attr sibling-block "id")
"")))))
""
true)))))

(defn- set-block-property-aux!
[block-or-id key value]
Expand Down Expand Up @@ -1962,7 +1962,7 @@
keep-uuid?]
:or {exclude-properties []}}]
(let [editing-block (when-let [editing-block (state/get-edit-block)]
(some-> (db/pull (:db/id editing-block))
(some-> (db/pull [:block/uuid (:block/uuid editing-block)])
(assoc :block/content (state/get-edit-content))))
has-unsaved-edits (and editing-block
(not= (:block/content (db/pull (:db/id editing-block)))
Expand Down Expand Up @@ -2425,8 +2425,9 @@
:else
(profile
"Insert block"
(do (save-current-block!)
(insert-new-block! state)))))))))
(outliner-tx/transact! {:outliner-op :insert-blocks}
(save-current-block!)
(insert-new-block! state)))))))))

(defn- inside-of-single-block
"When we are in a single block wrapper, we should always insert a new line instead of new block"
Expand Down Expand Up @@ -2580,15 +2581,18 @@
^js input (state/get-input)
current-pos (cursor/pos input)
value (gobj/get input "value")
right (outliner-core/get-right-node (outliner-core/block current-block))
right (outliner-core/get-right-sibling (:db/id current-block))
current-block-has-children? (db/has-children? (:block/uuid current-block))
collapsed? (util/collapsed? current-block)
first-child (:data (tree/-get-down (outliner-core/block current-block)))
next-block (if (or collapsed? (not current-block-has-children?))
(:data right)
(when right (db/pull (:db/id right)))
first-child)]
(cond
(and collapsed? right (db/has-children? (tree/-get-id right)))
(nil? next-block)
nil

(and collapsed? right (db/has-children? (:block/uuid right)))
nil

(and (not collapsed?) first-child (db/has-children? (:block/uuid first-child)))
Expand Down
5 changes: 2 additions & 3 deletions src/main/frontend/handler/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,9 @@
(plugin/open-waiting-updates-modal!))
(plugin-handler/set-auto-checking! false))))))

(defmethod handle :plugin/hook-db-tx [[_ {:keys [blocks tx-data tx-meta] :as payload}]]
(defmethod handle :plugin/hook-db-tx [[_ {:keys [blocks tx-data] :as payload}]]
(when-let [payload (and (seq blocks)
(merge payload {:tx-data (map #(into [] %) tx-data)
:tx-meta (dissoc tx-meta :editor-cursor)}))]
(merge payload {:tx-data (map #(into [] %) tx-data)}))]
(plugin-handler/hook-plugin-db :changed payload)
(plugin-handler/hook-plugin-block-changes payload)))

Expand Down
Loading

0 comments on commit 01479ef

Please sign in to comment.