diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 861c53053..82b4061fa 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -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)) diff --git a/src/main/frontend/components/page.cljs b/src/main/frontend/components/page.cljs index 4235672f9..09d6c1242 100644 --- a/src/main/frontend/components/page.cljs +++ b/src/main/frontend/components/page.cljs @@ -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])) diff --git a/src/main/frontend/components/page_menu.cljs b/src/main/frontend/components/page_menu.cljs index 3790dfcb4..c45669e21 100644 --- a/src/main/frontend/components/page_menu.cljs +++ b/src/main/frontend/components/page_menu.cljs @@ -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])) diff --git a/src/main/frontend/context/i18n.cljs b/src/main/frontend/context/i18n.cljs index aa9508aa5..9f41eb1f8 100644 --- a/src/main/frontend/context/i18n.cljs +++ b/src/main/frontend/context/i18n.cljs @@ -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])) diff --git a/src/main/frontend/db/model.cljs b/src/main/frontend/db/model.cljs index b20409d12..423447267 100644 --- a/src/main/frontend/db/model.cljs +++ b/src/main/frontend/db/model.cljs @@ -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))) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 24b30fe38..39eab6dcc 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -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))) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 9db4b7318..4158b00ca 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -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)])) diff --git a/src/main/frontend/util.cljc b/src/main/frontend/util.cljc index 9e0d2710e..3346b2893 100644 --- a/src/main/frontend/util.cljc +++ b/src/main/frontend/util.cljc @@ -1448,6 +1448,4 @@ (defn collapsed? [block] - (or (:block/collapsed? block) - ;; for backward compatiblity - (get-in block [:properties :collapsed]))) + (:block/collapsed? block))