Improve long page editing performance (#3855)

* Remove expensive parsing when saving files

* Add limit to page blocks query

* Don't collapse block's body to make it compatible with other tools

* Alert if there're unsaved changes when switching graphs

* DB schema migration for :block/collapsed? from it's property

Co-authored-by: Andelf <andelf@gmail.com>
This commit is contained in:
Tienson Qin
2022-01-18 10:37:31 +08:00
committed by GitHub
parent 6a151937d7
commit 6aba8c3241
28 changed files with 429 additions and 348 deletions

View File

@@ -481,7 +481,7 @@
(boolean? sibling?)
sibling?
(:collapsed (:block/properties current-block))
(util/collapsed? current-block)
true
:else
@@ -1189,7 +1189,7 @@
[repo block-ids]
(let [blocks (db-utils/pull-many repo '[*] (mapv (fn [id] [:block/uuid id]) block-ids))
blocks* (flatten
(mapv (fn [b] (if (:collapsed (:block/properties b))
(mapv (fn [b] (if (util/collapsed? b)
(vec (tree/sort-blocks (db/get-block-children repo (:block/uuid b)) b))
[b])) blocks))
block-ids* (mapv :block/uuid blocks*)
@@ -1280,7 +1280,7 @@
;; filter out blocks not belong to page with 'page-id'
(remove (fn [block] (some-> (:db/id (:block/page block)) (not= page-id))))
;; expand collapsed blocks
(mapv (fn [b] (if (:collapsed (:block/properties b))
(mapv (fn [b] (if (util/collapsed? b)
(vec (tree/sort-blocks (db/get-block-children repo (:block/uuid b)) b))
[b])))
(flatten))
@@ -2065,8 +2065,7 @@
(defn edit-box-on-change!
[e block id]
(let [value (util/evalue e)
repo (or (:block/repo block)
(state/get-current-repo))]
repo (state/get-current-repo)]
(state/set-edit-content! id value false)
(when @*auto-save-timeout
(js/clearTimeout @*auto-save-timeout))
@@ -2157,7 +2156,7 @@
block-self? (block-self-alone-when-insert? config block-id)
has-children? (db/has-children? (state/get-current-repo)
(:block/uuid editing-block))
collapsed? (:collapsed (:block/properties editing-block))]
collapsed? (util/collapsed? editing-block)]
(conj (match (mapv boolean [(seq fst-block-text) (seq snd-block-text)
block-self? has-children? (= parent left) collapsed?])
;; when zoom at editing-block
@@ -2779,7 +2778,7 @@
repo (state/get-current-repo)
right (outliner-core/get-right-node (outliner-core/block current-block))
current-block-has-children? (db/has-children? repo (:block/uuid current-block))
collapsed? (:collapsed (:block/properties 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)
@@ -3451,11 +3450,9 @@
(defn collapsable? [block-id]
(when block-id
(if-let [block (db-model/query-block-by-uuid block-id)]
(let [block (block/parse-title-and-body block)]
(and
(nil? (-> block :block/properties :collapsed))
(or (not-empty (:block/body block))
(db-model/has-children? block-id))))
(and
(not (util/collapsed? block))
(db-model/has-children? block-id))
false)))
(defn all-blocks-with-level
@@ -3495,7 +3492,7 @@
collapse?
(w/postwalk
(fn [b]
(if (and (map? b) (-> b :block/properties :collapsed))
(if (and (map? b) (util/collapsed? b))
(assoc b :block/children []) b)))
true
@@ -3513,15 +3510,44 @@
(let [config (:config (state/get-editor-args))]
(or (:ref? config) (:block? config))))
(defn- set-blocks-collapsed!
[block-ids value]
(let [block-ids (map (fn [block-id] (if (string? block-id) (uuid block-id) block-id)) block-ids)
repo (state/get-current-repo)
value (boolean value)]
(when repo
(ds/auto-transact!
[txs-state (ds/new-outliner-txs-state)]
{:outliner-op :collapse-expand-blocks
:skip-transact? false}
(doseq [block-id block-ids]
(when-let [block (db/entity [:block/uuid block-id])]
(let [current-value (boolean (util/collapsed? block))]
(when-not (= current-value value)
(let [block (outliner-core/block {:block/uuid block-id
:block/collapsed? value})]
(outliner-core/save-node block {:txs-state txs-state})))))))
(let [block-id (first block-ids)
input-pos (or (state/get-edit-pos) :max)]
(db/refresh! (state/get-current-repo)
{:key :block/change
:data [(db/pull [:block/uuid block-id])]})
;; update editing input content
(when-let [editing-block (state/get-edit-block)]
(when (= (:block/uuid editing-block) block-id)
(edit-block! editing-block
input-pos
(state/get-edit-input-id))))))))
(defn collapse-block! [block-id]
(when (collapsable? block-id)
(when-not (skip-collapsing-in-db?)
(set-block-property! block-id :collapsed true)))
(set-blocks-collapsed! [block-id] true)))
(state/set-collapsed-block! block-id true))
(defn expand-block! [block-id]
(when-not (skip-collapsing-in-db?)
(remove-block-property! block-id :collapsed))
(set-blocks-collapsed! [block-id] false))
(state/set-collapsed-block! block-id false))
(defn expand!
@@ -3552,8 +3578,7 @@
nil
(let [blocks-to-expand (->> blocks-with-level
(filter (fn [b] (= (:block/level b) level)))
(filter (fn [{:block/keys [properties]}]
(contains? properties :collapsed))))]
(filter util/collapsed?))]
(if (empty? blocks-to-expand)
(recur (inc level))
(doseq [{:block/keys [uuid]} blocks-to-expand]
@@ -3599,17 +3624,15 @@
([]
(collapse-all! nil))
([block-id]
(let [blocks-to-collapse (all-blocks-with-level {:expanded? true :root-block block-id})]
(doseq [{:block/keys [uuid]} blocks-to-collapse]
(collapse-block! uuid)))))
(let [blocks (all-blocks-with-level {:expanded? true :root-block block-id})]
(set-blocks-collapsed! (map :block/uuid blocks) true))))
(defn expand-all!
([]
(expand-all! nil))
([block-id]
(->> (all-blocks-with-level {:root-block block-id})
(map (comp expand-block! :block/uuid))
dorun)))
(let [blocks (all-blocks-with-level {:root-block block-id})]
(set-blocks-collapsed! (map :block/uuid blocks) false))))
(defn- get-block-with-its-children
[block-uuid]
@@ -3621,7 +3644,7 @@
(defn expand-all?
[block-uuid]
(let [blocks (get-block-with-its-children block-uuid)]
(some #(get-in % [:block/properties :collapsed]) blocks)))
(some util/collapsed? blocks)))
(defn collapse-all?
[block-uuid]
@@ -3727,7 +3750,7 @@
false
(and (:block? config)
(get-in block [:block/properties :collapsed]))
(util/collapsed? block))
true
:else
@@ -3740,4 +3763,4 @@
(state/get-ref-open-blocks-level)))))))]
(if (or (:ref? config) (:block? config))
collapsed?
(get-in block [:block/properties :collapsed]))))
(util/collapsed? block))))