Procházet zdrojové kódy

Merge branch 'master' into feat/integrated-title-bar

Konstantinos Kaloutas před 2 roky
rodič
revize
2cfa46cecb
35 změnil soubory, kde provedl 264 přidání a 166 odebrání
  1. 1 1
      deps.edn
  2. 1 1
      deps/graph-parser/src/logseq/graph_parser/extract.cljc
  3. 15 11
      deps/graph-parser/src/logseq/graph_parser/property.cljs
  4. 31 0
      e2e-tests/whiteboards.spec.ts
  5. 2 2
      package.json
  6. 13 8
      src/main/frontend/components/block.cljs
  7. 9 5
      src/main/frontend/components/container.cljs
  8. 1 1
      src/main/frontend/components/plugins.cljs
  9. 1 1
      src/main/frontend/config.cljs
  10. 1 0
      src/main/frontend/db/model.cljs
  11. 107 95
      src/main/frontend/extensions/pdf/core.cljs
  12. 2 1
      src/main/frontend/extensions/tldraw.cljs
  13. 24 14
      src/main/frontend/handler/editor.cljs
  14. 1 1
      src/main/frontend/handler/global_config.cljs
  15. 2 2
      src/main/frontend/handler/repo.cljs
  16. 7 1
      src/main/frontend/handler/whiteboard.cljs
  17. 12 4
      src/main/frontend/mobile/intent.cljs
  18. 1 1
      src/main/frontend/modules/file/core.cljs
  19. 1 3
      src/main/frontend/modules/outliner/core.cljs
  20. 6 3
      src/main/frontend/modules/outliner/datascript.cljc
  21. 1 1
      src/main/frontend/state.cljs
  22. 0 0
      src/resources/grammar/calc.bnf
  23. 0 0
      src/resources/templates/config.edn
  24. 0 0
      src/resources/templates/contents.md
  25. 0 0
      src/resources/templates/contents.org
  26. 0 0
      src/resources/templates/global-config.edn
  27. 0 0
      src/resources/zotero-items.edn
  28. 0 1
      templates/favorites.md
  29. 0 1
      templates/favorites.org
  30. 1 1
      tldraw/apps/tldraw-logseq/src/components/QuickLinks/QuickLinks.tsx
  31. 1 1
      tldraw/apps/tldraw-logseq/src/lib/shapes/GroupShape.tsx
  32. 2 1
      tldraw/packages/core/src/lib/TLPage/TLPage.ts
  33. 16 0
      tldraw/packages/core/src/lib/shapes/TLGroupShape/TLGroupShape.tsx
  34. 1 1
      typos.toml
  35. 4 4
      yarn.lock

+ 1 - 1
deps.edn

@@ -1,4 +1,4 @@
-{:paths ["src/main" "src/electron" "templates" "src/resources"]
+{:paths ["src/main" "src/electron" "src/resources"]
  :deps
  {org.clojure/clojure                   {:mvn/version "1.11.1"}
   rum/rum                               {:mvn/version "0.12.9"}

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

@@ -208,7 +208,7 @@
           pages (remove nil? pages)
           pages (map (fn [page] (assoc page :block/uuid (d/squuid))) pages)
           blocks (->> (remove nil? blocks)
-                      (map (fn [b] (dissoc b :block/title :block/body :block/level :block/children :block/meta :block/anchor))))]
+                      (map (fn [b] (dissoc b :block/title :block/body :block/level :block/children :block/meta))))]
       [pages blocks])
     (catch :default e
       (log/error :exception e))))

+ 15 - 11
deps/graph-parser/src/logseq/graph_parser/property.cljs

@@ -7,11 +7,11 @@
             [goog.string.format]))
 
 (def colons "Property delimiter for markdown mode" "::")
-(defn colons-org 
+(defn colons-org
   "Property delimiter for org mode"
   [property]
   (str ":" property ":"))
- 
+
 (defn ->block-content
   "Creates a block content string from properties map"
   [properties]
@@ -47,19 +47,23 @@
   "Properties used by logseq that user can edit and that can have linkable property values"
   #{:alias :aliases :tags})
 
+(def editable-view-and-table-properties
+  "Properties used by view and table component"
+  #{;; view props
+    :logseq.color
+    ;; table props
+    :logseq.table.version :logseq.table.compact :logseq.table.headers :logseq.table.hover
+    :logseq.table.borders :logseq.table.stripes :logseq.table.max-width})
+
 (defn editable-built-in-properties
   "Properties used by logseq that user can edit"
   []
-  (into #{:title :icon :template :template-including-parent :public :filters :exclude-from-graph-view
-          :logseq.query/nlp-date 
-          ;; view props 
-          :logseq.color
-          ;; table props
-          :logseq.table.version :logseq.table.compact :logseq.table.headers :logseq.table.hover 
-          :logseq.table.borders :logseq.table.stripes :logseq.table.max-width
+  (set/union #{:title :icon :template :template-including-parent :public :filters :exclude-from-graph-view
+               :logseq.query/nlp-date
           ;; org-mode only
-          :macro :filetags}
-        editable-linkable-built-in-properties))
+               :macro :filetags}
+             editable-linkable-built-in-properties
+             editable-view-and-table-properties))
 
 (defn hidden-built-in-properties
   "Properties used by logseq that user can't edit or see"

+ 31 - 0
e2e-tests/whiteboards.spec.ts

@@ -126,6 +126,37 @@ test('clone the rectangle', async ({ page }) => {
   await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
 })
 
+test('group the rectangles', async ({ page }) => {
+  await page.keyboard.press(modKey + '+a')
+  await page.keyboard.press(modKey + '+g')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(1)
+})
+
+test('delete the group', async ({ page }) => {
+  await page.keyboard.press(modKey + '+a')
+
+  await page.keyboard.press('Delete')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(0)
+    // should also delete the grouped shapes
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(0)
+})
+
+test('undo the group deletion', async ({ page }) => {
+  await page.keyboard.press(modKey + '+z')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(1)
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
+})
+
+test('undo the group action', async ({ page }) => {
+  await page.keyboard.press(modKey + '+z')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(0)
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
+})
+
 test('connect rectangles with an arrow', async ({ page }) => {
   const canvas = await page.waitForSelector('.logseq-tldraw')
   const bounds = (await canvas.boundingBox())!

+ 2 - 2
package.json

@@ -117,7 +117,7 @@
         "highlight.js": "10.4.1",
         "ignore": "5.1.8",
         "jszip": "3.8.0",
-        "mldoc": "^1.5.1",
+        "mldoc": "^1.5.5",
         "path": "0.12.7",
         "path-complete-extname": "1.0.0",
         "pixi-graph-fork": "0.2.0",
@@ -158,4 +158,4 @@
         "pixi-graph-fork/@pixi/mixin-get-child-by-name": "6.2.0",
         "pixi-graph-fork/@pixi/math": "6.2.0"
     }
-}
+}

+ 13 - 8
src/main/frontend/components/block.cljs

@@ -1792,8 +1792,8 @@
          (or
            (and empty-content?
                 (not edit?)
-                (not (:block/top? block))
-                (not (:block/bottom? block))
+                (not (:block.temp/top? block))
+                (not (:block.temp/bottom? block))
                 (not (util/react *control-show?)))
            (and doc-mode?
                 (not collapsed?)
@@ -2066,7 +2066,8 @@
 
 (def hidden-editable-block-properties
   "Properties that are hidden in a block (block property)"
-  #{:logseq.query/nlp-date})
+  (into #{:logseq.query/nlp-date}
+        gp-property/editable-view-and-table-properties))
 
 (assert (set/subset? hidden-editable-block-properties (gp-property/editable-built-in-properties))
         "Hidden editable page properties must be valid editable properties")
@@ -2779,7 +2780,8 @@
         block (if ref?
                 (merge block (db/sub-block (:db/id block)))
                 block)
-        {:block/keys [uuid children pre-block? top? refs level format content properties]} block
+        {:block/keys [uuid children pre-block? refs level format content properties]} block
+        {:block.temp/keys [top?]} block
         config (if navigated? (assoc config :id (str navigating-block)) config)
         block (merge block (block/parse-title-and-body uuid format pre-block? content))
         blocks-container-id (:blocks-container-id config)
@@ -2816,6 +2818,8 @@
         edit? (state/sub [:editor/editing? edit-input-id])
         card? (string/includes? data-refs-self "\"card\"")
         review-cards? (:review-cards? config)
+        own-number-list? (:own-order-number-list? config)
+        order-list? (boolean own-number-list?)
         selected? (when-not slide?
                     (state/sub-block-selected? blocks-container-id uuid))]
     [:div.ls-block
@@ -2828,6 +2832,7 @@
                     (when pre-block? " pre-block")
                     (when (and card? (not review-cards?)) " shadow-md")
                     (when selected? " selected noselect")
+                    (when order-list? " is-order-list")
                     (when (string/blank? content) " is-blank"))
         :blockid (str uuid)
         :haschild (str (boolean has-child?))}
@@ -2856,7 +2861,7 @@
      (when top?
        (dnd-separator-wrapper block block-id slide? true false))
 
-     [:div.flex.flex-row.pr-2
+     [:div.block-main-container.flex.flex-row.pr-2
       {:class (if (and heading? (seq (:block/title block))) "items-baseline" "")
        :on-touch-start (fn [event uuid] (block-handler/on-touch-start event uuid))
        :on-touch-move (fn [event]
@@ -2922,7 +2927,7 @@
 
    :should-update (fn [old-state new-state]
                     (let [compare-keys        [:block/uuid :block/content :block/parent :block/collapsed?
-                                               :block/properties :block/left :block/children :block/_refs :block/bottom? :block/top?]
+                                               :block/properties :block/left :block/children :block/_refs :block.temp/bottom? :block.temp/top?]
                           config-compare-keys [:show-cloze? :own-order-list-type :own-order-list-index]
                           b1                  (second (:rum/args old-state))
                           b2                  (second (:rum/args new-state))
@@ -3316,8 +3321,8 @@
   [config blocks idx item]
   (let [item (->
               (dissoc item :block/meta)
-              (assoc :block/top? (zero? idx)
-                     :block/bottom? (= (count blocks) (inc idx))))
+              (assoc :block.temp/top? (zero? idx)
+                     :block.temp/bottom? (= (count blocks) (inc idx))))
         config (assoc config :block/uuid (:block/uuid item))]
     (rum/with-key (block-container config item)
       (str (:blocks-container-id config) "-" (:block/uuid item)))))

+ 9 - 5
src/main/frontend/components/container.cljs

@@ -482,7 +482,7 @@
 
 (rum/defc main <
   {:did-mount (fn [state]
-                (when-let [element (gdom/getElement "main-content-container")]
+                (when-let [element (gdom/getElement "app-container")]
                   (dnd/subscribe!
                    element
                    :upload-files
@@ -493,19 +493,23 @@
                   (common-handler/listen-to-scroll! element)
                   (when (:margin-less-pages? (first (:rum/args state))) ;; makes sure full screen pages displaying without scrollbar
                     (set! (.. element -scrollTop) 0)))
-                state)}
+                state)
+   :will-unmount (fn [state]
+                   (when-let [el (gdom/getElement "app-container")]
+                     (dnd/unsubscribe! el :upload-files))
+                   state)}
   [{:keys [route-match margin-less-pages? route-name indexeddb-support? db-restoring? main-content show-action-bar? show-recording-bar?]}]
-  (let [left-sidebar-open? (state/sub :ui/left-sidebar-open?)
+  (let [left-sidebar-open?   (state/sub :ui/left-sidebar-open?)
         onboarding-and-home? (and (or (nil? (state/get-current-repo)) (config/demo-graph?))
                                   (not config/publishing?)
                                   (= :home route-name))
-        margin-less-pages? (or (and (mobile-util/native-platform?) onboarding-and-home?) margin-less-pages?)]
+        margin-less-pages?   (or (and (mobile-util/native-platform?) onboarding-and-home?) margin-less-pages?)]
     [:div#main-container.cp__sidebar-main-layout.flex-1.flex
      {:class (util/classnames [{:is-left-sidebar-open left-sidebar-open?}])}
 
      ;; desktop left sidebar layout
      (left-sidebar {:left-sidebar-open? left-sidebar-open?
-                    :route-match route-match})
+                    :route-match        route-match})
 
      [:div#main-content-container.scrollbar-spacing.w-full.flex.justify-center.flex-row.outline-none.relative
 

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

@@ -589,7 +589,7 @@
                     :options {:on-click
                               #(p/let [root (plugin-handler/get-ls-dotdir-root)]
                                  (js/apis.openPath (str root "/preferences.json")))}}
-                   {:title   [:span.flex.items-center (ui/icon "bug") "Open " [:code " ~/.logseq"]]
+                   {:title   [:span.flex.items-center (ui/icon "bug") "Open\u00A0" [:code "~/.logseq"]]
                     :options {:on-click
                               #(p/let [root (plugin-handler/get-ls-dotdir-root)]
                                  (js/apis.openPath root))}}]))

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

@@ -339,7 +339,7 @@
 (def custom-css-file "custom.css")
 (def export-css-file "export.css")
 (def custom-js-file "custom.js")
-(def config-default-content (rc/inline "config.edn"))
+(def config-default-content (rc/inline "templates/config.edn"))
 (def config-default-content-md5 (let [md5 (new crypt/Md5)]
                                   (.update md5 (crypt/stringToUtf8ByteArray config-default-content))
                                   (crypt/byteArrayToHex (.digest md5))))

+ 1 - 0
src/main/frontend/db/model.cljs

@@ -49,6 +49,7 @@
     :block/marker
     :block/priority
     :block/properties
+    :block/properties-order
     :block/properties-text-values
     :block/pre-block?
     :block/scheduled

+ 107 - 95
src/main/frontend/extensions/pdf/core.cljs

@@ -347,9 +347,8 @@
                                                     (.setAttribute target "data-x" ax)
                                                     (.setAttribute target "data-y" ay))
                                                   ))}
-                           :modifiers [;; minimum
-                                       (js/interact.modifiers.restrictSize
-                                        (bean/->js {:min {:width 60 :height 25}}))]
+                           :modifiers [(js/interact.modifiers.restrict
+                                         (bean/->js {:restriction (.closest el ".page")}))]
                            :inertia   true})
                          ))]
          ;; destroy
@@ -376,10 +375,10 @@
    (for [hl page-hls]
      (let [vw-hl (update-in hl [:position] #(pdf-utils/scaled-to-vw-pos viewer %))]
        (rum/with-key
-        (if (get-in hl [:content :image])
-          (pdf-highlight-area-region viewer vw-hl hl ops)
-          (pdf-highlights-text-region viewer vw-hl hl ops))
-        (:id hl))
+         (if (get-in hl [:content :image])
+           (pdf-highlight-area-region viewer vw-hl hl ops)
+           (pdf-highlights-text-region viewer vw-hl hl ops))
+         (:id hl))
        ))])
 
 (rum/defc ^:large-vars/cleanup-todo pdf-highlight-area-selection
@@ -388,41 +387,59 @@
   (let [^js viewer-clt          (.. viewer -viewer -classList)
         ^js cnt-el              (.-container viewer)
         *el                     (rum/use-ref nil)
-        *sta-el                 (rum/use-ref nil)
+        *start-el               (rum/use-ref nil)
         *cnt-rect               (rum/use-ref nil)
+        *page-el                (rum/use-ref nil)
+        *page-rect              (rum/use-ref nil)
+        *start-xy               (rum/use-ref nil)
 
-        [start-coord, set-start-coord!] (rum/use-state nil)
-        [end-coord, set-end-coord!] (rum/use-state nil)
+        [start, set-start!] (rum/use-state nil)
+        [end, set-end!] (rum/use-state nil)
         [_ set-area-mode!] (use-atom *area-mode?)
 
         should-start            (fn [^js e]
                                   (let [^js target (.-target e)]
-                                    (when (and (not
-                                                (.contains (.-classList target) "extensions__pdf-hls-area-region"))
+                                    (when (and (not (.contains (.-classList target) "extensions__pdf-hls-area-region"))
                                                (.closest target ".page"))
                                       (and e (or (.-metaKey e)
                                                  (and util/win32? (.-shiftKey e))
                                                  @*area-mode?)))))
 
-        reset-coords            #(do
-                                   (set-start-coord! nil)
-                                   (set-end-coord! nil)
-                                   (rum/set-ref! *sta-el nil))
+        reset-coords!           #(do
+                                   (set-start! nil)
+                                   (set-end! nil)
+                                   (rum/set-ref! *start-xy nil)
+                                   (rum/set-ref! *start-el nil)
+                                   (rum/set-ref! *cnt-rect nil)
+                                   (rum/set-ref! *page-el nil)
+                                   (rum/set-ref! *page-rect nil))
 
-        calc-coords             (fn [page-x page-y]
+        calc-coords!            (fn [page-x page-y]
                                   (when cnt-el
-                                    (let [cnt-rect (rum/deref *cnt-rect)
-                                          cnt-rect (or cnt-rect (bean/->clj (.toJSON (.getBoundingClientRect cnt-el))))
-                                          _        (rum/set-ref! *cnt-rect cnt-rect)]
+                                    (let [cnt-rect    (rum/deref *cnt-rect)
+                                          cnt-rect    (or cnt-rect (bean/->clj (.toJSON (.getBoundingClientRect cnt-el))))
+                                          page-rect   (rum/deref *page-rect)
+                                          [start-x, start-y] (rum/deref *start-xy)
+                                          dx-left?    (> start-x page-x)
+                                          dy-top?     (> start-y page-y)
+                                          page-left   (:left page-rect)
+                                          page-right  (:right page-rect)
+                                          page-top    (:top page-rect)
+                                          page-bottom (:bottom page-rect)
+                                          _           (rum/set-ref! *cnt-rect cnt-rect)]
 
                                       {:x (-> page-x
-                                              (- (:left cnt-rect))
+                                              (#(if dx-left?
+                                                  (if (< % page-left) page-left %)
+                                                  (if (> % page-right) page-right %)))
                                               (+ (.-scrollLeft cnt-el)))
                                        :y (-> page-y
-                                              (- (:top cnt-rect))
+                                              (#(if dy-top?
+                                                  (if (< % page-top) page-top %)
+                                                  (if (> % page-bottom) page-bottom %)))
                                               (+ (.-scrollTop cnt-el)))})))
 
-        calc-pos                (fn [start end]
+        calc-rect               (fn [start end]
                                   {:left   (min (:x start) (:x end))
                                    :top    (min (:y start) (:y end))
                                    :width  (js/Math.abs (- (:x end) (:x start)))
@@ -431,81 +448,78 @@
         disable-text-selection! #(js-invoke viewer-clt (if % "add" "remove") "disabled-text-selection")
 
         fn-move                 (rum/use-callback
-                                 (fn [^js/MouseEvent e]
-                                   (set-end-coord! (calc-coords (.-pageX e) (.-pageY e))))
-                                 [])]
+                                  (fn [^js/MouseEvent e]
+                                    (set-end! (calc-coords! (.-pageX e) (.-pageY e))))
+                                  [])]
 
     (rum/use-effect!
-     (fn []
-       (when-let [^js/HTMLElement root cnt-el]
-         (let [fn-start (fn [^js/MouseEvent e]
-                          (if (should-start e)
-                            (do
-                              (rum/set-ref! *sta-el (.-target e))
-                              (set-start-coord! (calc-coords (.-pageX e) (.-pageY e)))
-                              (disable-text-selection! true)
-
-                              (.addEventListener root "mousemove" fn-move))
-
-                            ;; reset
-                            (reset-coords)))
-
-               fn-end   (fn [^js/MouseEvent e]
-                          (when-let [start-el (rum/deref *sta-el)]
-                            (let [end (calc-coords (.-pageX e) (.-pageY e))
-                                  pos (calc-pos start-coord end)]
-
-                              (if (and (> (:width pos) 10)
-                                       (> (:height pos) 10))
-
-                                (when-let [^js page-el (.closest start-el ".page")]
-                                  (let [page-number (int (.-pageNumber (.-dataset page-el)))
-                                        page-pos    (merge pos {:top  (- (:top pos) (.-offsetTop page-el))
-                                                                :left (- (:left pos) (.-offsetLeft page-el))})
-                                        vw-pos      {:bounding page-pos :rects [] :page page-number}
-                                        sc-pos      (pdf-utils/vw-to-scaled-pos viewer vw-pos)
-
-                                        point       {:x (.-clientX e) :y (.-clientY e)}
-                                        hl          {:id         nil
-                                                     :page       page-number
-                                                     :position   sc-pos
-                                                     :content    {:text "[:span]" :image (js/Date.now)}
-                                                     :properties {}}]
-
-                                    ;; ctx tips
-                                    (show-ctx-menu! viewer hl point {:reset-fn #(reset-coords)})
-
-                                    ;; export area highlight
-                                    ;;(dd "[selection end] :start"
-                                    ;;    start-coord ":end" end ":pos" pos
-                                    ;;    ":page" page-number
-                                    ;;    ":offset" page-pos
-                                    ;;    ":vw-pos" vw-pos
-                                    ;;    ":sc-pos" sc-pos)
-                                    )
-
-                                  (set-area-mode! false))
-
-                                ;; reset
-                                (reset-coords)))
-
-                            (disable-text-selection! false)
-                            (.removeEventListener root "mousemove" fn-move)))]
-
-           (doto root
-             (.addEventListener "mousedown" fn-start)
-             (.addEventListener "mouseup" fn-end #js {:once true}))
-
-           ;; destroy
-           #(doto root
-              (.removeEventListener "mousedown" fn-start)
-              (.removeEventListener "mouseup" fn-end)))))
-     [start-coord])
+      (fn []
+        (when-let [^js/HTMLElement root cnt-el]
+          (let [fn-start (fn [^js/MouseEvent e]
+                           (if (should-start e)
+                             (let [target (.-target e)
+                                   page-el (.closest target ".page")
+                                   [x y] [(.-pageX e) (.-pageY e)]]
+                               (rum/set-ref! *start-el target)
+                               (rum/set-ref! *start-xy [x y])
+                               (rum/set-ref! *page-el page-el)
+                               (rum/set-ref! *page-rect (some-> page-el (.getBoundingClientRect) (.toJSON) (bean/->clj)))
+                               (set-start! (calc-coords! x y))
+                               (disable-text-selection! true)
+
+                               (.addEventListener root "mousemove" fn-move))
+
+                             ;; reset
+                             (do (reset-coords!)
+                                 (disable-text-selection! false))))
+
+                fn-end   (fn [^js/MouseEvent e]
+                           (when-let [start-el (rum/deref *start-el)]
+                             (let [end  (calc-coords! (.-pageX e) (.-pageY e))
+                                   rect (calc-rect start end)]
+
+                               (if (and (> (:width rect) 10)
+                                        (> (:height rect) 10))
+
+                                 (when-let [^js page-el (.closest start-el ".page")]
+                                   (let [page-number (int (.-pageNumber (.-dataset page-el)))
+                                         page-pos    (merge rect {:top  (- (:top rect) (.-offsetTop page-el))
+                                                                  :left (- (:left rect) (.-offsetLeft page-el))})
+                                         vw-pos      {:bounding page-pos :rects [] :page page-number}
+                                         sc-pos      (pdf-utils/vw-to-scaled-pos viewer vw-pos)
+
+                                         point       {:x (.-clientX e) :y (.-clientY e)}
+                                         hl          {:id         nil
+                                                      :page       page-number
+                                                      :position   sc-pos
+                                                      :content    {:text "[:span]" :image (js/Date.now)}
+                                                      :properties {}}]
+
+                                     ;; ctx tips
+                                     (show-ctx-menu! viewer hl point {:reset-fn #(reset-coords!)}))
+
+                                   (set-area-mode! false))
+
+                                 ;; reset
+                                 (reset-coords!)))
+
+                             (disable-text-selection! false)
+                             (.removeEventListener root "mousemove" fn-move)))]
+
+            (doto root
+              (.addEventListener "mousedown" fn-start)
+              (.addEventListener "mouseup" fn-end #js {:once true}))
+
+            ;; destroy
+            #(doto root
+               (.removeEventListener "mousedown" fn-start)
+               (.removeEventListener "mouseup" fn-end)))))
+      [start])
 
     [:div.extensions__pdf-area-selection
      {:ref *el}
-     (when (and start-coord end-coord)
-       [:div.shadow-rect {:style (calc-pos start-coord end-coord)}])]))
+     (when (and start end)
+       [:div.shadow-rect {:style (calc-rect start end)}])]))
 
 (rum/defc ^:large-vars/cleanup-todo pdf-highlights
   [^js el ^js viewer initial-hls loaded-pages {:keys [set-dirty-hls!]}]
@@ -641,8 +655,6 @@
     ;; render hls
     (rum/use-effect!
      (fn []
-       ;;(dd "=== rebuild highlights ===" (count highlights))
-
        (when-let [grouped-hls (and (sequential? highlights) (group-by :page highlights))]
          (doseq [page loaded-pages]
            (when-let [^js/HTMLDivElement hls-layer (pdf-utils/resolve-hls-layer! viewer page)]

+ 2 - 1
src/main/frontend/extensions/tldraw.cljs

@@ -138,7 +138,8 @@
                      (when-let [^js api (gobj/get tln "api")]
                       (p/then (when populate-onboarding?
                                 (whiteboard-handler/populate-onboarding-whiteboard api))
-                              #(do (state/focus-whiteboard-shape tln block-id)
+                              #(do (whiteboard-handler/cleanup! (.-currentPage tln))
+                                   (state/focus-whiteboard-shape tln block-id)
                                    (set-loaded-app tln))))))]
     (rum/use-effect! (fn []
                        (when (and loaded-app block-id)

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

@@ -341,8 +341,8 @@
                         (select-keys properties (property/hidden-properties))
                         (:block/properties block))]
     (-> block
-        (dissoc :block/top?
-                :block/bottom?)
+        (dissoc :block.temp/top?
+                :block.temp/bottom?)
         (assoc :block/content content
                :block/properties new-properties)
         (merge (if level {:block/level level} {})))))
@@ -407,10 +407,10 @@
            (save-block-inner! block value opts)))))))
 
 (defn- compute-fst-snd-block-text
-  [value pos]
+  [value selection-start selection-end]
   (when (string? value)
-    (let [fst-block-text (subs value 0 pos)
-          snd-block-text (string/triml (subs value pos))]
+    (let [fst-block-text (subs value 0 selection-start)
+          snd-block-text (string/triml (subs value selection-end))]
       [fst-block-text snd-block-text])))
 
 (declare save-current-block!)
@@ -448,13 +448,21 @@
     (= uuid block-id)))
 
 (defn insert-new-block-before-block-aux!
-  [config block _value {:keys [ok-handler]}]
-  (let [new-m {:block/uuid (db/new-block-id)
+  [config block value {:keys [ok-handler]}]
+  (let [edit-input-id (state/get-edit-input-id)
+        input (gdom/getElement edit-input-id)
+        input-text-selected? (util/input-text-selected? input)
+        new-m {:block/uuid (db/new-block-id)
                :block/content ""}
         prev-block (-> (merge (select-keys block [:block/parent :block/left :block/format
                                                   :block/page :block/journal?]) new-m)
                        (wrap-parse-block))
         left-block (db/pull (:db/id (:block/left block)))]
+    (when input-text-selected?
+      (let [selection-start (util/get-selection-start input)
+            selection-end (util/get-selection-end input)
+            [_ new-content] (compute-fst-snd-block-text value selection-start selection-end)]
+        (state/set-edit-content! edit-input-id new-content)))
     (profile
      "outliner insert block"
      (let [sibling? (not= (:db/id left-block) (:db/id (:block/parent block)))]
@@ -471,8 +479,9 @@
     :as _opts}]
   (let [block-self? (block-self-alone-when-insert? config uuid)
         input (gdom/getElement (state/get-edit-input-id))
-        pos (cursor/pos input)
-        [fst-block-text snd-block-text] (compute-fst-snd-block-text value pos)
+        selection-start (util/get-selection-start input)
+        selection-end (util/get-selection-end input)
+        [fst-block-text snd-block-text] (compute-fst-snd-block-text value selection-start selection-end)
         current-block (assoc block :block/content fst-block-text)
         current-block (apply dissoc current-block db-schema/retract-attributes)
         current-block (wrap-parse-block current-block)
@@ -526,8 +535,9 @@
                        block)
              block-self? (block-self-alone-when-insert? config block-id)
              input (gdom/getElement (state/get-edit-input-id))
-             pos (cursor/pos input)
-             [fst-block-text snd-block-text] (compute-fst-snd-block-text value pos)
+             selection-start (util/get-selection-start input)
+             selection-end (util/get-selection-end input)
+             [fst-block-text snd-block-text] (compute-fst-snd-block-text value selection-start selection-end)
              insert-fn (cond
                          block-self?
                          insert-new-block-aux!
@@ -826,7 +836,7 @@
                        (let [prev-block' (if (seq (:block/_refs block-e))
                                            (assoc prev-block
                                                   :block/uuid (:block/uuid block)
-                                                  :block/additional-properties (:block/properties block))
+                                                  :block.temp/additional-properties (:block/properties block))
                                            prev-block)]
                          (delete-block-aux! block delete-children?)
                          (save-block! repo prev-block' new-content {:editor/op :delete}))
@@ -2646,7 +2656,7 @@
             edit-block' (if next-block-has-refs?
                           (assoc edit-block
                                  :block/uuid (:block/uuid next-block)
-                                 :block/additional-properties (dissoc (:block/properties next-block) :block/uuid))
+                                 :block.temp/additional-properties (dissoc (:block/properties next-block) :block/uuid))
                           edit-block)]
         (outliner-tx/transact! transact-opts
           (delete-block-aux! next-block false)
@@ -2691,7 +2701,7 @@
         repo (state/get-current-repo)
         top-block? (= (:block/left block) (:block/page block))
         single-block? (inside-of-single-block (.-target e))
-        root-block? (= (:block/container block) (str (:block/uuid block)))]
+        root-block? (= (:block.temp/container block) (str (:block/uuid block)))]
     (mark-last-input-time! repo)
     (cond
       (not= selected-start selected-end)

+ 1 - 1
src/main/frontend/handler/global_config.cljs

@@ -41,7 +41,7 @@
     (state/set-global-config! config)
     config))
 
-(def default-content (rc/inline "global-config.edn"))
+(def default-content (rc/inline "templates/global-config.edn"))
 
 (defn- create-global-config-file-if-not-exists
   [repo-url]

+ 2 - 2
src/main/frontend/handler/repo.cljs

@@ -48,8 +48,8 @@
       (let [format (state/get-preferred-format)
             file-rpath (str "pages/" "contents." (config/get-file-extension format))
             default-content (case (name format)
-                              "org" (rc/inline "contents.org")
-                              "markdown" (rc/inline "contents.md")
+                              "org" (rc/inline "templates/contents.org")
+                              "markdown" (rc/inline "templates/contents.md")
                               "")]
         (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir pages-dir))
                 file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath default-content)]

+ 7 - 1
src/main/frontend/handler/whiteboard.cljs

@@ -153,13 +153,14 @@
         (compute-tx app tl-page new-id-nonces db-id-nonces page-name replace?)
         tx-data (concat delete-blocks [page-block] upserted-blocks)
         new-shapes (get-in metadata [:data :new-shapes])
+        deleted-shapes (get-in metadata [:data :deleted-shapes])
         metadata' (cond
                     ;; group
                     (some #(= "group" (:type %)) new-shapes)
                     (assoc metadata :whiteboard/op :group)
 
                     ;; ungroup
-                    (some #(= "group" (:type %)) (get-in metadata [:data :deleted-shapes]))
+                    (and (not-empty deleted-shapes) (every? #(= "group" (:type %)) deleted-shapes))
                     (assoc metadata :whiteboard/op :un-group)
 
                     ;; arrow
@@ -361,6 +362,11 @@
   [^js api ids]
   (apply (.-selectShapes api) ids))
 
+(defn cleanup!
+  [^js tl-page]
+  (let [shapes (.-shapes tl-page)]
+    (.cleanup tl-page (map #(.-id %) shapes))))
+
 (defn update-bindings!
   [^js tl-page page-name]
   (when-let [page (db/entity [:block/name page-name])]

+ 12 - 4
src/main/frontend/mobile/intent.cljs

@@ -65,6 +65,7 @@
   (p/let [basename (node-path/basename url)
           label (-> basename util/node-path.name)
           time (date/get-current-time)
+          date-ref-name (date/today)
           path (editor-handler/get-asset-path basename)
           _file (p/catch
                  (.copy Filesystem (clj->js {:from url :to path}))
@@ -75,21 +76,25 @@
           template (get-in (state/get-config)
                            [:quick-capture-templates :media]
                            "**{time}** [[quick capture]]: {url}")]
-    (-> (string/replace template "{time}" time)
+    (-> template
+        (string/replace "{time}" time)
+        (string/replace "{date}" date-ref-name)
+        (string/replace "{text}" "")
         (string/replace "{url}" (or url "")))))
 
 (defn- embed-text-file
   "Store external content with url into Logseq repo"
   [url title]
   (p/let [time (date/get-current-time)
+          date-ref-name (date/today)
           title (some-> (or title (node-path/basename url))
                         gp-util/safe-decode-uri-component
                         util/node-path.name
                         ;; make the title more user friendly
                         gp-util/page-name-sanity)
           path (node-path/join (config/get-repo-dir (state/get-current-repo))
-                          (config/get-pages-directory)
-                          (str (js/encodeURI (fs-util/file-name-sanity title)) (node-path/extname url)))
+                               (config/get-pages-directory)
+                               (str (js/encodeURI (fs-util/file-name-sanity title)) (node-path/extname url)))
           _ (p/catch
              (.copy Filesystem (clj->js {:from url :to path}))
              (fn [error]
@@ -98,7 +103,10 @@
           template (get-in (state/get-config)
                            [:quick-capture-templates :text]
                            "**{time}** [[quick capture]]: {url}")]
-    (-> (string/replace template "{time}" time)
+    (-> template
+        (string/replace "{time}" time)
+        (string/replace "{date}" date-ref-name)
+        (string/replace "{text}" "")
         (string/replace "{url}" (or url "")))))
 
 (defn- handle-received-media [result]

+ 1 - 1
src/main/frontend/modules/file/core.cljs

@@ -156,7 +156,7 @@
         (if (and (string/blank? new-content)
                  (not blocks-just-deleted?))
           (state/pub-event! [:capture-error {:error (js/Error. "Empty content")
-                                             :payload {:file-path file-path}}])
+                                             :payload {}}])
           (let [files [[file-path new-content]]
                 repo (state/get-current-repo)]
             (file-handler/alter-files-handler! repo files {} {}))))

+ 1 - 3
src/main/frontend/modules/outliner/core.cljs

@@ -140,7 +140,7 @@
     (assert (ds/outliner-txs-state? txs-state)
             "db should be satisfied outliner-tx-state?")
     (let [m (-> (:data this)
-                (dissoc :block/children :block/meta :block/top? :block/bottom?
+                (dissoc :block/children :block/meta :block.temp/top? :block.temp/bottom?
                         :block/title :block/body :block/level)
                 (gp-util/remove-nils))
           m (if (state/enable-block-timestamps?) (block-with-timestamps m) m)
@@ -564,8 +564,6 @@
       (do
         (state/pub-event! [:capture-error {:error "Outliner invalid structure"
                                            :payload {:type :outliner/invalid-structure
-                                                     :blocks blocks
-                                                     :target-block target-block'
                                                      :opt opts
                                                      :data (mapv #(dissoc % :block/content) tx)}}])
         (throw (ex-info "Invalid outliner data"

+ 6 - 3
src/main/frontend/modules/outliner/datascript.cljc

@@ -126,9 +126,12 @@
      (let [txs (remove-nil-from-transaction txs)
            txs (map (fn [m] (if (map? m)
                               (dissoc m
-                                      :block/children :block/meta :block/top? :block/bottom? :block/anchor
-                                      :block/title :block/body :block/level :block/container :db/other-tx
-                                      :block/additional-properties)
+                                      ;; TODO: Move these attributes to :block.temp when the risk is lower
+                                      :block/children :block/meta :block/title :block/body :block/level
+                                      :db/other-tx
+                                      ;; :block.temp is for temporary block attributes that aren't transacted
+                                      :block.temp/container :block.temp/top? :block.temp/bottom?
+                                      :block.temp/additional-properties)
                               m)) txs)
            txs (cond-> txs
                  (:uuid-changed opts)

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

@@ -1810,7 +1810,7 @@ Similar to re-frame subscriptions"
             container (util/get-block-container block-element)
             block (if container
                     (assoc block
-                           :block/container (gobj/get container "id"))
+                           :block.temp/container (gobj/get container "id"))
                     block)
             content (string/trim (or content ""))]
         (swap! state

+ 0 - 0
src/main/grammar/calc.bnf → src/resources/grammar/calc.bnf


+ 0 - 0
templates/config.edn → src/resources/templates/config.edn


+ 0 - 0
templates/contents.md → src/resources/templates/contents.md


+ 0 - 0
templates/contents.org → src/resources/templates/contents.org


+ 0 - 0
templates/global-config.edn → src/resources/templates/global-config.edn


+ 0 - 0
templates/zotero-items.edn → src/resources/zotero-items.edn


+ 0 - 1
templates/favorites.md

@@ -1 +0,0 @@
--

+ 0 - 1
templates/favorites.org

@@ -1 +0,0 @@
-*

+ 1 - 1
tldraw/apps/tldraw-logseq/src/components/QuickLinks/QuickLinks.tsx

@@ -25,7 +25,7 @@ export const QuickLinks: TLQuickLinksComponent<Shape> = observer(({ shape }) =>
         link[0].toLowerCase() !== app.currentPage.name &&
         handlers.getBlockPageName(link[0]) !== app.currentPage.name
     )
-  }, [shape.props.type, shape.props.parentId, shape.props.refs])
+  }, [shape.props.id, shape.props.type, shape.props.parentId, shape.props.refs])
 
   if (links.length === 0) return null
 

+ 1 - 1
tldraw/apps/tldraw-logseq/src/lib/shapes/GroupShape.tsx

@@ -29,7 +29,7 @@ export class GroupShape extends TLGroupShape<GroupShapeProps> {
     const Indicator = this.ReactIndicator
 
     return (
-      <SVGContainer {...events}>
+      <SVGContainer {...events} className="tl-group-container">
         <rect
           className={'tl-hitarea-fill'}
           x={strokeWidth / 2}

+ 2 - 1
tldraw/packages/core/src/lib/TLPage/TLPage.ts

@@ -1,4 +1,5 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
+import { deepEqual } from '@tldraw/core'
 import { intersectRayBounds, TLBounds } from '@tldraw/intersect'
 import Vec from '@tldraw/vec'
 import { action, autorun, computed, makeObservable, observable, toJS, transaction } from 'mobx'
@@ -264,7 +265,7 @@ export class TLPage<S extends TLShape = TLShape, E extends TLEventMap = TLEventM
           ...fromDelta,
         }
         shapeChanged = true
-        this.getShapeById(nextShape.id)?.update(nextShape, false, true)
+        this.getShapeById(nextShape.id)?.update(nextShape, false, deepEqual(fromDelta?.handles, fromShape?.props.handles))
       }
     })
 

+ 16 - 0
tldraw/packages/core/src/lib/shapes/TLGroupShape/TLGroupShape.tsx

@@ -3,6 +3,7 @@ import { computed, makeObservable } from 'mobx'
 import { BoundsUtils } from '../../../utils'
 import { TLBoxShape, TLBoxShapeProps } from '../TLBoxShape'
 import type { TLShape } from '../TLShape'
+import { useApp } from '@tldraw/react'
 
 export interface TLGroupShapeProps extends TLBoxShapeProps {
   children: string[] // shape ids
@@ -41,6 +42,21 @@ export class TLGroupShape<
   }
 
   getBounds = (): TLBounds => {
+    // A group without children needs to be removed
+    if (this.shapes.length === 0) {
+      const app = useApp<Shape>()
+      app.deleteShapes([this.id])
+
+      return {
+        minX: 0,
+        minY: 0,
+        maxX: 0,
+        maxY: 0,
+        width: 0,
+        height: 0,
+      }
+    }
+
     return BoundsUtils.getCommonBounds(this.shapes.map(s => s.getBounds()))
   }
 }

+ 1 - 1
typos.toml

@@ -13,4 +13,4 @@ fo = "fo"
 aks = "aks"
 Mannor = "Mannor"
 [files]
-extend-exclude = ["resources/*", "templates/*", "src/resources/*"]
+extend-exclude = ["resources/*", "src/resources/*"]

+ 4 - 4
yarn.lock

@@ -4667,10 +4667,10 @@ mkdirp@^1.0.3:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
-mldoc@^1.5.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.1.tgz#570ae860d621e167e9a586f5be2b1bb96faf8bb7"
-  integrity sha512-FlmspawzeYjIegvHlUxx2VoZx2ExHKS5h+f80yCFjhuW3yeqdvq4zFP19GJGVGbAWnyTL0DfUoROf84IMAL8Fw==
+mldoc@^1.5.5:
+  version "1.5.5"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.5.tgz#2f18439740cbcf474bf7d59266d4d98bbbc89412"
+  integrity sha512-hBVLgzlh/648l0b0Y2rkQ9KK65EBf4T+IINNFGERpn2MccXwIAiXTCZXuMIe4xfhWQ2C8KHb+k4Wb2Nw5O1TKQ==
   dependencies:
     yargs "^12.0.2"