From c94ad075cb586843e2fa4029045ea6c13d7e18df Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 12:50:16 +0800 Subject: [PATCH 01/11] chore: don't insert first page block when preview --- src/main/frontend/components/block.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index d6bdaf162..0525ccad1 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -420,7 +420,6 @@ [:span.text-sm.mr-2 "Alias:"] page-original-name])]) (let [page (db/entity [:block/name (string/lower-case redirect-page-name)])] - (editor-handler/insert-first-page-block-if-not-exists! redirect-page-name) (when-let [f (state/get-page-blocks-cp)] (f (state/get-current-repo) page {:sidebar? sidebar? :preview? true})))]))] (if (or (not manual?) open?) From 7ead1b5f642ec39b574de9375fd2137abf3eff3d Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 13:19:28 +0800 Subject: [PATCH 02/11] fix: removed delayed open preview as it can slow down editing --- src/main/frontend/components/block.cljs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 0525ccad1..95215c67d 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -380,25 +380,11 @@ (let [s (get page-entity :block/original-name page-name)] (if tag? (str "#" s) s))))])) -(defn- use-delayed-open [open? page-name] - "A react hook to debounce open? value. - If open? changed from false to open, there will be a `timeout` delay. - Otherwise, the value will be changed to false immediately" - (let [[deval set-deval!] (rum/use-state nil)] - (rum/use-effect! - (fn [] - (if open? (let [timer (js/setTimeout #(set-deval! open?) 1000)] - #(js/clearTimeout timer)) - (set-deval! open?))) ;; immediately change - [open? page-name]) - deval)) - (rum/defc page-preview-trigger [{:keys [children sidebar? tippy-position tippy-distance fixed-position? open? manual?] :as config} page-name] (let [redirect-page-name (or (model/get-redirect-page-name page-name (:block/alias? config)) page-name) page-original-name (model/get-page-original-name redirect-page-name) - debounced-open? (use-delayed-open open? page-name) html-template (fn [] (when redirect-page-name [:div.tippy-wrapper.overflow-y-auto.p-4 @@ -420,12 +406,12 @@ [:span.text-sm.mr-2 "Alias:"] page-original-name])]) (let [page (db/entity [:block/name (string/lower-case redirect-page-name)])] + (editor-handler/insert-first-page-block-if-not-exists! redirect-page-name) (when-let [f (state/get-page-blocks-cp)] (f (state/get-current-repo) page {:sidebar? sidebar? :preview? true})))]))] (if (or (not manual?) open?) (ui/tippy {:html html-template :interactive true - :open? debounced-open? :delay [1000, 100] :fixed-position? fixed-position? :position (or tippy-position "top") From 5e9c3ed151990f3fa98de0a7114580d30919764e Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 16:28:57 +0800 Subject: [PATCH 03/11] feat: journals support named template Also, simplified the template code a bit. --- src/main/frontend/components/editor.cljs | 3 +- src/main/frontend/db/model.cljs | 14 ++ src/main/frontend/handler/editor.cljs | 163 ++++++++++-------- src/main/frontend/handler/external.cljs | 8 +- src/main/frontend/handler/page.cljs | 14 +- .../modules/datascript_report/core.cljs | 5 +- src/main/frontend/state.cljs | 6 + templates/config.edn | 5 +- 8 files changed, 132 insertions(+), 86 deletions(-) diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 61c296c05..cafe1f58d 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -174,7 +174,6 @@ (when input (let [current-pos (cursor/pos input) edit-content (state/sub [:editor/content id]) - edit-block (state/sub :editor/block) q (or (when (>= (count edit-content) current-pos) (subs edit-content pos current-pos)) @@ -184,7 +183,7 @@ (state/set-editor-show-template-search! false))] (ui/auto-complete matched-templates - {:on-chosen (editor-handler/template-on-chosen-handler input id q format edit-block edit-content) + {:on-chosen (editor-handler/template-on-chosen-handler id) :on-enter non-exist-handler :empty-div [:div.text-gray-500.pl-4.pr-4 "Search for a template"] :item-render (fn [[template _block-db-id]] diff --git a/src/main/frontend/db/model.cljs b/src/main/frontend/db/model.cljs index 268353a9b..32e660b23 100644 --- a/src/main/frontend/db/model.cljs +++ b/src/main/frontend/db/model.cljs @@ -1183,6 +1183,20 @@ [(get m :template) e])) (into {})))) +(defn get-template-by-name + [name] + (when (string? name) + (->> (d/q + '[:find (pull ?b [*]) + :in $ ?name + :where + [?b :block/properties ?p] + [(get ?p :template) ?t] + [(= ?t ?name)]] + (conn/get-conn) + name) + ffirst))) + (defonce blocks-count-cache (atom nil)) (defn blocks-count diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 3531dc8f9..83999080d 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -390,9 +390,10 @@ (defn- compute-fst-snd-block-text [value pos] - (let [fst-block-text (subs value 0 pos) - snd-block-text (string/triml (subs value pos))] - [fst-block-text snd-block-text])) + (when (string? value) + (let [fst-block-text (subs value 0 pos) + snd-block-text (string/triml (subs value pos))] + [fst-block-text snd-block-text]))) (defn outliner-insert-block! [config current-block new-block sibling?] @@ -2017,42 +2018,43 @@ m))))) (defn paste-block-vec-tree-at-target - ([tree exclude-properties] - (paste-block-vec-tree-at-target tree exclude-properties nil nil nil)) - ([tree exclude-properties content-update-fn] - (paste-block-vec-tree-at-target tree exclude-properties content-update-fn nil nil)) - ([tree exclude-properties content-update-fn get-pos-fn page-block] - (let [repo (state/get-current-repo) - page (or page-block - (:block/page (db/entity (:db/id (state/get-edit-block))))) - file (:block/file page)] - (when-let [[target-block sibling? delete-editing-block? editing-block] - ((or get-pos-fn get-block-tree-insert-pos-at-point))] - (let [target-block (outliner-core/block target-block) - editing-block (outliner-core/block editing-block) - format (or (:block/format target-block) (state/get-preferred-format)) - new-block-uuids (atom #{}) - metadata-replaced-blocks - (zip/root - (loop [loc (zip/vector-zip tree)] - (if (zip/end? loc) - loc - (if (vector? (zip/node loc)) - (recur (zip/next loc)) - (let [uuid (random-uuid)] - (swap! new-block-uuids (fn [acc uuid] (conj acc uuid)) uuid) - (recur (zip/next (zip/edit - loc - (paste-block-tree-at-point-edit-aux - uuid file page exclude-properties format content-update-fn))))))))) - _ (outliner-core/save-node editing-block) - _ (outliner-core/insert-nodes metadata-replaced-blocks target-block sibling?) - _ (when delete-editing-block? - (when-let [id (:db/id (outliner-core/get-data editing-block))] - (outliner-core/delete-node (outliner-core/block (db/pull id)) true))) - new-blocks (db/pull-many repo '[*] (map (fn [id] [:block/uuid id]) @new-block-uuids))] - (db/refresh! repo {:key :block/insert :data new-blocks}) - (last metadata-replaced-blocks)))))) + [tree exclude-properties {:keys [content-update-fn + get-pos-fn + page-block] + :as opts}] + (let [repo (state/get-current-repo) + page (or page-block + (:block/page (db/entity (:db/id (state/get-edit-block))))) + file (:block/file page) + [target-block sibling? delete-editing-block? editing-block] + ((or get-pos-fn get-block-tree-insert-pos-at-point))] + (when target-block + (let [target-block (outliner-core/block target-block) + format (or (:block/format target-block) (state/get-preferred-format)) + new-block-uuids (atom #{}) + metadata-replaced-blocks + (zip/root + (loop [loc (zip/vector-zip tree)] + (if (zip/end? loc) + loc + (if (vector? (zip/node loc)) + (recur (zip/next loc)) + (let [uuid (random-uuid)] + (swap! new-block-uuids (fn [acc uuid] (conj acc uuid)) uuid) + (recur (zip/next (zip/edit + loc + (paste-block-tree-at-point-edit-aux + uuid file page exclude-properties format content-update-fn))))))))) + _ (when editing-block + (let [editing-block (outliner-core/block editing-block)] + (outliner-core/save-node editing-block))) + _ (outliner-core/insert-nodes metadata-replaced-blocks target-block sibling?) + _ (when (and delete-editing-block? editing-block) + (when-let [id (:db/id editing-block)] + (outliner-core/delete-node (outliner-core/block (db/pull id)) true))) + new-blocks (db/pull-many repo '[*] (map (fn [id] [:block/uuid id]) @new-block-uuids))] + (db/refresh! repo {:key :block/insert :data new-blocks}) + (last metadata-replaced-blocks))))) (defn- tree->vec-tree "tree: @@ -2105,45 +2107,58 @@ page-block (if (:block/name target-block) target-block (db/entity (:db/id (:block/page (db/pull target-block-id))))) ;; sibling? = false, when target-block is a page-block - sibling? (if (= target-block-id (:db/id page-block)) + sibling? (if (= target-block-id (:db/id page-block)) false sibling?)] (paste-block-vec-tree-at-target - block-tree [] nil - #(get-block-tree-insert-pos-after-target target-block-id sibling?) - page-block))) + block-tree [] + {:get-pos-fn #(get-block-tree-insert-pos-after-target target-block-id sibling?) + :page-block page-block}))) + +(defn insert-template! + ([element-id db-id] + (insert-template! element-id db-id {})) + ([element-id db-id opts] + (let [db-id (if (integer? db-id) + db-id + (:db/id (db-model/get-template-by-name (name db-id))))] + (when-let [repo (state/get-current-repo) + block (db/entity db-id) + format (:block/format block) + block-uuid (:block/uuid block) + template-including-parent? (not (false? (:template-including-parent (:block/properties block)))) + blocks (db/get-block-and-children repo block-uuid) + level-blocks (vals (blocks-with-level blocks)) + [root-block & blocks-exclude-root] level-blocks + root-block (assoc root-block :level 1) + sorted-blocks (tree/sort-blocks blocks-exclude-root root-block) + result-blocks (if template-including-parent? sorted-blocks (drop 1 sorted-blocks)) + tree (blocks-vec->tree result-blocks)] + (when element-id + (insert-command! element-id "" format {})) + (let [opts (merge + {:content-update-fn (fn [content] + (->> content + (property/remove-property format "template") + (property/remove-property format "template-including-parent") + template/resolve-dynamic-template!))} + opts) + last-block (paste-block-vec-tree-at-target tree [:id :template :template-including-parent] opts)] + (clear-when-saved!) + (db/refresh! repo {:key :block/insert :data [(db/pull db-id)]}) + ;; FIXME: + ;; (js/setTimeout + ;; #(edit-block! {:block/uuid (:block/uuid last-block)} :max nil (:block/uuid last-block)) + ;; 100) + ))) + + (when-let [input (gdom/getElement element-id)] + (.focus input)))) (defn template-on-chosen-handler - [_input id _q format _edit-block _edit-content] + [element-id] (fn [[_template db-id] _click?] - (let [repo (state/get-current-repo) - block (db/entity db-id) - block-uuid (:block/uuid block) - template-including-parent? (not (false? (:template-including-parent (:block/properties block)))) - blocks (if template-including-parent? (db/get-block-and-children repo block-uuid) (db/get-block-children repo block-uuid)) - level-blocks (vals (blocks-with-level blocks)) - grouped-blocks (group-by #(= db-id (:db/id %)) level-blocks) - root-block (or (first (get grouped-blocks true)) (assoc (db/pull db-id) :level 1)) - blocks-exclude-root (get grouped-blocks false) - sorted-blocks (tree/sort-blocks blocks-exclude-root root-block) - result-blocks (if template-including-parent? sorted-blocks (drop 1 sorted-blocks)) - tree (blocks-vec->tree result-blocks)] - (insert-command! id "" format {}) - (let [last-block (paste-block-vec-tree-at-target tree [:template :template-including-parent] - (fn [content] - (->> content - (property/remove-property format "template") - (property/remove-property format "template-including-parent") - template/resolve-dynamic-template!)))] - (clear-when-saved!) - (db/refresh! repo {:key :block/insert :data [(db/pull db-id)]}) - ;; FIXME: - ;; (js/setTimeout - ;; #(edit-block! {:block/uuid (:block/uuid last-block)} :max nil (:block/uuid last-block)) - ;; 100) - )) - (when-let [input (gdom/getElement id)] - (.focus input)))) + (insert-template! element-id db-id))) (defn parent-is-page? [{{:block/keys [parent page]} :data :as node}] @@ -2674,7 +2689,7 @@ tree* (->> tree (mapv #(assoc % :level (- (:block/level %) prefix-level))) (blocks-vec->tree))] - (paste-block-vec-tree-at-target tree* []))) + (paste-block-vec-tree-at-target tree* [] nil))) (defn- paste-segmented-text [format text] @@ -2706,7 +2721,7 @@ (string/replace (string/trim (:copy/content copied-blocks)) "\r" ""))) (do ;; copy from logseq internally - (paste-block-vec-tree-at-target copied-block-tree []) + (paste-block-vec-tree-at-target copied-block-tree [] nil) (util/stop e)) (do diff --git a/src/main/frontend/handler/external.cljs b/src/main/frontend/handler/external.cljs index 04fbb2a31..49ea3a43e 100644 --- a/src/main/frontend/handler/external.cljs +++ b/src/main/frontend/handler/external.cljs @@ -85,8 +85,8 @@ [page-block false])) tree (editor/blocks->tree-by-level parsed-blocks)] (editor/paste-block-vec-tree-at-target - tree [] nil - #(editor/get-block-tree-insert-pos-after-target - (:db/id target-block) sibling?) - page-block) + tree [] + {:get-pos-fn #(editor/get-block-tree-insert-pos-after-target + (:db/id target-block) sibling?) + :page-block page-block}) (finished-ok-handler [page-name]))))) diff --git a/src/main/frontend/handler/page.cljs b/src/main/frontend/handler/page.cljs index 61418e0aa..2b92379c2 100644 --- a/src/main/frontend/handler/page.cljs +++ b/src/main/frontend/handler/page.cljs @@ -585,7 +585,17 @@ (let [path (config/get-config-path)] (db/get-file path)))) (let [title (date/today) - today-page (string/lower-case title)] + today-page (string/lower-case title) + template (state/get-default-journal-template)] (when (db/page-empty? repo today-page) (create! title {:redirect? false - :create-first-block? true})))))) + :create-first-block? (not template)}) + (when template + (let [page (db/pull [:block/name today-page])] + (editor-handler/insert-template! + nil + template + {:get-pos-fn (fn [] + [page false false false]) + :page-block page}) + (ui-handler/re-render-root!)))))))) diff --git a/src/main/frontend/modules/datascript_report/core.cljs b/src/main/frontend/modules/datascript_report/core.cljs index 498165e4a..fd9136073 100644 --- a/src/main/frontend/modules/datascript_report/core.cljs +++ b/src/main/frontend/modules/datascript_report/core.cljs @@ -20,7 +20,10 @@ (let [r (safe-pull db-before '[*] db-id)] (when (= keys-of-deleted-entity (count r)) ;; TODO: What can cause this happen? - (log/error :outliner-pipeline/cannot-find-entity {:entity r})) + (js/console.error {:db-id db-id + :entity r}) + (log/error :outliner-pipeline/cannot-find-entity {:db-id db-id + :entity r})) r) r))) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index cffe66655..f9d0e00f2 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -219,6 +219,12 @@ [] (:custom-css-url (get-config))) +(defn get-default-journal-template + [] + (when-let [template (get-in (get-config) [:default-templates :journals])] + (when-not (string/blank? template) + (string/trim template)))) + (defn all-pages-public? [] (let [value (:publishing/all-pages-public? (get-config)) diff --git a/templates/config.edn b/templates/config.edn index e6e580af1..d191d4b59 100644 --- a/templates/config.edn +++ b/templates/config.edn @@ -13,9 +13,8 @@ ;; E.g. "/archived" "/test.md" :hidden [] - ;; When creating the new journal page, the app will use your template content here. - ;; Example for Markdown users: "[[Work]]\n -\n- [[Family]]\n -\n" - ;; Example for Org mode users: "** [[Work]]\n***\n** [[Family]]\n***\n" + ;; When creating the new journal page, the app will use your template if there is one. + ;; You only need to input your template name here. :default-templates {:journals ""} From 0ec534fbcff5f585268c580e7c4bf3a65162373d Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 16:30:04 +0800 Subject: [PATCH 04/11] fix: oops, wrong position for when-let --- src/main/frontend/handler/editor.cljs | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 83999080d..ee526fb54 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -2119,21 +2119,21 @@ ([element-id db-id] (insert-template! element-id db-id {})) ([element-id db-id opts] - (let [db-id (if (integer? db-id) - db-id - (:db/id (db-model/get-template-by-name (name db-id))))] - (when-let [repo (state/get-current-repo) - block (db/entity db-id) - format (:block/format block) - block-uuid (:block/uuid block) - template-including-parent? (not (false? (:template-including-parent (:block/properties block)))) - blocks (db/get-block-and-children repo block-uuid) - level-blocks (vals (blocks-with-level blocks)) - [root-block & blocks-exclude-root] level-blocks - root-block (assoc root-block :level 1) - sorted-blocks (tree/sort-blocks blocks-exclude-root root-block) - result-blocks (if template-including-parent? sorted-blocks (drop 1 sorted-blocks)) - tree (blocks-vec->tree result-blocks)] + (when-let [db-id (if (integer? db-id) + db-id + (:db/id (db-model/get-template-by-name (name db-id))))] + (let [repo (state/get-current-repo) + block (db/entity db-id) + format (:block/format block) + block-uuid (:block/uuid block) + template-including-parent? (not (false? (:template-including-parent (:block/properties block)))) + blocks (db/get-block-and-children repo block-uuid) + level-blocks (vals (blocks-with-level blocks)) + [root-block & blocks-exclude-root] level-blocks + root-block (assoc root-block :level 1) + sorted-blocks (tree/sort-blocks blocks-exclude-root root-block) + result-blocks (if template-including-parent? sorted-blocks (drop 1 sorted-blocks)) + tree (blocks-vec->tree result-blocks)] (when element-id (insert-command! element-id "" format {})) (let [opts (merge From c8e22f22ac68ab2ffccccd245c2001cfe401950c Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 17:59:44 +0800 Subject: [PATCH 05/11] fix: alias in search auto-complete --- src/main/frontend/components/search.cljs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/frontend/components/search.cljs b/src/main/frontend/components/search.cljs index d52b7db1b..79c143c84 100644 --- a/src/main/frontend/components/search.cljs +++ b/src/main/frontend/components/search.cljs @@ -141,9 +141,14 @@ (rum/defc search-auto-complete [{:keys [pages files blocks has-more?] :as result} search-q all?] (rum/with-context [[t] i18n/*tongue-context*] - (let [pages (when-not all? (map (fn [page] {:type :page - :data page - :alias (model/get-redirect-page-name page)}) pages)) + (let [pages (when-not all? (map (fn [page] + (let [alias (model/get-redirect-page-name page)] + (cond-> + {:type :page + :data page} + (not= (string/lower-case page) + (string/lower-case alias)) + (assoc :alias alias)))) pages)) files (when-not all? (map (fn [file] {:type :file :data file}) files)) blocks (map (fn [block] {:type :block :data block}) blocks) search-mode (state/sub :search/mode) From 27c7488003e2d8088accbdb12760a6ca1c8dcb47 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 20:25:01 +0800 Subject: [PATCH 06/11] perf: block rendering --- src/main/frontend/components/block.cljs | 29 ++++++++++++------------- src/main/frontend/handler/editor.cljs | 3 ++- yarn.lock | 5 ----- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 95215c67d..ab6c5264d 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -1232,7 +1232,7 @@ (:block/uuid child)))))])))) (rum/defcs block-control < rum/reactive - [state config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id] + [state config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit?] (let [has-children-blocks? (and (coll? children) (seq children)) has-child? (and (not (:pre-block? block)) @@ -1249,8 +1249,7 @@ empty-content? (string/blank? (property/remove-built-in-properties (:block/format block) - (:block/content block))) - edit? (state/sub [:editor/editing? edit-input-id])] + (:block/content block)))] [:div.mr-2.flex.flex-row.items-center {:style {:height 24 :margin-top 0 @@ -1686,9 +1685,8 @@ (str uuid "-" idx)))))])]]])) (rum/defc block-content-or-editor < rum/reactive - [config {:block/keys [uuid title body meta content page format repo children marker properties pre-block? idx] :as block} edit-input-id block-id slide? heading-level] + [config {:block/keys [uuid title body meta content page format repo children marker properties pre-block? idx] :as block} edit-input-id block-id slide? heading-level edit?] (let [editor-box (get config :editor-box) - edit? (state/sub [:editor/editing? edit-input-id]) editor-id (str "editor-" edit-input-id) slide? (:slide? config)] (if (and edit? editor-box) @@ -1896,7 +1894,7 @@ ;; :ref? true ;; :ref-child? true))])))) -(rum/defcs block-container < rum/static +(rum/defcs block-container < rum/reactive {:init (fn [state] (let [[config block] (:rum/args state) ref-collpased? (boolean @@ -1910,12 +1908,14 @@ ::control-show? (atom false) ::ref-collapsed? (atom ref-collpased?)))) :should-update (fn [old-state new-state] - (not= (:block/content (second (:rum/args old-state))) - (:block/content (second (:rum/args new-state)))))} + (let [compare-keys [:block/uuid :block/properties + :block/parent :block/left + :block/children :block/content]] + (not= (select-keys (second (:rum/args old-state)) compare-keys) + (select-keys (second (:rum/args new-state)) compare-keys))))} [state config {:block/keys [uuid title body meta content page format repo children pre-block? top? properties refs path-refs heading-level level type idx] :as block}] (let [blocks-container-id (:blocks-container-id config) config (update config :block merge block) - ;; Each block might have multiple queries, but we store only the first query's result config (if (nil? (:query-result config)) (assoc config :query-result (atom nil)) @@ -1941,7 +1941,8 @@ attrs (on-drag-and-mouse-attrs block uuid top? block-id *move-to has-child? *control-show? doc-mode?) data-refs (build-refs-data-value block (remove (set refs) path-refs)) data-refs-self (build-refs-data-value block refs) - edit-input-id (str "edit-block-" blocks-container-id "-" uuid)] + edit-input-id (str "edit-block-" blocks-container-id "-" uuid) + edit? (state/sub [:editor/editing? edit-input-id])] [:div.ls-block.flex.flex-col.rounded-sm (cond-> {:id block-id @@ -1979,9 +1980,9 @@ :on-mouse-leave (fn [e] (block-mouse-leave e has-child? *control-show? block-id doc-mode?))} (when (not slide?) - (block-control config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id)) + (block-control config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit?)) - (block-content-or-editor config block edit-input-id block-id slide? heading-level)] + (block-content-or-editor config block edit-input-id block-id slide? heading-level edit?)] (block-children config children collapsed? *ref-collapsed?) @@ -2513,9 +2514,7 @@ (assoc :block/top? (zero? idx) :block/bottom? (= (count blocks) (inc idx)))) config (assoc config :block/uuid (:block/uuid item))] - (rum/with-key - (block-container config item) - (:block/uuid item))))) + (block-container config item)))) (defonce ignore-scroll? (atom false)) (rum/defcs lazy-blocks < diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index ee526fb54..bf34aa4f4 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -446,7 +446,8 @@ (:block/uuid first-block)) blocks-container-id (when-let [id (:id config)] (and (util/uuid-string? id) (medley/uuid id)))] - (let [new-last-block (let [first-block-id {:db/id (:db/id first-block)}] + (let [new-last-block (let [first-block-uuid (:block/uuid (db/entity (:db/id first-block))) + first-block-id {:db/id (:db/id first-block)}] (assoc last-block :block/left first-block-id :block/parent (if child? diff --git a/yarn.lock b/yarn.lock index 784cc169f..9e82cb470 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7598,11 +7598,6 @@ react-grid-layout@^0.16.6: react-draggable "3.x" react-resizable "1.x" -react-icon-base@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.1.0.tgz#a196e33fdf1e7aaa1fda3aefbb68bdad9e82a79d" - integrity sha1-oZbjP98eeqof2jrvu2i9rZ6Cp50= - react-icons@^2.2.7: version "2.2.7" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650" From 5131c60bfcd20655ce328aeb6f899d5a30efb464 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 20:57:54 +0800 Subject: [PATCH 07/11] perf: block rendering --- src/main/frontend/components/block.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index ab6c5264d..80d8afeb1 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2514,7 +2514,8 @@ (assoc :block/top? (zero? idx) :block/bottom? (= (count blocks) (inc idx)))) config (assoc config :block/uuid (:block/uuid item))] - (block-container config item)))) + (rum/with-key (block-container config item) + (str (:block/uuid item)))))) (defonce ignore-scroll? (atom false)) (rum/defcs lazy-blocks < From 689330ceb3c467ab6af6ce8921ebaf4b8d61f0c1 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 21:38:17 +0800 Subject: [PATCH 08/11] feat: add :ui/show-empty-bullets? option The empty bullets will be hidden by default in the default mode. Also, hovering an empty block should display its bullet. --- src/main/frontend/components/block.cljs | 63 +++++++++++++++---------- templates/config.edn | 3 ++ 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 80d8afeb1..919479bff 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -1216,7 +1216,7 @@ (when (and (coll? children) (seq children) (not collapsed?)) - (let [doc-mode? (:document/mode? config)] + (let [doc-mode? (state/sub :document/mode?)] [:div.block-children {:style {:margin-left (if doc-mode? 12 21) :display (if collapsed? "none" "")}} (for [child children] @@ -1232,8 +1232,9 @@ (:block/uuid child)))))])))) (rum/defcs block-control < rum/reactive - [state config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit?] - (let [has-children-blocks? (and (coll? children) (seq children)) + [state config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit? doc-mode?] + (let [doc-mode? (state/sub :document/mode?) + has-children-blocks? (and (coll? children) (seq children)) has-child? (and (not (:pre-block? block)) (or has-children-blocks? (seq body))) @@ -1270,25 +1271,37 @@ (editor-handler/collapse-block! uuid)))))} [:span {:class (if control-show? "control-show" "control-hide")} (ui/rotating-arrow collapsed?)]] - (if (and empty-content? (not edit?) - (not (:block/top? block)) - (not (:block/bottom? block))) - [:span.bullet-container] + (let [bullet [:a {:on-click (fn [e] + (bullet-on-click e block config uuid))} + [:span.bullet-container.cursor + {:id (str "dot-" uuid) + :draggable true + :on-drag-start (fn [event] + (bullet-drag-start event block uuid block-id)) + :blockid (str uuid) + :class (str (when collapsed? "bullet-closed") + " " + (when (and (:document/mode? config) + (not collapsed?)) + "hide-inner-bullet"))} + [:span.bullet {:blockid (str uuid)}]]]] + (cond + (and (:ui/show-empty-bullets? (state/get-config)) (not doc-mode?)) + bullet - [:a {:on-click (fn [e] - (bullet-on-click e block config uuid))} - [:span.bullet-container.cursor - {:id (str "dot-" uuid) - :draggable true - :on-drag-start (fn [event] - (bullet-drag-start event block uuid block-id)) - :blockid (str uuid) - :class (str (when collapsed? "bullet-closed") - " " - (when (and (:document/mode? config) - (not collapsed?)) - "hide-inner-bullet"))} - [:span.bullet {:blockid (str uuid)}]]])])) + (or + (and empty-content? (not edit?) + (not (:block/top? block)) + (not (:block/bottom? block)) + (not (util/react *control-show?))) + (and doc-mode? + (not collapsed?) + (not (util/react *control-show?)))) + ;; hidden + [:span.bullet-container] + + :else + bullet))])) (rum/defc dnd-separator [block move-to block-content?] @@ -1841,8 +1854,7 @@ (defn- block-mouse-over [e has-child? *control-show? block-id doc-mode?] (util/stop e) - (when has-child? - (reset! *control-show? true)) + (reset! *control-show? true) (when-let [parent (gdom/getElement block-id)] (let [node (.querySelector parent ".bullet-container")] (when doc-mode? @@ -1856,8 +1868,7 @@ (defn- block-mouse-leave [e has-child? *control-show? block-id doc-mode?] (util/stop e) - (when has-child? - (reset! *control-show? false)) + (reset! *control-show? false) (when doc-mode? (when-let [parent (gdom/getElement block-id)] (when-let [node (.querySelector parent ".bullet-container")] @@ -1980,7 +1991,7 @@ :on-mouse-leave (fn [e] (block-mouse-leave e has-child? *control-show? block-id doc-mode?))} (when (not slide?) - (block-control config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit?)) + (block-control config block uuid block-id body children collapsed? *ref-collapsed? *control-show? edit-input-id edit? doc-mode?)) (block-content-or-editor config block edit-input-id block-id slide? heading-level edit?)] diff --git a/templates/config.edn b/templates/config.edn index d191d4b59..f6518145c 100644 --- a/templates/config.edn +++ b/templates/config.edn @@ -95,6 +95,9 @@ ;; Whether to show command doc on hover :ui/show-command-doc? true + ;; Whether to show empty bullets for non-document mode (the default mode) + :ui/show-empty-bullets? false + ;; The app will show those queries in today's journal page, ;; the "NOW" query asks the tasks which need to be finished "now", ;; the "NEXT" query asks the future tasks. From 37833239c0900d7332d73560076d316c6ca341ae Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Aug 2021 21:51:29 +0800 Subject: [PATCH 09/11] chore: bump version --- resources/package.json | 2 +- src/main/frontend/version.cljs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/package.json b/resources/package.json index 1eb308e81..0c9ae2d83 100644 --- a/resources/package.json +++ b/resources/package.json @@ -1,6 +1,6 @@ { "name": "Logseq", - "version": "0.3.0", + "version": "0.3.1", "main": "electron.js", "author": "Logseq", "description": "A privacy-first, open-source platform for knowledge management and collaboration.", diff --git a/src/main/frontend/version.cljs b/src/main/frontend/version.cljs index 592782cf9..6ac036d9b 100644 --- a/src/main/frontend/version.cljs +++ b/src/main/frontend/version.cljs @@ -1,3 +1,3 @@ (ns frontend.version) -(defonce version "0.3.0") +(defonce version "0.3.1") From e2101e9791fd59f53f83ea16020752b42eac6189 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Wed, 4 Aug 2021 08:22:08 +0800 Subject: [PATCH 10/11] fix: templates without parent fix #2546 --- src/main/frontend/handler/editor.cljs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index bf34aa4f4..62f5984e8 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -2128,10 +2128,11 @@ format (:block/format block) block-uuid (:block/uuid block) template-including-parent? (not (false? (:template-including-parent (:block/properties block)))) - blocks (db/get-block-and-children repo block-uuid) + blocks (if template-including-parent? (db/get-block-and-children repo block-uuid) (db/get-block-children repo block-uuid)) level-blocks (vals (blocks-with-level blocks)) - [root-block & blocks-exclude-root] level-blocks - root-block (assoc root-block :level 1) + grouped-blocks (group-by #(= db-id (:db/id %)) level-blocks) + root-block (or (first (get grouped-blocks true)) (assoc (db/pull db-id) :level 1)) + blocks-exclude-root (get grouped-blocks false) sorted-blocks (tree/sort-blocks blocks-exclude-root root-block) result-blocks (if template-including-parent? sorted-blocks (drop 1 sorted-blocks)) tree (blocks-vec->tree result-blocks)] From 2c51982a6b352a221b6e0941faaf59330a2f4bdf Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Wed, 4 Aug 2021 08:37:44 +0800 Subject: [PATCH 11/11] fix: Alias not working correctly close #2542 --- src/main/frontend/handler/extract.cljs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/frontend/handler/extract.cljs b/src/main/frontend/handler/extract.cljs index 04bc18cb5..40640a5ab 100644 --- a/src/main/frontend/handler/extract.cljs +++ b/src/main/frontend/handler/extract.cljs @@ -79,9 +79,9 @@ :block/path-refs block-path-ref-pages)))) blocks) page-entity (let [page-file? (= page (string/lower-case file)) - aliases (and (:alias properties) - (seq (remove #(= page %) - (:alias properties)))) + alias (:alias properties) + alias (if (string? alias) [alias] alias) + aliases (and alias (seq (remove #(= page %) alias))) page-list (when-let [list-content (:list properties)] (extract-page-list list-content))] (cond-> @@ -113,8 +113,9 @@ aliases)) (:tags properties) - (assoc :block/tags (let [tags (->> (:tags properties) - (remove string/blank?))] + (assoc :block/tags (let [tags (:tags properties) + tags (if (string? tags) [tags] tags) + tags (remove string/blank? tags)] (swap! ref-tags set/union (set tags)) (map (fn [tag] {:block/name (string/lower-case tag) :block/original-name tag})