Browse Source

perf: page filter and search

Tienson Qin 6 months ago
parent
commit
62514b74d8

+ 3 - 1
deps/db/src/logseq/db/common/view.cljs

@@ -311,6 +311,7 @@
                                           (= (:db/id block) id)
                                           (= id (:db/id (:block/page block)))
                                           (ldb/hidden? (:block/page block))
+                                          (ldb/hidden? block)
                                           (contains? (set (map :db/id (:block/tags block))) (:db/id entity))
                                           (some? (get block (:db/ident entity))))
                                          (or
@@ -331,7 +332,8 @@
                                         distinct))
                                      full-ref-blocks)
                              (remove nil?)
-                             (frequencies))]
+                             (frequencies)
+                             (sort-by second #(> %1 %2)))]
     {:ref-pages-count ref-pages-count
      :ref-blocks ref-blocks}))
 

+ 6 - 0
src/main/frontend/components/block.css

@@ -1082,3 +1082,9 @@ html.is-mac {
   aspect-ratio: 16 / 9;
   height: auto;
 }
+
+.ls-filters {
+    div[data-testid='virtuoso-item-list'] button {
+        @apply mb-2;
+    }
+}

+ 72 - 44
src/main/frontend/components/reference_filters.cljs

@@ -5,12 +5,14 @@
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
             [frontend.db :as db]
+            [frontend.db-mixins :as db-mixins]
             [frontend.handler.page :as page-handler]
             [frontend.search :as search]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [logseq.db.common.view :as db-view]
+            [logseq.shui.hooks :as hooks]
             [promesa.core :as p]
             [rum.core :as rum]))
 
@@ -18,50 +20,71 @@
   [references]
   (sort-by second #(> %1 %2) references))
 
+(rum/defc ref-button
+  [page filters ref-name ref-count]
+  (let [lc-reference (string/lower-case ref-name)]
+    (ui/button
+     [:span
+      ref-name
+      (when ref-count [:sup " " ref-count])]
+     :on-click (fn [e]
+                 (let [db-based? (config/db-based-graph? (state/get-current-repo))
+                       includes (set (map :block/name (:included filters)))
+                       excludes (set (map :block/name (:excluded filters)))
+                       included? (includes lc-reference)
+                       not-in-filters? (and (not included?) (not (excludes lc-reference)))
+                       shift? (.-shiftKey e)]
+                   (if db-based?
+                     (page-handler/db-based-save-filter! page (:db/id (db/get-page lc-reference))
+                                                         {:add? not-in-filters?
+                                                          :include? (if not-in-filters? (not shift?) included?)})
+                     (let [filters-m (->> (concat (map #(vector % true) includes) (map #(vector % false) excludes))
+                                          (into {}))
+                           filters' (if not-in-filters?
+                                      (assoc filters-m lc-reference (not shift?))
+                                      (dissoc filters-m lc-reference))]
+                       (page-handler/file-based-save-filter! page filters')))))
+     :small? true
+     :variant :outline)))
+
 (defn filtered-refs
-  [page filters filtered-references*]
-  [:div.flex.gap-2.flex-wrap.items-center
-   (let [filtered-references (if (de/entity? (first filtered-references*))
-                               (map (fn [e] [(:block/title e)]) filtered-references*)
-                               filtered-references*)] <
-        (for [[ref-name ref-count] filtered-references]
-          (when ref-name
-            (let [lc-reference (string/lower-case ref-name)]
-              (ui/button
-               [:span
-                ref-name
-                (when ref-count [:sup " " ref-count])]
-               :on-click (fn [e]
-                           (let [db-based? (config/db-based-graph? (state/get-current-repo))
-                                 includes (set (map :block/name (:included filters)))
-                                 excludes (set (map :block/name (:excluded filters)))
-                                 included? (includes lc-reference)
-                                 not-in-filters? (and (not included?) (not (excludes lc-reference)))
-                                 shift? (.-shiftKey e)]
-                             (if db-based?
-                               (page-handler/db-based-save-filter! page (:db/id (db/get-page lc-reference))
-                                                                   {:add? not-in-filters?
-                                                                    :include? (if not-in-filters? (not shift?) included?)})
-                               (let [filters-m (->> (concat (map #(vector % true) includes) (map #(vector % false) excludes))
-                                                    (into {}))
-                                     filters' (if not-in-filters?
-                                                (assoc filters-m lc-reference (not shift?))
-                                                (dissoc filters-m lc-reference))]
-                                 (page-handler/file-based-save-filter! page filters')))))
-               :small? true
-               :variant :outline
-               :key ref-name)))))])
+  [page filters filtered-references* virtual?]
+  (let [filtered-references (if (de/entity? (first filtered-references*))
+                              (map (fn [e] [(:block/title e)]) filtered-references*)
+                              filtered-references*)]
+    (if (and (> (count filtered-references) 100)
+             (not (false? virtual?)))
+      (ui/virtualized-list
+       {:style {:height 500
+                :width 500
+                :max-width 500}
+        :total-count (count filtered-references)
+        :compute-item-key (fn [idx]
+                            (str "ref-button-" idx))
+        :item-content (fn [idx]
+                        (let [[ref-name ref-count] (util/nth-safe filtered-references idx)]
+                          (ref-button page filters ref-name ref-count)))})
+      [:div.flex.gap-2.flex-wrap.items-center
+       {:style {:width 500
+                :max-width 500}}
+       (for [[ref-name ref-count] filtered-references]
+         (rum/with-key (ref-button page filters ref-name ref-count)
+           (str "ref-" ref-name)))])))
 
-(rum/defcs filter-dialog < (rum/local "" ::filterSearch) rum/reactive
-  [state page references]
-  (let [page-entity (db/sub-block (:db/id page))
-        filter-search (get state ::filterSearch)
+(rum/defc filter-dialog-aux
+  [page-entity references]
+  (let [[filter-search set-filter-search!] (hooks/use-state "")
+        [filtered-references set-filtered-references!] (hooks/use-state references)
         filters (db-view/get-filters (db/get-db) page-entity)
-        filtered-references  (frequencies-sort
-                              (if (= @filter-search "")
-                                references
-                                (search/fuzzy-search references @filter-search :limit 500 :extract-fn first)))
         {:keys [included excluded]} filters]
+    (hooks/use-effect!
+     (fn []
+       (let [references (if (= filter-search "")
+                          references
+                          (->> (search/fuzzy-search references filter-search :limit 100 :extract-fn first)
+                               frequencies-sort))]
+         (set-filtered-references! references)))
+     [(hooks/use-debounced-value filter-search 200)])
     [:div.ls-filters.filters
      [:div.sm:flex.sm:items-start
       [:div.mx-auto.flex-shrink-0.flex.items-center.justify-center.h-12.w-12.rounded-full.bg-gray-200.text-gray-500.sm:mx-0.sm:h-10.sm:w-10
@@ -75,12 +98,12 @@
         (when (seq included)
           [:div.flex.flex-row.flex-wrap.center-items
            [:div.mr-1.font-medium.py-1 (t :linked-references/filter-includes)]
-           (filtered-refs page-entity filters included)])
+           (filtered-refs page-entity filters included false)])
         (when (seq excluded)
           [:div.flex.flex-row.flex-wrap
            [:div.mr-1.font-medium.py-1 (t :linked-references/filter-excludes)]
 
-           (filtered-refs page-entity filters excluded)])])
+           (filtered-refs page-entity filters excluded false)])])
      [:div.cp__filters-input-panel.flex.focus-within:bg-gray-03
       (ui/icon "search")
       [:input.cp__filters-input.w-full.bg-transparent
@@ -89,7 +112,7 @@
         :ref (fn [^js el] (when el
                             (-> (p/delay 32) (p/then #(.focus el)))))
         :on-change (fn [e]
-                     (reset! filter-search (util/evalue e)))}]]
+                     (set-filter-search! (util/evalue e)))}]]
      (let [all-filters (set
                         (concat (map :block/name included)
                                 (map :block/name excluded)))
@@ -97,4 +120,9 @@
                         filtered-references)]
        (when (seq refs)
          [:div.mt-4
-          (filtered-refs page-entity filters refs)]))]))
+          (filtered-refs page-entity filters refs true)]))]))
+
+(rum/defc filter-dialog < rum/reactive db-mixins/query
+  [page references]
+  (let [page-entity (db/sub-block (:db/id page))]
+    (filter-dialog-aux page-entity references)))

+ 3 - 1
src/main/frontend/components/views.cljs

@@ -1339,6 +1339,8 @@
         {:ref #(reset! *scroller-ref %)
          :total-count (count blocks)
          :custom-scroll-parent (gdom/getElement "main-content-container")
+         :compute-item-key (fn [idx]
+                             (str (:db/id view-entity) "-card-" idx))
          :item-content (fn [idx]
                          (lazy-item (:data table) idx {}
                                     (fn [block]
@@ -1698,7 +1700,7 @@
                 :custom-scroll-parent (gdom/getElement "main-content-container")
                 :increase-viewport-by {:top 300 :bottom 300}
                 :compute-item-key (fn [idx]
-                                    (str "table-group" idx))
+                                    (str "table-group-" idx))
                 :skipAnimationFrameInResizeObserver true
                 :total-count (count (:rows table))
                 :item-content (fn [idx]

+ 7 - 1
src/main/frontend/worker/db_worker.cljs

@@ -532,7 +532,13 @@
         (boolean
          (some
           ;; check if there's any entity reference this `block` except the view-entity
-          (fn [ref] (not= id (:db/id (:logseq.property/view-for ref))))
+          (fn [ref]
+            (not
+             (or (= id (:db/id (:logseq.property/view-for ref)))
+                 (ldb/hidden? (:block/page ref))
+                 (ldb/hidden? ref)
+                 (contains? (set (map :db/id (:block/tags ref))) id)
+                 (some? (get ref (:db/ident block))))))
           (:block/_refs block)))))))
 
 (def-thread-api :thread-api/get-block-parents