Browse Source

fix: rtc creates duplicated first blocks for new journal pages (#11913)

* fix: rtc creates duplicated first blocks for new journal pages

The root cause is that those blocks from different clients have
different ids. Instead of using persistent block id, this fix avoids
generating the first block until users really start editing it.

* fix: add button not displayed when the last block is not empty

* fix: e2e tests

* enhance: remove dummy block

* fix: open-last-block
Tienson Qin 4 months ago
parent
commit
8eee397b45
31 changed files with 207 additions and 325 deletions
  1. 7 1
      clj-e2e/src/logseq/e2e/block.clj
  2. 4 4
      clj-e2e/src/logseq/e2e/util.clj
  3. 1 2
      clj-e2e/test/logseq/e2e/rtc_extra_test.clj
  4. 0 1
      src/main/frontend/common.css
  5. 1 2
      src/main/frontend/components/cmdk/core.cljs
  6. 1 2
      src/main/frontend/components/editor.cljs
  7. 32 89
      src/main/frontend/components/page.cljs
  8. 0 25
      src/main/frontend/components/page.css
  9. 1 2
      src/main/frontend/components/property/config.cljs
  10. 1 3
      src/main/frontend/components/property/value.cljs
  11. 5 5
      src/main/frontend/extensions/pdf/assets.cljs
  12. 1 2
      src/main/frontend/extensions/zotero/handler.cljs
  13. 62 62
      src/main/frontend/fs/sync.cljs
  14. 10 5
      src/main/frontend/handler/common/page.cljs
  15. 1 2
      src/main/frontend/handler/db_based/page.cljs
  16. 24 11
      src/main/frontend/handler/editor.cljs
  17. 0 1
      src/main/frontend/handler/import.cljs
  18. 1 5
      src/main/frontend/handler/page.cljs
  19. 2 3
      src/main/frontend/handler/profiler.cljs
  20. 7 7
      src/main/frontend/modules/shortcut/core.cljs
  21. 1 1
      src/main/frontend/worker/commands.cljs
  22. 0 1
      src/main/frontend/worker/handler/page.cljs
  23. 3 23
      src/main/frontend/worker/handler/page/db_based/page.cljs
  24. 4 24
      src/main/frontend/worker/handler/page/file_based/page.cljs
  25. 2 5
      src/main/logseq/api.cljs
  26. 1 1
      src/main/logseq/api/block.cljs
  27. 4 4
      src/test/frontend/db/db_based_model_test.cljs
  28. 5 5
      src/test/frontend/handler/db_based/recent_test.cljs
  29. 14 14
      src/test/frontend/worker/handler/page/file_based/rename_test.cljs
  30. 8 9
      src/test/frontend/worker/rtc/gen_client_op_test.cljs
  31. 4 4
      src/test/frontend/worker/rtc/rtc_fns_test.cljs

+ 7 - 1
clj-e2e/src/logseq/e2e/block.clj

@@ -8,10 +8,16 @@
             [wally.main :as w]))
             [wally.main :as w]))
 
 
 (defn open-last-block
 (defn open-last-block
+  "Open the last existing block or pressing add button to create a new block"
   []
   []
   (util/double-esc)
   (util/double-esc)
   (assert/assert-in-normal-mode?)
   (assert/assert-in-normal-mode?)
-  (w/click (last (w/query ".ls-page-blocks .ls-block .block-content"))))
+  (let [blocks-count (util/page-blocks-count)
+        last-block (-> (if (zero? blocks-count)
+                         (w/query ".ls-page-blocks .block-add-button")
+                         (w/query ".ls-page-blocks .page-blocks-inner .ls-block .block-content"))
+                       (last))]
+    (w/click last-block)))
 
 
 (defn save-block
 (defn save-block
   [text]
   [text]

+ 4 - 4
clj-e2e/src/logseq/e2e/util.clj

@@ -98,11 +98,11 @@
 (defn blocks-count
 (defn blocks-count
   "Blocks count including page title"
   "Blocks count including page title"
   []
   []
-  (count-elements ".ls-block"))
+  (count-elements ".ls-block:not(.block-add-button)"))
 
 
 (defn page-blocks-count
 (defn page-blocks-count
   []
   []
-  (count-elements ".ls-page-blocks .ls-block"))
+  (count-elements ".ls-page-blocks .page-blocks-inner .ls-block"))
 
 
 (defn exit-edit
 (defn exit-edit
   []
   []
@@ -132,7 +132,7 @@
 
 
 (defn get-page-blocks-contents
 (defn get-page-blocks-contents
   []
   []
-  (w/all-text-contents ".ls-page-blocks .ls-block .block-title-wrap"))
+  (w/all-text-contents ".ls-page-blocks .ls-block:not(.block-add-button) .block-title-wrap"))
 
 
 (def mac? (= "Mac OS X" (System/getProperty "os.name")))
 (def mac? (= "Mac OS X" (System/getProperty "os.name")))
 
 
@@ -184,7 +184,7 @@
   (w/click (first (w/query (format "a.menu-link:has-text(\"%s\")" tag))))
   (w/click (first (w/query (format "a.menu-link:has-text(\"%s\")" tag))))
   ;; wait tag added on ui
   ;; wait tag added on ui
   (assert/assert-is-visible
   (assert/assert-is-visible
-   (-> ".ls-block"
+   (-> ".ls-block:not(.block-add-button)"
        (loc/filter :has ".editor-wrapper textarea")
        (loc/filter :has ".editor-wrapper textarea")
        (loc/filter :has (format ".block-tag :text('%s')" tag)))))
        (loc/filter :has (format ".block-tag :text('%s')" tag)))))
 
 

+ 1 - 2
clj-e2e/test/logseq/e2e/rtc_extra_test.clj

@@ -15,8 +15,7 @@
    [logseq.e2e.rtc :as rtc]
    [logseq.e2e.rtc :as rtc]
    [logseq.e2e.settings :as settings]
    [logseq.e2e.settings :as settings]
    [logseq.e2e.util :as util]
    [logseq.e2e.util :as util]
-   [wally.main :as w]
-   [wally.repl :as repl]))
+   [wally.main :as w]))
 
 
 (defn- prepare-rtc-graph-fixture
 (defn- prepare-rtc-graph-fixture
   "open 2 app instances, add a rtc graph, check this graph available on other instance"
   "open 2 app instances, add a rtc graph, check this graph available on other instance"

+ 0 - 1
src/main/frontend/common.css

@@ -326,7 +326,6 @@ h1.title, h1.title input, .ls-page-title-container {
 
 
 .block-highlight,
 .block-highlight,
 .ls-block.selected,
 .ls-block.selected,
-.ls-dummy-block.selected,
 .ls-table-cell.selected
 .ls-table-cell.selected
 {
 {
   transition: background-color 0.2s cubic-bezier(0, 1, 0, 1);
   transition: background-color 0.2s cubic-bezier(0, 1, 0, 1);

+ 1 - 2
src/main/frontend/components/cmdk/core.cljs

@@ -542,8 +542,7 @@
     (p/let [result (cond
     (p/let [result (cond
                      create-class?
                      create-class?
                      (db-page-handler/<create-class! class
                      (db-page-handler/<create-class! class
-                                                     {:redirect? false
-                                                      :create-first-block? false})
+                                                     {:redirect? false})
                      create-whiteboard? (whiteboard-handler/<create-new-whiteboard-and-redirect! @!input)
                      create-whiteboard? (whiteboard-handler/<create-new-whiteboard-and-redirect! @!input)
                      create-page? (page-handler/<create! @!input {:redirect? true}))]
                      create-page? (page-handler/<create! @!input {:redirect? true}))]
       (shui/dialog-close! :ls-dialog-cmdk)
       (shui/dialog-close! :ls-dialog-cmdk)

+ 1 - 2
src/main/frontend/components/editor.cljs

@@ -122,8 +122,7 @@
         (state/set-edit-content! (.-id input) value')
         (state/set-edit-content! (.-id input) value')
         (state/clear-editor-action!)
         (state/clear-editor-action!)
         (p/let [page (db/get-page chosen-item)
         (p/let [page (db/get-page chosen-item)
-                _ (when-not page (page-handler/<create! chosen-item {:redirect? false
-                                                                     :create-first-block? false}))
+                _ (when-not page (page-handler/<create! chosen-item {:redirect? false}))
                 page' (db/get-page chosen-item)
                 page' (db/get-page chosen-item)
                 current-block (state/get-edit-block)]
                 current-block (state/get-edit-block)]
           (editor-handler/api-insert-new-block! chosen-item
           (editor-handler/api-insert-new-block! chosen-item

+ 32 - 89
src/main/frontend/components/page.cljs

@@ -28,7 +28,6 @@
             [frontend.format.mldoc :as mldoc]
             [frontend.format.mldoc :as mldoc]
             [frontend.handler.common :as common-handler]
             [frontend.handler.common :as common-handler]
             [frontend.handler.config :as config-handler]
             [frontend.handler.config :as config-handler]
-            [frontend.handler.dnd :as dnd]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.graph :as graph-handler]
             [frontend.handler.graph :as graph-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
@@ -36,7 +35,6 @@
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.mixins :as mixins]
             [frontend.mixins :as mixins]
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
-            [frontend.rum :as frontend-rum]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [frontend.util :as util]
@@ -101,93 +99,44 @@
 
 
 (declare page-cp)
 (declare page-cp)
 
 
-(if config/publishing?
-  (rum/defc dummy-block
-    [_page]
-    [:div])
-
-  (rum/defc dummy-block
-    [page]
-    (let [[hover set-hover!] (rum/use-state false)
-          click-handler-fn (fn []
-                             (p/let [result (editor-handler/insert-first-page-block-if-not-exists! (:block/uuid page))
-                                     result (:tx-data result)
-                                     first-child-id (first (map :block/uuid result))
-                                     first-child (when first-child-id (db/entity [:block/uuid first-child-id]))]
-                               (when first-child
-                                 (editor-handler/edit-block! first-child :max {:container-id :unknown-container}))))
-          drop-handler-fn (fn [^js event]
-                            (util/stop event)
-                            (p/let [block-uuids (state/get-selection-block-ids)
-                                    lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
-                                    selected (db/pull-many (state/get-current-repo) '[*] lookup-refs)
-                                    blocks (if (seq selected) selected [@component-block/*dragging-block])
-                                    _ (editor-handler/insert-first-page-block-if-not-exists! (:block/uuid page))]
-                              (js/setTimeout #(let [target-block page]
-                                                (dnd/move-blocks event blocks target-block nil :sibling))
-                                             0)))
-          *dummy-block-uuid (rum/use-ref (random-uuid))
-          *el-ref (rum/use-ref nil)
-          _ (frontend-rum/use-atom (@state/state :selection/blocks))
-          selection-ids (state/get-selection-block-ids)
-          selected? (contains? (set selection-ids) (rum/deref *dummy-block-uuid))
-          idstr (str (rum/deref *dummy-block-uuid))
-          focus! (fn [] (js/setTimeout #(some-> (rum/deref *el-ref) (.focus)) 16))]
-
-      ;; mounted
-      ;(hooks/use-effect! #(focus!) [])
-      (hooks/use-effect! #(if selected? (focus!)
-                              (some-> (rum/deref *el-ref) (.blur))) [selected?])
-
-      (shui/trigger-as
-       :div.ls-dummy-block.ls-block
-
-       {:style {:width "100%"
-                 ;; The same as .dnd-separator
-                :border-top (if hover
-                              "3px solid #ccc"
-                              nil)
-                :margin-left 20}
-        :ref *el-ref
-        :tabIndex 0
-        :on-click click-handler-fn
-        :id idstr
-        :blockid idstr
-        :class (when selected? "selected")}
-
-       [:div.flex.items-center
-        [:div.flex.items-center.mx-1 {:style {:height 24}}
-         [:span.bullet-container.cursor
-          [:span.bullet]]]
-
-        [:div.flex.flex-1.cursor-text
-         {:on-drag-enter #(set-hover! true)
-          :on-drag-over #(util/stop %)
-          :on-drop drop-handler-fn
-          :on-drag-leave #(set-hover! false)}
-         [:span.opacity-70.text
-          "Click here to edit..."]]]))))
-
 (rum/defc add-button
 (rum/defc add-button
-  [args container-id]
-  (let [*bullet-ref (rum/use-ref nil)]
-    [:div.flex-1.flex-col.rounded-sm.add-button-link-wrap
-     {:on-click (fn [e]
+  [block container-id]
+  (let [*ref (rum/use-ref nil)
+        has-children? (:block/_parent block)]
+    [:div.ls-block.block-add-button.flex-1.flex-col.rounded-sm.cursor-text.transition-opacity.ease-in.duration-100.!py-0
+     {:class (if has-children?
+               "opacity-0"
+               "opacity-50")
+      :data-blockId (:db/id block)
+      :ref *ref
+      :on-click (fn [e]
                   (util/stop e)
                   (util/stop e)
                   (state/set-state! :editor/container-id container-id)
                   (state/set-state! :editor/container-id container-id)
-                  (editor-handler/api-insert-new-block! "" args))
-      :on-mouse-over #(dom/add-class! (rum/deref *bullet-ref) "opacity-50")
-      :on-mouse-leave #(dom/remove-class! (rum/deref *bullet-ref) "opacity-50")
+                  (editor-handler/api-insert-new-block! ""
+                                                        {:block-uuid (:block/uuid block)}))
+      :on-mouse-over (fn []
+                       (let [ref (rum/deref *ref)
+                             prev-block (util/get-prev-block-non-collapsed (rum/deref *ref) {:up-down? true})]
+                         (cond
+                           (and prev-block (dom/has-class? prev-block "is-blank"))
+                           (dom/add-class! ref "opacity-0")
+                           (and prev-block has-children?)
+                           (dom/add-class! ref "opacity-50")
+                           :else
+                           (dom/add-class! ref "opacity-100"))))
+      :on-mouse-leave #(do
+                         (dom/remove-class! (rum/deref *ref) "opacity-50")
+                         (dom/remove-class! (rum/deref *ref) "opacity-100"))
       :on-key-down (fn [e]
       :on-key-down (fn [e]
                      (util/stop e)
                      (util/stop e)
                      (when (= "Enter" (util/ekey e))
                      (when (= "Enter" (util/ekey e))
                        (state/set-state! :editor/container-id container-id)
                        (state/set-state! :editor/container-id container-id)
-                       (editor-handler/api-insert-new-block! "" args)))
+                       (editor-handler/api-insert-new-block! "" block)))
       :tab-index 0}
       :tab-index 0}
      [:div.flex.flex-row
      [:div.flex.flex-row
       [:div.flex.items-center {:style {:height 28
       [:div.flex.items-center {:style {:height 28
                                        :margin-left 22}}
                                        :margin-left 22}}
-       [:span.bullet-container.cursor.opacity-0.transition-opacity.ease-in.duration-100 {:ref *bullet-ref}
+       [:span.bullet-container
         [:span.bullet]]]]]))
         [:span.bullet]]]]]))
 
 
 (rum/defcs page-blocks-cp < rum/reactive db-mixins/query
 (rum/defcs page-blocks-cp < rum/reactive db-mixins/query
@@ -219,8 +168,9 @@
       (cond
       (cond
         (and
         (and
          (not block?)
          (not block?)
+         (not config/publishing?)
          (empty? children) block)
          (empty? children) block)
-        (dummy-block block)
+        (add-button block (:container-id config))
 
 
         :else
         :else
         (let [document-mode? (state/sub :document/mode?)
         (let [document-mode? (state/sub :document/mode?)
@@ -233,16 +183,9 @@
                              config)
                              config)
               config (common-handler/config-with-document-mode hiccup-config)
               config (common-handler/config-with-document-mode hiccup-config)
               blocks (if block? [block] (db/sort-by-order children block))]
               blocks (if block? [block] (db/sort-by-order children block))]
-          (let [add-button? (not (or config/publishing?
-                                     (let [last-child-id (model/get-block-deep-last-open-child-id (db/get-db) (:db/id (last blocks)))
-                                           block' (if last-child-id (db/entity last-child-id) (last blocks))
-                                           link (:block/link block')]
-                                       (string/blank? (:block/title (or link block'))))))]
-            [:div.relative
-             {:class (when add-button? "show-add-button")}
-             (page-blocks-inner block blocks config sidebar? whiteboard? block-id)
-             (let [args {:block-uuid block-id}]
-               (add-button args (:container-id config)))]))))))
+          [:div.relative
+           (page-blocks-inner block blocks config sidebar? whiteboard? block-id)
+           (add-button block (:container-id config))])))))
 
 
 (rum/defc today-queries < rum/reactive
 (rum/defc today-queries < rum/reactive
   [repo today? sidebar?]
   [repo today? sidebar?]

+ 0 - 25
src/main/frontend/components/page.css

@@ -214,21 +214,6 @@ html.is-native-ios {
   @apply focus:ring-0 focus:ring-offset-0;
   @apply focus:ring-0 focus:ring-offset-0;
 }
 }
 
 
-.ls-dummy-block {
-  @apply mb-[20px] pt-[5px] pb-[3px] h-[28px];
-
-  &.selected {
-  }
-
-  .bullet {
-    @apply relative -top-[3px] left-[-2px];
-  }
-
-  .text {
-    @apply relative -top-[2px];
-  }
-}
-
 .ls-preview-popup {
 .ls-preview-popup {
   @apply pl-6;
   @apply pl-6;
 
 
@@ -251,16 +236,6 @@ html.is-native-ios {
   }
   }
 }
 }
 
 
-.add-button-link-wrap {
-  @apply invisible;
-}
-
-.show-add-button {
-  .add-button-link-wrap {
-    @apply visible;
-  }
-}
-
 .ls-page-blocks {
 .ls-page-blocks {
   @apply min-h-[60px] overflow-hidden;
   @apply min-h-[60px] overflow-hidden;
 }
 }

+ 1 - 2
src/main/frontend/components/property/config.cljs

@@ -76,8 +76,7 @@
   (when (string? value)
   (when (string? value)
     (let [page-name (string/trim value)]
     (let [page-name (string/trim value)]
       (when-not (string/blank? page-name)
       (when-not (string/blank? page-name)
-        (p/let [page (db-page-handler/<create-class! page-name {:redirect? false
-                                                                :create-first-block? false})]
+        (p/let [page (db-page-handler/<create-class! page-name {:redirect? false})]
           (:block/uuid page))))))
           (:block/uuid page))))))
 
 
 (rum/defc class-select
 (rum/defc class-select

+ 1 - 3
src/main/frontend/components/property/value.cljs

@@ -388,8 +388,7 @@
             (let [journal (date/js-date->journal-title d)]
             (let [journal (date/js-date->journal-title d)]
               (p/do!
               (p/do!
                (when-not (db/get-page journal)
                (when-not (db/get-page journal)
-                 (page-handler/<create! journal {:redirect? false
-                                                 :create-first-block? false}))
+                 (page-handler/<create! journal {:redirect? false}))
                (when (fn? on-change)
                (when (fn? on-change)
                  (let [value (if datetime? (tc/to-long d) (db/get-page journal))]
                  (let [value (if datetime? (tc/to-long d) (db/get-page journal))]
                    (on-change value)))
                    (on-change value)))
@@ -596,7 +595,6 @@
                   (do (log/error :msg "Given inline class does not exist" :inline-class inline-class)
                   (do (log/error :msg "Given inline class does not exist" :inline-class inline-class)
                       nil)))
                       nil)))
             create-options {:redirect? false
             create-options {:redirect? false
-                            :create-first-block? false
                             :tags (if inline-class-uuid
                             :tags (if inline-class-uuid
                                     [inline-class-uuid]
                                     [inline-class-uuid]
                                     ;; Only 1st class b/c page normally has
                                     ;; Only 1st class b/c page normally has

+ 5 - 5
src/main/frontend/extensions/pdf/assets.cljs

@@ -19,10 +19,10 @@
             [frontend.handler.property :as property-handler]
             [frontend.handler.property :as property-handler]
             [frontend.handler.property.util :as pu]
             [frontend.handler.property.util :as pu]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
-            [frontend.util.ref :as ref]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [frontend.util :as util]
+            [frontend.util.ref :as ref]
             [logseq.common.config :as common-config]
             [logseq.common.config :as common-config]
             [logseq.common.path :as path]
             [logseq.common.path :as path]
             [logseq.publishing.db :as publish-db]
             [logseq.publishing.db :as publish-db]
@@ -49,9 +49,9 @@
         url       (if blob-res? href
         url       (if blob-res? href
                       (assets-handler/normalize-asset-resource-url original-path))
                       (assets-handler/normalize-asset-resource-url original-path))
         filename' (if (or asset-res? web-link? blob-res?) filename
         filename' (if (or asset-res? web-link? blob-res?) filename
-                    (some-> url (js/decodeURIComponent)
-                      (get-in-repo-assets-full-filename)
-                      (string/replace '"/" "_")))
+                      (some-> url (js/decodeURIComponent)
+                              (get-in-repo-assets-full-filename)
+                              (string/replace '"/" "_")))
         filekey   (util/safe-sanitize-file-name
         filekey   (util/safe-sanitize-file-name
                    (subs filename' 0 (- (count filename') (inc (count ext-name)))))]
                    (subs filename' 0 (- (count filename') (inc (count ext-name)))))]
     (when-let [key (and (not (string/blank? filekey))
     (when-let [key (and (not (string/blank? filekey))
@@ -93,7 +93,7 @@
         (if-not page
         (if-not page
           (let [label (:filename pdf-current)]
           (let [label (:filename pdf-current)]
             (p/do!
             (p/do!
-             (page-handler/<create! page-name {:redirect?        false :create-first-block? false
+             (page-handler/<create! page-name {:redirect?        false
                                                :split-namespace? false
                                                :split-namespace? false
                                                :format           format
                                                :format           format
                                                :properties       {:file
                                                :properties       {:file

+ 1 - 2
src/main/frontend/extensions/zotero/handler.cljs

@@ -9,8 +9,8 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
             [frontend.handler.page :as page-handler]
-            [frontend.util.ref :as ref]
             [frontend.state :as state]
             [frontend.state :as state]
+            [frontend.util.ref :as ref]
             [promesa.core :as p]))
             [promesa.core :as p]))
 
 
 ;; TODO: test
 ;; TODO: test
@@ -64,7 +64,6 @@
    page-name
    page-name
    {:redirect? false
    {:redirect? false
     :format :markdown
     :format :markdown
-    :create-first-block? false
     :properties properties}))
     :properties properties}))
 
 
 (defn create-zotero-page
 (defn create-zotero-page

+ 62 - 62
src/main/frontend/fs/sync.cljs

@@ -474,7 +474,7 @@
   (comp
   (comp
    (partition-by #(.-updated? ^FileTxn %))
    (partition-by #(.-updated? ^FileTxn %))
    (map (fn [ts]
    (map (fn [ts]
-          (if (some-> (first ts) (.-updated?))
+          (if (some-> ^js (first ts) (.-updated?))
             (partition-all n ts)
             (partition-all n ts)
             (map list ts))))
             (map list ts))))
    cat))
    cat))
@@ -1335,7 +1335,7 @@
   [^FileTxn filetxn origin-db-content]
   [^FileTxn filetxn origin-db-content]
   (go
   (go
     (cond
     (cond
-      (.renamed? filetxn)
+      (.renamed? ^js filetxn)
       false
       false
       (.-deleted? filetxn)
       (.-deleted? filetxn)
       false
       false
@@ -1532,66 +1532,66 @@
 
 
 (defn- apply-filetxns
 (defn- apply-filetxns
   [*sync-state graph-uuid base-path filetxns *paused]
   [*sync-state graph-uuid base-path filetxns *paused]
-  (go
-    (cond
-      (.renamed? (first filetxns))
-      (let [^FileTxn filetxn (first filetxns)
-            from-path (.-from-path filetxn)
-            to-path (.-to-path filetxn)]
-        (assert (= 1 (count filetxns)))
-        (<! (<rename-local-file rsapi graph-uuid base-path
-                                (relative-path from-path)
-                                (relative-path to-path))))
-
-      (.-updated? (first filetxns))
-      (let [repo (state/get-current-repo)
-            txn->db-content-vec (->> filetxns
-                                     (mapv
-                                      #(when (is-journals-or-pages? %)
-                                         [% (db/get-file repo (relative-path %))]))
-                                     (remove nil?))]
-
-        (doseq [relative-p (map relative-path filetxns)]
-          (when-some [relative-p*
-                      (<! (<case-different-local-file-exist? graph-uuid rsapi base-path relative-p))]
-            (let [recent-remote->local-file-item {:remote->local-type :delete
-                                                  :checksum nil
-                                                  :path relative-p*}]
-              (println :debug "found case-different-same-local-file" relative-p relative-p*)
-              (swap! *sync-state sync-state--add-recent-remote->local-files
-                     [recent-remote->local-file-item])
-              (<! (<delete-local-files rsapi graph-uuid base-path [relative-p*]))
-              (go (<! (timeout 5000))
-                  (swap! *sync-state sync-state--remove-recent-remote->local-files
-                         [recent-remote->local-file-item])))))
-
-        (let [update-local-files-ch (if (state/enable-sync-diff-merge?)
-                                      (<fetch-remote-and-update-local-files graph-uuid base-path (map relative-path filetxns))
-                                      (<update-local-files rsapi graph-uuid base-path (map relative-path filetxns)))
-              r (<! (<with-pause update-local-files-ch *paused))]
-          (doseq [[filetxn origin-db-content] txn->db-content-vec]
-            (when (<! (need-add-version-file? filetxn origin-db-content))
-              (<! (<add-new-version rsapi repo (relative-path filetxn) origin-db-content))
-              (put-sync-event! {:event :created-local-version-file
-                                :data {:graph-uuid graph-uuid
-                                       :repo repo
-                                       :path (relative-path filetxn)
-                                       :epoch (tc/to-epoch (t/now))}})))
-          r))
-
-      (.-deleted? (first filetxns))
-      (let [filetxn (first filetxns)]
-        (assert (= 1 (count filetxns)))
-        (if (<! (<local-file-not-exist? graph-uuid rsapi base-path (relative-path filetxn)))
+  (let [^FileTxn filetxn (first filetxns)]
+    (go
+      (cond
+        (.renamed? filetxn)
+        (let [from-path (.-from-path filetxn)
+              to-path (.-to-path filetxn)]
+          (assert (= 1 (count filetxns)))
+          (<! (<rename-local-file rsapi graph-uuid base-path
+                                  (relative-path from-path)
+                                  (relative-path to-path))))
+
+        (.-updated? filetxn)
+        (let [repo (state/get-current-repo)
+              txn->db-content-vec (->> filetxns
+                                       (mapv
+                                        #(when (is-journals-or-pages? %)
+                                           [% (db/get-file repo (relative-path %))]))
+                                       (remove nil?))]
+
+          (doseq [relative-p (map relative-path filetxns)]
+            (when-some [relative-p*
+                        (<! (<case-different-local-file-exist? graph-uuid rsapi base-path relative-p))]
+              (let [recent-remote->local-file-item {:remote->local-type :delete
+                                                    :checksum nil
+                                                    :path relative-p*}]
+                (println :debug "found case-different-same-local-file" relative-p relative-p*)
+                (swap! *sync-state sync-state--add-recent-remote->local-files
+                       [recent-remote->local-file-item])
+                (<! (<delete-local-files rsapi graph-uuid base-path [relative-p*]))
+                (go (<! (timeout 5000))
+                    (swap! *sync-state sync-state--remove-recent-remote->local-files
+                           [recent-remote->local-file-item])))))
+
+          (let [update-local-files-ch (if (state/enable-sync-diff-merge?)
+                                        (<fetch-remote-and-update-local-files graph-uuid base-path (map relative-path filetxns))
+                                        (<update-local-files rsapi graph-uuid base-path (map relative-path filetxns)))
+                r (<! (<with-pause update-local-files-ch *paused))]
+            (doseq [[filetxn origin-db-content] txn->db-content-vec]
+              (when (<! (need-add-version-file? filetxn origin-db-content))
+                (<! (<add-new-version rsapi repo (relative-path filetxn) origin-db-content))
+                (put-sync-event! {:event :created-local-version-file
+                                  :data {:graph-uuid graph-uuid
+                                         :repo repo
+                                         :path (relative-path filetxn)
+                                         :epoch (tc/to-epoch (t/now))}})))
+            r))
+
+        (.-deleted? filetxn)
+        (let [filetxn (first filetxns)]
+          (assert (= 1 (count filetxns)))
+          (if (<! (<local-file-not-exist? graph-uuid rsapi base-path (relative-path filetxn)))
           ;; not exist, ignore
           ;; not exist, ignore
-          true
-          (let [r (<! (if (state/enable-sync-diff-merge?)
-                        (<apply-remote-deletion graph-uuid base-path [(relative-path filetxn)])
-                        (<delete-local-files rsapi graph-uuid base-path [(relative-path filetxn)])))]
-            (if (and (instance? ExceptionInfo r)
-                     (string/index-of (str (ex-cause r)) "No such file or directory"))
-              true
-              r)))))))
+            true
+            (let [r (<! (if (state/enable-sync-diff-merge?)
+                          (<apply-remote-deletion graph-uuid base-path [(relative-path filetxn)])
+                          (<delete-local-files rsapi graph-uuid base-path [(relative-path filetxn)])))]
+              (if (and (instance? ExceptionInfo r)
+                       (string/index-of (str (ex-cause r)) "No such file or directory"))
+                true
+                r))))))))
 
 
 (declare sync-state-reset-full-remote->local-files)
 (declare sync-state-reset-full-remote->local-files)
 (defn apply-filetxns-partitions
 (defn apply-filetxns-partitions
@@ -1646,7 +1646,7 @@
                                       :chan)))
                                       :chan)))
 
 
 (defmethod need-sync-remote? :max [_] true)
 (defmethod need-sync-remote? :max [_] true)
-(defmethod need-sync-remote? :txid [[txid remote->local-syncer]]
+(defmethod need-sync-remote? :txid [[txid ^Remote->LocalSyncer remote->local-syncer]]
   (let [remote-txid txid
   (let [remote-txid txid
         local-txid (.-txid remote->local-syncer)]
         local-txid (.-txid remote->local-syncer)]
     (or (nil? local-txid)
     (or (nil? local-txid)

+ 10 - 5
src/main/frontend/handler/common/page.cljs

@@ -4,11 +4,11 @@
   is still some file-specific tech debt to remove from create!"
   is still some file-specific tech debt to remove from create!"
   (:require [clojure.string :as string]
   (:require [clojure.string :as string]
             [datascript.core :as d]
             [datascript.core :as d]
+            [dommy.core :as dom]
             [frontend.config :as config]
             [frontend.config :as config]
             [frontend.db :as db]
             [frontend.db :as db]
             [frontend.db.conn :as conn]
             [frontend.db.conn :as conn]
             [frontend.fs :as fs]
             [frontend.fs :as fs]
-            [frontend.handler.block :as block-handler]
             [frontend.handler.config :as config-handler]
             [frontend.handler.config :as config-handler]
             [frontend.handler.db-based.editor :as db-editor-handler]
             [frontend.handler.db-based.editor :as db-editor-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.notification :as notification]
@@ -39,12 +39,11 @@
 (defn <create!
 (defn <create!
   ([title]
   ([title]
    (<create! title {}))
    (<create! title {}))
-  ([title {:keys [redirect?]
+  ([title {:keys [redirect? today-journal?]
            :or   {redirect? true}
            :or   {redirect? true}
            :as options}]
            :as options}]
    (when (string? title)
    (when (string? title)
      (p/let [repo (state/get-current-repo)
      (p/let [repo (state/get-current-repo)
-             conn (db/get-db repo false)
              db-based? (config/db-based-graph? repo)
              db-based? (config/db-based-graph? repo)
              title (if (and db-based? (string/includes? title " #")) ; tagged page
              title (if (and db-based? (string/includes? title " #")) ; tagged page
                      (wrap-tags title)
                      (wrap-tags title)
@@ -70,8 +69,14 @@
                    page (db/get-page (or page-uuid title'))]
                    page (db/get-page (or page-uuid title'))]
              (when redirect?
              (when redirect?
                (route-handler/redirect-to-page! page-uuid)
                (route-handler/redirect-to-page! page-uuid)
-               (when-let [first-block (ldb/get-first-child @conn (:db/id page))]
-                 (block-handler/edit-block! first-block :max {:container-id :unknown-container})))
+               (when-not today-journal?
+                 (js/setTimeout
+                  (fn []
+                    (when-let [block-add-button (->> (dom/sel ".block-add-button")
+                                                     (filter #(= (str (:db/id page)) (dom/attr % "data-blockId")))
+                                                     first)]
+                      (.click block-add-button)))
+                  200)))
              page)))))))
              page)))))))
 
 
 ;; favorite fns
 ;; favorite fns

+ 1 - 2
src/main/frontend/handler/db_based/page.cljs

@@ -95,8 +95,7 @@
   [chosen chosen-result class? edit-content current-pos last-pattern]
   [chosen chosen-result class? edit-content current-pos last-pattern]
   (let [tag (string/trim chosen)
   (let [tag (string/trim chosen)
         edit-block (state/get-edit-block)
         edit-block (state/get-edit-block)
-        create-opts {:redirect? false
-                     :create-first-block? false}]
+        create-opts {:redirect? false}]
     (when (:block/uuid edit-block)
     (when (:block/uuid edit-block)
       (p/let [result (when-not (de/entity? chosen-result) ; page not exists yet
       (p/let [result (when-not (de/entity? chosen-result) ; page not exists yet
                        (if class?
                        (if class?

+ 24 - 11
src/main/frontend/handler/editor.cljs

@@ -2590,8 +2590,14 @@
                           (string/trim value)))
                           (string/trim value)))
                (save-block! repo uuid value))
                (save-block! repo uuid value))
 
 
-             (if property-value-container?
+             (cond
+               (dom/has-class? sibling-block "block-add-button")
+               (.click sibling-block)
+
+               property-value-container?
                (focus-trigger current-block sibling-block)
                (focus-trigger current-block sibling-block)
+
+               :else
                (let [new-uuid (cljs.core/uuid sibling-block-id)
                (let [new-uuid (cljs.core/uuid sibling-block-id)
                      block (db/entity [:block/uuid new-uuid])]
                      block (db/entity [:block/uuid new-uuid])]
                  (edit-block! block
                  (edit-block! block
@@ -2647,18 +2653,25 @@
                               (first (dom/by-class sibling-block "ls-block"))))
                               (first (dom/by-class sibling-block "ls-block"))))
                           sibling-block)]
                           sibling-block)]
     (when sibling-block
     (when sibling-block
-      (if-let [sibling-block-id (dom/attr sibling-block "blockid")]
-        (do
-          (let [content (:block/title block)
-                value (state/get-edit-content)]
-            (when (and value (not= (clean-content! repo format content) (string/trim value)))
-              (save-block! repo uuid value)))
-
+      (let [content (:block/title block)
+            value (state/get-edit-content)]
+        (when (and value (not= (clean-content! repo format content) (string/trim value)))
+          (save-block! repo uuid value)))
+      (let [sibling-block-id (dom/attr sibling-block "blockid")]
+        (cond
+          sibling-block-id
           (let [container-id (some-> (dom/attr sibling-block "containerid") js/parseInt)
           (let [container-id (some-> (dom/attr sibling-block "containerid") js/parseInt)
                 block (db/entity repo [:block/uuid (cljs.core/uuid sibling-block-id)])]
                 block (db/entity repo [:block/uuid (cljs.core/uuid sibling-block-id)])]
-            (edit-block! block pos {:container-id container-id})))
-        (when (property-value-node? sibling-block)
-          (focus-trigger editing-block sibling-block))))))
+            (edit-block! block pos {:container-id container-id}))
+
+          (property-value-node? sibling-block)
+          (focus-trigger editing-block sibling-block)
+
+          (dom/has-class? sibling-block "block-add-button")
+          (.click sibling-block)
+
+          :else
+          nil)))))
 
 
 (defn keydown-arrow-handler
 (defn keydown-arrow-handler
   [direction]
   [direction]

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

@@ -69,7 +69,6 @@
      (try (page-handler/<create! title {:redirect?           false
      (try (page-handler/<create! title {:redirect?           false
                                         :format              page-format
                                         :format              page-format
                                         :uuid                uuid
                                         :uuid                uuid
-                                        :create-first-block? false
                                         :properties          properties
                                         :properties          properties
                                         :whiteboard?         whiteboard?})
                                         :whiteboard?         whiteboard?})
           (catch :default e
           (catch :default e

+ 1 - 5
src/main/frontend/handler/page.cljs

@@ -28,11 +28,11 @@
             [frontend.mobile.util :as mobile-util]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.outliner.op :as outliner-op]
             [frontend.modules.outliner.op :as outliner-op]
             [frontend.modules.outliner.ui :as ui-outliner-tx]
             [frontend.modules.outliner.ui :as ui-outliner-tx]
-            [frontend.util.ref :as ref]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.util :as util]
             [frontend.util :as util]
             [frontend.util.cursor :as cursor]
             [frontend.util.cursor :as cursor]
             [frontend.util.page :as page-util]
             [frontend.util.page :as page-util]
+            [frontend.util.ref :as ref]
             [frontend.util.url :as url-util]
             [frontend.util.url :as url-util]
             [goog.functions :refer [debounce]]
             [goog.functions :refer [debounce]]
             [goog.object :as gobj]
             [goog.object :as gobj]
@@ -278,7 +278,6 @@
                      (when-not (de/entity? chosen-result)
                      (when-not (de/entity? chosen-result)
                        (<create! chosen'
                        (<create! chosen'
                                  {:redirect? false
                                  {:redirect? false
-                                  :create-first-block? false
                                   :split-namespace? true})))
                                   :split-namespace? true})))
             ref-text' (if result
             ref-text' (if result
                         (let [title (:block/title result)]
                         (let [title (:block/title result)]
@@ -335,9 +334,6 @@
                          (p/do!
                          (p/do!
                           (<create! title {:redirect? false
                           (<create! title {:redirect? false
                                            :split-namespace? false
                                            :split-namespace? false
-                                           :create-first-block? (if db-based?
-                                                                  true
-                                                                  (not (state/get-default-journal-template)))
                                            :today-journal? true})
                                            :today-journal? true})
                           (when-not db-based? (state/pub-event! [:journal/insert-template today-page]))
                           (when-not db-based? (state/pub-event! [:journal/insert-template today-page]))
                           (ui-handler/re-render-root!)
                           (ui-handler/re-render-root!)

+ 2 - 3
src/main/frontend/handler/profiler.cljs

@@ -84,7 +84,7 @@
                                    (when (> coll-size data-count-threshold)
                                    (when (> coll-size data-count-threshold)
                                      (vswap! *ref-hash->coll-size assoc @*ref-hash coll-size)
                                      (vswap! *ref-hash->coll-size assoc @*ref-hash coll-size)
                                      (vswap! *ref-hash->ref assoc @*ref-hash ref))
                                      (vswap! *ref-hash->ref assoc @*ref-hash ref))
-                                   (let [watches-count (count (.-watches ref))]
+                                   (let [watches-count (count (.-watches ^js ref))]
                                      (when (> watches-count watches-count-threshold)
                                      (when (> watches-count watches-count-threshold)
                                        (vswap! *ref-hash->watches-count assoc @*ref-hash watches-count)
                                        (vswap! *ref-hash->watches-count assoc @*ref-hash watches-count)
                                        (vswap! *ref-hash->ref assoc @*ref-hash ref))))))
                                        (vswap! *ref-hash->ref assoc @*ref-hash ref))))))
@@ -120,5 +120,4 @@
                 :custom-key-fn (fn [args result] {:a args :r result}))
                 :custom-key-fn (fn [args result] {:a args :r result}))
 
 
   (mem-leak-detect)
   (mem-leak-detect)
-  [@*ref-hash->coll-size @*ref-hash->watches-count]
-  )
+  [@*ref-hash->coll-size @*ref-hash->watches-count])

+ 7 - 7
src/main/frontend/modules/shortcut/core.cljs

@@ -8,8 +8,8 @@
             [frontend.modules.shortcut.data-helper :as dh]
             [frontend.modules.shortcut.data-helper :as dh]
             [frontend.modules.shortcut.utils :as shortcut-utils]
             [frontend.modules.shortcut.utils :as shortcut-utils]
             [frontend.state :as state]
             [frontend.state :as state]
-            [frontend.util :as util]
             [frontend.storage :as storage]
             [frontend.storage :as storage]
+            [frontend.util :as util]
             [goog.events :as events]
             [goog.events :as events]
             [goog.ui.KeyboardShortcutHandler.EventType :as EventType]
             [goog.ui.KeyboardShortcutHandler.EventType :as EventType]
             [lambdaisland.glogi :as log])
             [lambdaisland.glogi :as log])
@@ -225,7 +225,7 @@
 (defn listen-all! []
 (defn listen-all! []
   (doseq [{:keys [handler group dispatch-fn]} (vals @*installed-handlers)
   (doseq [{:keys [handler group dispatch-fn]} (vals @*installed-handlers)
           :when (not= group :shortcut.handler/misc)]
           :when (not= group :shortcut.handler/misc)]
-    (if (.isDisposed handler)
+    (if (.isDisposed ^js handler)
       (install-shortcut-handler! group {})
       (install-shortcut-handler! group {})
       (events/listen handler EventType/SHORTCUT_TRIGGERED dispatch-fn))))
       (events/listen handler EventType/SHORTCUT_TRIGGERED dispatch-fn))))
 
 
@@ -282,15 +282,15 @@
                 (dissoc id)
                 (dissoc id)
 
 
                 (and global?
                 (and global?
-                  (or (string? binding)
-                    (vector? binding)
-                    (boolean? binding)))
+                     (or (string? binding)
+                         (vector? binding)
+                         (boolean? binding)))
                 (assoc id binding)))]
                 (assoc id binding)))]
       ;; TODO: exclude current graph config shortcuts
       ;; TODO: exclude current graph config shortcuts
       (config-handler/set-config!
       (config-handler/set-config!
-        :shortcuts (into-shortcuts (:shortcuts (state/get-graph-config))))
+       :shortcuts (into-shortcuts (:shortcuts (state/get-graph-config))))
       (if (util/electron?)
       (if (util/electron?)
         (global-config-handler/set-global-config-kv!
         (global-config-handler/set-global-config-kv!
-          :shortcuts (into-shortcuts (:shortcuts (state/get-global-config))))
+         :shortcuts (into-shortcuts (:shortcuts (state/get-global-config))))
         ;; web browser platform
         ;; web browser platform
         (storage/set :ls-shortcuts (into-shortcuts (storage/get :ls-shortcuts)))))))
         (storage/set :ls-shortcuts (into-shortcuts (storage/get :ls-shortcuts)))))))

+ 1 - 1
src/main/frontend/worker/commands.cljs

@@ -168,7 +168,7 @@
                                             {:page-uuid (:block/uuid (d/entity db journal-day))}
                                             {:page-uuid (:block/uuid (d/entity db journal-day))}
                                             (let [formatter (:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))
                                             (let [formatter (:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))
                                                   title (date-time-util/format (t/to-default-time-zone (tc/to-date-time next-time-long)) formatter)]
                                                   title (date-time-util/format (t/to-default-time-zone (tc/to-date-time next-time-long)) formatter)]
-                                              (worker-db-page/create db title {:create-first-block? false})))
+                                              (worker-db-page/create db title {})))
               value (if date? [:block/uuid page-uuid] next-time-long)]
               value (if date? [:block/uuid page-uuid] next-time-long)]
           (concat
           (concat
            tx-data
            tx-data

+ 0 - 1
src/main/frontend/worker/handler/page.cljs

@@ -27,7 +27,6 @@
 (defn create!
 (defn create!
   "Create page. Has the following options:
   "Create page. Has the following options:
 
 
-   * :create-first-block?      - when true, create an empty block if the page is empty.
    * :uuid                     - when set, use this uuid instead of generating a new one.
    * :uuid                     - when set, use this uuid instead of generating a new one.
    * :class?                   - when true, adds a :block/tags ':logseq.class/Tag'
    * :class?                   - when true, adds a :block/tags ':logseq.class/Tag'
    * :whiteboard?              - when true, adds a :block/tags ':logseq.class/Whiteboard'
    * :whiteboard?              - when true, adds a :block/tags ':logseq.class/Whiteboard'

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

@@ -7,13 +7,11 @@
             [logseq.common.util.namespace :as ns-util]
             [logseq.common.util.namespace :as ns-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.common.entity-plus :as entity-plus]
-            [logseq.db.common.order :as db-order]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.build :as db-property-build]
             [logseq.db.frontend.property.build :as db-property-build]
-            [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.text :as text]
             [logseq.graph-parser.text :as text]
             [logseq.outliner.validate :as outliner-validate]))
             [logseq.outliner.validate :as outliner-validate]))
@@ -75,16 +73,6 @@
         title      (common-util/remove-boundary-slashes title)]
         title      (common-util/remove-boundary-slashes title)]
     title))
     title))
 
 
-(defn build-first-block-tx
-  [page-uuid]
-  (let [page-id [:block/uuid page-uuid]]
-    [(sqlite-util/block-with-timestamps
-      {:block/uuid (ldb/new-block-id)
-       :block/page page-id
-       :block/parent page-id
-       :block/order (db-order/gen-key nil nil)
-       :block/title ""})]))
-
 (defn- get-page-by-parent-name
 (defn- get-page-by-parent-name
   [db parent-title child-title]
   [db parent-title child-title]
   (some->>
   (some->>
@@ -168,10 +156,9 @@
 (defn create
 (defn create
   "Pure function without side effects"
   "Pure function without side effects"
   [db title*
   [db title*
-   {:keys [create-first-block? tags properties uuid persist-op? whiteboard?
+   {:keys [tags properties uuid persist-op? whiteboard?
            class? today-journal? split-namespace?]
            class? today-journal? split-namespace?]
-    :or   {create-first-block?      true
-           properties               nil
+    :or   {properties               nil
            uuid                     nil
            uuid                     nil
            persist-op?              true}
            persist-op?              true}
     :as options}]
     :as options}]
@@ -221,17 +208,10 @@
 
 
           (let [page-uuid (:block/uuid page)
           (let [page-uuid (:block/uuid page)
                 page-txs  (build-page-tx db properties page (select-keys options [:whiteboard? :class? :tags]))
                 page-txs  (build-page-tx db properties page (select-keys options [:whiteboard? :class? :tags]))
-                first-block-tx (when (and
-                                      (nil? (d/entity db [:block/uuid page-uuid]))
-                                      create-first-block?
-                                      (not (or whiteboard? class?))
-                                      page-txs)
-                                 (build-first-block-tx (:block/uuid (first page-txs))))
                 txs      (concat
                 txs      (concat
                           ;; transact doesn't support entities
                           ;; transact doesn't support entities
                           (remove de/entity? parents)
                           (remove de/entity? parents)
-                          page-txs
-                          first-block-tx)
+                          page-txs)
                 tx-meta (cond-> {:persist-op? persist-op?
                 tx-meta (cond-> {:persist-op? persist-op?
                                  :outliner-op :create-page}
                                  :outliner-op :create-page}
                           today-journal?
                           today-journal?

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

@@ -9,8 +9,7 @@
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.property :as gp-property]
             [logseq.graph-parser.property :as gp-property]
-            [logseq.graph-parser.text :as text]
-            [logseq.outliner.core :as outliner-core]))
+            [logseq.graph-parser.text :as text]))
 
 
 (defn- file-based-properties-block
 (defn- file-based-properties-block
   [repo conn config date-formatter properties format page]
   [repo conn config date-formatter properties format page]
@@ -53,21 +52,9 @@
         page-name  (common-util/page-name-sanity-lc title)]
         page-name  (common-util/page-name-sanity-lc title)]
     [title page-name]))
     [title page-name]))
 
 
-(defn- build-first-block-tx
-  [page-uuid format]
-  (let [page-id [:block/uuid page-uuid]]
-    [(outliner-core/block-with-timestamps
-      {:block/uuid (ldb/new-block-id)
-       :block/page page-id
-       :block/parent page-id
-       :block/order (db-order/gen-key nil nil)
-       :block/title ""
-       :block/format format})]))
-
 (defn create!
 (defn create!
-  [repo conn config title {:keys [create-first-block? format properties uuid persist-op? whiteboard? today-journal?]
-                           :or   {create-first-block?      true
-                                  format                   nil
+  [repo conn config title {:keys [format properties uuid persist-op? today-journal?]
+                           :or   {format                   nil
                                   properties               nil
                                   properties               nil
                                   uuid                     nil
                                   uuid                     nil
                                   persist-op?              true}
                                   persist-op?              true}
@@ -105,16 +92,9 @@
                                (fn [p]
                                (fn [p]
                                  (assoc p :block/namespace [:block/uuid (:block/uuid (last txs))])))
                                  (assoc p :block/namespace [:block/uuid (:block/uuid (last txs))])))
                        page-txs)
                        page-txs)
-            first-block-tx (when (and
-                                  (nil? (d/entity @conn [:block/uuid page-uuid]))
-                                  create-first-block?
-                                  (not whiteboard?)
-                                  page-txs)
-                             (build-first-block-tx (:block/uuid (first page-txs)) format))
             txs      (concat
             txs      (concat
                       txs
                       txs
-                      page-txs
-                      first-block-tx)]
+                      page-txs)]
         (when (seq txs)
         (when (seq txs)
           (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
           (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
                                            :outliner-op :create-page}
                                            :outliner-op :create-page}

+ 2 - 5
src/main/logseq/api.cljs

@@ -656,7 +656,7 @@
   [name ^js properties ^js opts]
   [name ^js properties ^js opts]
   (let [properties (bean/->clj properties)
   (let [properties (bean/->clj properties)
         db-base? (config/db-based-graph? (state/get-current-repo))
         db-base? (config/db-based-graph? (state/get-current-repo))
-        {:keys [redirect createFirstBlock format journal]} (bean/->clj opts)]
+        {:keys [redirect format journal]} (bean/->clj opts)]
     (p/let [page (<pull-block name)
     (p/let [page (<pull-block name)
             new-page (when-not page
             new-page (when-not page
                        (page-handler/<create!
                        (page-handler/<create!
@@ -664,7 +664,6 @@
                         (cond->
                         (cond->
                          {:redirect? (if (boolean? redirect) redirect true)
                          {:redirect? (if (boolean? redirect) redirect true)
                           :journal? journal
                           :journal? journal
-                          :create-first-block? (if (boolean? createFirstBlock) createFirstBlock true)
                           :format format}
                           :format format}
                           (not db-base?)
                           (not db-base?)
                           (assoc :properties properties))))
                           (assoc :properties properties))))
@@ -741,7 +740,7 @@
                 page-name              (when page-name (util/page-name-sanity-lc page-name))
                 page-name              (when page-name (util/page-name-sanity-lc page-name))
                 _                      (when (and page-name
                 _                      (when (and page-name
                                                   (nil? (ldb/get-page (db/get-db) page-name)))
                                                   (nil? (ldb/get-page (db/get-db) page-name)))
-                                         (page-handler/<create! block-uuid-or-page-name {:create-first-block? false}))
+                                         (page-handler/<create! block-uuid-or-page-name {}))
                 custom-uuid            (or customUUID (:id properties))
                 custom-uuid            (or customUUID (:id properties))
                 custom-uuid            (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
                 custom-uuid            (when custom-uuid (sdk-utils/uuid-or-throw-error custom-uuid))
                 edit-block?            (if (nil? focus) true focus)
                 edit-block?            (if (nil? focus) true focus)
@@ -1067,7 +1066,6 @@
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
                                                                       {:redirect?           false
                                                                       {:redirect?           false
-                                                                       :create-first-block? false
                                                                        :format              (state/get-preferred-format)}))]
                                                                        :format              (state/get-preferred-format)}))]
     (when-let [block (db-model/get-page uuid-or-page-name)]
     (when-let [block (db-model/get-page uuid-or-page-name)]
       (-> (api-block/<sync-children-blocks! block)
       (-> (api-block/<sync-children-blocks! block)
@@ -1085,7 +1083,6 @@
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
                                                                       {:redirect?           false
                                                                       {:redirect?           false
-                                                                       :create-first-block? false
                                                                        :format              (state/get-preferred-format)}))]
                                                                        :format              (state/get-preferred-format)}))]
     (when-let [block (db-model/get-page uuid-or-page-name)]
     (when-let [block (db-model/get-page uuid-or-page-name)]
       (let [target   (str (:block/uuid block))]
       (let [target   (str (:block/uuid block))]

+ 1 - 1
src/main/logseq/api/block.cljs

@@ -78,7 +78,7 @@
                   (when-let [page (some-> v (str) (string/trim))]
                   (when-let [page (some-> v (str) (string/trim))]
                     (let [id (:db/id (ldb/get-case-page (conn/get-db) page))]
                     (let [id (:db/id (ldb/get-case-page (conn/get-db) page))]
                       (if (nil? id)
                       (if (nil? id)
-                        (-> (page-handler/<create! page {:redirect? false :create-first-block? false})
+                        (-> (page-handler/<create! page {:redirect? false})
                             (p/then #(:db/id %)))
                             (p/then #(:db/id %)))
                         id))))
                         id))))
                 (p/all)
                 (p/all)

+ 4 - 4
src/test/frontend/db/db_based_model_test.cljs

@@ -22,7 +22,7 @@
 (use-fixtures :each start-and-destroy-db)
 (use-fixtures :each start-and-destroy-db)
 
 
 (deftest get-all-classes-test
 (deftest get-all-classes-test
-  (let [opts {:redirect? false :create-first-block? false :class? true}
+  (let [opts {:redirect? false :class? true}
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class2" opts)]
         _ (test-helper/create-page! "class2" opts)]
     (is (= (set
     (is (= (set
@@ -34,7 +34,7 @@
            (set (map :block/title (model/get-all-classes repo)))))))
            (set (map :block/title (model/get-all-classes repo)))))))
 
 
 (deftest ^:fix-me get-class-objects-test
 (deftest ^:fix-me get-class-objects-test
-  (let [opts {:redirect? false :create-first-block? false :class? true}
+  (let [opts {:redirect? false}
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class1" opts)
         class (db/get-case-page "class1")
         class (db/get-case-page "class1")
         _ (test-helper/save-block! repo fbid "Block 1" {:tags ["class1"]})]
         _ (test-helper/save-block! repo fbid "Block 1" {:tags ["class1"]})]
@@ -53,14 +53,14 @@
               (:db/id (db/entity [:block/uuid sbid]))])))))
               (:db/id (db/entity [:block/uuid sbid]))])))))
 
 
 (deftest hidden-page-test
 (deftest hidden-page-test
-  (let [opts {:redirect? false :create-first-block? false}
+  (let [opts {:redirect? false}
         _ (test-helper/create-page! "page 1" opts)]
         _ (test-helper/create-page! "page 1" opts)]
     (is (false? (model/hidden-page? (db/get-page "page 1"))))
     (is (false? (model/hidden-page? (db/get-page "page 1"))))
     (is (true? (model/hidden-page? "$$$test")))
     (is (true? (model/hidden-page? "$$$test")))
     (is (true? (model/hidden-page? (str "$$$" (random-uuid)))))))
     (is (true? (model/hidden-page? (str "$$$" (random-uuid)))))))
 
 
 (deftest get-class-children-test
 (deftest get-class-children-test
-  (let [opts {:redirect? false :create-first-block? false :class? true}
+  (let [opts {:redirect? false}
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class2" opts)
         _ (test-helper/create-page! "class2" opts)
         _ (test-helper/create-page! "class3" opts)
         _ (test-helper/create-page! "class3" opts)

+ 5 - 5
src/test/frontend/handler/db_based/recent_test.cljs

@@ -1,9 +1,9 @@
 (ns frontend.handler.db-based.recent-test
 (ns frontend.handler.db-based.recent-test
-  (:require [frontend.handler.db-based.recent :as db-recent-handler]
-            [clojure.test :refer [deftest is testing use-fixtures]]
-            [frontend.test.helper :as test-helper]
+  (:require [clojure.test :refer [deftest is testing use-fixtures]]
             [datascript.core :as d]
             [datascript.core :as d]
-            [frontend.db :as db]))
+            [frontend.db :as db]
+            [frontend.handler.db-based.recent :as db-recent-handler]
+            [frontend.test.helper :as test-helper]))
 
 
 (def init-data (test-helper/initial-test-page-and-blocks))
 (def init-data (test-helper/initial-test-page-and-blocks))
 (defn start-and-destroy-db
 (defn start-and-destroy-db
@@ -19,7 +19,7 @@
     (let [pages (map (fn [i] (str "Page " i)) (range 15))]
     (let [pages (map (fn [i] (str "Page " i)) (range 15))]
       ;; create pages
       ;; create pages
       (doseq [page pages]
       (doseq [page pages]
-        (test-helper/create-page! page {:redirect? false :create-first-block? false :class? true})
+        (test-helper/create-page! page {:redirect? false})
         (db-recent-handler/add-page-to-recent! (:db/id (db/get-page page)) false))
         (db-recent-handler/add-page-to-recent! (:db/id (db/get-page page)) false))
       (is (= (map :block/title (db-recent-handler/get-recent-pages)) (reverse pages)))
       (is (= (map :block/title (db-recent-handler/get-recent-pages)) (reverse pages)))
       (testing "Click existing recent item shouldn't update its position"
       (testing "Click existing recent item shouldn't update its position"

+ 14 - 14
src/test/frontend/worker/handler/page/file_based/rename_test.cljs

@@ -1,12 +1,12 @@
 (ns frontend.worker.handler.page.file-based.rename-test
 (ns frontend.worker.handler.page.file-based.rename-test
-  (:require [clojure.test :refer [deftest is testing use-fixtures are]]
-            [frontend.test.helper :as test-helper]
+  (:require [clojure.string :as string]
+            [clojure.test :refer [deftest is testing use-fixtures are]]
             [datascript.core :as d]
             [datascript.core :as d]
             [frontend.db :as db]
             [frontend.db :as db]
-            [clojure.string :as string]
+            [frontend.handler.editor :as editor-handler]
+            [frontend.test.helper :as test-helper]
             [frontend.util :as util]
             [frontend.util :as util]
-            [frontend.worker.handler.page.file-based.rename :as file-page-rename]
-            [frontend.handler.editor :as editor-handler]))
+            [frontend.worker.handler.page.file-based.rename :as file-page-rename]))
 
 
 ;; FIXME: merge properties from both pages
 ;; FIXME: merge properties from both pages
 
 
@@ -39,7 +39,7 @@
       (is (= "New name" (:block/title (db/entity (:db/id page)))))))
       (is (= "New name" (:block/title (db/entity (:db/id page)))))))
 
 
   (testing "Merge existing page"
   (testing "Merge existing page"
-    (test-helper/create-page! "Existing page" {:redirect? false :create-first-block? true})
+    (test-helper/create-page! "Existing page" {:redirect? false})
     (let [page (db/get-page "new name")]
     (let [page (db/get-page "new name")]
       (page-rename (:block/uuid page) "Existing page"))
       (page-rename (:block/uuid page) "Existing page"))
     (let [e1 (db/get-page "new name")
     (let [e1 (db/get-page "new name")
@@ -47,10 +47,10 @@
       ;; Old page deleted
       ;; Old page deleted
       (is (nil? e1))
       (is (nil? e1))
       ;; Blocks from both pages have been merged
       ;; Blocks from both pages have been merged
-      (is (= (count (:block/_page e2)) (+ 1 (dec (count init-data))))))))
+      (is (= (count (:block/_page e2)) (dec (count init-data)))))))
 
 
 (deftest merge-with-empty-page
 (deftest merge-with-empty-page
-  (test-helper/create-page! "Existing page" {:redirect? false :create-first-block? false})
+  (test-helper/create-page! "Existing page" {:redirect? false})
   (let [page (db/get-page "test")]
   (let [page (db/get-page "test")]
     (page-rename (:block/uuid page) "Existing page"))
     (page-rename (:block/uuid page) "Existing page"))
   (let [e1 (db/get-page "test")
   (let [e1 (db/get-page "test")
@@ -63,7 +63,7 @@
 (deftest merge-existing-pages-should-update-ref-ids
 (deftest merge-existing-pages-should-update-ref-ids
   (testing "Merge existing page"
   (testing "Merge existing page"
     (editor-handler/save-block! repo fbid "Block 1 [[Test]]")
     (editor-handler/save-block! repo fbid "Block 1 [[Test]]")
-    (test-helper/create-page! "Existing page" {:redirect? false :create-first-block? true})
+    (test-helper/create-page! "Existing page" {:redirect? false})
     (let [page (db/get-page "test")]
     (let [page (db/get-page "test")]
       (page-rename (:block/uuid page) "Existing page"))
       (page-rename (:block/uuid page) "Existing page"))
     (let [e1 (db/get-page "test")
     (let [e1 (db/get-page "test")
@@ -71,7 +71,7 @@
       ;; Old page deleted
       ;; Old page deleted
       (is (nil? e1))
       (is (nil? e1))
       ;; Blocks from both pages have been merged
       ;; Blocks from both pages have been merged
-      (is (= (count (:block/_page e2)) (+ 1 (dec (count init-data)))))
+      (is (= (count (:block/_page e2)) (dec (count init-data))))
       ;; Content updated
       ;; Content updated
       (is (= "Block 1 [[Existing page]]" (:block/title (db/entity [:block/uuid fbid])))))))
       (is (= "Block 1 [[Existing page]]" (:block/title (db/entity [:block/uuid fbid])))))))
 
 
@@ -182,8 +182,8 @@
   (are [x y] (= (let [[content old-name new-name] x]
   (are [x y] (= (let [[content old-name new-name] x]
                   (replace-old-page! content old-name new-name))
                   (replace-old-page! content old-name new-name))
                 y)
                 y)
-       ["#foo bla [[foo]] bla #foo" "foo" "bar"]
-       "#bar bla [[bar]] bla #bar"
+    ["#foo bla [[foo]] bla #foo" "foo" "bar"]
+    "#bar bla [[bar]] bla #bar"
 
 
-       ["#logseq/foo bla [[logseq/foo]] bla [[file:./pages/logseq.foo.org][logseq/foo]] bla #logseq/foo" "logseq/foo" "logseq/bar"]
-       "#logseq/bar bla [[logseq/bar]] bla [[file:./pages/logseq.bar.org][logseq/bar]] bla #logseq/bar"))
+    ["#logseq/foo bla [[logseq/foo]] bla [[file:./pages/logseq.foo.org][logseq/foo]] bla #logseq/foo" "logseq/foo" "logseq/bar"]
+    "#logseq/bar bla [[logseq/bar]] bla [[file:./pages/logseq.bar.org][logseq/bar]] bla #logseq/bar"))

+ 8 - 9
src/test/frontend/worker/rtc/gen_client_op_test.cljs

@@ -130,8 +130,7 @@
       (testing "add page"
       (testing "add page"
         (worker-page/create! repo conn (worker-state/get-config repo)
         (worker-page/create! repo conn (worker-state/get-config repo)
                              "TEST-PAGE"
                              "TEST-PAGE"
-                             {:uuid page-uuid
-                              :create-first-block? false})
+                             {:uuid page-uuid})
         (is (some? (d/pull @conn '[*] [:block/uuid page-uuid])))
         (is (some? (d/pull @conn '[*] [:block/uuid page-uuid])))
         (is (= {page-uuid #{:update-page :update}}
         (is (= {page-uuid #{:update-page :update}}
                (ops-coll=>block-uuid->op-types (client-op/get&remove-all-block-ops repo)))))
                (ops-coll=>block-uuid->op-types (client-op/get&remove-all-block-ops repo)))))
@@ -168,10 +167,10 @@
                         :block/tags :block/title :db/cardinality}]
                         :block/tags :block/title :db/cardinality}]
     #_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
     #_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
     (is (->> (me/find (subject/generate-rtc-ops-from-property-entities [ent])
     (is (->> (me/find (subject/generate-rtc-ops-from-property-entities [ent])
-               ([:move _ {:block-uuid ?block-uuid}]
-                [:update-page _ {:block-uuid ?block-uuid}]
-                [:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
-               !av-coll-attrs)
+                      ([:move _ {:block-uuid ?block-uuid}]
+                       [:update-page _ {:block-uuid ?block-uuid}]
+                       [:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
+                      !av-coll-attrs)
              set
              set
              (set/difference av-coll-attrs)
              (set/difference av-coll-attrs)
              empty?))))
              empty?))))
@@ -184,9 +183,9 @@
                         :block/tags :block/title}]
                         :block/tags :block/title}]
     #_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
     #_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
     (is (->> (me/find (subject/generate-rtc-ops-from-class-entities [ent])
     (is (->> (me/find (subject/generate-rtc-ops-from-class-entities [ent])
-               ([:update-page _ {:block-uuid ?block-uuid}]
-                [:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
-               !av-coll-attrs)
+                      ([:update-page _ {:block-uuid ?block-uuid}]
+                       [:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
+                      !av-coll-attrs)
              set
              set
              (set/difference av-coll-attrs)
              (set/difference av-coll-attrs)
              empty?))))
              empty?))))

+ 4 - 4
src/test/frontend/worker/rtc/rtc_fns_test.cljs

@@ -166,7 +166,7 @@
         [page-uuid
         [page-uuid
          uuid1-client uuid2-client
          uuid1-client uuid2-client
          uuid1-remote uuid2-remote] (repeatedly random-uuid)]
          uuid1-remote uuid2-remote] (repeatedly random-uuid)]
-    (test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
+    (test-helper/create-page! page-name {:redirect? false :uuid page-uuid})
     (outliner-tx/transact!
     (outliner-tx/transact!
      opts
      opts
      (outliner-core/insert-blocks!
      (outliner-core/insert-blocks!
@@ -236,7 +236,7 @@
         [page-uuid
         [page-uuid
          uuid1-client uuid2-client
          uuid1-client uuid2-client
          uuid1-not-exist] (repeatedly random-uuid)]
          uuid1-not-exist] (repeatedly random-uuid)]
-    (test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
+    (test-helper/create-page! page-name {:redirect? false})
     (outliner-tx/transact!
     (outliner-tx/transact!
      opts
      opts
      (outliner-core/insert-blocks!
      (outliner-core/insert-blocks!
@@ -301,7 +301,7 @@ result:
           page-name "apply-remote-remove-ops-test2"
           page-name "apply-remote-remove-ops-test2"
           [page-uuid
           [page-uuid
            uuid1 uuid2 uuid3] (repeatedly random-uuid)]
            uuid1 uuid2 uuid3] (repeatedly random-uuid)]
-      (test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page-uuid})
+      (test-helper/create-page! page-name {:redirect? false})
       (outliner-tx/transact!
       (outliner-tx/transact!
        opts
        opts
        (outliner-core/insert-blocks!
        (outliner-core/insert-blocks!
@@ -391,7 +391,7 @@ result:
           [page1-uuid page2-uuid
           [page1-uuid page2-uuid
            uuid1-client uuid2-client
            uuid1-client uuid2-client
            uuid1-remote uuid2-remote] (repeatedly random-uuid)]
            uuid1-remote uuid2-remote] (repeatedly random-uuid)]
-      (test-helper/create-page! page-name {:redirect? false :create-first-block? false :uuid page1-uuid})
+      (test-helper/create-page! page-name {:redirect? false})
       (outliner-tx/transact!
       (outliner-tx/transact!
        opts
        opts
        (outliner-core/insert-blocks!
        (outliner-core/insert-blocks!