Browse Source

fix: don't re-render the unrelated blocks when inserting a new block

Tienson Qin 5 years ago
parent
commit
3c18e0ef84

+ 41 - 100
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

+ 9 - 8
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]]

+ 2 - 0
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

+ 3 - 2
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)
 

+ 5 - 0
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)

+ 35 - 36
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)))