mirror of https://github.com/logseq/logseq
fix: incremental expand/collapse
parent
fe3f066a05
commit
e9e763f62f
|
@ -1418,7 +1418,6 @@
|
|||
has-children-blocks?)
|
||||
control-show? (util/react *control-show?)
|
||||
ref? (:ref? config)
|
||||
block? (:block? config)
|
||||
empty-content? (block-content-empty? block)]
|
||||
[:div.mr-1.flex.flex-row.items-center.sm:mr-2
|
||||
{:style {:height 24
|
||||
|
@ -1430,7 +1429,7 @@
|
|||
:on-click (fn [event]
|
||||
(util/stop event)
|
||||
(when-not (and (not collapsed?) (not has-child?))
|
||||
(if (or ref? block?)
|
||||
(if ref?
|
||||
(state/toggle-collapsed-block! uuid)
|
||||
(if collapsed?
|
||||
(editor-handler/expand-block! uuid)
|
||||
|
@ -2170,13 +2169,27 @@
|
|||
children)
|
||||
(distinct @refs)))
|
||||
|
||||
(defn- root-block?
|
||||
[config block]
|
||||
(and (:block? config)
|
||||
(util/collapsed? block)
|
||||
(= (:id config)
|
||||
(str (:block/uuid block)))))
|
||||
|
||||
(rum/defcs block-container < rum/reactive
|
||||
{:init (fn [state]
|
||||
(let [[config block] (:rum/args state)]
|
||||
(when (and (nil? (state/get-collapsed (:block/uuid block)))
|
||||
(or (:ref? config) (:block? config)))
|
||||
(state/set-collapsed-block! (:block/uuid block)
|
||||
(editor-handler/block-default-collapsed? block config)))
|
||||
(let [[config block] (:rum/args state)
|
||||
block-id (:block/uuid block)]
|
||||
(cond
|
||||
(:ref? config)
|
||||
(state/set-collapsed-block! block-id
|
||||
(editor-handler/block-default-collapsed? block config))
|
||||
|
||||
(root-block? config block)
|
||||
(state/set-collapsed-block! block-id false)
|
||||
|
||||
:else
|
||||
nil)
|
||||
(assoc state ::control-show? (atom false))))
|
||||
:should-update (fn [old-state new-state]
|
||||
(let [compare-keys [:block/uuid :block/content :block/parent :block/collapsed? :block/children
|
||||
|
@ -2201,11 +2214,14 @@
|
|||
config)
|
||||
heading? (and (= type :heading) heading-level (<= heading-level 6))
|
||||
*control-show? (get state ::control-show?)
|
||||
ref? (boolean (:ref? config))
|
||||
block? (boolean (:block? config))
|
||||
collapsed? (if (or ref? block?)
|
||||
ref? (:ref? config)
|
||||
db-collapsed? (util/collapsed? block)
|
||||
collapsed? (cond
|
||||
(or ref? (root-block? config block))
|
||||
(state/sub-collapsed uuid)
|
||||
(util/collapsed? block))
|
||||
|
||||
:else
|
||||
db-collapsed?)
|
||||
breadcrumb-show? (:breadcrumb-show? config)
|
||||
slide? (boolean (:slide? config))
|
||||
custom-query? (boolean (:custom-query? config))
|
||||
|
@ -2858,7 +2874,7 @@
|
|||
|
||||
|
||||
(defn- get-segment
|
||||
[config flat-blocks idx blocks->vec-tree]
|
||||
[_config flat-blocks idx blocks->vec-tree]
|
||||
(let [new-idx (if (< idx block-handler/initial-blocks-length)
|
||||
block-handler/initial-blocks-length
|
||||
(+ idx block-handler/step-loading-blocks))
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
(if block-id
|
||||
(when-let [root-block (db/pull [:block/uuid block-id])]
|
||||
(let [blocks (-> (db/get-block-and-children repo block-id)
|
||||
(model/sort-blocks root-block {:block? true}))]
|
||||
(model/sort-blocks root-block {}))]
|
||||
(cons root-block blocks)))
|
||||
(db/get-page-blocks repo page-name))))
|
||||
|
||||
|
@ -65,11 +65,7 @@
|
|||
state)
|
||||
|
||||
(rum/defc page-blocks-inner <
|
||||
{:init (fn [state]
|
||||
(when-let [block-id (last (:rum/args state))]
|
||||
(state/set-collapsed-block! block-id false))
|
||||
state)
|
||||
:did-mount open-first-block!
|
||||
{:did-mount open-first-block!
|
||||
:did-update open-first-block!}
|
||||
[page-name _blocks hiccup sidebar? _block-uuid]
|
||||
[:div.page-blocks-inner {:style {:margin-left (if sidebar? 0 -20)}}
|
||||
|
@ -259,78 +255,78 @@
|
|||
(db/get-page-format page))
|
||||
journal? (db/journal-page? page-name)
|
||||
fmt-journal? (boolean (date/journal-title->int page-name))
|
||||
sidebar? (:sidebar? option)]
|
||||
(let [route-page-name path-page-name
|
||||
page (if block?
|
||||
(->> (:db/id (:block/page (db/entity repo [:block/uuid block-id])))
|
||||
(db/entity repo))
|
||||
(do
|
||||
(when-not (db/entity repo [:block/name page-name])
|
||||
(let [m (format-block/page-name->map path-page-name true)]
|
||||
(db/transact! repo [m])))
|
||||
(db/pull [:block/name page-name])))
|
||||
{:keys [icon]} (:block/properties page)
|
||||
page-name (:block/name page)
|
||||
page-original-name (:block/original-name page)
|
||||
title (or page-original-name page-name)
|
||||
icon (or icon "")
|
||||
today? (and
|
||||
journal?
|
||||
(= page-name (util/page-name-sanity-lc (date/journal-name))))]
|
||||
[:div.flex-1.page.relative
|
||||
(merge (if (seq (:block/tags page))
|
||||
(let [page-names (model/get-page-names-by-ids (map :db/id (:block/tags page)))]
|
||||
{:data-page-tags (text/build-data-value page-names)})
|
||||
{})
|
||||
sidebar? (:sidebar? option)
|
||||
route-page-name path-page-name
|
||||
page (if block?
|
||||
(->> (:db/id (:block/page (db/entity repo [:block/uuid block-id])))
|
||||
(db/entity repo))
|
||||
(do
|
||||
(when-not (db/entity repo [:block/name page-name])
|
||||
(let [m (format-block/page-name->map path-page-name true)]
|
||||
(db/transact! repo [m])))
|
||||
(db/pull [:block/name page-name])))
|
||||
{:keys [icon]} (:block/properties page)
|
||||
page-name (:block/name page)
|
||||
page-original-name (:block/original-name page)
|
||||
title (or page-original-name page-name)
|
||||
icon (or icon "")
|
||||
today? (and
|
||||
journal?
|
||||
(= page-name (util/page-name-sanity-lc (date/journal-name))))]
|
||||
[:div.flex-1.page.relative
|
||||
(merge (if (seq (:block/tags page))
|
||||
(let [page-names (model/get-page-names-by-ids (map :db/id (:block/tags page)))]
|
||||
{:data-page-tags (text/build-data-value page-names)})
|
||||
{})
|
||||
|
||||
{:key path-page-name
|
||||
:class (util/classnames [{:is-journals (or journal? fmt-journal?)}])})
|
||||
{:key path-page-name
|
||||
:class (util/classnames [{:is-journals (or journal? fmt-journal?)}])})
|
||||
|
||||
[:div.relative
|
||||
(when (and (not sidebar?)
|
||||
(not block?))
|
||||
[:div.flex.flex-row.space-between
|
||||
[:div.flex-1.flex-row
|
||||
(page-title page-name icon title format fmt-journal?)]
|
||||
(when (not config/publishing?)
|
||||
[:div.flex.flex-row
|
||||
(when plugin-handler/lsp-enabled?
|
||||
(plugins/hook-ui-slot :page-head-actions-slotted nil)
|
||||
(plugins/hook-ui-items :pagebar))])])
|
||||
[:div
|
||||
(when (and block? (not sidebar?))
|
||||
(let [config {:id "block-parent"
|
||||
:block? true}]
|
||||
[:div.mb-4
|
||||
(block/block-parents config repo block-id {:level-limit 3})]))
|
||||
[:div.relative
|
||||
(when (and (not sidebar?)
|
||||
(not block?))
|
||||
[:div.flex.flex-row.space-between
|
||||
[:div.flex-1.flex-row
|
||||
(page-title page-name icon title format fmt-journal?)]
|
||||
(when (not config/publishing?)
|
||||
[:div.flex.flex-row
|
||||
(when plugin-handler/lsp-enabled?
|
||||
(plugins/hook-ui-slot :page-head-actions-slotted nil)
|
||||
(plugins/hook-ui-items :pagebar))])])
|
||||
[:div
|
||||
(when (and block? (not sidebar?))
|
||||
(let [config {:id "block-parent"
|
||||
:block? true}]
|
||||
[:div.mb-4
|
||||
(block/block-parents config repo block-id {:level-limit 3})]))
|
||||
|
||||
;; blocks
|
||||
(let [page (if block?
|
||||
(db/entity repo [:block/uuid block-id])
|
||||
page)]
|
||||
(page-blocks-cp repo page {:sidebar? sidebar?}))]]
|
||||
;; blocks
|
||||
(let [page (if block?
|
||||
(db/entity repo [:block/uuid block-id])
|
||||
page)]
|
||||
(page-blocks-cp repo page {:sidebar? sidebar?}))]]
|
||||
|
||||
(when-not block?
|
||||
(today-queries repo today? sidebar?))
|
||||
(when-not block?
|
||||
(today-queries repo today? sidebar?))
|
||||
|
||||
(when-not block?
|
||||
(tagged-pages repo page-name))
|
||||
(when-not block?
|
||||
(tagged-pages repo page-name))
|
||||
|
||||
;; referenced blocks
|
||||
[:div {:key "page-references"}
|
||||
(rum/with-key
|
||||
(reference/references route-page-name false)
|
||||
(str route-page-name "-refs"))]
|
||||
;; referenced blocks
|
||||
[:div {:key "page-references"}
|
||||
(rum/with-key
|
||||
(reference/references route-page-name false)
|
||||
(str route-page-name "-refs"))]
|
||||
|
||||
(when-not block?
|
||||
[:div
|
||||
(when (not journal?)
|
||||
(hierarchy/structures route-page-name))
|
||||
(when-not block?
|
||||
[:div
|
||||
(when (not journal?)
|
||||
(hierarchy/structures route-page-name))
|
||||
|
||||
;; TODO: or we can lazy load them
|
||||
(when-not sidebar?
|
||||
[:div {:key "page-unlinked-references"}
|
||||
(reference/unlinked-references route-page-name)])])]))))
|
||||
;; TODO: or we can lazy load them
|
||||
(when-not sidebar?
|
||||
[:div {:key "page-unlinked-references"}
|
||||
(reference/unlinked-references route-page-name)])])])))
|
||||
|
||||
(defonce layout (atom [js/window.innerWidth js/window.innerHeight]))
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
[rum.core :as rum]
|
||||
[frontend.handler.shell :as shell]
|
||||
[frontend.handler.plugin :as plugin-handler]
|
||||
[frontend.mobile.util :as mobile-util]))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns frontend.context.i18n
|
||||
(:require [frontend.dicts :as dicts]
|
||||
[frontend.modules.shortcut.dict :as shortcut-dict]
|
||||
[rum.core :as rum]
|
||||
[medley.core :refer [deep-merge]]
|
||||
[frontend.state :as state]))
|
||||
|
||||
|
|
|
@ -420,14 +420,13 @@
|
|||
;; TODO: both zipmap and map lookup are slow in cljs
|
||||
;; zipmap 20k blocks takes 30ms on my M1 Air.
|
||||
(defn sort-blocks
|
||||
[blocks parent {:keys [limit block?] :as config}]
|
||||
[blocks parent {:keys [limit] :as config}]
|
||||
(let [ids->blocks (zipmap (map
|
||||
(fn [b]
|
||||
[(:db/id (:block/parent b))
|
||||
(:db/id (:block/left b))])
|
||||
blocks)
|
||||
blocks)
|
||||
collapsed-blocks (if block? (state/sub-collapsed-blocks) nil)]
|
||||
blocks)]
|
||||
(loop [node parent
|
||||
next-siblings '()
|
||||
result []]
|
||||
|
@ -439,12 +438,7 @@
|
|||
next-siblings (if (and next-sibling child-block)
|
||||
(cons next-sibling next-siblings)
|
||||
next-siblings)
|
||||
collapsed? (if block?
|
||||
(let [v (get collapsed-blocks (:block/uuid node))]
|
||||
(if (some? v)
|
||||
v
|
||||
(:block/collapsed? node)))
|
||||
(:block/collapsed? node))]
|
||||
collapsed? (:block/collapsed? node)]
|
||||
(if-let [node (and
|
||||
(or (not collapsed?)
|
||||
(= (:db/id node) (:db/id parent)))
|
||||
|
|
|
@ -3433,6 +3433,7 @@
|
|||
if :root-block is not nil, only return root block with its children
|
||||
if :expanded? true, return expanded children
|
||||
if :collapse? true, return without any collapsed children
|
||||
if :incremental? true, collapse/expand will be step by step
|
||||
for example:
|
||||
- a
|
||||
- b (collapsed)
|
||||
|
@ -3444,7 +3445,8 @@
|
|||
[{:block a :level 1}
|
||||
{:block b :level 2}
|
||||
{:block e :level 2}]"
|
||||
[{:keys [collapse? expanded? root-block] :or {collapse? false expanded? false root-block nil}}]
|
||||
[{:keys [collapse? expanded? incremental? root-block]
|
||||
:or {collapse? false expanded? false incremental? true root-block nil}}]
|
||||
(when-let [page (or (state/get-current-page)
|
||||
(date/today))]
|
||||
(let [block? (util/uuid-string? page)
|
||||
|
@ -3452,36 +3454,49 @@
|
|||
blocks (if block-id
|
||||
(db/get-block-and-children (state/get-current-repo) block-id)
|
||||
(db/get-page-blocks-no-cache page))
|
||||
blocks (tree/blocks->vec-tree blocks (or block-id page))
|
||||
root-block (or block-id root-block)]
|
||||
(->>
|
||||
(cond->> blocks
|
||||
root-block
|
||||
(map (fn find [root]
|
||||
(if (= root-block (:block/uuid root))
|
||||
root
|
||||
(first (filter find (:block/children root []))))))
|
||||
(if incremental?
|
||||
(let [blocks (tree/blocks->vec-tree blocks (or block-id page))]
|
||||
(->>
|
||||
(cond->> blocks
|
||||
root-block
|
||||
(map (fn find [root]
|
||||
(if (= root-block (:block/uuid root))
|
||||
root
|
||||
(first (filter find (:block/children root []))))))
|
||||
|
||||
collapse?
|
||||
(w/postwalk
|
||||
(fn [b]
|
||||
(if (and (map? b) (util/collapsed? b))
|
||||
(assoc b :block/children []) b)))
|
||||
collapse?
|
||||
(w/postwalk
|
||||
(fn [b]
|
||||
(if (and (map? b)
|
||||
(util/collapsed? b)
|
||||
(not= root-block (:block/uuid b)))
|
||||
(assoc b :block/children []) b)))
|
||||
|
||||
true
|
||||
(mapcat (fn [x] (tree-seq map? :block/children x)))
|
||||
true
|
||||
(mapcat (fn [x] (tree-seq map? :block/children x)))
|
||||
|
||||
expanded?
|
||||
(filter (fn [b] (collapsable? (:block/uuid b))))
|
||||
expanded?
|
||||
(filter (fn [b] (collapsable? (:block/uuid b))))
|
||||
|
||||
true
|
||||
(map (fn [x] (dissoc x :block/children))))
|
||||
(remove nil?)))))
|
||||
true
|
||||
(map (fn [x] (dissoc x :block/children))))
|
||||
(remove nil?)))
|
||||
|
||||
(cond->> blocks
|
||||
collapse?
|
||||
(filter util/collapsed?)
|
||||
|
||||
expanded?
|
||||
(filter (fn [b] (collapsable? (:block/uuid b))))
|
||||
|
||||
true
|
||||
(remove nil?))))))
|
||||
|
||||
(defn- skip-collapsing-in-db?
|
||||
[]
|
||||
(let [config (:config (state/get-editor-args))]
|
||||
(or (:ref? config) (:block? config))))
|
||||
(:ref? config)))
|
||||
|
||||
(defn- set-blocks-collapsed!
|
||||
[block-ids value]
|
||||
|
@ -3515,15 +3530,13 @@
|
|||
(defn collapse-block! [block-id]
|
||||
(when (collapsable? block-id)
|
||||
(when-not (skip-collapsing-in-db?)
|
||||
(set-block-property! block-id :collapsed true)
|
||||
(set-blocks-collapsed! [block-id] true)))
|
||||
(state/set-collapsed-block! block-id true))
|
||||
|
||||
(defn expand-block! [block-id]
|
||||
(when-not (skip-collapsing-in-db?)
|
||||
(set-block-property! block-id :collapsed false)
|
||||
(set-blocks-collapsed! [block-id] false))
|
||||
(state/set-collapsed-block! block-id false))
|
||||
(set-blocks-collapsed! [block-id] false)
|
||||
(state/set-collapsed-block! block-id false)))
|
||||
|
||||
(defn expand!
|
||||
([e] (expand! e false))
|
||||
|
@ -3561,7 +3574,7 @@
|
|||
(defn collapse!
|
||||
([e] (collapse! e false))
|
||||
([e clear-selection?]
|
||||
(util/stop e)
|
||||
(when e (util/stop e))
|
||||
(cond
|
||||
(state/editing?)
|
||||
(when-let [block-id (:block/uuid (state/get-edit-block))]
|
||||
|
@ -3594,44 +3607,32 @@
|
|||
(doseq [{:block/keys [uuid]} blocks-to-collapse]
|
||||
(collapse-block! uuid))))))))))
|
||||
|
||||
(defn- zoom-in?
|
||||
[]
|
||||
(let [page (state/get-current-page)]
|
||||
(boolean
|
||||
(and
|
||||
(string? page)
|
||||
(util/uuid-string? page)))))
|
||||
|
||||
(defn collapse-all!
|
||||
([]
|
||||
(collapse-all! nil))
|
||||
([block-id]
|
||||
(let [blocks (all-blocks-with-level {:expanded? true :root-block block-id})
|
||||
(let [blocks (all-blocks-with-level {:incremental? false
|
||||
:expanded? true
|
||||
:root-block block-id})
|
||||
block-ids (map :block/uuid blocks)]
|
||||
(if (zoom-in?)
|
||||
(doseq [block-id block-ids]
|
||||
(state/set-collapsed-block! block-id true))
|
||||
(set-blocks-collapsed! block-ids true)))))
|
||||
(set-blocks-collapsed! block-ids true))))
|
||||
|
||||
(defn expand-all!
|
||||
([]
|
||||
(expand-all! nil))
|
||||
([block-id]
|
||||
(let [blocks (all-blocks-with-level {:root-block block-id})
|
||||
(let [blocks (all-blocks-with-level {:incremental? false
|
||||
:collapse? true
|
||||
:root-block block-id})
|
||||
block-ids (map :block/uuid blocks)]
|
||||
(if (zoom-in?)
|
||||
(doseq [block-id block-ids]
|
||||
(state/set-collapsed-block! block-id false))
|
||||
(set-blocks-collapsed! block-ids false)))))
|
||||
(set-blocks-collapsed! block-ids false))))
|
||||
|
||||
(defn toggle-open! []
|
||||
(let [all-collapsed?
|
||||
(->> (all-blocks-with-level {:collapse? true})
|
||||
(filter (fn [b] (collapsable? (:block/uuid b))))
|
||||
(empty?))]
|
||||
(if all-collapsed?
|
||||
(expand-all!)
|
||||
(collapse-all!))))
|
||||
(let [all-expanded? (empty? (all-blocks-with-level {:incremental? false
|
||||
:collapse? true}))]
|
||||
(if all-expanded?
|
||||
(collapse-all!)
|
||||
(expand-all!))))
|
||||
|
||||
(defn select-all-blocks!
|
||||
[]
|
||||
|
@ -3713,27 +3714,11 @@
|
|||
(defn block-default-collapsed?
|
||||
"Whether a block should be collapsed by default.
|
||||
Currently, this handles several cases:
|
||||
1. Zoom in mode, it will open the current block if it's collapsed.
|
||||
2. Queries.
|
||||
3. References."
|
||||
1. References."
|
||||
[block config]
|
||||
(let [collapsed? (cond
|
||||
(and (:block? config)
|
||||
(= (:id config) (str (:block/uuid block))))
|
||||
false
|
||||
|
||||
(and (:block? config)
|
||||
(util/collapsed? block))
|
||||
true
|
||||
|
||||
:else
|
||||
(boolean
|
||||
(and
|
||||
(seq (:block/children block))
|
||||
(or (:custom-query? config)
|
||||
(and (:ref? config)
|
||||
(>= (:ref/level block)
|
||||
(state/get-ref-open-blocks-level)))))))]
|
||||
(if (or (:ref? config) (:block? config))
|
||||
collapsed?
|
||||
(util/collapsed? block))))
|
||||
(if (:ref? config)
|
||||
(and
|
||||
(seq (:block/children block))
|
||||
(>= (:ref/level block)
|
||||
(state/get-ref-open-blocks-level)))
|
||||
(util/collapsed? block)))
|
||||
|
|
|
@ -1605,11 +1605,3 @@
|
|||
(defn sub-collapsed
|
||||
[block-id]
|
||||
(sub [:ui/collapsed-blocks (get-current-repo) block-id]))
|
||||
|
||||
(defn get-collapsed
|
||||
[block-id]
|
||||
(get @state [:ui/collapsed-blocks (get-current-repo) block-id]))
|
||||
|
||||
(defn sub-collapsed-blocks
|
||||
[]
|
||||
(sub [:ui/collapsed-blocks (get-current-repo)]))
|
||||
|
|
|
@ -1448,6 +1448,4 @@
|
|||
|
||||
(defn collapsed?
|
||||
[block]
|
||||
(or (:block/collapsed? block)
|
||||
;; for backward compatiblity
|
||||
(get-in block [:properties :collapsed])))
|
||||
(:block/collapsed? block))
|
||||
|
|
Loading…
Reference in New Issue