diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 09fe09d37d..390d581035 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2795,133 +2795,155 @@ [block* result] [nil result]))) -(rum/defc ^:large-vars/cleanup-todo block-container-inner < rum/reactive db-mixins/query - [state repo config* block {:keys [edit? edit-input-id navigating-block navigated?]}] - (let [ref? (:ref? config*) - custom-query? (boolean (:custom-query? config*)) - ref-or-custom-query? (or ref? custom-query?) - *navigating-block (get state ::navigating-block) - {:block/keys [uuid pre-block? refs content properties]} block - config (build-config config* block {:navigated? navigated? :navigating-block navigating-block}) - level (:level config) - blocks-container-id (:blocks-container-id config) - heading? (pu/lookup properties :heading) - *control-show? (get state ::control-show?) - db-collapsed? (util/collapsed? block) - collapsed? (cond - (or ref-or-custom-query? (root-block? config block)) - (state/sub-collapsed uuid) +(defn- hide-block? + [ref] + (boolean + (when ref + (let [top (.-top (.getBoundingClientRect ref))] + (not (<= top (+ js/window.innerHeight 500))))))) - :else - db-collapsed?) - breadcrumb-show? (:breadcrumb-show? config) - *show-left-menu? (::show-block-left-menu? state) - *show-right-menu? (::show-block-right-menu? state) - slide? (boolean (:slide? config)) - doc-mode? (:document/mode? config) - embed? (:embed? config) - reference? (:reference? config) - whiteboard-block? (pu/shape-block? block) - block-id (str "ls-block-" blocks-container-id "-" uuid) - has-child? (first (:block/_parent (db/entity (:db/id block)))) - top? (zero? (:idx config)) - original-block (:original-block config) - attrs (on-drag-and-mouse-attrs block original-block uuid top? block-id *move-to) - children-refs (get-children-refs block) - data-refs (build-refs-data-value children-refs) - data-refs-self (build-refs-data-value refs) - card? (string/includes? data-refs-self "\"card\"") - review-cards? (:review-cards? config) - own-number-list? (:own-order-number-list? config) - order-list? (boolean own-number-list?) - selected? (when-not slide? - (state/sub-block-selected? blocks-container-id uuid))] - [:div.ls-block - (cond-> - {:id block-id - :data-refs data-refs - :data-refs-self data-refs-self - :data-collapsed (and collapsed? has-child?) - :class (str (str "id" uuid) ; ID starts with a number can't be selected - (when pre-block? " pre-block") - (when (and card? (not review-cards?)) " shadow-md") - (when selected? " selected") - (when order-list? " is-order-list") - (when (string/blank? content) " is-blank")) - :blockid (str uuid) - :haschild (str (boolean has-child?))} +(rum/defcs ^:large-vars/cleanup-todo block-container-inner < rum/reactive db-mixins/query + (rum/local nil ::ref) + (rum/local nil ::hidden?) + {:did-mount (fn [state] + (let [hide? (hide-block? @(::ref state))] + (reset! (::hidden? state) hide?) + state))} + [inner-state state repo config* block {:keys [edit? edit-input-id navigating-block navigated?]}] + (let [*hidden? (::hidden? inner-state) + *ref (::ref inner-state) + _scroll-top (state/sub :ui/main-container-scroll-top)] + (when-not (nil? @*hidden?) + (reset! *hidden? (hide-block? @*ref))) - original-block - (assoc :originalblockid (str (:block/uuid original-block))) + [:div {:ref (fn [r] (when-not @*ref (reset! *ref r)))} + (if (and (not edit?) @*hidden?) + [:div {:style {:height 24}}] + (let [ref? (:ref? config*) + custom-query? (boolean (:custom-query? config*)) + ref-or-custom-query? (or ref? custom-query?) + *navigating-block (get state ::navigating-block) + {:block/keys [uuid pre-block? refs content properties]} block + config (build-config config* block {:navigated? navigated? :navigating-block navigating-block}) + level (:level config) + blocks-container-id (:blocks-container-id config) + heading? (pu/lookup properties :heading) + *control-show? (get state ::control-show?) + db-collapsed? (util/collapsed? block) + collapsed? (cond + (or ref-or-custom-query? (root-block? config block)) + (state/sub-collapsed uuid) - level - (assoc :level level) + :else + db-collapsed?) + breadcrumb-show? (:breadcrumb-show? config) + *show-left-menu? (::show-block-left-menu? state) + *show-right-menu? (::show-block-right-menu? state) + slide? (boolean (:slide? config)) + doc-mode? (:document/mode? config) + embed? (:embed? config) + reference? (:reference? config) + whiteboard-block? (pu/shape-block? block) + block-id (str "ls-block-" blocks-container-id "-" uuid) + has-child? (first (:block/_parent (db/entity (:db/id block)))) + top? (zero? (:idx config)) + original-block (:original-block config) + attrs (on-drag-and-mouse-attrs block original-block uuid top? block-id *move-to) + children-refs (get-children-refs block) + data-refs (build-refs-data-value children-refs) + data-refs-self (build-refs-data-value refs) + card? (string/includes? data-refs-self "\"card\"") + review-cards? (:review-cards? config) + own-number-list? (:own-order-number-list? config) + order-list? (boolean own-number-list?) + selected? (when-not slide? + (state/sub-block-selected? blocks-container-id uuid))] + [:div.ls-block + (cond-> + {:id block-id + :data-refs data-refs + :data-refs-self data-refs-self + :data-collapsed (and collapsed? has-child?) + :class (str (str "id" uuid) ; ID starts with a number can't be selected + (when pre-block? " pre-block") + (when (and card? (not review-cards?)) " shadow-md") + (when selected? " selected") + (when order-list? " is-order-list") + (when (string/blank? content) " is-blank")) + :blockid (str uuid) + :haschild (str (boolean has-child?))} - (not slide?) - (merge attrs) + original-block + (assoc :originalblockid (str (:block/uuid original-block))) - (or reference? embed?) - (assoc :data-transclude true) + level + (assoc :level level) - embed? - (assoc :data-embed true) + (not slide?) + (merge attrs) - custom-query? - (assoc :data-query true)) + (or reference? embed?) + (assoc :data-transclude true) - (when (and ref? breadcrumb-show?) - (breadcrumb config repo uuid {:show-page? false - :indent? true - :navigating-block *navigating-block})) + embed? + (assoc :data-embed true) + + custom-query? + (assoc :data-query true)) + + (when (and ref? breadcrumb-show?) + (breadcrumb config repo uuid {:show-page? false + :indent? true + :navigating-block *navigating-block})) ;; only render this for the first block in each container - (when top? - (dnd-separator-wrapper block block-id slide? true false)) + (when top? + (dnd-separator-wrapper block block-id slide? true false)) - [:div.block-main-container.flex.flex-row.pr-2 - {:class (if (and heading? (seq (:block/title block))) "items-baseline" "") - :on-touch-start (fn [event uuid] (block-handler/on-touch-start event uuid)) - :on-touch-move (fn [event] - (block-handler/on-touch-move event block uuid edit? *show-left-menu? *show-right-menu?)) - :on-touch-end (fn [event] - (block-handler/on-touch-end event block uuid *show-left-menu? *show-right-menu?)) - :on-touch-cancel (fn [_e] - (block-handler/on-touch-cancel *show-left-menu? *show-right-menu?)) - :on-mouse-over (fn [e] - (block-mouse-over e *control-show? block-id doc-mode?)) - :on-mouse-leave (fn [e] - (block-mouse-leave e *control-show? block-id doc-mode?))} - (when (not slide?) - (block-control config block uuid block-id collapsed? *control-show? edit?)) + [:div.block-main-container.flex.flex-row.pr-2 + {:class (if (and heading? (seq (:block/title block))) "items-baseline" "") + :on-touch-start (fn [event uuid] (block-handler/on-touch-start event uuid)) + :on-touch-move (fn [event] + (block-handler/on-touch-move event block uuid edit? *show-left-menu? *show-right-menu?)) + :on-touch-end (fn [event] + (block-handler/on-touch-end event block uuid *show-left-menu? *show-right-menu?)) + :on-touch-cancel (fn [_e] + (block-handler/on-touch-cancel *show-left-menu? *show-right-menu?)) + :on-mouse-over (fn [e] + (block-mouse-over e *control-show? block-id doc-mode?)) + :on-mouse-leave (fn [e] + (block-mouse-leave e *control-show? block-id doc-mode?))} + (when (not slide?) + (block-control config block uuid block-id collapsed? *control-show? edit?)) - (when @*show-left-menu? - (block-left-menu config block)) + (when @*show-left-menu? + (block-left-menu config block)) - (if whiteboard-block? - (block-reference {} (str uuid) nil) + (if whiteboard-block? + (block-reference {} (str uuid) nil) ;; Not embed self - [:div.flex.flex-col.w-full - (let [block (merge block (block/parse-title-and-body uuid (:block/format block) pre-block? content)) - hide-block-refs-count? (and (:embed? config) - (= (:block/uuid block) (:embed-id config)))] - (block-content-or-editor config block edit-input-id block-id edit? hide-block-refs-count? selected?)) - (when (and (config/db-based-graph? repo) (not collapsed?)) - (db-properties-cp config - block - edit-input-id - {:selected? selected? - :in-block-container? true}))]) + [:div.flex.flex-col.w-full + (let [block (merge block (block/parse-title-and-body uuid (:block/format block) pre-block? content)) + hide-block-refs-count? (and (:embed? config) + (= (:block/uuid block) (:embed-id config)))] + (block-content-or-editor config block edit-input-id block-id edit? hide-block-refs-count? selected?)) + (when (and (config/db-based-graph? repo) (not collapsed?)) + (db-properties-cp config + block + edit-input-id + {:selected? selected? + :in-block-container? true}))]) - (when @*show-right-menu? - (block-right-menu config block edit?))] + (when @*show-right-menu? + (block-right-menu config block edit?))] - (when-not (:hide-children? config) - (let [children (db/sort-by-left (:block/_parent block) block) - config' (-> (update config :level inc) - (dissoc :original-block))] - (block-children config' block children collapsed?))) + (when-not (:hide-children? config) + (let [children (db/sort-by-left (:block/_parent block) block) + config' (-> (update config :level inc) + (dissoc :original-block))] + (block-children config' block children collapsed?))) - (dnd-separator-wrapper block block-id slide? false false)])) + (dnd-separator-wrapper block block-id slide? false false)]))])) (defn- block-changed? [old-block new-block] @@ -3359,7 +3381,7 @@ [config col] (map #(markup-element-cp config %) col)) -(rum/defc block-item < +(rum/defcs block-item < {:should-update (fn [old-state new-state] (let [config-compare-keys [:show-cloze? :hide-children? :own-order-list-type :own-order-list-index :original-block] b1 (second (:rum/args old-state)) @@ -3370,7 +3392,7 @@ (not= (select-keys (first (:rum/args old-state)) config-compare-keys) (select-keys (first (:rum/args new-state)) config-compare-keys)))] (boolean result)))} - [config item {:keys [top? bottom? edit-block]}] + [state config item {:keys [top? bottom?]}] (let [original-block item linked-block (:block/link item) item (or linked-block item) @@ -3381,38 +3403,25 @@ config (assoc config :block/uuid (:block/uuid item)) config' (if linked-block (assoc config :original-block original-block) - config) - ref? (:ref? config) - custom-query? (boolean (:custom-query? config)) - lazy? (or ref? custom-query? (:lazy? config)) - initial-state (= (:block/uuid item) (:block/uuid edit-block)) - cp-f (fn [] - (rum/with-key (block-container config' item) - (str (:blocks-container-id config') - "-" - (:block/uuid item) - (when linked-block - (str "-" (:block/uuid original-block))))))] - (if lazy? - (ui/lazy-visible cp-f - {:debug-id (str "block-container-ref " (:db/id item)) - :initial-state initial-state - :fade-in? false}) - (cp-f)))) + config)] + (rum/with-key (block-container config' item) + (str (:blocks-container-id config') + "-" + (:block/uuid item) + (when linked-block + (str "-" (:block/uuid original-block))))))) (defn- block-list [config blocks] - (let [edit-block (state/get-edit-block)] - (for [[idx item] (medley/indexed blocks)] - (let [top? (zero? idx) - bottom? (= (count blocks) (inc idx))] - (rum/with-key - (block-item (assoc config :idx idx) item {:top? top? - :bottom? bottom? - :edit-block edit-block}) - (str "blocks-" (:blocks-container-id config) - "-" - (:block/uuid item))))))) + (for [[idx item] (medley/indexed blocks)] + (let [top? (zero? idx) + bottom? (= (count blocks) (inc idx))] + (rum/with-key + (block-item (assoc config :idx idx) item {:top? top? + :bottom? bottom?}) + (str "blocks-" (:blocks-container-id config) + "-" + (:block/uuid item)))))) (rum/defcs blocks-container < {:init (fn [state] (assoc state ::init-blocks-container-id (atom nil)))} diff --git a/src/main/frontend/components/container.cljs b/src/main/frontend/components/container.cljs index 78eae06d79..5a7615a78b 100644 --- a/src/main/frontend/components/container.cljs +++ b/src/main/frontend/components/container.cljs @@ -486,7 +486,7 @@ (rum/defc main < {:did-mount (fn [state] - (when-let [element (gdom/getElement "app-container")] + (when-let [element (gdom/getElement "main-content-container")] (dnd/subscribe! element :upload-files @@ -499,7 +499,7 @@ (set! (.. element -scrollTop) 0))) state) :will-unmount (fn [state] - (when-let [el (gdom/getElement "app-container")] + (when-let [el (gdom/getElement "main-content-container")] (dnd/unsubscribe! el :upload-files)) state)} [{:keys [route-match margin-less-pages? route-name indexeddb-support? db-restoring? main-content show-action-bar? show-recording-bar?]}] diff --git a/src/main/frontend/components/page.cljs b/src/main/frontend/components/page.cljs index 738e6ba794..e4ca4349eb 100644 --- a/src/main/frontend/components/page.cljs +++ b/src/main/frontend/components/page.cljs @@ -85,13 +85,14 @@ (rum/defc page-blocks-inner < {:did-mount open-root-block!} - [page-name _block hiccup sidebar? whiteboard? _block-uuid] - [:div.page-blocks-inner {:style {:margin-left (if (or sidebar? whiteboard?) 0 -20)}} - (rum/with-key - (content/content page-name - {:hiccup hiccup - :sidebar? sidebar?}) - (str page-name "-hiccup"))]) + [page-name _block blocks config sidebar? whiteboard? _block-uuid] + (let [hiccup (component-block/->hiccup blocks config {})] + [:div.page-blocks-inner {:style {:margin-left (if (or sidebar? whiteboard?) 0 -20)}} + (rum/with-key + (content/content page-name + {:hiccup hiccup + :sidebar? sidebar?}) + (str page-name "-hiccup"))])) (declare page) @@ -124,7 +125,8 @@ [:a.add-button-link.block (ui/icon "circle-plus")]]]]) -(rum/defc page-blocks-cp < rum/reactive db-mixins/query +(rum/defcs page-blocks-cp < rum/reactive db-mixins/query + (rum/local nil ::ref) {:will-mount (fn [state] (let [page-e (second (:rum/args state)) page-name (:block/name page-e)] @@ -133,7 +135,7 @@ (date/journal-title->int (date/today)))) (state/pub-event! [:journal/insert-template page-name]))) state)} - [repo page-e {:keys [sidebar? whiteboard?] :as config}] + [state repo page-e {:keys [sidebar? whiteboard?] :as config}] (when page-e (let [page-name (or (:block/name page-e) (str (:block/uuid page-e))) @@ -151,7 +153,8 @@ (dummy-block page-name) :else - (let [document-mode? (state/sub :document/mode?) + (let [*ref (::ref state) + document-mode? (state/sub :document/mode?) hiccup-config (merge {:id (if block? (str block-id) page-name) :db/id (:db/id block) @@ -159,13 +162,10 @@ :editor-box editor/box :document/mode? document-mode?} config) - hiccup-config (common-handler/config-with-document-mode hiccup-config) - blocks (if block? [block] (db/sort-by-left (:block/_parent block) block)) - non-collapsed-blocks-count (count (remove :block/collapsed? (:block/_page (db/entity (:db/id page-e))))) - lazy? (> non-collapsed-blocks-count 50) - hiccup (component-block/->hiccup blocks (assoc hiccup-config :lazy? lazy?) {})] - [:div - (page-blocks-inner page-name block hiccup sidebar? whiteboard? block-id) + config (common-handler/config-with-document-mode hiccup-config) + blocks (if block? [block] (db/sort-by-left (:block/_parent block) block))] + [:div {:ref #(reset! *ref %)} + (page-blocks-inner page-name block blocks config sidebar? whiteboard? block-id) (when-not config/publishing? (let [args (if block-id {:block-uuid block-id} diff --git a/src/main/frontend/handler/common.cljs b/src/main/frontend/handler/common.cljs index 03a6c1f28d..8449e3098a 100644 --- a/src/main/frontend/handler/common.cljs +++ b/src/main/frontend/handler/common.cljs @@ -7,7 +7,9 @@ [frontend.util :as util] [frontend.handler.property :as property-handler] [goog.object :as gobj] - ["ignore" :as Ignore])) + [goog.dom :as gdom] + ["ignore" :as Ignore] + [goog.functions :refer [debounce]])) (defn copy-to-clipboard-without-id-property! [repo format raw-text html blocks] @@ -71,13 +73,16 @@ (defn listen-to-scroll! [element] - (let [*scroll-timer (atom nil)] - (.addEventListener element "scroll" - (fn [] - (when @*scroll-timer - (js/clearTimeout @*scroll-timer)) - (state/set-state! :ui/scrolling? true) - (state/save-scroll-position! (util/scroll-top)) - (reset! *scroll-timer (js/setTimeout - (fn [] (state/set-state! :ui/scrolling? false)) 500))) - false))) + (let [*scroll-timer (atom nil) + on-scroll (fn [] + (when @*scroll-timer + (js/clearTimeout @*scroll-timer)) + (state/set-state! :ui/scrolling? true) + (state/save-scroll-position! (util/scroll-top)) + (state/save-main-container-position! + (-> (gdom/getElement "main-content-container") + (gobj/get "scrollTop"))) + (reset! *scroll-timer (js/setTimeout + (fn [] (state/set-state! :ui/scrolling? false)) 500))) + debounced-on-scroll (debounce on-scroll 100)] + (.addEventListener element "scroll" debounced-on-scroll false))) diff --git a/src/main/frontend/modules/outliner/datascript.cljs b/src/main/frontend/modules/outliner/datascript.cljs index 17331755ab..fe5774985c 100644 --- a/src/main/frontend/modules/outliner/datascript.cljs +++ b/src/main/frontend/modules/outliner/datascript.cljs @@ -170,7 +170,7 @@ rs (db/transact! repo txs (assoc opts :outliner/transact? true)) tx-id (get-tx-id rs)] ;; TODO: disable this when db is stable - (when config/dev? (validate-db! rs)) + ;; (when config/dev? (validate-db! rs)) (state/update-state! :history/tx->editor-cursor (fn [m] (assoc m tx-id before-editor-cursor))) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 119032c347..3636efe215 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1351,6 +1351,10 @@ Similar to re-frame subscriptions" ([value path] (set-state! :ui/paths-scroll-positions value :path-in-sub-atom path))) +(defn save-main-container-position! + [value] + (set-state! :ui/main-container-scroll-top value)) + (defn get-saved-scroll-position ([] (get-saved-scroll-position js/window.location.hash))