浏览代码

Merge remote-tracking branch 'upstream/master' into whiteboards

Peng Xiao 3 年之前
父节点
当前提交
3a732aa4e2

+ 40 - 19
src/main/frontend/components/block.cljs

@@ -2163,9 +2163,10 @@
       [:div.more (ui/icon "dots-circle-horizontal" {:style {:fontSize 16}})])]])
 
 (rum/defcs block-content-or-editor < rum/reactive
-  (rum/local true :hide-block-refs?)
+  (rum/local true ::hide-block-refs?)
   [state config {:block/keys [uuid format] :as block} edit-input-id block-id heading-level edit? hide-block-refs-count?]
-  (let [*hide-block-refs? (get state :hide-block-refs?)
+  (let [*hide-block-refs? (get state ::hide-block-refs?)
+        hide-block-refs? @*hide-block-refs?
         editor-box (get config :editor-box)
         editor-id (str "editor-" edit-input-id)
         slide? (:slide? config)
@@ -2222,7 +2223,7 @@
 
              (block-refs-count block *hide-block-refs?)])]
 
-         (when (and (not @*hide-block-refs?) (> refs-count 0))
+         (when (and (not hide-block-refs?) (> refs-count 0))
            (let [refs-cp (state/get-component :block/linked-references)]
              (refs-cp uuid)))]))))
 
@@ -2468,9 +2469,7 @@
         *navigating-block (get state ::navigating-block)
         navigating-block (rum/react *navigating-block)
         navigated? (and (not= (:block/uuid block) navigating-block) navigating-block)
-        block (if (or navigated?
-                      custom-query?
-                      (and ref? (:block/uuid config)))
+        block (if navigated?
                 (let [block (db/pull [:block/uuid navigating-block])
                       blocks (db/get-paginated-blocks repo (:db/id block)
                                                       {:scoped-block-id (:db/id block)})
@@ -2613,7 +2612,7 @@
   (let [repo (state/get-current-repo)
         ref? (:ref? config)
         custom-query? (boolean (:custom-query? config))]
-    (if (and ref? (not custom-query?) (not (:ref-query-child? config)))
+    (if (and (or ref? custom-query?) (not (:ref-query-child? config)))
       (ui/lazy-visible
        (fn [] (block-container-inner state repo config block)))
       (block-container-inner state repo config block))))
@@ -2997,7 +2996,8 @@
    (ui/block-error "Query Error:" {:content (:query q)})
    (ui/lazy-visible
     (fn [] (custom-query* config q))
-    {:debug-id q})))
+    {:debug-id q
+     :trigger-once? false})))
 
 (defn admonition
   [config type result]
@@ -3344,7 +3344,7 @@
              (assoc state
                     ::initial-block    first-block
                     ::navigating-block (atom (:block/uuid first-block)))))}
-  [state blocks config]
+  [state block config]
   (let [repo (state/get-current-repo)
         *navigating-block (::navigating-block state)
         navigating-block (rum/react *navigating-block)
@@ -3357,10 +3357,10 @@
                  (let [block navigating-block-entity]
                    (db/get-paginated-blocks repo (:db/id block)
                                             {:scoped-block-id (:db/id block)}))
-                 blocks)]
+                 [block])]
     [:div
      (when (:breadcrumb-show? config)
-       (breadcrumb config (state/get-current-repo) navigating-block
+       (breadcrumb config (state/get-current-repo) (or navigating-block (:block/uuid block))
                    {:show-page? false
                     :navigating-block *navigating-block}))
      (blocks-container blocks (assoc config
@@ -3375,8 +3375,7 @@
    (cond-> option
      (:document/mode? config) (assoc :class "doc-mode"))
    (cond
-     (and (or (:ref? config) (:custom-query? config))
-          (:group-by-page? config))
+     (and (:custom-query? config) (:group-by-page? config))
      [:div.flex.flex-col
       (let [blocks (sort-by (comp :block/journal-day first) > blocks)]
         (for [[page blocks] blocks]
@@ -3384,8 +3383,7 @@
            (fn []
              (let [alias? (:block/alias? page)
                    page (db/entity (:db/id page))
-                   blocks (tree/non-consecutive-blocks->vec-tree blocks)
-                   parent-blocks (group-by :block/parent blocks)]
+                   blocks' (tree/non-consecutive-blocks->vec-tree blocks)]
                [:div.my-2 (cond-> {:key (str "page-" (:db/id page))}
                             (:ref? config)
                             (assoc :class "color-level px-2 sm:px-7 py-2 rounded"))
@@ -3393,11 +3391,34 @@
                  [:div
                   (page-cp config page)
                   (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
-                 (for [[parent blocks] parent-blocks]
+                 (for [block blocks']
                    (rum/with-key
-                     (breadcrumb-with-container blocks config)
-                     (:db/id parent)))
-                 {:debug-id page})])))))]
+                     (breadcrumb-with-container block config)
+                     (:db/id block)))
+                 {:debug-id page
+                  :trigger-once? false})])))))]
+
+     (and (:ref? config) (:group-by-page? config))
+     [:div.flex.flex-col
+      (let [blocks (sort-by (comp :block/journal-day first) > blocks)]
+        (for [[page parent-blocks] blocks]
+         (ui/lazy-visible
+          (fn []
+            (let [alias? (:block/alias? page)
+                  page (db/entity (:db/id page))]
+              [:div.my-2 (cond-> {:key (str "page-" (:db/id page))}
+                           (:ref? config)
+                           (assoc :class "color-level px-2 sm:px-7 py-2 rounded"))
+               (ui/foldable
+                [:div
+                 (page-cp config page)
+                 (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
+                (for [block parent-blocks]
+                  (let [block' (update block :block/children tree/non-consecutive-blocks->vec-tree)]
+                    (rum/with-key
+                      (breadcrumb-with-container block' config)
+                      (:db/id block'))))
+                {:debug-id page})])))))]
 
      (and (:group-by-page? config)
           (vector? (first blocks)))

+ 2 - 1
src/main/frontend/components/journal.cljs

@@ -59,7 +59,8 @@
         (blocks-cp repo page)
         (ui/lazy-visible
          (fn [] (blocks-cp repo page))
-         {:debug-id (str "journal-blocks " page)}))
+         {:trigger-once? false
+          :debug-id (str "journal-blocks " page)}))
 
       {})
 

+ 1 - 1
src/main/frontend/components/page.cljs

@@ -433,7 +433,7 @@
          (tagged-pages repo page-name))
 
        ;; referenced blocks
-       (when-not whiteboard?
+       (when-not (or block? whiteboard?)
          [:div {:key "page-references"}
           (rum/with-key
             (reference/references route-page-name)

+ 4 - 2
src/main/frontend/components/query_table.cljs

@@ -10,7 +10,8 @@
             [frontend.util.property :as property]
             [frontend.format.block :as block]
             [medley.core :as medley]
-            [rum.core :as rum]))
+            [rum.core :as rum]
+            [frontend.modules.outliner.tree :as tree]))
 
 ;; TODO: extract to table utils
 (defn- sort-result-by
@@ -82,7 +83,8 @@
   (rum/local false ::select?)
   [state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
   (when current-block
-    (let [p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
+    (let [result (tree/filter-top-level-blocks result)
+          p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
           p-desc? (get-in current-block [:block/properties :query-sort-desc])
           select? (get state ::select?)
           *sort-by-item (get state ::sort-by-item)

+ 124 - 64
src/main/frontend/components/reference.cljs

@@ -13,19 +13,49 @@
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
-            [rum.core :as rum]))
+            [rum.core :as rum]
+            [frontend.modules.outliner.tree :as tree]))
 
 (defn- frequencies-sort
   [references]
   (sort-by second #(> %1 %2) references))
 
+(defn filtered-refs
+  [page-name filters filters-atom filtered-references]
+  [:div.flex.gap-1.flex-wrap
+   (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]
+                       (swap! filters-atom #(if (nil? (get filters lc-reference))
+                                              (assoc % lc-reference (not (.-shiftKey e)))
+                                              (dissoc % lc-reference)))
+                       (page-handler/save-filter! page-name @filters-atom))
+           :small? true
+           :intent "link"
+           :key ref-name))))])
+
 (rum/defcs filter-dialog-inner < rum/reactive (rum/local "" ::filterSearch)
-  [state filters-atom _close-fn references page-name]
+  [state filters-atom *references page-name]
   (let [filter-search (get state ::filterSearch)
+        references (rum/react *references)
         filtered-references  (frequencies-sort
                               (if (= @filter-search "")
                                 references
-                                (search/fuzzy-search references @filter-search :limit 500 :extract-fn first)))]
+                                (search/fuzzy-search references @filter-search :limit 500 :extract-fn first)))
+        filters (rum/react filters-atom)
+        includes (keep (fn [[page include?]]
+                         (let [page' (model-db/get-page-original-name page)]
+                           (when include? [page'])))
+                       filters)
+        excludes (keep (fn [[page include?]]
+                         (let [page' (model-db/get-page-original-name page)]
+                           (when-not include? [page'])))
+                       filters)]
     [: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
@@ -34,6 +64,16 @@
        [:h3#modal-headline.text-lg.leading-6.font-medium "Filter"]
        [:span.text-xs
         "Click to include and shift-click to exclude. Click again to remove."]]]
+     (when (seq filters)
+       [:div.cp__filters.mb-4.ml-2
+        (when (seq includes)
+          [:div.flex.flex-row.flex-wrap.center-items
+           [:div.mr-1.font-medium.py-1 "Includes: "]
+           (filtered-refs page-name filters filters-atom includes)])
+        (when (seq excludes)
+          [:div.flex.flex-row.flex-wrap
+           [:div.mr-1.font-medium.py-1 "Excludes: " ]
+           (filtered-refs page-name filters filters-atom excludes)])])
      [:div.cp__filters-input-panel.flex
       (ui/icon "search")
       [:input.cp__filters-input.w-full
@@ -41,30 +81,17 @@
         :auto-focus true
         :on-change (fn [e]
                      (reset! filter-search (util/evalue e)))}]]
-     (when (seq filtered-references)
-       (let [filters (rum/react filters-atom)]
-         [:div.mt-5.sm:mt-4.sm:flex.sm.gap-1.flex-wrap
-          (for [[ref-name ref-count] filtered-references]
-            (when ref-name
-              (let [lc-reference (string/lower-case ref-name)
-                    filtered (get filters lc-reference)
-                    color (condp = filtered
-                            true "text-green-400"
-                            false "text-red-400"
-                            nil)]
-                [:button.border.rounded.px-1.mb-1.mr-1.select-none
-                 {:key ref-name :class color :style {:border-color "currentColor"}
-                  :on-click (fn [e]
-                              (swap! filters-atom #(if (nil? (get filters lc-reference))
-                                                     (assoc % lc-reference (not (.-shiftKey e)))
-                                                     (dissoc % lc-reference)))
-                              (page-handler/save-filter! page-name @filters-atom))}
-                 ref-name [:sub " " ref-count]])))]))]))
+     (let [all-filters (set (keys filters))
+           refs (remove (fn [[page _]] (all-filters (util/page-name-sanity-lc page)))
+                        filtered-references)]
+       (when (seq refs)
+         [:div.mt-4
+          (filtered-refs page-name filters filters-atom refs)]))]))
 
 (defn filter-dialog
-  [filters-atom references page-name]
-  (fn [close-fn]
-    (filter-dialog-inner filters-atom close-fn references page-name)))
+  [filters-atom *references page-name]
+  (fn []
+    (filter-dialog-inner filters-atom *references page-name)))
 
 (rum/defc block-linked-references < rum/reactive db-mixins/query
   [block-id]
@@ -80,16 +107,10 @@
      (content/content block-id
                       {:hiccup ref-hiccup})]))
 
-(rum/defc references-inner < rum/reactive db-mixins/query
-  [page-name block-id filters *filtered-ref-blocks ref-pages]
+(rum/defc references-inner
+  [page-name filters filtered-ref-blocks]
   [:div.references-blocks
-   (let [ref-blocks (if block-id
-                      (db/get-block-referenced-blocks block-id)
-                      (db/get-page-referenced-blocks page-name))
-         filtered-ref-blocks (if block-id
-                               ref-blocks
-                               (block-handler/get-filtered-ref-blocks ref-blocks filters ref-pages))
-         ref-hiccup (block/->hiccup filtered-ref-blocks
+   (let [ref-hiccup (block/->hiccup filtered-ref-blocks
                                     {:id page-name
                                      :ref? true
                                      :breadcrumb-show? true
@@ -97,24 +118,21 @@
                                      :editor-box editor/box
                                      :filters filters}
                                     {})]
-     (reset! *filtered-ref-blocks filtered-ref-blocks)
      (content/content page-name {:hiccup ref-hiccup}))])
 
 (rum/defc references-cp
-  [repo page-entity page-name block-id filters-atom filter-state n-ref]
+  [page-name filters filters-atom filter-state total filter-n filtered-ref-blocks *ref-pages]
   (let [threshold (state/get-linked-references-collapsed-threshold)
-        default-collapsed? (>= n-ref threshold)
-        filters (when (seq filter-state)
-                  (-> (group-by second filter-state)
-                      (update-vals #(map first %))))
-        *filtered-ref-blocks (atom nil)
-        *collapsed? (atom nil)
-        ref-pages (when-not block-id
-                    (block-handler/get-blocks-refed-pages repo page-entity))]
+        default-collapsed? (>= total threshold)
+        *collapsed? (atom nil)]
     (ui/foldable
      [:div.flex.flex-row.flex-1.justify-between.items-center
-      [:h2.font-bold.opacity-50 (str n-ref " Linked Reference"
-                                     (when (> n-ref 1) "s"))]
+      [:h2.font-bold.opacity-50 (str
+                                 (when (seq filters)
+                                   (str filter-n " of "))
+                                 total
+                                 " Linked Reference"
+                                 (when (> total 1) "s"))]
       [:a.filter.fade-link
        {:title "Filter"
         :on-mouse-over (fn [_e]
@@ -124,10 +142,8 @@
         :on-mouse-down (fn [e]
                          (util/stop-propagation e))
         :on-click (fn []
-                    (let [ref-pages (map :block/original-name ref-pages)
-                          references (frequencies ref-pages)]
-                      (state/set-modal! (filter-dialog filters-atom references page-name)
-                                        {:center? true})))}
+                    (state/set-modal! (filter-dialog filters-atom *ref-pages page-name)
+                                      {:center? true}))}
        (ui/icon "filter" {:class (cond
                                    (empty? filter-state)
                                    ""
@@ -140,36 +156,81 @@
                           :style {:fontSize 24}})]]
 
      (fn []
-       (references-inner page-name block-id filters *filtered-ref-blocks ref-pages))
+       (references-inner page-name filters filtered-ref-blocks))
 
      {:default-collapsed? default-collapsed?
       :title-trigger? true
       :init-collapsed (fn [collapsed-atom]
                         (reset! *collapsed? collapsed-atom))})))
 
+(defn- get-filtered-children
+  [block parent->blocks]
+  (let [children (get parent->blocks (:db/id block))]
+    (set
+     (loop [blocks children
+            result (vec children)]
+       (if (empty? blocks)
+         result
+         (let [fb (first blocks)
+               children (get parent->blocks (:db/id fb))]
+           (recur
+            (concat children (rest blocks))
+            (conj result fb))))))))
+
 (rum/defcs references* < rum/reactive db-mixins/query
+  (rum/local nil ::ref-pages)
   {:init (fn [state]
            (let [page-name (first (:rum/args state))
                  filters (when page-name
-                           (atom (page-handler/get-filters (string/lower-case page-name))))]
+                           (atom (page-handler/get-filters (util/page-name-sanity-lc page-name))))]
              (assoc state ::filters filters)))}
   [state page-name]
   (when page-name
-    (let [page-name (string/lower-case page-name)
-          page-entity (db/entity [:block/name page-name])
+    (let [page-name (util/page-name-sanity-lc page-name)
+          *ref-pages (::ref-pages state)
           repo (state/get-current-repo)
           filters-atom (get state ::filters)
           filter-state (rum/react filters-atom)
-          block-id (parse-uuid page-name)
-          id (if block-id
-               (:db/id (db/pull [:block/uuid block-id]))
-               (:db/id page-entity))
-          n-ref (model-db/get-linked-references-count id)]
-      (when (or (seq filter-state) (> n-ref 0))
+          ref-blocks (db/get-page-referenced-blocks page-name)
+          page-id (:db/id (db/entity repo [:block/name page-name]))
+          aliases (db/page-alias-set repo page-name)
+          aliases-exclude-self (set (remove #{page-id} aliases))
+          top-level-blocks (filter (fn [b] (some aliases (set (map :db/id (:block/refs b))))) ref-blocks)
+          top-level-blocks-ids (set (map :db/id top-level-blocks))
+          filters (when (seq filter-state)
+                    (-> (group-by second filter-state)
+                        (update-vals #(map first %))))
+          filtered-ref-blocks (block-handler/filter-blocks ref-blocks filters)
+          total (count top-level-blocks)
+          filtered-top-blocks (filter (fn [b] (top-level-blocks-ids (:db/id b))) filtered-ref-blocks)
+          filter-n (count filtered-top-blocks)
+          parent->blocks (group-by (fn [x] (:db/id (x :block/parent))) filtered-ref-blocks)
+          result (->> (group-by :block/page filtered-top-blocks)
+                      (map (fn [[page blocks]]
+                             (let [blocks (sort-by (fn [b] (not= (:db/id page) (:db/id (:block/parent b)))) blocks)
+                                   result (map (fn [block]
+                                                 (let [filtered-children (get-filtered-children block parent->blocks)
+                                                       refs (when-not (contains? top-level-blocks-ids (:db/id (:block/parent block)))
+                                                              (block-handler/get-blocks-refed-pages aliases (cons block filtered-children)))
+                                                       block' (assoc (tree/block-entity->map block) :block/children filtered-children)]
+                                                   [block' refs])) blocks)
+                                   blocks' (map first result)
+                                   page' (if (contains? aliases-exclude-self (:db/id page))
+                                           {:db/id (:db/id page)
+                                            :block/alias? true
+                                            :block/journal-day (:block/journal-day page)}
+                                           page)]
+                               [[page' blocks'] (mapcat second result)]))))
+          filtered-ref-blocks' (map first result)
+          ref-pages (->>
+                     (mapcat second result)
+                     (map :block/original-name)
+                     frequencies)]
+      (reset! *ref-pages ref-pages)
+      (when (or (seq filter-state) (> filter-n 0))
         [:div.references.flex-1.flex-row
          [:div.content.pt-6
-          (references-cp repo page-entity page-name block-id
-                         filters-atom filter-state n-ref)]]))))
+          (references-cp page-name filters filters-atom filter-state total filter-n filtered-ref-blocks' *ref-pages)]]))))
 
 (rum/defc references
   [page-name]
@@ -178,8 +239,7 @@
    (ui/lazy-visible
     (fn []
       (references* page-name))
-    {:trigger-once? true
-     :debug-id (str page-name " references")})))
+    {:debug-id (str page-name " references")})))
 
 (rum/defcs unlinked-references-aux
   < rum/reactive db-mixins/query

+ 8 - 0
src/main/frontend/components/reference.css

@@ -10,3 +10,11 @@
   padding-left: 0.5rem;
   align-items: center;
 }
+
+.references-blocks .breadcrumb {
+  margin-left: 1.5rem;
+}
+
+.ls-filters {
+    max-width: 704px;
+}

+ 3 - 29
src/main/frontend/db/model.cljs

@@ -1206,7 +1206,8 @@
          (->>
           (react/q repo
             [:frontend.db.react/refs page-id]
-            {:query-fn (fn []
+            {:use-cache? false
+             :query-fn (fn []
                          (let [entities (mapcat (fn [id]
                                                   (:block/_path-refs (db-utils/entity id))) pages)
                                blocks (map (fn [e] {:block/parent (:block/parent e)
@@ -1217,34 +1218,7 @@
             nil)
           react
           :entities
-          (remove (fn [block] (= page-id (:db/id (:block/page block)))))
-          db-utils/group-by-page
-          (map (fn [[k blocks]]
-                 (let [k (if (contains? aliases (:db/id k))
-                           {:db/id (:db/id k)
-                            :block/alias? true
-                            :block/journal-day (:block/journal-day k)}
-                           k)]
-                   [k blocks])))))))))
-
-(defn get-linked-references-count
-  [id]
-  (when-let [block (db-utils/entity id)]
-    (let [repo (state/get-current-repo)
-          page? (:block/name block)
-          result (if page?
-                   (let [pages (page-alias-set repo (:block/name block))]
-                     @(react/q repo [:frontend.db.react/refs-count id] {}
-                        '[:find [?block ...]
-                          :in $ [?ref-page ...] ?id
-                          :where
-                          [?block :block/refs ?ref-page]
-                          [?block :block/page ?p]
-                          [(not= ?p ?id)]]
-                        pages
-                        id))
-                   (:block/_refs block))]
-      (count result))))
+          (remove (fn [block] (= page-id (:db/id (:block/page block)))))))))))
 
 (defn get-date-scheduled-or-deadlines
   [journal-title]

+ 8 - 13
src/main/frontend/db/react.cljs

@@ -33,10 +33,6 @@
 ;; ::refs
 ;; get BLOCKS referencing PAGE or BLOCK
 (s/def ::refs (s/tuple #(= ::refs %) int?))
-;; ::refs-count
-;; get refs count
-(s/def ::refs-count int?)
-
 ;; custom react-query
 (s/def ::custom any?)
 
@@ -46,7 +42,6 @@
                                 :journals ::journals
                                 :page<-pages ::page<-pages
                                 :refs ::refs
-                                :refs-count ::refs-count
                                 :custom ::custom))
 
 (s/def ::affected-keys (s/coll-of ::react-query-keys))
@@ -240,7 +235,10 @@
   (let [blocks (->> (filter (fn [datom] (contains? #{:block/left :block/parent :block/page} (:a datom))) tx-data)
                     (map :v)
                     (distinct))
-        refs (->> (filter (fn [datom] (contains? #{:block/refs :block/path-refs} (:a datom))) tx-data)
+        refs (->> (filter (fn [datom]
+                            (when (contains? #{:block/refs :block/path-refs} (:a datom))
+                              (not= (:v datom)
+                                    (:db/id (:block/page (db-utils/entity (:e datom))))))) tx-data)
                   (map :v)
                   (distinct))
         other-blocks (->> (filter (fn [datom] (= "block" (namespace (:a datom)))) tx-data)
@@ -259,10 +257,9 @@
                                          (:db/id (:block/page block)))
                                 blocks [[::block (:db/id block)]]
                                 path-refs (:block/path-refs block)
-                                path-refs' (mapcat (fn [ref]
-                                                     [
-                                                      ;; [::refs-count (:db/id ref)]
-                                                      [::refs (:db/id ref)]]) path-refs)
+                                path-refs' (keep (fn [ref]
+                                                   (when-not (= (:db/id ref) page-id)
+                                                     [::refs (:db/id ref)])) path-refs)
                                 page-blocks (when page-id
                                               [[::page-blocks page-id]])]
                             (concat blocks page-blocks path-refs')))
@@ -270,9 +267,7 @@
 
                        (mapcat
                         (fn [ref]
-                          [
-                           ;; [::refs-count (:db/id entity)]
-                           [::refs ref]])
+                          [[::refs ref]])
                         refs)
 
                        (when-let [current-page-id (:db/id (get-current-page))]

+ 22 - 41
src/main/frontend/handler/block.cljs

@@ -13,9 +13,7 @@
    [frontend.state :as state]
    [frontend.util :as util]
    [goog.dom :as gdom]
-   [logseq.graph-parser.block :as gp-block]
-   [frontend.modules.instrumentation.posthog :as posthog]
-   [cljs-bean.core :as bean]))
+   [logseq.graph-parser.block :as gp-block]))
 
 ;;  Fns
 
@@ -250,48 +248,31 @@
   (reset! *swipe nil))
 
 (defn get-blocks-refed-pages
-  [repo page-entity]
-  (let [pages (db-model/page-alias-set repo (:block/name page-entity))
-        refs (->> pages
-                  (mapcat (fn [id] (:block/_path-refs (db/entity id))))
-                  (mapcat (fn [b] (conj (:block/path-refs b) (:block/page b))))
-                  (remove (fn [r] (= (:db/id page-entity) (:db/id r)))))]
+  [aliases ref-blocks]
+  (let [refs (->> (mapcat (fn [b] (conj (:block/path-refs b) (:block/page b))) ref-blocks)
+                  distinct
+                  (remove #(aliases (:db/id %))))]
     (keep (fn [ref]
             (when (:block/name ref)
               {:db/id (:db/id ref)
                :block/name (:block/name ref)
                :block/original-name (:block/original-name ref)})) refs)))
 
-(defn- filter-blocks
-  [ref-blocks filters ref-pages]
-  (let [ref-pages (distinct ref-pages)]
-    (if (empty? filters)
-      ref-blocks
-      (let [ref-pages (zipmap (map :block/name ref-pages) (map :db/id ref-pages))
-            exclude-ids (->> (keep (fn [page] (get ref-pages page)) (get filters false))
-                             (set))
-            include-ids (->> (keep (fn [page] (get ref-pages page)) (get filters true))
-                             (set))]
-        (cond->> ref-blocks
-          (seq exclude-ids)
-          (remove (fn [block]
-                    (let [ids (set (map :db/id (:block/path-refs block)))]
-                      (seq (set/intersection exclude-ids ids)))))
+(defn filter-blocks
+  [ref-blocks filters]
+  (if (empty? filters)
+    ref-blocks
+    (let [exclude-ids (->> (keep (fn [page] (:db/id (db/entity [:block/name (util/page-name-sanity-lc page)]))) (get filters false))
+                           (set))
+          include-ids (->> (keep (fn [page] (:db/id (db/entity [:block/name (util/page-name-sanity-lc page)]))) (get filters true))
+                           (set))]
+      (cond->> ref-blocks
+        (seq exclude-ids)
+        (remove (fn [block]
+                  (let [ids (set (map :db/id (:block/path-refs block)))]
+                    (seq (set/intersection exclude-ids ids)))))
 
-          (seq include-ids)
-          (remove (fn [block]
-                    (let [ids (set (map :db/id (:block/path-refs block)))]
-                      (empty? (set/intersection include-ids ids))))))))))
-
-(defn get-filtered-ref-blocks
-  [ref-blocks filters ref-pages]
-  (try
-    (let [ref-blocks' (doall (mapcat second ref-blocks))
-          filtered-blocks (filter-blocks ref-blocks' filters ref-pages)]
-      (group-by :block/page filtered-blocks))
-    (catch :default e
-      (js/console.error e)
-      (posthog/capture :bad-ref-blocks (bean/->js
-                                        {:ref-blocks ref-blocks
-                                         :filters filters
-                                         :ref-pages ref-pages})))))
+        (seq include-ids)
+        (filter (fn [block]
+                  (let [ids (set (map :db/id (:block/path-refs block)))]
+                    (set/subset? include-ids ids))))))))

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

@@ -757,7 +757,8 @@
                    (remove nil?))]
       (doseq [id ids]
         (let [block (db/pull [:block/uuid id])]
-          (set-marker block))))))
+          (when (not-empty (:block/content block))
+            (set-marker block)))))))
 
 (defn cycle-todo!
   []

+ 10 - 11
src/main/frontend/modules/outliner/pipeline.cljs

@@ -21,12 +21,9 @@
 ;; 1. For each changed block, new-refs = its page + :block/refs + parents :block/refs
 ;; 2. Its children' block/path-refs might need to be updated too.
 (defn compute-block-path-refs
-  [tx-meta blocks]
+  [{:keys [tx-meta]} blocks]
   (let [repo (state/get-current-repo)
-        blocks (remove :block/name blocks)
-        blocks (if (= (:outliner-op tx-meta) :insert-blocks)
-                 (butlast blocks)
-                 blocks)]
+        blocks (remove :block/name blocks)]
     (when (:outliner-op tx-meta)
       (when (react/path-refs-need-recalculated? tx-meta)
         (let [*computed-ids (atom #{})]
@@ -44,13 +41,15 @@
                             refs-changed? (not= old-refs new-refs)
                             children (db-model/get-block-children-ids repo (:block/uuid block))
                             children-refs (map (fn [id]
-                                                 {:db/id (:db/id (db/entity [:block/uuid id]))
-                                                  :block/path-refs (concat
-                                                                    (map :db/id (:block/path-refs (db/entity id)))
-                                                                    new-refs)}) children)]
+                                                 (let [entity (db/entity [:block/uuid id])]
+                                                   {:db/id (:db/id entity)
+                                                    :block/path-refs (concat
+                                                                      (map :db/id (:block/path-refs entity))
+                                                                      new-refs)})) children)]
                         (swap! *computed-ids set/union (set (cons (:block/uuid block) children)))
                         (util/concat-without-nil
-                         [(when (and refs-changed? (seq new-refs))
+                         [(when (and (seq new-refs)
+                                     refs-changed?)
                             {:db/id (:db/id block)
                              :block/path-refs new-refs})]
                          children-refs))))
@@ -66,7 +65,7 @@
             repo (state/get-current-repo)
             refs-tx (util/profile
                      "Compute path refs: "
-                     (set (compute-block-path-refs (:tx-meta tx-report) blocks)))
+                     (set (compute-block-path-refs tx-report blocks)))
             truncate-refs-tx (map (fn [m] [:db/retract (:db/id m) :block/path-refs]) refs-tx)
             tx (util/concat-without-nil truncate-refs-tx refs-tx)
             tx-report' (if (seq tx)

+ 20 - 11
src/main/frontend/modules/outliner/tree.cljs

@@ -84,20 +84,29 @@
       (assoc root' :block/children children)
       root')))
 
+(defn block-entity->map
+  [e]
+  {:db/id (:db/id e)
+   :block/uuid (:block/uuid e)
+   :block/parent {:db/id (:db/id (:block/parent e))}
+   :block/left {:db/id (:db/id (:block/left e))}
+   :block/page (:block/page e)
+   :block/refs (:block/refs e)})
+
+(defn filter-top-level-blocks
+  [blocks]
+  (let [id->blocks (zipmap (map :db/id blocks) blocks)]
+    (filter #(nil?
+              (id->blocks
+               (:db/id (:block/parent (id->blocks (:db/id %)))))) blocks)))
+
 (defn non-consecutive-blocks->vec-tree
   "`blocks` need to be in the same page."
   [blocks]
-  (let [blocks (map (fn [e] {:db/id (:db/id e)
-                             :block/uuid (:block/uuid e)
-                             :block/parent {:db/id (:db/id (:block/parent e))}
-                             :block/left {:db/id (:db/id (:block/left e))}
-                             :block/page {:db/id (:db/id (:block/page e))}}) blocks)
-        parent->children (group-by :block/parent blocks)
-        id->blocks (zipmap (map :db/id blocks) blocks)
-        top-level-blocks (filter #(nil?
-                                   (id->blocks
-                                    (:db/id (:block/parent (id->blocks (:db/id %)))))) blocks)
-        top-level-blocks' (model/try-sort-by-left top-level-blocks (:block/parent (first top-level-blocks)))]
+  (let [blocks (map block-entity->map blocks)
+        top-level-blocks (filter-top-level-blocks blocks)
+        top-level-blocks' (model/try-sort-by-left top-level-blocks (:block/parent (first top-level-blocks)))
+        parent->children (group-by :block/parent blocks)]
     (map #(tree parent->children %) top-level-blocks')))
 
 (defn- sort-blocks-aux

+ 10 - 8
src/main/frontend/modules/shortcut/data_helper.cljs

@@ -46,14 +46,16 @@
 
 (defn normalize-user-keyname
   [k]
-  (some-> k
-          (util/safe-lower-case)
-          (str/replace #";+" "semicolon")
-          (str/replace #"=+" "equals")
-          (str/replace #"~+" "dash")
-          (str/replace "[" "open-square-bracket")
-          (str/replace "]" "close-square-bracket")
-          (str/replace "'" "single-quote")))
+  (let [keynames {";" "semicolon"
+                   "=" "equals"
+                   "-" "dash"
+                   "[" "open-square-bracket"
+                   "]" "close-square-bracket"
+                   "'" "single-quote"}]
+    (some-> k
+            (util/safe-lower-case)
+            (str/replace #"[;=-\[\]']" (fn [s]
+                                         (get keynames s))))))
 
 ;; returns a vector to preserve order
 (defn binding-by-category [name]

+ 6 - 13
src/main/frontend/ui.cljs

@@ -147,7 +147,7 @@
 
 (defn button
   [text & {:keys [background href class intent on-click small? large?]
-           :or {small? false large? false}
+           :or   {small? false large? false}
            :as   option}]
   (let [klass (when-not intent ".bg-indigo-600.hover:bg-indigo-700.focus:border-indigo-700.active:bg-indigo-700.text-center")
         klass (if background (string/replace klass "indigo" background) klass)
@@ -947,24 +947,17 @@
   ([content-fn]
    (lazy-visible content-fn nil))
   ([content-fn {:keys [trigger-once? _debug-id]
-                :or {trigger-once? false}}]
+                :or {trigger-once? true}}]
    (if (or (util/mobile?) (mobile-util/native-platform?))
      (content-fn)
      (let [[visible? set-visible!] (rum/use-state false)
-           [last-changed-time set-last-changed-time!] (rum/use-state nil)
            inViewState (useInView #js {:rootMargin "100px"
                                        :triggerOnce trigger-once?
                                        :onChange (fn [in-view? entry]
-                                                   (let [self-top (.-top (.-boundingClientRect entry))
-                                                         time' (util/time-ms)]
-                                                     (when (and
-                                                            (or (and (not visible?) in-view?)
-                                                                ;; hide only the components below the current top for better ux
-                                                                (and visible? (not in-view?) (> self-top 0)))
-                                                            (or (nil? last-changed-time)
-                                                                (and (some? last-changed-time)
-                                                                     (> (- time' last-changed-time) 50))))
-                                                       (set-last-changed-time! time')
+                                                   (let [self-top (.-top (.-boundingClientRect entry))]
+                                                     (when (or (and (not visible?) in-view?)
+                                                               ;; hide only the components below the current top for better ux
+                                                               (and visible? (not in-view?) (> self-top 0)))
                                                        (set-visible! in-view?))))})
            ref (.-ref inViewState)]
        (lazy-visible-inner visible? content-fn ref)))))