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

pull/6489/head
Peng Xiao 2022-08-22 17:55:46 +08:00
commit 3a732aa4e2
14 changed files with 260 additions and 214 deletions

View File

@ -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)))

View File

@ -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)}))
{})

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

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

View File

@ -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]

View File

@ -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))]

View File

@ -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))))))))

View File

@ -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!
[]

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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)))))