diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 6c86f10d7..1756224c7 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -456,7 +456,8 @@ (defn outliner-insert-block! [current-block new-block child?] - (let [[current-node new-node] + (let [dummy? (:block/dummy? current-block) + [current-node new-node] (mapv outliner-core/block [current-block new-block]) has-children? (db/has-children? (state/get-current-repo) (tree/-get-id current-node)) @@ -469,9 +470,14 @@ :else (not has-children?))] - ;; perf: multiple file writes - (outliner-core/save-node current-node) - (outliner-core/insert-node new-node current-node sibling?))) + (let [*blocks (atom [current-node]) + _ (outliner-core/insert-node new-node current-node sibling? {:blocks-atom *blocks + :skip-transact? true}) + tx-f (fn [] + (outliner-core/save-node current-node) + (outliner-core/insert-node new-node current-node sibling?))] + (if dummy? (tx-f) (state/add-tx! tx-f)) + @*blocks))) (defn- block-self-alone-when-insert? [config uuid] @@ -485,6 +491,52 @@ current-page))] (= uuid (and block-id (medley/uuid block-id))))) +;; FIXME: painful +(defn update-cache-for-block-insert! + "Currently, this only affects current editor container to improve the performance." + [repo config {:block/keys [page uuid] :as block} blocks] + (let [blocks (map :data blocks) + [first-block last-block right-block] blocks + child? (= (first (:block/parent last-block)) + (:block/uuid first-block)) + block-container-id (when-let [id (:id config)] + (and (util/uuid-string? id) (medley/uuid id))) + new-last-block (let [first-block-id {:db/id (:db/id first-block)}] + (assoc last-block + :block/left first-block-id + :block/parent (if child? + first-block-id + ;; sibling + (:block/parent first-block)))) + blocks [first-block new-last-block] + page-blocks-atom (db/get-page-blocks-cache-atom repo (:db/id page)) + [before-part after-part] (and page-blocks-atom + (split-with + #(not= uuid (:block/uuid %)) + @page-blocks-atom)) + after-part (rest after-part) + blocks (concat before-part blocks after-part) + blocks (if right-block + (map (fn [block] + (if (= (:block/uuid right-block) (:block/uuid block)) + (assoc block :block/left (:block/left right-block)) + block)) blocks) + blocks)] + (when page-blocks-atom + (reset! page-blocks-atom blocks)) + + ;; update block children cache if exists + ;; (when blocks-container-id + ;; (let [blocks-atom (db/get-block-blocks-cache-atom repo blocks-container-id) + ;; [before-part after-part] (and blocks-atom + ;; (split-with + ;; #(not= uuid (:block/uuid %)) + ;; @blocks-atom)) + ;; after-part (rest after-part)] + ;; (when blocks-atom + ;; (reset! blocks-atom (concat before-part blocks after-part))))) + )) + (defn insert-new-block-aux! [config {:block/keys [uuid content repo format] @@ -500,21 +552,24 @@ [fst-block-text snd-block-text] (compute-fst-snd-block-text value pos) current-block (-> (assoc block :block/content fst-block-text) (wrap-parse-block)) + dummy? (:block/dummy? current-block) new-m {:block/uuid (db/new-block-id) :block/content snd-block-text} next-block (-> (merge block new-m) (dissoc :db/id :block/collapsed? :block/properties :block/pre-block? :block/meta) - (wrap-parse-block))] + (wrap-parse-block)) + blocks (profile + "outliner insert block" + (outliner-insert-block! current-block next-block block-self?))] (do - (profile - "outliner insert block" - (outliner-insert-block! current-block next-block block-self?)) - (profile - "db refresh" - (let [opts {:key :block/insert - :data [current-block next-block]}] - (db/refresh! repo opts))) - (ok-handler next-block) + (if dummy? + (profile + "db refresh" + (let [opts {:key :block/insert + :data [current-block next-block]}] + (db/refresh! repo opts))) + (profile "update cache " (update-cache-for-block-insert! repo config block blocks))) + (profile "ok handler" (ok-handler next-block)) (state/set-editor-op! nil)))) (defn clear-when-saved! @@ -582,10 +637,8 @@ value {:ok-handler (fn [last-block] - (let [last-id (:block/uuid last-block)] - ;; perf: improvement - (edit-block! last-block 0 format id) - (clear-when-saved!)))})))))) + (edit-block! last-block 0 format id) + (clear-when-saved!))})))))) (defn update-timestamps-content! [{:block/keys [repeated? marker] :as block} content] diff --git a/src/main/frontend/modules/outliner/core.cljs b/src/main/frontend/modules/outliner/core.cljs index 83538df8e..631771be3 100644 --- a/src/main/frontend/modules/outliner/core.cljs +++ b/src/main/frontend/modules/outliner/core.cljs @@ -146,6 +146,7 @@ [:db/retract id attribute]) db-schema/retract-attributes)))))) (swap! txs-state conj (dissoc m :db/other-tx)) + this ;; TODO: enable for the database-only version ;; (let [[m page-tx] (with-timestamp (:data this))] ;; (swap! txs-state conj m page-tx) @@ -195,13 +196,14 @@ node (-> (tree/-set-left-id new-node parent-id) (tree/-set-parent-id parent-id)) right-node (tree/-get-down parent-node)] - (do - (if (tree/satisfied-inode? right-node) - (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node)) - saved-new-node (tree/-save node txs-state)] - (tree/-save new-right-node txs-state) - saved-new-node) - (tree/-save node txs-state))))) + (if (tree/satisfied-inode? right-node) + (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node)) + saved-new-node (tree/-save node txs-state)] + (tree/-save new-right-node txs-state) + [saved-new-node new-right-node]) + (do + (tree/-save node txs-state) + [node])))) (defn insert-node-as-sibling "Insert a node as sibling." @@ -210,21 +212,29 @@ (let [node (-> (tree/-set-left-id new-node (tree/-get-id left-node)) (tree/-set-parent-id (tree/-get-parent-id left-node))) right-node (tree/-get-right left-node)] - (do - (if (tree/satisfied-inode? right-node) - (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node)) - saved-new-node (tree/-save node txs-state)] - (tree/-save new-right-node txs-state) - saved-new-node) - (tree/-save node txs-state))))) + (if (tree/satisfied-inode? right-node) + (let [new-right-node (tree/-set-left-id right-node (tree/-get-id new-node)) + saved-new-node (tree/-save node txs-state)] + (tree/-save new-right-node txs-state) + [saved-new-node new-right-node]) + (do + (tree/-save node txs-state) + [node])))) (defn insert-node - [new-node target-node sibling?] - (ds/auto-transact! - [txs-state (ds/new-outliner-txs-state)] {:outliner-op :insert-node} - (if sibling? - (insert-node-as-sibling txs-state new-node target-node) - (insert-node-as-first-child txs-state new-node target-node)))) + ([new-node target-node sibling?] + (insert-node new-node target-node sibling? nil)) + ([new-node target-node sibling? {:keys [blocks-atom skip-transact?] + :or {skip-transact? false}}] + (ds/auto-transact! + [txs-state (ds/new-outliner-txs-state)] {:outliner-op :insert-node + :skip-transact? skip-transact?} + (let [result (if sibling? + (insert-node-as-sibling txs-state new-node target-node) + (insert-node-as-first-child txs-state new-node target-node))] + (when blocks-atom + (swap! blocks-atom concat result)) + (first result))))) (defn- walk-&-insert-nodes diff --git a/src/main/frontend/modules/outliner/datascript.cljc b/src/main/frontend/modules/outliner/datascript.cljc index 547c96338..f669f8f53 100644 --- a/src/main/frontend/modules/outliner/datascript.cljc +++ b/src/main/frontend/modules/outliner/datascript.cljc @@ -37,7 +37,8 @@ #?(:cljs (defn transact! [txs opts] - (when (seq txs) + (when (and (seq txs) + (not (:skip-transact? opts))) (let [conn (conn/get-conn false) editor-cursor (state/get-last-edit-block) meta (merge opts {:editor-cursor editor-cursor}) diff --git a/src/main/frontend/modules/shortcut/mixin.cljs b/src/main/frontend/modules/shortcut/mixin.cljs index b9d4f420c..9500161dd 100644 --- a/src/main/frontend/modules/shortcut/mixin.cljs +++ b/src/main/frontend/modules/shortcut/mixin.cljs @@ -14,7 +14,7 @@ (js/setTimeout (fn [] (swap! state-store assoc k state)) - 100) + 5) state) :did-remount diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 4380ca708..6493aec04 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -709,11 +709,12 @@ :editor/last-edit-block-id edit-input-id :cursor-range cursor-range)))) - (let [input (gdom/getElement edit-input-id) - pos (count cursor-range)] - (set! (.-value input) (string/trim content)) - (when move-cursor? - (util/move-cursor-to input pos))))))) + (when-let [input (gdom/getElement edit-input-id)] + (let [pos (count cursor-range)] + (when content + (set! (.-value input) (string/trim content))) + (when move-cursor? + (util/move-cursor-to input pos)))))))) (defn clear-edit! []