Browse Source

perf: don't re-render blocks when selection changes

Tienson Qin 1 year ago
parent
commit
45150c0f05

+ 6 - 10
src/main/frontend/components/block.cljs

@@ -2886,9 +2886,8 @@
         attrs (on-drag-and-mouse-attrs block original-block uuid top? block-id *move-to)
         own-number-list? (:own-order-number-list? config)
         order-list? (boolean own-number-list?)
-        selected? (when-not (:slide? config)
-                    (state/sub-block-selected? uuid))
-        children (ldb/get-children block)]
+        children (ldb/get-children block)
+        selected? (contains? (set (state/get-selection-block-ids)) (:block/uuid block))]
     (when-not (= (:editor/deleting-block @state/state) (:block/uuid block))
       [:div.ls-block
        (cond->
@@ -2952,8 +2951,7 @@
                             :block-id block-id
                             :collapsed? collapsed?
                             :*control-show? *control-show?
-                            :edit? edit?
-                            :selected? selected?})))
+                            :edit? edit?})))
 
         (when (and @*show-left-menu? (not in-whiteboard?))
           (block-left-menu config block))
@@ -2969,8 +2967,7 @@
                                       {:edit-input-id edit-input-id
                                        :block-id block-id
                                        :edit? edit?
-                                       :hide-block-refs-count? hide-block-refs-count?
-                                       :selected? selected?}))])
+                                       :hide-block-refs-count? hide-block-refs-count?}))])
 
         (when (and @*show-right-menu? (not in-whiteboard?))
           (block-right-menu config block edit?))]
@@ -2980,8 +2977,7 @@
           (db-properties-cp config
                             block
                             edit-input-id
-                            {:selected? selected?
-                             :in-block-container? true})])
+                            {:in-block-container? true})])
 
        (when-not (or (:hide-children? config) in-whiteboard?)
          (let [config' (-> (update config :level inc)
@@ -3407,7 +3403,7 @@
 
 (rum/defc block-item <
   {:should-update (fn [old-state new-state]
-                    (let [config-compare-keys [:show-cloze? :hide-children? :own-order-list-type :own-order-list-index :original-block :selected? :edit? :hide-bullet?]
+                    (let [config-compare-keys [:show-cloze? :hide-children? :own-order-list-type :own-order-list-index :original-block :edit? :hide-bullet?]
                           b1                  (second (:rum/args old-state))
                           b2                  (second (:rum/args new-state))
                           result              (or

+ 1 - 3
src/main/frontend/handler/editor.cljs

@@ -2808,12 +2808,10 @@
 
 (defn indent-outdent
   [indent?]
-  (let [_editor (state/get-input)
-        {:keys [block]} (get-state)]
+  (let [{:keys [block]} (get-state)]
     (when block
       (block-handler/indent-outdent-blocks! [block] indent? save-current-block!))))
 
-
 (defn keydown-tab-handler
   [direction]
   (fn [e]

+ 43 - 22
src/main/frontend/state.cljs

@@ -20,7 +20,8 @@
             [promesa.core :as p]
             [rum.core :as rum]
             [frontend.rum :as r]
-            [logseq.db.sqlite.util :as sqlite-util]))
+            [logseq.db.sqlite.util :as sqlite-util]
+            [clojure.set :as set]))
 
 (defonce *profile-state
   (atom {}))
@@ -1156,6 +1157,39 @@ Similar to re-frame subscriptions"
   [start-block]
   (set-state! :selection/start-block start-block))
 
+(defn get-selection-blocks
+  []
+  (util/sort-by-height @(:selection/blocks @state)))
+
+(defn get-selection-block-ids
+  []
+  (get-selected-block-ids (get-selection-blocks)))
+
+(defn- dom-clear-selection!
+  []
+  (doseq [node (dom/by-class "ls-block selected")]
+    (dom/remove-class! node "selected")))
+
+(defn mark-dom-blocks-as-selected
+  ([]
+   (mark-dom-blocks-as-selected (get-selection-block-ids)))
+  ([ids]
+   (doseq [id ids]
+     (doseq [node (array-seq (gdom/getElementsByClass (str "id" id)))]
+       (dom/add-class! node "selected")))))
+
+(defn- set-selection-blocks-aux!
+  [blocks]
+  (let [selected-ids (set (get-selected-block-ids @(:selection/blocks @state)))
+        _ (set-state! :selection/blocks blocks)
+        new-ids (set (get-selection-block-ids))
+        added (set/difference new-ids selected-ids)
+        removed (set/difference selected-ids new-ids)]
+    (mark-dom-blocks-as-selected added)
+    (doseq [id removed]
+      (doseq [node (array-seq (gdom/getElementsByClass (str "id" id)))]
+        (dom/remove-class! node "selected")))))
+
 (defn set-selection-blocks!
   ([blocks]
    (set-selection-blocks! blocks :down))
@@ -1163,7 +1197,7 @@ Similar to re-frame subscriptions"
    (when (seq blocks)
      (let [blocks (vec (util/sort-by-height (remove nil? blocks)))]
        (set-state! :selection/mode true)
-       (set-state! :selection/blocks blocks)
+       (set-selection-blocks-aux! blocks)
        (set-state! :selection/direction direction)))))
 
 (defn into-selection-mode!
@@ -1172,22 +1206,13 @@ Similar to re-frame subscriptions"
 
 (defn clear-selection!
   []
+  (dom-clear-selection!)
   (set-state! :selection/mode false)
   (set-state! :selection/blocks nil)
   (set-state! :selection/direction :down)
   (set-state! :selection/start-block nil)
   (set-state! :selection/selected-all? false))
 
-(defn get-selection-blocks
-  []
-  (let [blocks (util/sort-by-height (bean/->clj (dom/by-class "ls-block selected")))]
-    (set-state! :selection/blocks blocks)
-    blocks))
-
-(defn get-selection-block-ids
-  []
-  (get-selected-block-ids (get-selection-blocks)))
-
 (defn get-selection-start-block-or-first
   []
   (or (get-selection-start-block)
@@ -1209,19 +1234,15 @@ Similar to re-frame subscriptions"
         blocks (-> (if (sequential? block-or-blocks)
                      (apply conj selection-blocks block-or-blocks)
                      (conj selection-blocks block-or-blocks))
-                   distinct
-                   util/sort-by-height
-                   vec)]
-    (set-state! :selection/mode true)
-    (set-state! :selection/blocks blocks)
-    (set-state! :selection/direction direction)))
+                   distinct)]
+    (set-selection-blocks! blocks direction)))
 
 (defn drop-selection-block!
   [block]
   (set-state! :selection/mode true)
-  (set-state! :selection/blocks (-> (remove #(= block %) (get-selection-blocks))
-                                    util/sort-by-height
-                                    vec)))
+  (set-selection-blocks-aux! (-> (remove #(= block %) (get-selection-blocks))
+                                 util/sort-by-height
+                                 vec)))
 
 (defn drop-last-selection-block!
   []
@@ -1237,7 +1258,7 @@ Similar to re-frame subscriptions"
                     util/sort-by-height
                     vec)]
     (set-state! :selection/mode true)
-    (set-state! :selection/blocks blocks')
+    (set-selection-blocks-aux! blocks')
     last-block))
 
 (defn get-selection-direction