diff --git a/deps/shui/src/logseq/shui/context.cljs b/deps/shui/src/logseq/shui/context.cljs index fd3bbafe8..5967537d7 100644 --- a/deps/shui/src/logseq/shui/context.cljs +++ b/deps/shui/src/logseq/shui/context.cljs @@ -12,23 +12,22 @@ (defn make-context [{:keys [block-config app-config inline int->local-time-2]}] {;; Shui needs access to the global configuration of the application :config app-config - ;; Until components are converted over, they need to fallback to the old inline function + ;; Until components are converted over, they need to fallback to the old inline function ;; Wrap the old inline function to allow for interception, but fallback to the old inline function - :inline-block (inline->inline-block inline block-config) + :inline-block (inline->inline-block inline block-config) :map-inline-block (inline->map-inline-block inline block-config) ;; Currently frontend component are provided an object map containin at least the following keys: - ;; These will be passed through in a whitelisted fashion so as to be able to track the dependencies + ;; These will be passed through in a whitelisted fashion so as to be able to track the dependencies ;; back to the core application ;; TODO: document the following :block (:block block-config) ;; the db entity of the current block :block? (:block? block-config) :blocks-container-id (:blocks-container-id block-config) :editor-box (:editor-box block-config) - :id (:id block-config) + :id (:id block-config) :mode? (:mode? block-config) :query-result (:query-result block-config) :sidebar? (:sidebar? block-config) - :start-time (:start-time block-config) :uuid (:uuid block-config) :whiteboard? (:whiteboard? block-config) ;; Some functions from logseq's application will be used in the shui components. To avoid circular dependencies, diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 2cadaf0fe..dd81766e0 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2805,148 +2805,133 @@ (let [top (.-top (.getBoundingClientRect ref))] (not (<= top (+ js/window.innerHeight 1000))))))) -(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))) +(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) - [: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) + :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? (:top? 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?))} - :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?))} + original-block + (assoc :originalblockid (str (:block/uuid original-block))) - original-block - (assoc :originalblockid (str (:block/uuid original-block))) + level + (assoc :level level) - level - (assoc :level level) + (not slide?) + (merge attrs) - (not slide?) - (merge attrs) + (or reference? embed?) + (assoc :data-transclude true) - (or reference? embed?) - (assoc :data-transclude true) + embed? + (assoc :data-embed true) - embed? - (assoc :data-embed true) + custom-query? + (assoc :data-query 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})) + (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] @@ -3384,7 +3369,7 @@ [config col] (map #(markup-element-cp config %) col)) -(rum/defcs block-item < +(rum/defc block-item-inner < {: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)) @@ -3395,7 +3380,7 @@ (not= (select-keys (first (:rum/args old-state)) config-compare-keys) (select-keys (first (:rum/args new-state)) config-compare-keys)))] (boolean result)))} - [state config item {:keys [top? bottom?]}] + [config item {:keys [top? bottom?]}] (let [original-block item linked-block (:block/link item) item (or linked-block item) @@ -3414,19 +3399,54 @@ (when linked-block (str "-" (:block/uuid original-block))))))) +(defn- get-hidden-atom + [sub-id *ref] + (rum/derived-atom [(:ui/main-container-scroll-top @state/state)] [::lazy-display sub-id] + (fn [top] + (boolean (hide-block? @*ref))))) + +(rum/defcs block-item < rum/reactive + {:init (fn [state] + (let [id (random-uuid) + *ref (atom nil) + *hidden? (get-hidden-atom id *ref)] + (assoc state ::sub-id id ::ref *ref ::hidden? *hidden?))) + :should-update (fn [old-state new-state] + (let [args-1 (:rum/args old-state) + args-2 (:rum/args new-state)] + (not= [(first args-1) (last args-1)] + [(first args-2) (last args-2)]))) + :did-mount (fn [state] + (let [hide? (hide-block? @(::ref state))] + (reset! (::hidden? state) hide?) + state))} + [state config item opts] + (let [*hidden? (::hidden? state) + hidden? (rum/react *hidden?) + *ref (::ref state)] + [:div {:ref (fn [r] (when-not @*ref (reset! *ref r))) + :key (str "item-" + (:blocks-container-id config) + "-" + (:block/uuid item))} + (if hidden? + [:div {:style {:height 24}}] + (block-item-inner config item opts))])) + (defn- block-list [config blocks] (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?}) + (block-item (assoc config :top? top?) item + {:top? top? + :bottom? bottom?}) (str "blocks-" (:blocks-container-id config) "-" (:block/uuid item)))))) -(rum/defcs blocks-container < +(rum/defcs blocks-container < rum/static {:init (fn [state] (assoc state ::init-blocks-container-id (atom nil)))} [state blocks config] (let [*init-blocks-container-id (::init-blocks-container-id state) @@ -3438,10 +3458,9 @@ config (assoc config :blocks-container-id blocks-container-id) doc-mode? (:document/mode? config)] (when (seq blocks) - (let [config (assoc config :start-time (util/time-ms))] - [:div.blocks-container.flex-1 + [:div.blocks-container.flex-1 {:class (when doc-mode? "document-mode")} - (block-list config blocks)])))) + (block-list config blocks)]))) (rum/defcs breadcrumb-with-container < rum/reactive db-mixins/query {:init (fn [state] diff --git a/src/main/frontend/components/page.cljs b/src/main/frontend/components/page.cljs index eadaec4fa..408cda256 100644 --- a/src/main/frontend/components/page.cljs +++ b/src/main/frontend/components/page.cljs @@ -127,7 +127,6 @@ (ui/icon "circle-plus")]]]]) (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)] @@ -150,12 +149,11 @@ (and (not block?) - (empty? (:block/_parent block))) + (empty? (:block/_parent block))) (dummy-block page-name) :else - (let [*ref (::ref state) - document-mode? (state/sub :document/mode?) + (let [document-mode? (state/sub :document/mode?) hiccup-config (merge {:id (if block? (str block-id) page-name) :db/id (:db/id block) @@ -165,7 +163,7 @@ config) 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 %)} + [:div (page-blocks-inner page-name block blocks config sidebar? whiteboard? block-id) (when-not config/publishing? (let [args (if block-id @@ -506,15 +504,14 @@ page-name (util/page-name-sanity-lc path-page-name) block-id (parse-uuid page-name) block? (boolean block-id) - db-id (if block? - (let [entity (db/entity [:block/uuid block-id])] - (:db/id entity)) - (do - (when-not (db/entity repo [:block/name page-name]) - (let [m (block/page-name->map path-page-name true)] - (db/transact! repo [m]))) - (:db/id (db/entity [:block/name page-name])))) - page (db/sub-block db-id) + page (if block? + (let [entity (db/entity [:block/uuid block-id])] + entity) + (do + (when-not (db/entity repo [:block/name page-name]) + (let [m (block/page-name->map path-page-name true)] + (db/transact! repo [m]))) + (db/entity [:block/name page-name]))) block-id (:block/uuid page) block? (some? (:block/page page)) journal? (db/journal-page? page-name) @@ -600,10 +597,7 @@ {:selected? false}))]) ;; blocks - (let [page (if block? - (db/entity repo [:block/uuid block-id]) - page) - _ (and block? page (reset! *current-block-page (:block/name (:block/page page)))) + (let [_ (and block? page (reset! *current-block-page (:block/name (:block/page page)))) _ (when (and block? (not page)) (route-handler/redirect-to-page! @*current-block-page))] (page-blocks-cp repo page {:sidebar? sidebar? :whiteboard? whiteboard?}))]]) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 3636efe21..378e48e25 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -98,6 +98,7 @@ false) ;; remember scroll positions of visited paths :ui/paths-scroll-positions (atom {}) + :ui/main-container-scroll-top (atom nil) :ui/shortcut-tooltip? (if (false? (storage/get :ui/shortcut-tooltip?)) false true) @@ -120,11 +121,11 @@ :editor/in-composition? false :editor/content (atom {}) :editor/block (atom nil) - :editor/block-dom-id nil + :editor/block-dom-id (atom nil) :editor/set-timestamp-block nil ;; click rendered block timestamp-cp to set timestamp :editor/last-input-time (atom {}) :editor/document-mode? document-mode? - :editor/args nil + :editor/args (atom nil) :editor/on-paste? (atom false) :editor/last-key-code (atom nil) :editor/block-op-type nil ;; :cut, :copy @@ -1301,7 +1302,7 @@ Similar to re-frame subscriptions" (defn get-editing-block-dom-id [] - (:editor/block-dom-id @state)) + @(:editor/block-dom-id @state)) (defn set-root-component! [component] @@ -1353,7 +1354,8 @@ Similar to re-frame subscriptions" (defn save-main-container-position! [value] - (set-state! :ui/main-container-scroll-top value)) + (when (not= value @(:ui/main-container-scroll-top @state)) + (set-state! :ui/main-container-scroll-top value))) (defn get-saved-scroll-position ([] @@ -1860,7 +1862,7 @@ Similar to re-frame subscriptions" (defn get-editor-args [] - (:editor/args @state)) + @(:editor/args @state)) (defn set-page-blocks-cp! [value] @@ -1907,13 +1909,15 @@ Similar to re-frame subscriptions" :block.temp/container (gobj/get container "id")) block) content (string/trim (or content ""))] - (swap! state - (fn [state] - (-> state - (assoc - :editor/editing? {edit-input-id true} - :editor/set-timestamp-block nil - :cursor-range cursor-range)))) + (util/profile + "swap! state" + (swap! state + (fn [state] + (-> state + (assoc + :editor/editing? {edit-input-id true} + :editor/set-timestamp-block nil + :cursor-range cursor-range))))) (set-state! :editor/block block) (set-state! :editor/content content :path-in-sub-atom edit-input-id) (set-state! :editor/last-key-code nil)