Quellcode durchsuchen

fix: reuse page uuids when parsing files

This commit also removes `with-id?` because it's too confusing.

Fixes LOG-3143
Tienson Qin vor 1 Jahr
Ursprung
Commit
b294896f8a

+ 1 - 1
deps/db/src/logseq/db.cljs

@@ -73,7 +73,7 @@
      (when (seq tx-data)
      (when (seq tx-data)
 
 
        ;; (prn :debug :transact :sync? (= d/transact! (or @*transact-fn d/transact!)) :tx-meta tx-meta)
        ;; (prn :debug :transact :sync? (= d/transact! (or @*transact-fn d/transact!)) :tx-meta tx-meta)
-       ;;  (cljs.pprint/pprint tx-data)
+       ;; (cljs.pprint/pprint tx-data)
 
 
        (let [f (or @*transact-fn d/transact!)]
        (let [f (or @*transact-fn d/transact!)]
          (try
          (try

+ 3 - 1
deps/graph-parser/src/logseq/graph_parser.cljs

@@ -113,7 +113,9 @@ Options available:
                           (assoc :file/created-at (common-util/time-ms)))])
                           (assoc :file/created-at (common-util/time-ms)))])
          result (if skip-db-transact?
          result (if skip-db-transact?
                   tx
                   tx
-                  (ldb/transact! conn tx (select-keys options [:new-graph? :from-disk?])))]
+                  (do
+                    (ldb/transact! conn tx (select-keys options [:new-graph? :from-disk?]))
+                    nil))]
      {:tx result
      {:tx result
       :ast ast})))
       :ast ast})))
 
 

+ 26 - 30
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -299,16 +299,12 @@
 (defn page-name->map
 (defn page-name->map
   "Create a page's map structure given a original page name (string).
   "Create a page's map structure given a original page name (string).
    map as input is supported for legacy compatibility.
    map as input is supported for legacy compatibility.
-   `with-id?`: if true, assign uuid to the map structure.
-    if the page entity already exists, no-op.
-    else, if with-id? is a uuid, the uuid is used.
-    otherwise, generate a uuid.
    `with-timestamp?`: assign timestampes to the map structure.
    `with-timestamp?`: assign timestampes to the map structure.
     Useful when creating new pages from references or namespaces,
     Useful when creating new pages from references or namespaces,
     as there's no chance to introduce timestamps via editing in page
     as there's no chance to introduce timestamps via editing in page
    `skip-existing-page-check?`: if true, allows pages to have the same name"
    `skip-existing-page-check?`: if true, allows pages to have the same name"
-  [original-page-name with-id? db with-timestamp? date-formatter
-   & {:keys [from-page class? skip-existing-page-check?]}]
+  [original-page-name db with-timestamp? date-formatter
+   & {:keys [page-uuid from-page class? skip-existing-page-check?]}]
   (let [db-based? (ldb/db-based-graph? db)]
   (let [db-based? (ldb/db-based-graph? db)]
     (cond
     (cond
       (and original-page-name (string? original-page-name))
       (and original-page-name (string? original-page-name))
@@ -317,7 +313,7 @@
             namespace? (and (not db-based?)
             namespace? (and (not db-based?)
                             (not (boolean (text/get-nested-page-name original-page-name)))
                             (not (boolean (text/get-nested-page-name original-page-name)))
                             (text/namespace-page? original-page-name))
                             (text/namespace-page? original-page-name))
-            page-entity (when (and db (not skip-existing-page-check?))
+            page-entity (when db
                           (if class?
                           (if class?
                             (ldb/get-case-page db original-page-name)
                             (ldb/get-case-page db original-page-name)
                             (ldb/get-page db original-page-name)))
                             (ldb/get-page db original-page-name)))
@@ -325,17 +321,18 @@
         (merge
         (merge
          {:block/name page-name
          {:block/name page-name
           :block/original-name original-page-name}
           :block/original-name original-page-name}
-         (when with-id?
-           (let [new-uuid (or
-                           (cond page-entity      (:block/uuid page-entity)
-                                 (uuid? with-id?) with-id?)
-                           (d/squuid))]
-             {:block/uuid new-uuid}))
+         (let [new-uuid (if skip-existing-page-check?
+                          (d/squuid)
+                          (or
+                           (cond page-entity       (:block/uuid page-entity)
+                                 (uuid? page-uuid) page-uuid)
+                           (d/squuid)))]
+           {:block/uuid new-uuid})
          (when namespace?
          (when namespace?
            (let [namespace (first (common-util/split-last "/" original-page-name))]
            (let [namespace (first (common-util/split-last "/" original-page-name))]
              (when-not (string/blank? namespace)
              (when-not (string/blank? namespace)
                {:block/namespace {:block/name (common-util/page-name-sanity-lc namespace)}})))
                {:block/namespace {:block/name (common-util/page-name-sanity-lc namespace)}})))
-         (when (and with-timestamp? (not page-entity)) ;; Only assign timestamp on creating new entity
+         (when (and with-timestamp? (or skip-existing-page-check? (not page-entity))) ;; Only assign timestamp on creating new entity
            (let [current-ms (common-util/time-ms)]
            (let [current-ms (common-util/time-ms)]
              {:block/created-at current-ms
              {:block/created-at current-ms
               :block/updated-at current-ms}))
               :block/updated-at current-ms}))
@@ -347,14 +344,14 @@
       (and (map? original-page-name) (:block/uuid original-page-name))
       (and (map? original-page-name) (:block/uuid original-page-name))
       original-page-name
       original-page-name
 
 
-      (and (map? original-page-name) with-id?)
-      (assoc original-page-name :block/uuid (d/squuid))
+      (map? original-page-name)
+      (assoc original-page-name :block/uuid (or page-uuid (d/squuid)))
 
 
       :else
       :else
       nil)))
       nil)))
 
 
 (defn- with-page-refs-and-tags
 (defn- with-page-refs-and-tags
-  [{:keys [title body tags refs marker priority] :as block} with-id? db date-formatter]
+  [{:keys [title body tags refs marker priority] :as block} db date-formatter]
   (let [db-based? (ldb/db-based-graph? db)
   (let [db-based? (ldb/db-based-graph? db)
         refs (->> (concat tags refs (when-not db-based? [marker priority]))
         refs (->> (concat tags refs (when-not db-based? [marker priority]))
                   (remove string/blank?)
                   (remove string/blank?)
@@ -399,10 +396,10 @@
                              (let [macro? (and (map? item)
                              (let [macro? (and (map? item)
                                                (= "macro" (:type item)))]
                                                (= "macro" (:type item)))]
                                (when-not macro?
                                (when-not macro?
-                                 (let [result (page-name->map item with-id? db true date-formatter)
+                                 (let [result (page-name->map item db true date-formatter)
                                        page-name (:block/name result)
                                        page-name (:block/name result)
                                        id (get @*name->id page-name)]
                                        id (get @*name->id page-name)]
-                                   (when (and with-id? (nil? id))
+                                   (when (nil? id)
                                      (swap! *name->id assoc page-name (:block/uuid result)))
                                      (swap! *name->id assoc page-name (:block/uuid result)))
                                    (if id
                                    (if id
                                      (assoc result :block/uuid id)
                                      (assoc result :block/uuid id)
@@ -466,12 +463,12 @@
 (defn get-page-refs-from-properties
 (defn get-page-refs-from-properties
   [properties db date-formatter user-config]
   [properties db date-formatter user-config]
   (let [page-refs (get-page-ref-names-from-properties properties user-config)]
   (let [page-refs (get-page-ref-names-from-properties properties user-config)]
-    (map (fn [page] (page-name->map page true db true date-formatter)) page-refs)))
+    (map (fn [page] (page-name->map page db true date-formatter)) page-refs)))
 
 
 (defn- with-page-block-refs
 (defn- with-page-block-refs
-  [block with-id? db date-formatter]
+  [block db date-formatter]
   (some-> block
   (some-> block
-          (with-page-refs-and-tags with-id? db date-formatter)
+          (with-page-refs-and-tags db date-formatter)
           with-block-refs
           with-block-refs
           (update :refs (fn [col] (remove nil? col)))))
           (update :refs (fn [col] (remove nil? col)))))
 
 
@@ -525,7 +522,7 @@
                                 :block/macros (extract-macros-from-ast body)
                                 :block/macros (extract-macros-from-ast body)
                                 :block/body body}
                                 :block/body body}
                          {:keys [tags refs]}
                          {:keys [tags refs]}
-                         (with-page-block-refs {:body body :refs property-refs} true db date-formatter)]
+                         (with-page-block-refs {:body body :refs property-refs} db date-formatter)]
                      (cond-> block
                      (cond-> block
                        tags
                        tags
                        (assoc :block/tags tags)
                        (assoc :block/tags tags)
@@ -543,7 +540,7 @@
     properties))
     properties))
 
 
 (defn- construct-block
 (defn- construct-block
-  [block properties timestamps body encoded-content format pos-meta with-id? {:keys [block-pattern db date-formatter]}]
+  [block properties timestamps body encoded-content format pos-meta {:keys [block-pattern db date-formatter]}]
   (let [id (get-custom-id-or-new-id properties)
   (let [id (get-custom-id-or-new-id properties)
         ref-pages-in-properties (->> (:page-refs properties)
         ref-pages-in-properties (->> (:page-refs properties)
                                      (remove string/blank?))
                                      (remove string/blank?))
@@ -581,7 +578,7 @@
                 block)
                 block)
         block (-> block
         block (-> block
                   (assoc :body body)
                   (assoc :body body)
-                  (with-page-block-refs with-id? db date-formatter)
+                  (with-page-block-refs db date-formatter)
                   (update :tags (fn [tags] (map #(assoc % :block/format format) tags)))
                   (update :tags (fn [tags] (map #(assoc % :block/format format) tags)))
                   (update :refs (fn [refs] (map #(if (map? %) (assoc % :block/format format) %) refs))))
                   (update :refs (fn [refs] (map #(if (map? %) (assoc % :block/format format) %) refs))))
         block (update block :refs concat (:block-refs properties))
         block (update block :refs concat (:block-refs properties))
@@ -635,12 +632,11 @@
   Args:
   Args:
     `blocks`: mldoc ast.
     `blocks`: mldoc ast.
     `content`: markdown or org-mode text.
     `content`: markdown or org-mode text.
-    `with-id?`: If `with-id?` equals to true, all the referenced pages will have new db ids.
     `format`: content's format, it could be either :markdown or :org-mode.
     `format`: content's format, it could be either :markdown or :org-mode.
     `options`: Options supported are :user-config, :block-pattern,
     `options`: Options supported are :user-config, :block-pattern,
                :extract-macros, :date-formatter, :page-name, :db-graph-mode? and :db"
                :extract-macros, :date-formatter, :page-name, :db-graph-mode? and :db"
-  [blocks content with-id? format {:keys [user-config db-graph-mode?] :as options}]
-  {:pre [(seq blocks) (string? content) (boolean? with-id?) (contains? #{:markdown :org} format)]}
+  [blocks content format {:keys [user-config db-graph-mode?] :as options}]
+  {:pre [(seq blocks) (string? content) (contains? #{:markdown :org} format)]}
   (let [encoded-content (utf8/encode content)
   (let [encoded-content (utf8/encode content)
         [blocks body pre-block-properties]
         [blocks body pre-block-properties]
         (loop [headings []
         (loop [headings []
@@ -668,7 +664,7 @@
                   (recur headings (rest blocks) timestamps properties body))
                   (recur headings (rest blocks) timestamps properties body))
 
 
                 (heading-block? block)
                 (heading-block? block)
-                (let [block' (construct-block block properties timestamps body encoded-content format pos-meta with-id? options)
+                (let [block' (construct-block block properties timestamps body encoded-content format pos-meta options)
                       block'' (if db-graph-mode?
                       block'' (if db-graph-mode?
                                 block'
                                 block'
                                 (assoc block' :macros (extract-macros-from-ast (cons block body))))]
                                 (assoc block' :macros (extract-macros-from-ast (cons block body))))]
@@ -806,6 +802,6 @@
                   (common-util/uuid-string? %)
                   (common-util/uuid-string? %)
                   {:block/uuid (uuid %)}
                   {:block/uuid (uuid %)}
                   :else
                   :else
-                  (page-name->map % true db true date-formatter))
+                  (page-name->map % db true date-formatter))
                refs')
                refs')
           set))))
           set))))

+ 9 - 4
deps/graph-parser/src/logseq/graph_parser/extract.cljc

@@ -161,7 +161,7 @@
         page-m (->
         page-m (->
                 (common-util/remove-nils-non-nested
                 (common-util/remove-nils-non-nested
                  (assoc
                  (assoc
-                  (gp-block/page-name->map page false db true date-formatter
+                  (gp-block/page-name->map page db true date-formatter
                                            :from-page from-page)
                                            :from-page from-page)
                   :block/file {:file/path (common-util/path-normalize file)}))
                   :block/file {:file/path (common-util/path-normalize file)}))
                 (extract-page-alias-and-tags page-name properties))]
                 (extract-page-alias-and-tags page-name properties))]
@@ -212,7 +212,7 @@
           options' (assoc options :page-name page-name)
           options' (assoc options :page-name page-name)
           ;; In case of diff-merge (2way) triggered, use the uuids to override the ones extracted from the AST
           ;; In case of diff-merge (2way) triggered, use the uuids to override the ones extracted from the AST
           override-uuids (resolve-uuid-fn format ast content options')
           override-uuids (resolve-uuid-fn format ast content options')
-          blocks (->> (gp-block/extract-blocks ast content false format options')
+          blocks (->> (gp-block/extract-blocks ast content format options')
                       (attach-block-ids-if-match override-uuids)
                       (attach-block-ids-if-match override-uuids)
                       (mapv #(gp-block/fix-block-id-if-duplicated! db page-name extracted-block-ids %))
                       (mapv #(gp-block/fix-block-id-if-duplicated! db page-name extracted-block-ids %))
                       ;; FIXME: use page uuid
                       ;; FIXME: use page uuid
@@ -243,7 +243,7 @@
                               (when (text/namespace-page? page)
                               (when (text/namespace-page? page)
                                 (->> (common-util/split-namespace-pages page)
                                 (->> (common-util/split-namespace-pages page)
                                      (map (fn [page]
                                      (map (fn [page]
-                                            (-> (gp-block/page-name->map page true db true date-formatter)
+                                            (-> (gp-block/page-name->map page db true date-formatter)
                                                 (assoc :block/format format))))))))
                                                 (assoc :block/format format))))))))
           pages (->> (concat
           pages (->> (concat
                       [page-map]
                       [page-map]
@@ -254,7 +254,12 @@
                      (remove nil?))
                      (remove nil?))
           pages (common-util/distinct-by :block/name pages)
           pages (common-util/distinct-by :block/name pages)
           pages (remove nil? pages)
           pages (remove nil? pages)
-          pages (map (fn [page] (assoc page :block/uuid (d/squuid))) pages)
+          pages (map (fn [page]
+                       (let [page-id (or (when db
+                                           (:block/uuid (ldb/get-page db (:block/name page))))
+                                         (d/squuid))]
+                         (assoc page :block/uuid page-id)))
+                     pages)
           blocks (->> (remove nil? blocks)
           blocks (->> (remove nil? blocks)
                       (map (fn [b] (dissoc b :block/title :block/body :block/level :block/children :block/meta))))]
                       (map (fn [b] (dissoc b :block/title :block/body :block/level :block/children :block/meta))))]
       [pages blocks])
       [pages blocks])

+ 1 - 1
deps/graph-parser/test/logseq/graph_parser/block_test.cljs

@@ -102,7 +102,7 @@
                                          {})))
                                          {})))
         "Default to enabled when :property-pages/enabled? is not in config")
         "Default to enabled when :property-pages/enabled? is not in config")
 
 
-    (is (= ["tags" "foo" "bar"]
+    (is (= ["foo" "bar" "tags"]
            (:page-refs
            (:page-refs
             (extract-properties
             (extract-properties
              ;; tags is linkable and background-color is not
              ;; tags is linkable and background-color is not

+ 1 - 1
src/main/frontend/components/diff.cljs

@@ -36,7 +36,7 @@
   [:div.cp__diff-file
   [:div.cp__diff-file
    [:div.cp__diff-file-header
    [:div.cp__diff-file-header
     [:span.cp__diff-file-header-content.pl-1.font-medium
     [:span.cp__diff-file-header-content.pl-1.font-medium
-     (str "File " path " has been modified on the disk.")]]
+     (str "File " path "has been modified on the disk.")]]
    [:div.p-4
    [:div.p-4
     (when (not= (string/trim disk-content) (string/trim db-content))
     (when (not= (string/trim disk-content) (string/trim db-content))
       (ui/foldable
       (ui/foldable

+ 0 - 1
src/main/frontend/db_worker.cljs

@@ -552,7 +552,6 @@
    [this repo]
    [this repo]
    (let [conn (worker-state/get-datascript-conn repo)
    (let [conn (worker-state/get-datascript-conn repo)
          writes @file/*writes]
          writes @file/*writes]
-
      ;; Clean pages that have been deleted
      ;; Clean pages that have been deleted
      (when conn
      (when conn
        (swap! file/*writes (fn [writes]
        (swap! file/*writes (fn [writes]

+ 20 - 24
src/main/frontend/format/block.cljs

@@ -16,11 +16,10 @@
 (defn extract-blocks
 (defn extract-blocks
   "Wrapper around logseq.graph-parser.block/extract-blocks that adds in system state
   "Wrapper around logseq.graph-parser.block/extract-blocks that adds in system state
 and handles unexpected failure."
 and handles unexpected failure."
-  [blocks content format {:keys [with-id? page-name]
-                          :or {with-id? true}}]
+  [blocks content format {:keys [page-name]}]
   (let [repo (state/get-current-repo)]
   (let [repo (state/get-current-repo)]
     (try
     (try
-     (gp-block/extract-blocks blocks content with-id? format
+     (gp-block/extract-blocks blocks content format
                               {:user-config (state/get-config)
                               {:user-config (state/get-config)
                                :block-pattern (config/get-block-pattern format)
                                :block-pattern (config/get-block-pattern format)
                                :db (db/get-db repo)
                                :db (db/get-db repo)
@@ -36,10 +35,10 @@ and handles unexpected failure."
 
 
 (defn page-name->map
 (defn page-name->map
   "Wrapper around logseq.graph-parser.block/page-name->map that adds in db"
   "Wrapper around logseq.graph-parser.block/page-name->map that adds in db"
-  ([original-page-name with-id?]
-   (page-name->map original-page-name with-id? true))
-  ([original-page-name with-id? with-timestamp?]
-   (gp-block/page-name->map original-page-name with-id? (db/get-db (state/get-current-repo)) with-timestamp? (state/get-date-formatter))))
+  ([original-page-name]
+   (page-name->map original-page-name true))
+  ([original-page-name with-timestamp?]
+   (gp-block/page-name->map original-page-name (db/get-db (state/get-current-repo)) with-timestamp? (state/get-date-formatter))))
 
 
 (defn- normalize-as-percentage
 (defn- normalize-as-percentage
   [block]
   [block]
@@ -69,23 +68,20 @@ and handles unexpected failure."
        (first)))
        (first)))
 
 
 (defn parse-block
 (defn parse-block
-  ([block]
-   (parse-block block nil))
-  ([{:block/keys [uuid content format] :as block} {:keys [with-id?]
-                                                   :or {with-id? true}}]
-   (when-not (string/blank? content)
-     (let [block (dissoc block :block/pre-block?)
-           format (or format :markdown)
-           parse-config (mldoc/get-default-config format)
-           ast (format/to-edn content format parse-config)
-           blocks (extract-blocks ast content format {:with-id? with-id?})
-           new-block (first blocks)
-           block (cond->
-                  (merge block new-block)
-                   (> (count blocks) 1)
-                   (assoc :block/warning :multiple-blocks))
-           block (dissoc block :block/title :block/body :block/level)]
-       (if uuid (assoc block :block/uuid uuid) block)))))
+  [{:block/keys [uuid content format] :as block}]
+  (when-not (string/blank? content)
+    (let [block (dissoc block :block/pre-block?)
+          format (or format :markdown)
+          parse-config (mldoc/get-default-config format)
+          ast (format/to-edn content format parse-config)
+          blocks (extract-blocks ast content format {})
+          new-block (first blocks)
+          block (cond->
+                 (merge block new-block)
+                  (> (count blocks) 1)
+                  (assoc :block/warning :multiple-blocks))
+          block (dissoc block :block/title :block/body :block/level)]
+      (if uuid (assoc block :block/uuid uuid) block))))
 
 
 (defn parse-title-and-body
 (defn parse-title-and-body
   ([block]
   ([block]

+ 73 - 69
src/main/frontend/fs/watcher_handler.cljs

@@ -19,7 +19,8 @@
             [logseq.common.config :as common-config]
             [logseq.common.config :as common-config]
             [logseq.common.util.block-ref :as block-ref]
             [logseq.common.util.block-ref :as block-ref]
             [promesa.core :as p]
             [promesa.core :as p]
-            [frontend.db.async :as db-async]))
+            [frontend.db.async :as db-async]
+            [frontend.db.transact :as db-transact]))
 
 
 ;; all IPC paths must be normalized! (via common-util/path-normalize)
 ;; all IPC paths must be normalized! (via common-util/path-normalize)
 
 
@@ -59,84 +60,87 @@
 
 
 (defn handle-changed!
 (defn handle-changed!
   [type {:keys [dir path content stat global-dir] :as payload}]
   [type {:keys [dir path content stat global-dir] :as payload}]
-  (when dir
-    (let [;; Global directory events don't know their originating repo so we rely
+  (let [repo (state/get-current-repo)
+        ^js sqlite @state/*db-worker]
+    (p/let [writes-finished? (when sqlite (.file-writes-finished? sqlite repo))]
+      (when (and dir writes-finished? (db-transact/request-finished?))
+        (let [;; Global directory events don't know their originating repo so we rely
           ;; on the client to correctly identify it
           ;; on the client to correctly identify it
-          repo (cond
-                 global-dir (state/get-current-repo)
+              repo (cond
+                     global-dir (state/get-current-repo)
                  ;; FIXME(andelf): hack for demo graph, demo graph does not bind to local directory
                  ;; FIXME(andelf): hack for demo graph, demo graph does not bind to local directory
-                 (string/starts-with? dir "memory://") "Logseq demo"
-                 :else (config/get-local-repo dir))
-          repo-dir (config/get-local-dir repo)
-          {:keys [mtime]} stat
-          ext (keyword (path/file-ext path))]
-      (when (contains? #{:org :md :markdown :css :js :edn :excalidraw :tldr} ext)
-        (p/let [db-content (db-async/<get-file repo path)
-                exists-in-db? (not (nil? db-content))
-                db-content (or db-content "")]
-          (when (or content (contains? #{"unlink" "unlinkDir" "addDir"} type))
-            (cond
-              (and (= "unlinkDir" type) dir)
-              (state/pub-event! [:graph/dir-gone dir])
-
-              (and (= "addDir" type) dir)
-              (state/pub-event! [:graph/dir-back repo dir])
-
-              (contains? (:file/unlinked-dirs @state/state) dir)
-              nil
-
-              (and (= "add" type)
-                   (not= (string/trim content) (string/trim db-content)))
-              (let [backup? (not (string/blank? db-content))]
-                (handle-add-and-change! repo path content db-content mtime backup?))
-
-              (and (= "change" type)
-                   (= dir repo-dir)
-                   (not= (string/trim content) (string/trim db-content))
-                   (not (common-config/local-asset? path)))
-              (when-not (and
-                         (string/includes? path (str "/" (config/get-journals-directory) "/"))
-                         (or
-                          (= (string/trim content)
-                             (string/trim (or (state/get-default-journal-template) "")))
-                          (= (string/trim content) "-")
-                          (= (string/trim content) "*")))
-                (handle-add-and-change! repo path content db-content mtime (not global-dir))) ;; no backup for global dir
-
-              (and (= "unlink" type)
-                   exists-in-db?)
-              (p/let [dir-exists? (fs/file-exists? dir "")]
-                (when dir-exists?
-                  (when-let [page-name (db/get-file-page path)]
-                    (println "Delete page: " page-name ", file path: " path ".")
-                    (page-handler/<delete! page-name #()))))
+                     (string/starts-with? dir "memory://") "Logseq demo"
+                     :else (config/get-local-repo dir))
+              repo-dir (config/get-local-dir repo)
+              {:keys [mtime]} stat
+              ext (keyword (path/file-ext path))]
+          (when (contains? #{:org :md :markdown :css :js :edn :excalidraw :tldr} ext)
+            (p/let [db-content (db-async/<get-file repo path)
+                    exists-in-db? (not (nil? db-content))
+                    db-content (or db-content "")]
+              (when (or content (contains? #{"unlink" "unlinkDir" "addDir"} type))
+                (cond
+                  (and (= "unlinkDir" type) dir)
+                  (state/pub-event! [:graph/dir-gone dir])
+
+                  (and (= "addDir" type) dir)
+                  (state/pub-event! [:graph/dir-back repo dir])
+
+                  (contains? (:file/unlinked-dirs @state/state) dir)
+                  nil
+
+                  (and (= "add" type)
+                       (not= (string/trim content) (string/trim db-content)))
+                  (let [backup? (not (string/blank? db-content))]
+                    (handle-add-and-change! repo path content db-content mtime backup?))
+
+                  (and (= "change" type)
+                       (= dir repo-dir)
+                       (not= (string/trim content) (string/trim db-content))
+                       (not (common-config/local-asset? path)))
+                  (when-not (and
+                             (string/includes? path (str "/" (config/get-journals-directory) "/"))
+                             (or
+                              (= (string/trim content)
+                                 (string/trim (or (state/get-default-journal-template) "")))
+                              (= (string/trim content) "-")
+                              (= (string/trim content) "*")))
+                    (handle-add-and-change! repo path content db-content mtime (not global-dir))) ;; no backup for global dir
+
+                  (and (= "unlink" type)
+                       exists-in-db?)
+                  (p/let [dir-exists? (fs/file-exists? dir "")]
+                    (when dir-exists?
+                      (when-let [page-name (db/get-file-page path)]
+                        (println "Delete page: " page-name ", file path: " path ".")
+                        (page-handler/<delete! page-name #()))))
 
 
           ;; global config handling
           ;; global config handling
-              (and (= "change" type)
-                   (= dir (global-config-handler/global-config-dir)))
-              (when (= path "config.edn")
-                (file-handler/alter-global-file
-                 (global-config-handler/global-config-path) content {:from-disk? true}))
+                  (and (= "change" type)
+                       (= dir (global-config-handler/global-config-dir)))
+                  (when (= path "config.edn")
+                    (file-handler/alter-global-file
+                     (global-config-handler/global-config-path) content {:from-disk? true}))
 
 
-              (and (= "change" type)
-                   (not exists-in-db?))
-              (js/console.error "Can't get file in the db: " path)
+                  (and (= "change" type)
+                       (not exists-in-db?))
+                  (js/console.error "Can't get file in the db: " path)
 
 
-              (and (contains? #{"add" "change" "unlink"} type)
-                   (string/ends-with? path "logseq/custom.css"))
-              (do
-                (println "reloading custom.css")
-                (ui-handler/add-style-if-exists!))
+                  (and (contains? #{"add" "change" "unlink"} type)
+                       (string/ends-with? path "logseq/custom.css"))
+                  (do
+                    (println "reloading custom.css")
+                    (ui-handler/add-style-if-exists!))
 
 
-              (contains? #{"add" "change" "unlink"} type)
-              nil
+                  (contains? #{"add" "change" "unlink"} type)
+                  nil
 
 
-              :else
-              (log/error :fs/watcher-no-handler {:type type
-                                                 :payload payload})))))
+                  :else
+                  (log/error :fs/watcher-no-handler {:type type
+                                                     :payload payload})))))
 
 
       ;; return nil, otherwise the entire db will be transferred by ipc
       ;; return nil, otherwise the entire db will be transferred by ipc
-      nil)))
+          nil)))))
 
 
 (defn load-graph-files!
 (defn load-graph-files!
   "This fn replaces the former initial fs watcher"
   "This fn replaces the former initial fs watcher"

+ 1 - 0
src/main/frontend/handler/events.cljs

@@ -394,6 +394,7 @@
   (p/let [_ (page-handler/create-today-journal!)]
   (p/let [_ (page-handler/create-today-journal!)]
     (ui-handler/re-render-root!)))
     (ui-handler/re-render-root!)))
 
 
+;; FIXME: this still happens when writing fast
 (defmethod handle :file/not-matched-from-disk [[_ path disk-content db-content]]
 (defmethod handle :file/not-matched-from-disk [[_ path disk-content db-content]]
   (when-let [repo (state/get-current-repo)]
   (when-let [repo (state/get-current-repo)]
     (let [^js sqlite @db-browser/*worker]
     (let [^js sqlite @db-browser/*worker]

+ 0 - 1
src/main/frontend/handler/export.cljs

@@ -121,7 +121,6 @@
 
 
 (defn- <export-repo-as-edn-str [repo]
 (defn- <export-repo-as-edn-str [repo]
   (p/let [result (<build-blocks repo)]
   (p/let [result (<build-blocks repo)]
-    (prn :debug :result result)
     (let [sb (StringBuffer.)]
     (let [sb (StringBuffer.)]
       (pprint/pprint result (StringBufferWriter. sb))
       (pprint/pprint result (StringBufferWriter. sb))
       (str sb))))
       (str sb))))

+ 1 - 1
src/main/frontend/state.cljs

@@ -1605,7 +1605,7 @@ Similar to re-frame subscriptions"
 (defn close-modal!
 (defn close-modal!
   [& {:keys [force?]
   [& {:keys [force?]
       :or {force? false}}]
       :or {force? false}}]
-  (when (or force? (not (or (editing?) (:error/multiple-tabs-access-opfs? @state))))
+  (when (or force? (not (:error/multiple-tabs-access-opfs? @state)))
     (close-dropdowns!)
     (close-dropdowns!)
     (if (seq (get-sub-modals))
     (if (seq (get-sub-modals))
       (close-sub-modal!)
       (close-sub-modal!)

+ 3 - 2
src/main/frontend/worker/handler/page.cljs

@@ -15,8 +15,9 @@
   (assert (uuid? uuid) (str "rtc-create-page! `uuid` is not a uuid " uuid))
   (assert (uuid? uuid) (str "rtc-create-page! `uuid` is not a uuid " uuid))
   (let [date-formatter    (common-config/get-date-formatter config)
   (let [date-formatter    (common-config/get-date-formatter config)
         [title page-name] (db-worker-page/get-title-and-pagename title)
         [title page-name] (db-worker-page/get-title-and-pagename title)
-        page              (-> (gp-block/page-name->map title uuid @conn true date-formatter
-                                                       {:skip-existing-page-check? true})
+        page              (-> (gp-block/page-name->map title @conn true date-formatter
+                                                       {:page-uuid uuid
+                                                        :skip-existing-page-check? true})
                               (assoc :block/format :markdown))
                               (assoc :block/format :markdown))
         result            (ldb/transact! conn [page] {:persist-op? false
         result            (ldb/transact! conn [page] {:persist-op? false
                                                       :outliner-op :create-page})]
                                                       :outliner-op :create-page})]

+ 5 - 4
src/main/frontend/worker/handler/page/db_based/page.cljs

@@ -68,11 +68,12 @@
            persist-op?              true}
            persist-op?              true}
     :as options}]
     :as options}]
   (let [date-formatter (common-config/get-date-formatter config)
   (let [date-formatter (common-config/get-date-formatter config)
-        [title page-name] (get-title-and-pagename title)
-        with-uuid? (if (uuid? uuid) uuid true)]
+        [title page-name] (get-title-and-pagename title)]
     (when-not (ldb/get-case-page @conn page-name)
     (when-not (ldb/get-case-page @conn page-name)
       (let [format    :markdown
       (let [format    :markdown
-            page      (-> (gp-block/page-name->map title with-uuid? @conn true date-formatter :class? class?)
+            page      (-> (gp-block/page-name->map title @conn true date-formatter
+                                                   {:class? class?
+                                                    :page-uuid (when (uuid? uuid) uuid)})
                           (assoc :block/format format))
                           (assoc :block/format format))
             page-uuid (:block/uuid page)
             page-uuid (:block/uuid page)
             page-txs  (build-page-tx conn properties page (select-keys options [:whiteboard? :class? :tags]))
             page-txs  (build-page-tx conn properties page (select-keys options [:whiteboard? :class? :tags]))
@@ -90,4 +91,4 @@
                                                                       today-journal?
                                                                       today-journal?
                                                                       (assoc :create-today-journal? true
                                                                       (assoc :create-today-journal? true
                                                                              :today-journal-name page-name)))])]
                                                                              :today-journal-name page-name)))])]
-        [result page-name page-uuid]))))
+        [result page-name page-uuid]))))

+ 3 - 3
src/main/frontend/worker/handler/page/file_based/page.cljs

@@ -75,8 +75,7 @@
   (let [date-formatter (common-config/get-date-formatter config)
   (let [date-formatter (common-config/get-date-formatter config)
         split-namespace? (not (or (string/starts-with? title "hls__")
         split-namespace? (not (or (string/starts-with? title "hls__")
                                   (date/valid-journal-title? date-formatter title)))
                                   (date/valid-journal-title? date-formatter title)))
-        [title page-name] (get-title-and-pagename title)
-        with-uuid? (if (uuid? uuid) uuid true)]
+        [title page-name] (get-title-and-pagename title)]
     (when-not (ldb/get-page @conn page-name)
     (when-not (ldb/get-page @conn page-name)
       (let [pages    (if split-namespace?
       (let [pages    (if split-namespace?
                        (common-util/split-namespace-pages title)
                        (common-util/split-namespace-pages title)
@@ -84,7 +83,8 @@
             format   (or format (common-config/get-preferred-format config))
             format   (or format (common-config/get-preferred-format config))
             pages    (map (fn [page]
             pages    (map (fn [page]
                             ;; only apply uuid to the deepest hierarchy of page to create if provided.
                             ;; 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)
+                            (-> (gp-block/page-name->map page @conn true date-formatter
+                                                         {:page-uuid (when (uuid? uuid) uuid)})
                                 (assoc :block/format format)))
                                 (assoc :block/format format)))
                           pages)
                           pages)
             txs      (->> pages
             txs      (->> pages

+ 1 - 1
src/test/frontend/db/model_test.cljs

@@ -79,7 +79,7 @@
 - link to ns [[one]]
 - link to ns [[one]]
 - link to page one [[page ONE]]"}])
 - link to page one [[page ONE]]"}])
 
 
-  (is (= '("one/two/tree" "page one")
+  (is (= '("one/two/tree" "tags" "page one")
          (map second (model/get-pages-relation test-helper/test-db true)))
          (map second (model/get-pages-relation test-helper/test-db true)))
       "(get-pages-relation) Must be only ns one/two/tree")
       "(get-pages-relation) Must be only ns one/two/tree")