From 3c18e0ef841ba31a3cdbe3c43ad691b285223db1 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 13 Nov 2020 21:08:05 +0800 Subject: [PATCH] fix: don't re-render the unrelated blocks when inserting a new block --- src/main/frontend/components/block.cljs | 141 +++++++--------------- src/main/frontend/components/journal.cljs | 17 +-- src/main/frontend/components/page.cljs | 2 + src/main/frontend/db.cljs | 5 +- src/main/frontend/handler/common.cljs | 5 + src/main/frontend/handler/editor.cljs | 71 ++++++----- 6 files changed, 95 insertions(+), 146 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index e2d97f5e8..fc84beb99 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -1195,7 +1195,10 @@ collapsed? (:block/collapsed? block)] (when collapsed? (expand/collapse! block)) - state))} + state)) + :should-update (fn [old-state new-state] + (not= (:block/content (second (:rum/args old-state))) + (:block/content (second (:rum/args new-state)))))} [config {:block/keys [uuid title level body meta content dummy? page format repo children collapsed? pre-block? idx properties] :as block}] (let [ref? (boolean (:ref? config)) breadcrumb-show? (:breadcrumb-show? config) @@ -1699,83 +1702,6 @@ [config col] (map #(markup-element-cp config %) col)) -(rum/defcs build-blocks < rum/reactive - {:init (fn [state] - (let [blocks (first (:rum/args state)) - segment-data (if (> (count blocks) max-blocks-per-page) - (take max-blocks-per-page blocks) - blocks)] - (assoc state - ::segment (atom segment-data) - ::idx (atom 0)))) - :did-update (fn [state] - (let [blocks (first (:rum/args state)) - segment (get state ::segment) - idx (get state ::idx)] - (when (and - (seq @segment) - (> (count blocks) max-blocks-per-page)) - (reset! segment (->> blocks - (drop @idx) - (take max-blocks-per-page)))) - state))} - [state blocks config] - (let [segment (get state ::segment) - idx (get state ::idx) - custom-query? (:custom-query? config) - ref? (:ref? config)] - (let [blocks-cp (fn [blocks segment?] - (let [first-block (first blocks) - blocks' (if (and (:block/pre-block? first-block) - (db/pre-block-with-only-title? (:block/repo first-block) (:block/uuid first-block))) - (rest blocks) - blocks) - first-id (:block/uuid (first blocks'))] - (for [item blocks'] - (let [item (-> (if (:block/dummy? item) - item - (dissoc item :block/meta))) - item (if (= first-id (:block/uuid item)) - (assoc item :block/idx 0) - item) - config (assoc config :block/uuid (:block/uuid item))] - (rum/with-key - (block-container config item) - (:block/uuid item)))))) - blocks->vec-tree #(if (or custom-query? ref?) % (db/blocks->vec-tree %))] - (if (> (count blocks) max-blocks-per-page) - (ui/infinite-list - (blocks-cp (blocks->vec-tree (rum/react segment)) true) - {:on-load (fn [] - (when (= (count @segment) max-blocks-per-page) - (if (zero? @idx) - (reset! idx (dec max-blocks-per-page)) - (swap! idx + virtual-list-scroll-step)) - (let [tail (take-last virtual-list-previous @segment) - new-segment (->> blocks - (drop (inc @idx)) - (take virtual-list-scroll-step))] - (reset! segment - (->> (concat tail new-segment) - (remove nil?)))))) - :on-top-reached (fn [] - (when (> @idx 0) - (if (> @idx (dec max-blocks-per-page)) - (swap! idx - max-blocks-per-page) - (reset! idx 0)) - (if (zero? @idx) - (reset! segment - (take max-blocks-per-page blocks)) - (let [tail (take virtual-list-previous @segment) - prev (->> blocks - (drop (inc @idx)) - (take virtual-list-scroll-step))] - (reset! segment - (->> (concat prev tail) - (remove nil?))) - (util/scroll-to 100)))))}) - (blocks-cp (blocks->vec-tree blocks) false))))) - (defn build-slide-sections ([blocks config] (build-slide-sections blocks config nil)) @@ -1813,12 +1739,14 @@ (editor-handler/insert-new-block-without-save-previous! config last-block))} svg/plus-circle])))) -(rum/defc blocks-container < rum/static +(defn blocks-container [blocks config] (let [blocks (map #(dissoc % :block/children) blocks) sidebar? (:sidebar? config) ref? (:ref? config) - custom-query? (:custom-query? config)] + custom-query? (:custom-query? config) + blocks->vec-tree #(if (or custom-query? ref?) % (db/blocks->vec-tree %)) + blocks (blocks->vec-tree blocks)] (when (seq blocks) [:div.blocks-container.flex-1 {:style {:margin-left (cond @@ -1826,31 +1754,44 @@ 0 :else -18)}} - (build-blocks blocks config) + (let [first-block (first blocks) + blocks' (if (and (:block/pre-block? first-block) + (db/pre-block-with-only-title? (:block/repo first-block) (:block/uuid first-block))) + (rest blocks) + blocks) + first-id (:block/uuid (first blocks'))] + (for [item blocks'] + (let [item (-> (if (:block/dummy? item) + item + (dissoc item :block/meta))) + item (if (= first-id (:block/uuid item)) + (assoc item :block/idx 0) + item) + config (assoc config :block/uuid (:block/uuid item))] + (rum/with-key + (block-container config item) + (:block/uuid item))))) ;; (add-button config ref? custom-query? blocks) ]))) ;; headers to hiccup -(rum/defc ->hiccup < rum/reactive +(defn ->hiccup [blocks config option] - (let [document-mode? (state/sub [:document/mode?]) - config (assoc config - :document/mode? document-mode?)] - [:div.content - (cond-> option - document-mode? - (assoc :class "doc-mode")) - (if (:group-by-page? config) - [:div.flex.flex-col - (for [[page blocks] blocks] - (let [page (db/entity (:db/id page))] - [:div.my-2 (cond-> {:key (str "page-" (:db/id page))} - (:ref? config) - (assoc :class "bg-base-2 px-7 py-2 rounded")) - (ui/foldable - (page-cp config page) - (blocks-container blocks config))]))] - (blocks-container blocks config))])) + [:div.content + (cond-> option + (:document/mode? config) + (assoc :class "doc-mode")) + (if (:group-by-page? config) + [:div.flex.flex-col + (for [[page blocks] blocks] + (let [page (db/entity (:db/id page))] + [:div.my-2 (cond-> {:key (str "page-" (:db/id page))} + (:ref? config) + (assoc :class "bg-base-2 px-7 py-2 rounded")) + (ui/foldable + (page-cp config page) + (blocks-container blocks config))]))] + (blocks-container blocks config))]) (comment ;; timestamps diff --git a/src/main/frontend/components/journal.cljs b/src/main/frontend/components/journal.cljs index 543402211..d69ca91d8 100644 --- a/src/main/frontend/components/journal.cljs +++ b/src/main/frontend/components/journal.cljs @@ -39,24 +39,25 @@ :error false))) state)} - [blocks encoded-page-name page] - (let [start-level (or (:block/level (first blocks)) 1)] + [blocks encoded-page-name page document-mode?] + (let [start-level (or (:block/level (first blocks)) 1) + config {:id encoded-page-name + :start-level 2 + :editor-box editor/box + :document/mode? document-mode?}] (content/content encoded-page-name - {:hiccup (block/->hiccup blocks - {:id encoded-page-name - :start-level 2 - :editor-box editor/box} - {})}))) + {:hiccup (block/->hiccup blocks config {})}))) (rum/defc blocks-cp < rum/reactive db-mixins/query {} [repo page encoded-page-name format] (let [raw-blocks (db/get-page-blocks repo page) + document-mode? (state/sub :document/mode?) blocks (->> (db/with-dummy-block raw-blocks format nil true) (db/with-block-refs-count repo))] - (blocks-inner blocks encoded-page-name page))) + (blocks-inner blocks encoded-page-name page document-mode?))) (rum/defc journal-cp < rum/reactive [[title format]] diff --git a/src/main/frontend/components/page.cljs b/src/main/frontend/components/page.cljs index 1c8719d2e..bac199d22 100644 --- a/src/main/frontend/components/page.cljs +++ b/src/main/frontend/components/page.cljs @@ -4,6 +4,7 @@ [frontend.handler.file :as file] [frontend.handler.page :as page-handler] [frontend.handler.ui :as ui-handler] + [frontend.handler.common :as common-handler] [frontend.handler.route :as route-handler] [frontend.handler.notification :as notification] [frontend.handler.editor :as editor-handler] @@ -69,6 +70,7 @@ :sidebar? sidebar? :block? block? :editor-box editor/box} + hiccup-config (common-handler/config-with-document-mode hiccup-config) hiccup (block/->hiccup page-blocks hiccup-config {})] (rum/with-key (content/content encoded-page-name diff --git a/src/main/frontend/db.cljs b/src/main/frontend/db.cljs index 61ed4a218..4d32bfd42 100644 --- a/src/main/frontend/db.cljs +++ b/src/main/frontend/db.cljs @@ -303,7 +303,7 @@ :else (case key - :block/change + (list :block/change :block/insert) (when (seq data) (let [blocks data pre-block? (:block/pre-block? (first blocks)) @@ -317,7 +317,8 @@ (fn [block] (when-let [page-id (:db/id (:block/page block))] [[:blocks (:block/uuid block)] - [:page/blocks page-id] + (when (not= key :block/insert) ; already reseted + [:page/blocks page-id]) [:page/ref-pages page-id]])) blocks) diff --git a/src/main/frontend/handler/common.cljs b/src/main/frontend/handler/common.cljs index cdc36ed4a..797947d56 100644 --- a/src/main/frontend/handler/common.cljs +++ b/src/main/frontend/handler/common.cljs @@ -48,6 +48,11 @@ [content] (util/copy-to-clipboard! (text/remove-id-property content))) +(defn config-with-document-mode + [config] + (assoc config + :document/mode? (state/sub [:document/mode?]))) + (comment (let [repo (state/get-current-repo)] (p/let [remote-oid (get-remote-ref repo) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index d30ee7470..5e090e36e 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -453,8 +453,8 @@ :error) ;; create the file (let [content (str (util/default-content-with-title format - (or (:page/original-name page) - (:page/name page))) + (or (:page/original-name page) + (:page/name page))) (text/remove-level-spaces value (keyword format)))] (p/let [_ (fs/create-if-not-exists dir file-path content)] (db/reset-file! repo path content) @@ -618,10 +618,11 @@ pages blocks after-blocks) - {:key :block/change + {:key :block/insert :data (map (fn [block] (assoc block :block/page page)) blocks)} [[file-path new-content]]) (state/set-editor-op! nil))] + ;; Replace with batch transactions (state/add-tx! transact-fn) @@ -654,9 +655,7 @@ (reset! blocks-atom (->> (concat before-part blocks after-part) (remove nil?)))))) (when ok-handler - (let [first-block (first blocks) - last-block (last blocks)] - (ok-handler [first-block last-block snd-block-text]))))))] + (ok-handler (last blocks))))))] (cond (and (not file) page) ;; TODO: replace with handler.page/create! @@ -776,7 +775,7 @@ new-value {:create-new-block? true :ok-handler - (fn [[_first-block last-block _new-block-content]] + (fn [last-block] (let [last-id (:block/uuid last-block)] (edit-block! last-block 0 format id) (clear-when-saved!))) @@ -797,7 +796,7 @@ (:block/content last-block) {:create-new-block? true :ok-handler - (fn [[_first-block last-block _new-block-content]] + (fn [last-block] (js/setTimeout #(edit-last-block-for-new-page! last-block :max) 50)) :with-level? true :new-level new-level @@ -1590,33 +1589,33 @@ [state direction] (state/set-editor-op! :indent-outdent) (let [{:keys [block block-parent-id value config]} (get-state state) - start-level (:start-level config) - format (:block/format block) - block-pattern (config/get-block-pattern format) - level (:block/level block) - previous-level (or (get-previous-block-level block-parent-id) 1) - [add? remove?] (case direction - :left [false true] - :right [true false] - [(<= level previous-level) - (and (> level previous-level) - (> level 2))]) - final-level (cond - add? (inc level) - remove? (if (> level 2) - (dec level) - level) - :else level) - new-value (block/with-levels value format (assoc block :block/level final-level))] - (when (and - (not (and (= direction :left) - (and - (get config :id) - (util/uuid-string? (get config :id))) - (<= final-level start-level))) - (<= (- final-level previous-level) 1)) - (save-block-if-changed! block new-value - {:indent-left? (= direction :left)}))) + start-level (:start-level config) + format (:block/format block) + block-pattern (config/get-block-pattern format) + level (:block/level block) + previous-level (or (get-previous-block-level block-parent-id) 1) + [add? remove?] (case direction + :left [false true] + :right [true false] + [(<= level previous-level) + (and (> level previous-level) + (> level 2))]) + final-level (cond + add? (inc level) + remove? (if (> level 2) + (dec level) + level) + :else level) + new-value (block/with-levels value format (assoc block :block/level final-level))] + (when (and + (not (and (= direction :left) + (and + (get config :id) + (util/uuid-string? (get config :id))) + (<= final-level start-level))) + (<= (- final-level previous-level) 1)) + (save-block-if-changed! block new-value + {:indent-left? (= direction :left)}))) (state/set-editor-op! nil)) (defn adjust-blocks-level! @@ -1664,7 +1663,7 @@ hc2 (if (or move-upwards-to-parent? move-down-to-higher-level?) [sibling-block] (db/get-block-and-children-no-cache repo (:block/uuid sibling-block)))] - ;; Same page and next to the other + ;; Same page and next to the other (when (and (= (:db/id (:block/page block)) (:db/id (:block/page sibling-block)))