From 27198738fd1a893c47862b077a2e98e1cbb58f5f Mon Sep 17 00:00:00 2001 From: Andelf Date: Thu, 25 Jan 2024 16:36:20 +0800 Subject: [PATCH 01/16] fix(android): sync crash caused by wrong logging See-also: #10916 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5172c28fa..27b1368b5 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@excalidraw/excalidraw": "0.16.1", "@highlightjs/cdn-assets": "10.4.1", "@isomorphic-git/lightning-fs": "^4.6.0", - "@logseq/capacitor-file-sync": "5.0.1", + "@logseq/capacitor-file-sync": "5.0.2", "@logseq/diff-merge": "0.2.2", "@logseq/react-tweet-embed": "1.3.1-1", "@radix-ui/colors": "^0.1.8", diff --git a/yarn.lock b/yarn.lock index 5a17b5893..f4793eece 100644 --- a/yarn.lock +++ b/yarn.lock @@ -496,10 +496,10 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@logseq/capacitor-file-sync@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-5.0.1.tgz#e154f715597785518ccd7d058f353acb67fbc2b8" - integrity sha512-C1fLSS53orxsUWBsNb6LKwuOdlEU9ZhxkweMjNKG9VaSkLFTFqpjFG36OTso23WQ7hC5e45jjXq79aoWuqJaKA== +"@logseq/capacitor-file-sync@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-5.0.2.tgz#10c56e35b41b1a0afd293c9b045fbcfe150c3477" + integrity sha512-FymsTeRtF66zG+oeO+ohZxWICMQMC8An4n9pdI0zz1WaGLer4oWC/lUghlC2DpztRLA32p0CH28tEzF5+2jARg== "@logseq/diff-merge@0.2.2": version "0.2.2" From 402ee7870db137ffcba5b024a8028180ed522d3f Mon Sep 17 00:00:00 2001 From: Andelf Date: Fri, 26 Jan 2024 19:04:51 +0800 Subject: [PATCH 02/16] fix(mobile): build search index with simpler preprocessing rules See-also: #10771 --- src/main/frontend/search/db.cljs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/frontend/search/db.cljs b/src/main/frontend/search/db.cljs index 6a01679c8..d43186505 100644 --- a/src/main/frontend/search/db.cljs +++ b/src/main/frontend/search/db.cljs @@ -20,8 +20,10 @@ (some-> content (util/search-normalize (state/enable-search-remove-accents?)))) -(defn block->index - "Convert a block to the index for searching" +(defn- strict-block->index + "Convert a block to the index for searching. + + Applies full text preprocessing to the content, including removing built-in properties" [{:block/keys [uuid page content format] :as block :or {format :markdown}}] (when-not (> (count content) (max-len)) @@ -32,6 +34,21 @@ :page page :content (sanitize content)})))) +(defn- loose-block->index + "Convert a block to the index for searching + + For speed, applies no preprocessing to the content" + [{:block/keys [uuid page content] :as block}] + (when-not (string/blank? content) + {:id (:db/id block) + :uuid (str uuid) + :page page + :content content})) + +(defonce block->index (if (util/electron?) + strict-block->index + loose-block->index)) + (defn page->index "Convert a page name to the index for searching (page content level) Generate index based on the DB content AT THE POINT OF TIME" From 7bad07d2bf98266789844610f7e18eb838ccb940 Mon Sep 17 00:00:00 2001 From: Andelf Date: Thu, 25 Jan 2024 13:09:16 +0800 Subject: [PATCH 03/16] fix(mobile): commit composing text before cycle todo Close #10879 Close #8503 Close #10013 --- src/main/frontend/handler/editor.cljs | 20 ++++++++++++-------- src/main/frontend/mobile/mobile_bar.cljs | 11 ++++++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 08f7420f5..73d2c0fee 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -740,17 +740,21 @@ (let [[new-content _] (marker/cycle-marker content marker new-marker format (state/get-preferred-workflow))] (save-block-if-changed! block new-content)))) +(defn cycle-todo-by-block-ids! + [ids] + (when-let [ids (filter uuid? (distinct ids))] + (outliner-tx/transact! {:outliner-op :cycle-todos} + (doseq [id ids] + (let [block (db/pull [:block/uuid id])] + (when (not-empty (:block/content block)) + (set-marker block))))))) + (defn cycle-todos! [] (when-let [blocks (seq (get-selected-blocks))] - (let [ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")] - (uuid id)) blocks)) - (remove nil?))] - (outliner-tx/transact! {:outliner-op :cycle-todos} - (doseq [id ids] - (let [block (db/pull [:block/uuid id])] - (when (not-empty (:block/content block)) - (set-marker block)))))))) + (let [ids (map #(when-let [id (dom/attr % "blockid")] + (uuid id)) blocks)] + (cycle-todo-by-block-ids! ids)))) (defn cycle-todo! [] diff --git a/src/main/frontend/mobile/mobile_bar.cljs b/src/main/frontend/mobile/mobile_bar.cljs index 593817ee6..233e78f1d 100644 --- a/src/main/frontend/mobile/mobile_bar.cljs +++ b/src/main/frontend/mobile/mobile_bar.cljs @@ -91,7 +91,16 @@ (command #(if (state/sub :document/mode?) (editor-handler/insert-new-block! nil) (commands/simple-insert! parent-id "\n" {})) {:icon "arrow-back"}) - (command editor-handler/cycle-todo! {:icon "checkbox"} true) + ;; On mobile devies, some IME(keyboard) uses composing mode. + ;; The composing text can be committed by losing focus. + ;; 100ms is enough to commit the composing text to db. + (command #(when-let [block-id (:block/uuid (state/get-edit-block))] + (editor-handler/escape-editing true) + (js/setTimeout + (fn [] + (editor-handler/cycle-todo-by-block-ids! [block-id])) + 100)) + {:icon "checkbox"} true) (command #(mobile-camera/embed-photo parent-id) {:icon "camera"} true) (command history/undo! {:icon "rotate" :class "rotate-180"} true) (command history/redo! {:icon "rotate-clockwise" :class "rotate-180"} true) From 03d4b272b2243f27a1d43fec21e228631641c431 Mon Sep 17 00:00:00 2001 From: Andelf Date: Thu, 25 Jan 2024 20:48:58 +0800 Subject: [PATCH 04/16] fix(android): blur input when composing --- src/main/frontend/handler/editor.cljs | 20 ++++++++------------ src/main/frontend/mobile/mobile_bar.cljs | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 73d2c0fee..08f7420f5 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -740,21 +740,17 @@ (let [[new-content _] (marker/cycle-marker content marker new-marker format (state/get-preferred-workflow))] (save-block-if-changed! block new-content)))) -(defn cycle-todo-by-block-ids! - [ids] - (when-let [ids (filter uuid? (distinct ids))] - (outliner-tx/transact! {:outliner-op :cycle-todos} - (doseq [id ids] - (let [block (db/pull [:block/uuid id])] - (when (not-empty (:block/content block)) - (set-marker block))))))) - (defn cycle-todos! [] (when-let [blocks (seq (get-selected-blocks))] - (let [ids (map #(when-let [id (dom/attr % "blockid")] - (uuid id)) blocks)] - (cycle-todo-by-block-ids! ids)))) + (let [ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")] + (uuid id)) blocks)) + (remove nil?))] + (outliner-tx/transact! {:outliner-op :cycle-todos} + (doseq [id ids] + (let [block (db/pull [:block/uuid id])] + (when (not-empty (:block/content block)) + (set-marker block)))))))) (defn cycle-todo! [] diff --git a/src/main/frontend/mobile/mobile_bar.cljs b/src/main/frontend/mobile/mobile_bar.cljs index 233e78f1d..023920b2a 100644 --- a/src/main/frontend/mobile/mobile_bar.cljs +++ b/src/main/frontend/mobile/mobile_bar.cljs @@ -13,11 +13,21 @@ [goog.dom :as gdom] [rum.core :as rum])) + +(defn- blur-if-compositing + "Call blur on the textarea if it is in composition mode, let the IME commit the composing text" + [] + (when-let [edit-input-id (and (state/editor-in-composition?) + (state/get-edit-input-id))] + (let [textarea-el (gdom/getElement edit-input-id)] + (.blur textarea-el)))) + (rum/defc indent-outdent [indent? icon] [:div [:button.bottom-action {:on-mouse-down (fn [e] (util/stop e) + (blur-if-compositing) (editor-handler/indent-outdent indent?))} (ui/icon icon {:size ui/icon-size})]]) @@ -94,12 +104,9 @@ ;; On mobile devies, some IME(keyboard) uses composing mode. ;; The composing text can be committed by losing focus. ;; 100ms is enough to commit the composing text to db. - (command #(when-let [block-id (:block/uuid (state/get-edit-block))] - (editor-handler/escape-editing true) - (js/setTimeout - (fn [] - (editor-handler/cycle-todo-by-block-ids! [block-id])) - 100)) + (command #(do + (blur-if-compositing) + (editor-handler/cycle-todo!)) {:icon "checkbox"} true) (command #(mobile-camera/embed-photo parent-id) {:icon "camera"} true) (command history/undo! {:icon "rotate" :class "rotate-180"} true) From 8f736e82c735f1339349ca313dbf079191c925ac Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Mon, 29 Jan 2024 08:50:42 -0500 Subject: [PATCH 05/16] fix lint --- src/main/frontend/handler/common/page.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/frontend/handler/common/page.cljs b/src/main/frontend/handler/common/page.cljs index b7c5008af..c52653557 100644 --- a/src/main/frontend/handler/common/page.cljs +++ b/src/main/frontend/handler/common/page.cljs @@ -20,7 +20,6 @@ [logseq.db :as ldb] [frontend.db.conn :as conn] [datascript.core :as d] - [frontend.handler.editor :as editor-handler] [frontend.modules.outliner.ui :as ui-outliner-tx] [logseq.outliner.core :as outliner-core])) From 28e637e8555f81dbf7aaaa8a03410bbaaa90ba62 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Mon, 29 Jan 2024 09:55:34 -0500 Subject: [PATCH 06/16] chore: merge 2 new property fns together refactor possible since page-name-sanity-lc in common-util --- deps/db/src/logseq/db/frontend/property/util.cljs | 13 +------------ deps/db/src/logseq/db/sqlite/create_graph.cljs | 7 +++---- deps/db/src/logseq/db/sqlite/util.cljs | 13 ++++++++----- .../src/logseq/tasks/db_graph/create_graph.cljs | 14 +++++++------- src/main/frontend/handler/db_based/property.cljs | 7 +------ 5 files changed, 20 insertions(+), 34 deletions(-) diff --git a/deps/db/src/logseq/db/frontend/property/util.cljs b/deps/db/src/logseq/db/frontend/property/util.cljs index 5c301f098..b131f74cc 100644 --- a/deps/db/src/logseq/db/frontend/property/util.cljs +++ b/deps/db/src/logseq/db/frontend/property/util.cljs @@ -47,16 +47,6 @@ (assoc :block/type #{"hidden"} :block/format :markdown)))) -(defn new-property-tx - "Provide attributes for a new built-in property given name, schema and uuid. - TODO: Merge this with sqlite-util/build-new-property once common-util/page-name-sanity-lc - is available to deps/db" - [prop-name prop-schema prop-uuid] - {:block/uuid prop-uuid - :block/schema (merge {:type :default} prop-schema) - :block/original-name (name prop-name) - :block/name (common-util/page-name-sanity-lc (name prop-name))}) - (defn build-closed-values "Builds all the tx needed for property with closed values including the hidden page and closed value blocks as needed" @@ -76,8 +66,7 @@ (:closed-values property))) property-schema (assoc (:block/schema property) :values (mapv :block/uuid closed-value-blocks-tx)) - property-tx (merge (sqlite-util/build-new-property - (new-property-tx prop-name property-schema (:block/uuid property))) + property-tx (merge (sqlite-util/build-new-property prop-name property-schema (:block/uuid property)) property-attributes)] (into [property-tx page-tx] (when-not closed-value-page-uuids? closed-value-blocks-tx)))) diff --git a/deps/db/src/logseq/db/sqlite/create_graph.cljs b/deps/db/src/logseq/db/sqlite/create_graph.cljs index b0bc1fa39..9aa330e06 100644 --- a/deps/db/src/logseq/db/sqlite/create_graph.cljs +++ b/deps/db/src/logseq/db/sqlite/create_graph.cljs @@ -22,10 +22,9 @@ {:block/schema schema :block/uuid (d/squuid) :closed-values closed-values} {:icon-id (get default-property-uuids :icon)}) [(sqlite-util/build-new-property - {:block/schema schema - :block/original-name (or original-name k-name) - :block/name (common-util/page-name-sanity-lc k-name) - :block/uuid (get default-property-uuids k-keyword (d/squuid))})]))) + (or original-name k-name) + schema + (get default-property-uuids k-keyword (d/squuid)))]))) db-property/built-in-properties))) (defn build-db-initial-data diff --git a/deps/db/src/logseq/db/sqlite/util.cljs b/deps/db/src/logseq/db/sqlite/util.cljs index 7782dae00..c540704d6 100644 --- a/deps/db/src/logseq/db/sqlite/util.cljs +++ b/deps/db/src/logseq/db/sqlite/util.cljs @@ -35,12 +35,15 @@ (defn build-new-property "Build a standard new property so that it is is consistent across contexts" - [block] + [prop-name prop-schema prop-uuid] (block-with-timestamps - (merge {:block/type "property" - :block/journal? false - :block/format :markdown} - block))) + {:block/type "property" + :block/journal? false + :block/format :markdown + :block/uuid prop-uuid + :block/schema (merge {:type :default} prop-schema) + :block/original-name (name prop-name) + :block/name (common-util/page-name-sanity-lc (name prop-name))})) (defn build-new-class diff --git a/scripts/src/logseq/tasks/db_graph/create_graph.cljs b/scripts/src/logseq/tasks/db_graph/create_graph.cljs index feb466815..461ea7610 100644 --- a/scripts/src/logseq/tasks/db_graph/create_graph.cljs +++ b/scripts/src/logseq/tasks/db_graph/create_graph.cljs @@ -176,13 +176,13 @@ :property-attributes {:db/id (or (property-db-ids (name prop-name)) (throw (ex-info "No :db/id for property" {:property prop-name})))}}) - [(sqlite-util/build-new-property - (merge (db-property-util/new-property-tx prop-name (get-in properties [prop-name :block/schema]) uuid) - {:db/id (or (property-db-ids (name prop-name)) - (throw (ex-info "No :db/id for property" {:property prop-name})))} - (when-let [props (not-empty (get-in properties [prop-name :properties]))] - {:block/properties (->block-properties-tx props uuid-maps) - :block/refs (build-property-refs props property-db-ids)})))])) + [(merge + (sqlite-util/build-new-property prop-name (get-in properties [prop-name :block/schema]) uuid) + {:db/id (or (property-db-ids (name prop-name)) + (throw (ex-info "No :db/id for property" {:property prop-name})))} + (when-let [props (not-empty (get-in properties [prop-name :properties]))] + {:block/properties (->block-properties-tx props uuid-maps) + :block/refs (build-property-refs props property-db-ids)}))])) property-uuids)) pages-and-blocks-tx (vec diff --git a/src/main/frontend/handler/db_based/property.cljs b/src/main/frontend/handler/db_based/property.cljs index f1fa4ca5d..56ea096f8 100644 --- a/src/main/frontend/handler/db_based/property.cljs +++ b/src/main/frontend/handler/db_based/property.cljs @@ -105,12 +105,7 @@ :block/uuid property-uuid :block/type "property"})] {:outliner-op :save-block}) - (db/transact! repo [(sqlite-util/build-new-property - (cond-> {:block/original-name k-name - :block/name (util/page-name-sanity-lc k-name) - :block/uuid property-uuid} - (seq schema) - (assoc :block/schema schema)))] + (db/transact! repo [(sqlite-util/build-new-property k-name schema property-uuid)] {:outliner-op :insert-blocks})))) (defn validate-property-value From b020be6047306164878facc9c416bb596645c61f Mon Sep 17 00:00:00 2001 From: rcmerci Date: Tue, 30 Jan 2024 15:49:07 +0800 Subject: [PATCH 07/16] feat: import favorites from config-edn --- src/main/frontend/components/imports.cljs | 89 +++++++++++++++++----- src/main/frontend/db_worker.cljs | 2 +- src/main/frontend/handler/common/page.cljs | 2 +- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/main/frontend/components/imports.cljs b/src/main/frontend/components/imports.cljs index 6283542a4..2ac4a164f 100644 --- a/src/main/frontend/components/imports.cljs +++ b/src/main/frontend/components/imports.cljs @@ -30,7 +30,12 @@ [borkdude.rewrite-edn :as rewrite] [rum.core :as rum] [frontend.handler.repo :as repo-handler] - [frontend.handler.common.config-edn :as config-edn-common-handler])) + [frontend.handler.common.config-edn :as config-edn-common-handler] + [datascript.core :as d] + [logseq.common.util :as common-util] + [logseq.db :as ldb] + [frontend.modules.outliner.ui :as ui-outliner-tx] + [logseq.outliner.core :as outliner-core])) ;; Can't name this component as `frontend.components.import` since shadow-cljs ;; will complain about it. @@ -222,30 +227,71 @@ (db-editor-handler/save-file! "logseq/config.edn" migrated-content)) (edn/read-string migrated-content)))))) +(defn- build-hidden-favorites-page-blocks + [page-block-uuid-coll] + (map + (fn [uuid] + {:block/link [:block/uuid uuid] + :block/content "" + :block/format :markdown}) + page-block-uuid-coll)) + +(def hidden-favorites-page-name "$$$favorites") +(def hidden-favorites-page-tx + {:block/uuid (d/squuid) + :block/name hidden-favorites-page-name + :block/original-name hidden-favorites-page-name + :block/journal? false + :block/type #{"hidden"} + :block/format :markdown}) + +(defn- import-favorites-from-config-edn! + [db-conn repo config-file] + (let [now (inst-ms (js/Date.))] + (p/do! + (ldb/transact! repo [(assoc hidden-favorites-page-tx + :block/created-at now + :block/updated-at now)]) + (p/let [content (when config-file (.text config-file))] + (when-let [content-edn (try (edn/read-string content) + (catch :default _ nil))] + (when-let [favorites (seq (:favorites content-edn))] + (when-let [page-block-uuid-coll + (seq + (keep (fn [page-name] + (some-> (d/entity @db-conn [:block/name (common-util/page-name-sanity-lc page-name)]) + :block/uuid)) + favorites))] + (let [page-entity (d/entity @db-conn [:block/name hidden-favorites-page-name])] + (ui-outliner-tx/transact! + {:outliner-op :insert-blocks} + (outliner-core/insert-blocks! repo db-conn (build-hidden-favorites-page-blocks page-block-uuid-coll) + page-entity {})))))))))) + (rum/defc confirm-graph-name-dialog - [initial-name on-graph-name-confirmed] - (let [[input set-input!] (rum/use-state initial-name) - on-submit #(do (on-graph-name-confirmed input) - (state/close-modal!))] - [:div.container - [:div.sm:flex.sm:items-start - [:div.mt-3.text-center.sm:mt-0.sm:text-left - [:h3#modal-headline.leading-6.font-medium - "Imported new graph name:"]]] + [initial-name on-graph-name-confirmed] + (let [[input set-input!] (rum/use-state initial-name) + on-submit #(do (on-graph-name-confirmed input) + (state/close-modal!))] + [:div.container + [:div.sm:flex.sm:items-start + [:div.mt-3.text-center.sm:mt-0.sm:text-left + [:h3#modal-headline.leading-6.font-medium + "Imported new graph name:"]]] - [:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2.mb-4 - {:auto-focus true - :default-value input - :on-change (fn [e] - (set-input! (util/evalue e))) - :on-key-press (fn [e] - (when (= "Enter" (util/ekey e)) - (on-submit)))}] + [:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2.mb-4 + {:auto-focus true + :default-value input + :on-change (fn [e] + (set-input! (util/evalue e))) + :on-key-press (fn [e] + (when (= "Enter" (util/ekey e)) + (on-submit)))}] - [:div.mt-5.sm:mt-4.flex - (ui/button "Confirm" - {:on-click on-submit})]])) + [:div.mt-5.sm:mt-4.flex + (ui/button "Confirm" + {:on-click on-submit})]])) (defn graph-folder-to-db-import-handler "Import from a graph folder as a DB-based graph. @@ -277,6 +323,7 @@ (async/c (import-config-file! config-file))) (async/c (import-favorites-from-config-edn! db-conn repo config-file))) (state/set-state! :graph/importing nil) (finished-cb)))))] (state/set-modal! diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 9608ab8e6..d259acf89 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -328,7 +328,7 @@ nil) (catch :default e (prn :debug :error) - (js/console.error e))))) + (js/console.error e tx-data))))) (getInitialData [_this repo] diff --git a/src/main/frontend/handler/common/page.cljs b/src/main/frontend/handler/common/page.cljs index c52653557..2d007514a 100644 --- a/src/main/frontend/handler/common/page.cljs +++ b/src/main/frontend/handler/common/page.cljs @@ -26,7 +26,7 @@ (defn build-hidden-page-tx-data [page-name] (let [page-name* (str "$$$" page-name)] - (assoc (block/page-name->map page-name* false false) + (assoc (block/page-name->map page-name* true false) :block/type #{"hidden"} :block/format :markdown))) From 00cb045dc1fa552ac48261106e18bd47c8edfb3e Mon Sep 17 00:00:00 2001 From: rcmerci Date: Tue, 30 Jan 2024 15:53:22 +0800 Subject: [PATCH 08/16] chore: clean-ns --- src/main/frontend/components/imports.cljs | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/frontend/components/imports.cljs b/src/main/frontend/components/imports.cljs index 2ac4a164f..229017984 100644 --- a/src/main/frontend/components/imports.cljs +++ b/src/main/frontend/components/imports.cljs @@ -1,9 +1,11 @@ (ns frontend.components.imports "Import data into Logseq." - (:require [cljs.core.async.interop :refer [p->c]] + (:require [borkdude.rewrite-edn :as rewrite] + [cljs.core.async.interop :refer [p->c]] [clojure.core.async :as async] [clojure.edn :as edn] [clojure.string :as string] + [datascript.core :as d] [frontend.components.onboarding.setups :as setups] [frontend.components.repo :as repo] [frontend.components.svg :as svg] @@ -11,12 +13,15 @@ [frontend.context.i18n :refer [t]] [frontend.db :as db] [frontend.fs :as fs] - [frontend.persist-db.browser :as db-browser] + [frontend.handler.common.config-edn :as config-edn-common-handler] [frontend.handler.db-based.editor :as db-editor-handler] [frontend.handler.import :as import-handler] [frontend.handler.notification :as notification] + [frontend.handler.repo :as repo-handler] [frontend.handler.route :as route-handler] [frontend.handler.ui :as ui-handler] + [frontend.modules.outliner.ui :as ui-outliner-tx] + [frontend.persist-db.browser :as db-browser] [frontend.state :as state] [frontend.ui :as ui] [frontend.util :as util] @@ -24,18 +29,13 @@ [goog.functions :refer [debounce]] [goog.object :as gobj] [logseq.common.path :as path] - [logseq.graph-parser :as graph-parser] - [medley.core :as medley] - [promesa.core :as p] - [borkdude.rewrite-edn :as rewrite] - [rum.core :as rum] - [frontend.handler.repo :as repo-handler] - [frontend.handler.common.config-edn :as config-edn-common-handler] - [datascript.core :as d] [logseq.common.util :as common-util] [logseq.db :as ldb] - [frontend.modules.outliner.ui :as ui-outliner-tx] - [logseq.outliner.core :as outliner-core])) + [logseq.graph-parser :as graph-parser] + [logseq.outliner.core :as outliner-core] + [medley.core :as medley] + [promesa.core :as p] + [rum.core :as rum])) ;; Can't name this component as `frontend.components.import` since shadow-cljs ;; will complain about it. From ebc801241d1b4541b91c8cd0b0380fa0d58f8ef4 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 30 Jan 2024 15:57:33 +0800 Subject: [PATCH 09/16] chore: remove repeated get-title-and-pagename calls --- src/main/frontend/handler/common/page.cljs | 7 +- src/main/frontend/worker/handler/page.cljs | 95 +++++++++++----------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/main/frontend/handler/common/page.cljs b/src/main/frontend/handler/common/page.cljs index 2d007514a..b8e99afc6 100644 --- a/src/main/frontend/handler/common/page.cljs +++ b/src/main/frontend/handler/common/page.cljs @@ -50,8 +50,7 @@ (let [repo (state/get-current-repo) conn (db/get-db repo false) config (state/get-config repo) - _ (worker-page/create! repo conn config title options) - [_ page-name] (worker-page/get-title-and-pagename title)] + [_ page-name] (worker-page/create! repo conn config title options)] (when redirect? (route-handler/redirect-to-page! page-name)) (when-let [first-block (first (:block/_left (db/entity [:block/name page-name])))] @@ -67,8 +66,8 @@ (p/let [repo (state/get-current-repo) conn (db/get-db repo false) config (state/get-config repo) - _ (worker-page/create! repo conn config title options) - [_ page-name] (worker-page/get-title-and-pagename title)] + [p page-name] (worker-page/create! repo conn config title options) + _result p] (when redirect? (route-handler/redirect-to-page! page-name)) (let [page (db/entity [:block/name page-name])] diff --git a/src/main/frontend/worker/handler/page.cljs b/src/main/frontend/worker/handler/page.cljs index e3491f002..57184167d 100644 --- a/src/main/frontend/worker/handler/page.cljs +++ b/src/main/frontend/worker/handler/page.cljs @@ -81,56 +81,57 @@ (date/valid-journal-title? date-formatter title))) [title page-name] (get-title-and-pagename title) - with-uuid? (if (uuid? uuid) uuid true)] ;; FIXME: prettier validation - (when (ldb/page-empty? @conn page-name) - (let [pages (if split-namespace? - (common-util/split-namespace-pages title) - [title]) - format (or format (common-config/get-preferred-format config)) - pages (map (fn [page] + with-uuid? (if (uuid? uuid) uuid true) + result (when (ldb/page-empty? @conn page-name) + (let [pages (if split-namespace? + (common-util/split-namespace-pages title) + [title]) + format (or format (common-config/get-preferred-format config)) + pages (map (fn [page] ;; only apply uuid to the deepest hierarchy of page to create if provided. - (-> (gp-block/page-name->map page (if (= page title) with-uuid? true) @conn true date-formatter) - (assoc :block/format format))) - pages) - txs (->> pages + (-> (gp-block/page-name->map page (if (= page title) with-uuid? true) @conn true date-formatter) + (assoc :block/format format))) + pages) + txs (->> pages ;; for namespace pages, only last page need properties - drop-last - (mapcat #(build-page-tx repo conn config date-formatter format nil % {})) - (remove nil?)) - txs (map-indexed (fn [i page] - (if (zero? i) - page - (assoc page :block/namespace - [:block/uuid (:block/uuid (nth txs (dec i)))]))) - txs) - page-txs (build-page-tx repo conn config date-formatter format properties (last pages) (select-keys options [:whiteboard? :class? :tags])) - page-txs (if (seq txs) - (update page-txs 0 - (fn [p] - (assoc p :block/namespace [:block/uuid (:block/uuid (last txs))]))) - page-txs) - first-block-tx (when (and - create-first-block? - (not (or whiteboard? class?)) - (ldb/page-empty? @conn (:db/id (d/entity @conn [:block/name page-name]))) + drop-last + (mapcat #(build-page-tx repo conn config date-formatter format nil % {})) + (remove nil?)) + txs (map-indexed (fn [i page] + (if (zero? i) + page + (assoc page :block/namespace + [:block/uuid (:block/uuid (nth txs (dec i)))]))) + txs) + page-txs (build-page-tx repo conn config date-formatter format properties (last pages) (select-keys options [:whiteboard? :class? :tags])) + page-txs (if (seq txs) + (update page-txs 0 + (fn [p] + (assoc p :block/namespace [:block/uuid (:block/uuid (last txs))]))) page-txs) - (let [page-id [:block/uuid (:block/uuid (first page-txs))]] - [(sqlite-util/block-with-timestamps - {:block/uuid (ldb/new-block-id) - :block/page page-id - :block/parent page-id - :block/left page-id - :block/content "" - :block/format format})])) - txs (concat - txs - page-txs - first-block-tx)] - (when (seq txs) - (ldb/transact! conn txs (cond-> {:persist-op? persist-op?} - today-journal? - (assoc :create-today-journal? true - :today-journal-name page-name)))))))) + first-block-tx (when (and + create-first-block? + (not (or whiteboard? class?)) + (ldb/page-empty? @conn (:db/id (d/entity @conn [:block/name page-name]))) + page-txs) + (let [page-id [:block/uuid (:block/uuid (first page-txs))]] + [(sqlite-util/block-with-timestamps + {:block/uuid (ldb/new-block-id) + :block/page page-id + :block/parent page-id + :block/left page-id + :block/content "" + :block/format format})])) + txs (concat + txs + page-txs + first-block-tx)] + (when (seq txs) + (ldb/transact! conn txs (cond-> {:persist-op? persist-op?} + today-journal? + (assoc :create-today-journal? true + :today-journal-name page-name))))))] ;; FIXME: prettier validation + [result page-name])) (defn db-refs->page "Replace [[page name]] with page name" From 09dcf654c7c6ebc8a56e5d2d5d3cafe0ac5d2de4 Mon Sep 17 00:00:00 2001 From: rcmerci Date: Tue, 30 Jan 2024 18:02:50 +0800 Subject: [PATCH 10/16] fix(rtc): fix :block/link sync --- src/main/frontend/worker/rtc/core.cljs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/frontend/worker/rtc/core.cljs b/src/main/frontend/worker/rtc/core.cljs index a69af3081..7818d2b62 100644 --- a/src/main/frontend/worker/rtc/core.cljs +++ b/src/main/frontend/worker/rtc/core.cljs @@ -302,7 +302,11 @@ (d/pull-many @conn [:db/id]) (filter :db/id))) (contains? key-set :properties) (assoc :block/properties - (transit/read transit-r (:properties op-value))))] + (transit/read transit-r (:properties op-value))) + (contains? key-set :link) (assoc :block/link (some->> (:link op-value) + (vector :block/uuid) + (d/pull @conn [:db/id]) + :db/id)))] (transact-db! :save-block repo conn date-formatter new-block))))))) (defn apply-remote-move-ops From faa5e43966b3115bf460f432c453cb27c471e8b2 Mon Sep 17 00:00:00 2001 From: charlie Date: Tue, 30 Jan 2024 19:45:29 +0800 Subject: [PATCH 11/16] enhance(ui): accent color for the property status icon --- src/main/frontend/components/property.css | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/frontend/components/property.css b/src/main/frontend/components/property.css index 8d4b32b1d..1934da31a 100644 --- a/src/main/frontend/components/property.css +++ b/src/main/frontend/components/property.css @@ -209,3 +209,20 @@ a.control-link { margin-bottom: 1rem; } } + +.property-select { + .menu-link:hover, a.menu-link.chosen { + .iconTablerExtInProgress50, + .iconTablerExtBacklog, + .iconTablerExtTodo, + .iconTablerExtDoing, + .iconTablerExtInReview, + .iconTablerExtDone { + @apply text-accent-09; + } + + .iconTablerExtCancelled { + @apply text-red-rx-09; + } + } +} \ No newline at end of file From 9db7cd3be902d44eaa3a6872dd79b765a91d7f39 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Tue, 30 Jan 2024 15:12:51 -0500 Subject: [PATCH 12/16] fix: new db graph shouldn't have deprecated config.edn warnings --- src/main/frontend/components/imports.cljs | 9 ++------- src/main/frontend/handler/common/config_edn.cljs | 5 +++-- src/main/frontend/handler/repo.cljs | 15 ++++++++++++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/frontend/components/imports.cljs b/src/main/frontend/components/imports.cljs index 229017984..ca11a071a 100644 --- a/src/main/frontend/components/imports.cljs +++ b/src/main/frontend/components/imports.cljs @@ -1,7 +1,6 @@ (ns frontend.components.imports "Import data into Logseq." - (:require [borkdude.rewrite-edn :as rewrite] - [cljs.core.async.interop :refer [p->c]] + (:require [cljs.core.async.interop :refer [p->c]] [clojure.core.async :as async] [clojure.edn :as edn] [clojure.string :as string] @@ -13,7 +12,6 @@ [frontend.context.i18n :refer [t]] [frontend.db :as db] [frontend.fs :as fs] - [frontend.handler.common.config-edn :as config-edn-common-handler] [frontend.handler.db-based.editor :as db-editor-handler] [frontend.handler.import :as import-handler] [frontend.handler.notification :as notification] @@ -219,10 +217,7 @@ (-> (when config-file (.text config-file)) (p/then (fn [content] - (let [migrated-content (-> (reduce rewrite/dissoc - (rewrite/parse-string (str content)) - (keys config-edn-common-handler/file-only-config)) - str)] + (let [migrated-content (repo-handler/migrate-db-config content)] (p/do! (db-editor-handler/save-file! "logseq/config.edn" migrated-content)) (edn/read-string migrated-content)))))) diff --git a/src/main/frontend/handler/common/config_edn.cljs b/src/main/frontend/handler/common/config_edn.cljs index 37640a5bb..b7e77b060 100644 --- a/src/main/frontend/handler/common/config_edn.cljs +++ b/src/main/frontend/handler/common/config_edn.cljs @@ -103,8 +103,9 @@ nested keys or positional errors e.g. tuples" :block-hidden-properties "is not used in DB graphs as hiding a property is done in its configuration" :ignored-page-references-keywords - "is not used in DB graphs" - :file/name-format + ;; TODO: Remove key when default is changed + ;; "is not used in DB graphs" + ;; :file/name-format "is not used in DB graphs" :feature/enable-block-timestamps? "is not used in DB graphs as it is always enabled"}) diff --git a/src/main/frontend/handler/repo.cljs b/src/main/frontend/handler/repo.cljs index 448db3bd5..c231bc933 100644 --- a/src/main/frontend/handler/repo.cljs +++ b/src/main/frontend/handler/repo.cljs @@ -11,6 +11,7 @@ [frontend.fs.nfs :as nfs] [frontend.handler.file :as file-handler] [frontend.handler.repo-config :as repo-config-handler] + [frontend.handler.common.config-edn :as config-edn-common-handler] [frontend.handler.common.file :as file-common-handler] [frontend.handler.route :as route-handler] [frontend.handler.ui :as ui-handler] @@ -35,7 +36,8 @@ [clojure.core.async :as async] [frontend.mobile.util :as mobile-util] [medley.core :as medley] - [logseq.common.path :as path])) + [logseq.common.path :as path] + [borkdude.rewrite-edn :as rewrite])) ;; Project settings should be checked in two situations: ;; 1. User changes the config.edn directly in logseq.com (fn: alter-file) @@ -104,7 +106,7 @@ :else default-content) file-rpath (path/path-join (config/get-journals-directory) (str file-name "." - (config/get-file-extension format))) + (config/get-file-extension format))) page-exists? (db/entity repo-url [:block/name (util/page-name-sanity-lc title)]) empty-blocks? (db/page-empty? repo-url (util/page-name-sanity-lc title))] (when (or empty-blocks? (not page-exists?)) @@ -518,13 +520,20 @@ (let [full-graph-name (string/lower-case (str config/db-version-prefix graph-name))] (some #(= (some-> (:url %) string/lower-case) full-graph-name) (state/get-repos)))) +(defn migrate-db-config + [content] + (-> (reduce rewrite/dissoc + (rewrite/parse-string (str content)) + (keys config-edn-common-handler/file-only-config)) + str)) + (defn- create-db [full-graph-name {:keys [file-graph-import?]}] (-> (p/let [_ (persist-db/ Date: Tue, 30 Jan 2024 15:26:19 -0500 Subject: [PATCH 13/16] fix: deprecate :favorites for db config related to LOG-3031. Also comment all known file graph only config keys --- deps/common/resources/templates/config.edn | 7 +++++++ src/main/frontend/handler/common/config_edn.cljs | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/deps/common/resources/templates/config.edn b/deps/common/resources/templates/config.edn index 8c88f62c5..ebb36fcfb 100644 --- a/deps/common/resources/templates/config.edn +++ b/deps/common/resources/templates/config.edn @@ -14,6 +14,7 @@ :preferred-workflow :now ;; Exclude directories/files. + ;; This is _only_ for file graphs. ;; Example usage: ;; :hidden ["/archived" "/test.md" "../assets/archived"] :hidden [] @@ -144,6 +145,7 @@ ;; :whiteboards-directory "whiteboards" ;; Enabling this option converts + ;; This is _only_ for file graphs. ;; [[Grant Ideas]] to [[file:./grant_ideas.org][Grant Ideas]] for org-mode. ;; For more information, visit https://github.com/logseq/logseq/issues/672 ;; :org-mode/insert-file-link? false @@ -289,6 +291,7 @@ ;; :journal? false} ; Default value: false ;; Favorites to list on the left sidebar + ;; This is _only_ for file graphs. :favorites [] ;; Set flashcards interval. @@ -307,19 +310,23 @@ ;; :block-hidden-properties #{:public :icon} ;; Create a page for all properties. + ;; This is _only_ for file graphs. ;; Default value: true :property-pages/enabled? true ;; Properties to exclude from having property pages + ;; This is _only_ for file graphs. ;; Example usage: ;; :property-pages/excludelist #{:duration :author} ;; By default, property value separated by commas will not be treated as ;; page references. You can add properties to enable it. + ;; This is _only_ for file graphs. ;; Example usage: ;; :property/separated-by-commas #{:alias :tags} ;; Properties that are ignored when parsing property values for references + ;; This is _only_ for file graphs. ;; Example usage: ;; :ignored-page-references-keywords #{:author :website} diff --git a/src/main/frontend/handler/common/config_edn.cljs b/src/main/frontend/handler/common/config_edn.cljs index b7e77b060..4199b0bf0 100644 --- a/src/main/frontend/handler/common/config_edn.cljs +++ b/src/main/frontend/handler/common/config_edn.cljs @@ -108,7 +108,9 @@ nested keys or positional errors e.g. tuples" ;; :file/name-format "is not used in DB graphs" :feature/enable-block-timestamps? - "is not used in DB graphs as it is always enabled"}) + "is not used in DB graphs as it is always enabled" + :favorites + "is not stored in config for DB graphs"}) (defn detect-deprecations "Detects config keys that will or have been deprecated" From 0b52f8ad58c2c47f2bbea0b3f2c0f5229c6fd5c4 Mon Sep 17 00:00:00 2001 From: rcmerci Date: Wed, 31 Jan 2024 23:49:12 +0800 Subject: [PATCH 14/16] enhance: make ui reactive when favorites updated --- src/main/frontend/components/container.cljs | 3 +- src/main/frontend/handler/page.cljs | 43 ++++++++++++--------- src/main/frontend/state.cljs | 8 +++- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/main/frontend/components/container.cljs b/src/main/frontend/components/container.cljs index 0f35eee2e..0b2ffd052 100644 --- a/src/main/frontend/components/container.cljs +++ b/src/main/frontend/components/container.cljs @@ -132,7 +132,8 @@ (rum/defc favorites < rum/reactive [t] - (let [favorite-entities (page-handler/get-favorites)] + (let [_favorites-updated? (state/sub :favorites/updated?) + favorite-entities (page-handler/get-favorites)] (nav-content-item [:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th (ui/icon "star" {:size 16}) diff --git a/src/main/frontend/handler/page.cljs b/src/main/frontend/handler/page.cljs index c04970175..b52892671 100644 --- a/src/main/frontend/handler/page.cljs +++ b/src/main/frontend/handler/page.cljs @@ -49,21 +49,25 @@ (defn editor-cursor (atom {}) :system/info {} ;; Whether block is selected - :ui/select-query-cache (atom {})}))) + :ui/select-query-cache (atom {}) + + :favorites/updated? (atom 0)}))) ;; Block ast state ;; =============== @@ -2369,3 +2371,7 @@ Similar to re-frame subscriptions" (when (and max-tx-id (nil? (:after (get @(:history/tx->editor-cursor @state) max-tx-id)))) (update-state! :history/tx->editor-cursor (fn [m] (assoc-in m [max-tx-id :after] editor-cursor)))))) + +(defn update-favorites-updated! + [] + (update-state! :favorites/updated? inc)) From bf56cd32523850bddb4057c729ce112049405ceb Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Wed, 31 Jan 2024 11:09:52 -0500 Subject: [PATCH 15/16] chore: move legacy fns to legacy ns title property is for file graphs and should be kept with its ns to avoid confusion --- deps/common/src/logseq/common/util.cljs | 68 +------------------ deps/common/test/logseq/common/util_test.cljs | 4 +- .../src/logseq/graph_parser/extract.cljc | 64 ++++++++++++++++- .../logseq/graph_parser/extract_test.cljs | 38 +++++++++++ .../graph_parser/util/file_name_test.cljs | 43 ------------ src/test/frontend/db/name_sanity_test.cljs | 4 +- 6 files changed, 106 insertions(+), 115 deletions(-) delete mode 100644 deps/graph-parser/test/logseq/graph_parser/util/file_name_test.cljs diff --git a/deps/common/src/logseq/common/util.cljs b/deps/common/src/logseq/common/util.cljs index 558b0e882..4f4eb26c3 100644 --- a/deps/common/src/logseq/common/util.cljs +++ b/deps/common/src/logseq/common/util.cljs @@ -18,12 +18,6 @@ (log/error :decode-uri-component-failed uri) uri))) -(defn safe-url-decode - [string] - (if (string/includes? string "%") - (some-> string str safe-decode-uri-component) - string)) - (defn path-normalize "Normalize file path (for reading paths from FS, not required by writing) Keep capitalization senstivity" @@ -129,12 +123,7 @@ result)) (map string/trim)))) -(defn decode-namespace-underlines - "Decode namespace underlines to slashed; - If continuous underlines, only decode at start; - Having empty namespace is invalid." - [string] - (string/replace string "___" "/")) +(def url-encoded-pattern #"(?i)%[0-9a-f]{2}") ;; (?i) for case-insensitive mode (defn page-name-sanity "Sanitize the page-name. Unify different diacritics and other visual differences. @@ -146,24 +135,6 @@ (remove-boundary-slashes) (path-normalize))) -(defn make-valid-namespaces - "Remove those empty namespaces from title to make it a valid page name." - [title] - (->> (string/split title "/") - (remove empty?) - (string/join "/"))) - -(def url-encoded-pattern #"(?i)%[0-9a-f]{2}") ;; (?i) for case-insensitive mode - -(defn- tri-lb-title-parsing - "Parsing file name under the new file name format - Avoid calling directly" - [file-name] - (some-> file-name - (decode-namespace-underlines) - (string/replace url-encoded-pattern safe-url-decode) - (make-valid-namespaces))) - (defn page-name-sanity-lc "Sanitize the query string for a page name (mandate for :block/name)" [s] @@ -202,22 +173,6 @@ ;; default (keyword format))) -(defn path->file-name - ;; Only for internal paths, as they are converted to POXIS already - ;; https://github.com/logseq/logseq/blob/48b8e54e0fdd8fbd2c5d25b7f1912efef8814714/deps/graph-parser/src/logseq/graph_parser/extract.cljc#L32 - ;; Should be converted to POXIS first for external paths - [path] - (if (string/includes? path "/") - (last (split-last "/" path)) - path)) - -(defn path->file-body - [path] - (when-let [file-name (path->file-name path)] - (if (string/includes? file-name ".") - (first (split-last "." file-name)) - file-name))) - (defn path->file-ext [path-or-file-name] (second (re-find #"(?:\.)(\w+)[^.]*$" path-or-file-name))) @@ -245,27 +200,6 @@ (catch :default _ false))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Keep for backward compatibility ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Rule of dir-ver 0 -;; Source: https://github.com/logseq/logseq/blob/e7110eea6790eda5861fdedb6b02c2a78b504cd9/deps/graph-parser/src/logseq/graph_parser/extract.cljc#L35 -(defn legacy-title-parsing - [file-name-body] - (let [title (string/replace file-name-body "." "/")] - (or (safe-decode-uri-component title) title))) - -;; Register sanitization / parsing fns in: -;; logseq.common.util (parsing only) -;; frontend.util.fs (sanitization only) -(defn title-parsing - "Convert file name in the given file name format to page title" - [file-name-body filename-format] - (case filename-format - :triple-lowbar (tri-lb-title-parsing file-name-body) - (legacy-title-parsing file-name-body))) - (defn safe-read-string ([content] (safe-read-string {} content)) diff --git a/deps/common/test/logseq/common/util_test.cljs b/deps/common/test/logseq/common/util_test.cljs index fc42fdf22..98d97df6a 100644 --- a/deps/common/test/logseq/common/util_test.cljs +++ b/deps/common/test/logseq/common/util_test.cljs @@ -27,7 +27,9 @@ "C:\\Users\\foo\\Documents\\audio.mp3" "mp3" "/root/Documents/audio" nil "/root/Documents/audio." nil - "special/characters/aäääöüß.7z" "7z")) + "special/characters/aäääöüß.7z" "7z" + "asldk lakls .lsad" "lsad" + "中文asldk lakls .lsad" "lsad")) (deftest url? (are [x y] diff --git a/deps/graph-parser/src/logseq/graph_parser/extract.cljc b/deps/graph-parser/src/logseq/graph_parser/extract.cljc index 011af5bf1..d34d88778 100644 --- a/deps/graph-parser/src/logseq/graph_parser/extract.cljc +++ b/deps/graph-parser/src/logseq/graph_parser/extract.cljc @@ -27,6 +27,66 @@ (common-util/safe-decode-uri-component (string/replace result "." "/")) result)))) +(defn- path->file-name + ;; Only for internal paths, as they are converted to POXIS already + ;; https://github.com/logseq/logseq/blob/48b8e54e0fdd8fbd2c5d25b7f1912efef8814714/deps/graph-parser/src/logseq/graph_parser/extract.cljc#L32 + ;; Should be converted to POXIS first for external paths + [path] + (if (string/includes? path "/") + (last (common-util/split-last "/" path)) + path)) + +(defn- path->file-body + [path] + (when-let [file-name (path->file-name path)] + (if (string/includes? file-name ".") + (first (common-util/split-last "." file-name)) + file-name))) + +(defn- safe-url-decode + [string] + (if (string/includes? string "%") + (some-> string str common-util/safe-decode-uri-component) + string)) + +(defn- decode-namespace-underlines + "Decode namespace underlines to slashed; + If continuous underlines, only decode at start; + Having empty namespace is invalid." + [string] + (string/replace string "___" "/")) + +(defn- make-valid-namespaces + "Remove those empty namespaces from title to make it a valid page name." + [title] + (->> (string/split title "/") + (remove empty?) + (string/join "/"))) + +(defn- tri-lb-title-parsing + "Parsing file name under the new file name format + Avoid calling directly" + [file-name] + (some-> file-name + (decode-namespace-underlines) + (string/replace common-util/url-encoded-pattern safe-url-decode) + (make-valid-namespaces))) + +;; Keep for backward compatibility +;; Rule of dir-ver 0 +;; Source: https://github.com/logseq/logseq/blob/e7110eea6790eda5861fdedb6b02c2a78b504cd9/deps/graph-parser/src/logseq/graph_parser/extract.cljc#L35 +(defn- legacy-title-parsing + [file-name-body] + (let [title (string/replace file-name-body "." "/")] + (or (common-util/safe-decode-uri-component title) title))) + +(defn title-parsing + "Convert file name in the given file name format to page title" + [file-name-body filename-format] + (case filename-format + :triple-lowbar (tri-lb-title-parsing file-name-body) + (legacy-title-parsing file-name-body))) + (defn- get-page-name "Get page name with overridden order of `title::` property @@ -54,9 +114,9 @@ (and first-block (string? title) title)) - file-name (when-let [result (common-util/path->file-body file)] + file-name (when-let [result (path->file-body file)] (if (common-config/mldoc-support? (common-util/get-file-ext file)) - (common-util/title-parsing result filename-format) + (title-parsing result filename-format) result))] (or property-name file-name diff --git a/deps/graph-parser/test/logseq/graph_parser/extract_test.cljs b/deps/graph-parser/test/logseq/graph_parser/extract_test.cljs index dca75a5d2..704bfb56b 100644 --- a/deps/graph-parser/test/logseq/graph_parser/extract_test.cljs +++ b/deps/graph-parser/test/logseq/graph_parser/extract_test.cljs @@ -3,6 +3,44 @@ [logseq.graph-parser.extract :as extract] [clojure.pprint :as pprint])) +;; This is a copy of frontend.util.fs/multiplatform-reserved-chars for reserved chars testing +(def multiplatform-reserved-chars ":\\*\\?\"<>|\\#\\\\") + +;; Stuffs should be parsable (don't crash) when users dump some random files +(deftest page-name-parsing-tests + (is (string? (#'extract/tri-lb-title-parsing "___-_-_-_---___----"))) + (is (string? (#'extract/tri-lb-title-parsing "_____///____---___----"))) + (is (string? (#'extract/tri-lb-title-parsing "/_/////---/_----"))) + (is (string? (#'extract/tri-lb-title-parsing "/\\#*%lasdf\\//__--dsll_____----....-._0x2B"))) + (is (string? (#'extract/tri-lb-title-parsing "/\\#*%l;;&&;&\\//__--dsll_____----....-._0x2B"))) + (is (string? (#'extract/tri-lb-title-parsing multiplatform-reserved-chars))) + (is (string? (#'extract/tri-lb-title-parsing "dsa&;l dsalfjk jkl")))) + +(deftest uri-decoding-tests + (is (= (#'extract/safe-url-decode "%*-sd%%%saf%=lks") "%*-sd%%%saf%=lks")) ;; Contains %, but invalid + (is (= (#'extract/safe-url-decode "%2FDownloads%2FCNN%3AIs%5CAll%3AYou%20Need.pdf") "/Downloads/CNN:Is\\All:You Need.pdf")) + (is (= (#'extract/safe-url-decode "asldkflksdaf啦放假啦睡觉啦啊啥的都撒娇浪费;dla") "asldkflksdaf啦放假啦睡觉啦啊啥的都撒娇浪费;dla"))) + +(deftest page-name-sanitization-backward-tests + (is (= "abc.def.ghi.jkl" (#'extract/tri-lb-title-parsing "abc.def.ghi.jkl"))) + (is (= "abc/def/ghi/jkl" (#'extract/tri-lb-title-parsing "abc%2Fdef%2Fghi%2Fjkl"))) + (is (= "abc%/def/ghi/jkl" (#'extract/tri-lb-title-parsing "abc%25%2Fdef%2Fghi%2Fjkl"))) + (is (= "abc%2——ef/ghi/jkl" (#'extract/tri-lb-title-parsing "abc%2——ef%2Fghi%2Fjkl"))) + (is (= "abc&2Fghi/jkl" (#'extract/tri-lb-title-parsing "abc&2Fghi%2Fjkl"))) + (is (= "abc<2Fghi/jkl" (#'extract/tri-lb-title-parsing "abc<2Fghi%2Fjkl"))) + (is (= "abc%2Fghi/jkl" (#'extract/tri-lb-title-parsing "abc%2Fghi%2Fjkl"))) + (is (= "abc;&;2Fghi/jkl" (#'extract/tri-lb-title-parsing "abc;&;2Fghi%2Fjkl"))) + ;; happens when importing some compatible files on *nix / macOS + (is (= multiplatform-reserved-chars (#'extract/tri-lb-title-parsing multiplatform-reserved-chars)))) + +(deftest path-utils-tests + (is (= "asldk lakls " (#'extract/path->file-body "/data/app/asldk lakls .lsad"))) + (is (= "asldk lakls " (#'extract/path->file-body "asldk lakls .lsad"))) + (is (= "asldk lakls" (#'extract/path->file-body "asldk lakls"))) + (is (= "asldk lakls" (#'extract/path->file-body "/data/app/asldk lakls"))) + (is (= "asldk lakls" (#'extract/path->file-body "file://data/app/asldk lakls.as"))) + (is (= "中文asldk lakls" (#'extract/path->file-body "file://中文data/app/中文asldk lakls.as")))) + (defn- extract [text] (let [{:keys [blocks]} (extract/extract "a.md" text {:block-pattern "-"}) diff --git a/deps/graph-parser/test/logseq/graph_parser/util/file_name_test.cljs b/deps/graph-parser/test/logseq/graph_parser/util/file_name_test.cljs deleted file mode 100644 index d628a006e..000000000 --- a/deps/graph-parser/test/logseq/graph_parser/util/file_name_test.cljs +++ /dev/null @@ -1,43 +0,0 @@ -(ns logseq.graph-parser.util.file-name-test - (:require [logseq.common.util :as common-util] - [cljs.test :refer [is deftest]])) - -;; This is a copy of frontend.util.fs/multiplatform-reserved-chars for reserved chars testing -(def multiplatform-reserved-chars ":\\*\\?\"<>|\\#\\\\") - -;; Stuffs should be parsable (don't crash) when users dump some random files -(deftest page-name-parsing-tests - (is (string? (#'common-util/tri-lb-title-parsing "___-_-_-_---___----"))) - (is (string? (#'common-util/tri-lb-title-parsing "_____///____---___----"))) - (is (string? (#'common-util/tri-lb-title-parsing "/_/////---/_----"))) - (is (string? (#'common-util/tri-lb-title-parsing "/\\#*%lasdf\\//__--dsll_____----....-._0x2B"))) - (is (string? (#'common-util/tri-lb-title-parsing "/\\#*%l;;&&;&\\//__--dsll_____----....-._0x2B"))) - (is (string? (#'common-util/tri-lb-title-parsing multiplatform-reserved-chars))) - (is (string? (#'common-util/tri-lb-title-parsing "dsa&;l dsalfjk jkl")))) - -(deftest uri-decoding-tests - (is (= (common-util/safe-url-decode "%*-sd%%%saf%=lks") "%*-sd%%%saf%=lks")) ;; Contains %, but invalid - (is (= (common-util/safe-url-decode "%2FDownloads%2FCNN%3AIs%5CAll%3AYou%20Need.pdf") "/Downloads/CNN:Is\\All:You Need.pdf")) - (is (= (common-util/safe-url-decode "asldkflksdaf啦放假啦睡觉啦啊啥的都撒娇浪费;dla") "asldkflksdaf啦放假啦睡觉啦啊啥的都撒娇浪费;dla"))) - -(deftest page-name-sanitization-backward-tests - (is (= "abc.def.ghi.jkl" (#'common-util/tri-lb-title-parsing "abc.def.ghi.jkl"))) - (is (= "abc/def/ghi/jkl" (#'common-util/tri-lb-title-parsing "abc%2Fdef%2Fghi%2Fjkl"))) - (is (= "abc%/def/ghi/jkl" (#'common-util/tri-lb-title-parsing "abc%25%2Fdef%2Fghi%2Fjkl"))) - (is (= "abc%2——ef/ghi/jkl" (#'common-util/tri-lb-title-parsing "abc%2——ef%2Fghi%2Fjkl"))) - (is (= "abc&2Fghi/jkl" (#'common-util/tri-lb-title-parsing "abc&2Fghi%2Fjkl"))) - (is (= "abc<2Fghi/jkl" (#'common-util/tri-lb-title-parsing "abc<2Fghi%2Fjkl"))) - (is (= "abc%2Fghi/jkl" (#'common-util/tri-lb-title-parsing "abc%2Fghi%2Fjkl"))) - (is (= "abc;&;2Fghi/jkl" (#'common-util/tri-lb-title-parsing "abc;&;2Fghi%2Fjkl"))) - ;; happens when importing some compatible files on *nix / macOS - (is (= multiplatform-reserved-chars (#'common-util/tri-lb-title-parsing multiplatform-reserved-chars)))) - -(deftest path-utils-tests - (is (= "asldk lakls " (common-util/path->file-body "/data/app/asldk lakls .lsad"))) - (is (= "asldk lakls " (common-util/path->file-body "asldk lakls .lsad"))) - (is (= "asldk lakls" (common-util/path->file-body "asldk lakls"))) - (is (= "asldk lakls" (common-util/path->file-body "/data/app/asldk lakls"))) - (is (= "asldk lakls" (common-util/path->file-body "file://data/app/asldk lakls.as"))) - (is (= "中文asldk lakls" (common-util/path->file-body "file://中文data/app/中文asldk lakls.as"))) - (is (= "lsad" (common-util/path->file-ext "asldk lakls .lsad"))) - (is (= "lsad" (common-util/path->file-ext "中文asldk lakls .lsad")))) diff --git a/src/test/frontend/db/name_sanity_test.cljs b/src/test/frontend/db/name_sanity_test.cljs index e81171c6d..7d34763fa 100644 --- a/src/test/frontend/db/name_sanity_test.cljs +++ b/src/test/frontend/db/name_sanity_test.cljs @@ -1,7 +1,7 @@ (ns frontend.db.name-sanity-test (:require [cljs.test :refer [deftest testing is]] [clojure.string :as string] - [logseq.common.util :as common-util] + [logseq.graph-parser.extract :as extract] [frontend.worker.handler.page.rename :as worker-page-rename] [frontend.util.fs :as fs-util] [frontend.worker.file.util :as wfu])) @@ -11,7 +11,7 @@ [page-name] (testing (str "Test sanitization page-name: " page-name) (let [file-name (#'wfu/tri-lb-file-name-sanity page-name) - page-name' (#'common-util/tri-lb-title-parsing file-name) + page-name' (#'extract/tri-lb-title-parsing file-name) url-single (js/encodeURIComponent file-name) url-double (js/encodeURIComponent url-single) file-name' (js/decodeURIComponent url-single) From a68c5eea52f266d788d21c2a9de6ad66bf4fdcee Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Wed, 31 Jan 2024 13:34:09 -0500 Subject: [PATCH 16/16] fix: file/name-format is file graph only Confirmed this with the last refactor. Also remove references to setting that was removed in eb6e5942f8158901776dcaa3d5e48e08c0193400 --- deps/common/resources/templates/config.edn | 4 ++-- src/main/frontend/handler/common/config_edn.cljs | 5 ++--- src/main/frontend/handler/events.cljs | 7 +------ 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/deps/common/resources/templates/config.edn b/deps/common/resources/templates/config.edn index ebb36fcfb..0e1b6b6a9 100644 --- a/deps/common/resources/templates/config.edn +++ b/deps/common/resources/templates/config.edn @@ -405,10 +405,10 @@ ;; :list? false} ;; Default value: false ;; Configure the escaping method for special characters in page titles. + ;; This is _only_ for file graphs. ;; Warning: ;; This is a dangerous operation. To modify the setting, - ;; access the 'Filename format' setting and follow the instructions. - ;; Otherwise, You may need to manually rename all affected files and + ;; you'll need to manually rename all affected files and ;; re-index them on all clients after synchronization. ;; Incorrect handling may result in messy page titles. ;; Available options: diff --git a/src/main/frontend/handler/common/config_edn.cljs b/src/main/frontend/handler/common/config_edn.cljs index 4199b0bf0..e740a43c9 100644 --- a/src/main/frontend/handler/common/config_edn.cljs +++ b/src/main/frontend/handler/common/config_edn.cljs @@ -103,9 +103,8 @@ nested keys or positional errors e.g. tuples" :block-hidden-properties "is not used in DB graphs as hiding a property is done in its configuration" :ignored-page-references-keywords - ;; TODO: Remove key when default is changed - ;; "is not used in DB graphs" - ;; :file/name-format + "is not used in DB graphs" + :file/name-format "is not used in DB graphs" :feature/enable-block-timestamps? "is not used in DB graphs as it is always enabled" diff --git a/src/main/frontend/handler/events.cljs b/src/main/frontend/handler/events.cljs index df25be7cd..7f664c482 100644 --- a/src/main/frontend/handler/events.cljs +++ b/src/main/frontend/handler/events.cljs @@ -777,12 +777,7 @@ "Check " [:a {:href "https://docs.logseq.com/#/page/logseq%20file%20and%20folder%20naming%20rules" :target "_blank"} "Logseq file and folder naming rules"] - " for more details."] - [:p - (util/format "To solve this problem, we suggest you quit Logseq and update the filename format (on Settings > Advanced > Filename format > click EDIT button)%s to avoid more potential bugs." - (if (and util/mac? (not (mobile-util/native-ios?))) - "" - " in other devices"))]]]] + " for more details."]]]] :warning false))