Browse Source

Merge branch 'master' into feat/whiteboards-color-system

Konstantinos Kaloutas 3 years ago
parent
commit
0f57a4ad00
43 changed files with 375 additions and 193 deletions
  1. 2 2
      android/app/build.gradle
  2. 11 16
      deps/graph-parser/src/logseq/graph_parser/block.cljs
  3. 5 5
      deps/graph-parser/src/logseq/graph_parser/extract.cljc
  4. 17 0
      deps/graph-parser/test/logseq/graph_parser_test.cljs
  5. 4 4
      ios/App/App.xcodeproj/project.pbxproj
  6. 78 0
      ios/App/App.xcodeproj/xcshareddata/xcschemes/Logseq.xcscheme
  7. 2 2
      package.json
  8. 5 1
      resources/css/common.css
  9. 1 1
      resources/package.json
  10. 5 4
      src/electron/electron/core.cljs
  11. 11 4
      src/main/frontend/components/block.cljs
  12. 31 28
      src/main/frontend/components/content.cljs
  13. 1 1
      src/main/frontend/components/file_sync.cljs
  14. 1 1
      src/main/frontend/components/header.cljs
  15. 1 1
      src/main/frontend/components/header.css
  16. 5 5
      src/main/frontend/components/page.cljs
  17. 4 0
      src/main/frontend/components/page.css
  18. 28 17
      src/main/frontend/components/settings.cljs
  19. 1 0
      src/main/frontend/components/whiteboard.css
  20. 3 2
      src/main/frontend/dicts.cljc
  21. 17 8
      src/main/frontend/extensions/slide.cljs
  22. 18 16
      src/main/frontend/fs/capacitor_fs.cljs
  23. 35 20
      src/main/frontend/fs/sync.cljs
  24. 7 1
      src/main/frontend/handler/editor.cljs
  25. 1 1
      src/main/frontend/handler/events.cljs
  26. 1 1
      src/main/frontend/handler/file_sync.cljs
  27. 7 4
      src/main/frontend/handler/user.cljs
  28. 1 1
      src/main/frontend/handler/whiteboard.cljs
  29. 1 1
      src/main/frontend/mobile/record.cljs
  30. 2 0
      src/main/frontend/mobile/util.cljs
  31. 2 0
      src/main/frontend/modules/outliner/file.cljs
  32. 1 3
      src/main/frontend/modules/shortcut/before.cljs
  33. 1 0
      src/main/frontend/publishing/html.cljs
  34. 8 2
      src/main/frontend/state.cljs
  35. 1 1
      src/main/frontend/util.cljc
  36. 1 1
      src/main/frontend/version.cljs
  37. 16 8
      tldraw/apps/tldraw-logseq/src/app.tsx
  38. 2 2
      tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx
  39. 1 0
      tldraw/apps/tldraw-logseq/src/lib/tools/LogseqPortalTool/states/CreatingState.tsx
  40. 10 9
      tldraw/apps/tldraw-logseq/src/styles.css
  41. 10 9
      tldraw/packages/core/src/lib/TLApp/TLApp.ts
  42. 8 3
      tldraw/packages/react/src/hooks/useSetup.ts
  43. 8 8
      yarn.lock

+ 2 - 2
android/app/build.gradle

@@ -6,8 +6,8 @@ android {
         applicationId "com.logseq.app"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
-        versionCode 43
-        versionName "0.8.9"
+        versionCode 44
+        versionName "0.8.10"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
              // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

+ 11 - 16
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -67,11 +67,6 @@
                                     (not (contains? supported-formats ext))))
                        value)))
 
-                  (and
-                   (= typ "Complex")
-                   (= (:protocol value) "file")
-                   (:link value))
-
                   (and
                    (= typ "File")
                    (second (first (:label (second block)))))))
@@ -320,7 +315,7 @@
   (let [refs (->> (concat tags refs [marker priority])
                   (remove string/blank?)
                   (distinct))
-        refs (atom refs)]
+        *refs (atom refs)]
     (walk/prewalk
      (fn [form]
        ;; skip custom queries
@@ -328,29 +323,29 @@
                       (= (first form) "Custom")
                       (= (second form) "query"))
          (when-let [page (get-page-reference form supported-formats)]
-           (swap! refs conj page))
+           (swap! *refs conj page))
          (when-let [tag (get-tag form)]
            (let [tag (text/page-ref-un-brackets! tag)]
              (when (gp-util/tag-valid? tag)
-               (swap! refs conj tag))))
+               (swap! *refs conj tag))))
          form))
      (concat title body))
-    (let [refs (remove string/blank? @refs)
-          children-pages (->> (mapcat (fn [p]
+    (swap! *refs #(remove string/blank? %))
+    (let [children-pages (->> @*refs
+                              (mapcat (fn [p]
                                         (let [p (if (map? p)
                                                   (:block/original-name p)
                                                   p)]
                                           (when (string? p)
                                             (let [p (or (text/get-nested-page-name p) p)]
                                               (when (text/namespace-page? p)
-                                                (gp-util/split-namespace-pages p))))))
-                                      refs)
+                                                (gp-util/split-namespace-pages p)))))))
                               (remove string/blank?)
                               (distinct))
-          refs (->> (distinct (concat refs children-pages))
-                    (remove nil?))
-          refs (map (fn [ref] (page-name->map ref with-id? db true date-formatter)) refs)]
-      (assoc block :refs refs))))
+          refs' (->> (distinct (concat @*refs children-pages))
+                     (remove nil?)
+                     (map (fn [ref] (page-name->map ref with-id? db true date-formatter))))]
+      (assoc block :refs refs'))))
 
 (defn- with-block-refs
   [{:keys [title body] :as block}]

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

@@ -222,11 +222,11 @@
   (let [_ (when verbose (println "Parsing start: " file))
         {:keys [pages blocks]} (gp-util/safe-read-string content)
         blocks (map
-                 (fn [block]
-                   (-> block
-                       (gp-util/dissoc-in [:block/parent :block/name])
-                       (gp-util/dissoc-in [:block/left :block/name])))
-                 blocks)
+                (fn [block]
+                  (-> block
+                      (gp-util/dissoc-in [:block/parent :block/name])
+                      (gp-util/dissoc-in [:block/left :block/name])))
+                blocks)
         serialized-page (first pages)
         ;; whiteboard edn file should normally have valid :block/original-name, :block/name, :block/uuid
         page-name (-> (or (:block/name serialized-page)

+ 17 - 0
deps/graph-parser/test/logseq/graph_parser_test.cljs

@@ -322,6 +322,23 @@
                                "title:: core.async"
                                {})
       (is (= #{"core.async"}
+             (->> (d/q '[:find (pull ?b [*])
+                         :in $
+                         :where [?b :block/name]]
+                       @conn)
+                  (map (comp :block/name first))
+                  (remove built-in-pages)
+                  set)))))
+
+  (testing "for file and web uris"
+    (let [conn (ldb/start-conn)
+          built-in-pages (set (map string/lower-case default-db/built-in-pages-names))]
+      (graph-parser/parse-file conn
+                               "foo.md"
+                               (str "- [Filename.txt](file:///E:/test/Filename.txt)\n"
+                                    "- [example](https://example.com)")
+                               {})
+      (is (= #{"foo"}
              (->> (d/q '[:find (pull ?b [*])
                          :in $
                          :where [?b :block/name]]

+ 4 - 4
ios/App/App.xcodeproj/project.pbxproj

@@ -515,7 +515,7 @@
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				MARKETING_VERSION = 0.8.9;
+				MARKETING_VERSION = 0.8.10;
 				OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -542,7 +542,7 @@
 				INFOPLIST_FILE = App/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				MARKETING_VERSION = 0.8.9;
+				MARKETING_VERSION = 0.8.10;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
@@ -567,7 +567,7 @@
 				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
-				MARKETING_VERSION = 0.8.9;
+				MARKETING_VERSION = 0.8.10;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq.ShareViewController;
@@ -594,7 +594,7 @@
 				INFOPLIST_KEY_NSHumanReadableCopyright = "";
 				IPHONEOS_DEPLOYMENT_TARGET = 13.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
-				MARKETING_VERSION = 0.8.9;
+				MARKETING_VERSION = 0.8.10;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.logseq.logseq.ShareViewController;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 78 - 0
ios/App/App.xcodeproj/xcshareddata/xcschemes/Logseq.xcscheme

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1400"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "504EC3031FED79650016851F"
+               BuildableName = "Logseq.app"
+               BlueprintName = "Logseq"
+               ReferencedContainer = "container:App.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "504EC3031FED79650016851F"
+            BuildableName = "Logseq.app"
+            BlueprintName = "Logseq"
+            ReferencedContainer = "container:App.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "504EC3031FED79650016851F"
+            BuildableName = "Logseq.app"
+            BlueprintName = "Logseq"
+            ReferencedContainer = "container:App.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 2 - 2
package.json

@@ -89,7 +89,7 @@
         "@capacitor/status-bar": "^4.0.0",
         "@excalidraw/excalidraw": "0.12.0",
         "@kanru/rage-wasm": "^0.3.0",
-        "@logseq/capacitor-file-sync": "0.0.12",
+        "@logseq/capacitor-file-sync": "0.0.13",
         "@logseq/react-tweet-embed": "1.3.1-1",
         "@sentry/react": "^6.18.2",
         "@sentry/tracing": "^6.18.2",
@@ -97,7 +97,7 @@
         "@tippyjs/react": "4.2.5",
         "aes-js": "3.1.2",
         "bignumber.js": "^9.0.2",
-        "capacitor-voice-recorder": "2.1.0",
+        "capacitor-voice-recorder": "4.0.0",
         "check-password-strength": "2.0.7",
         "chokidar": "3.5.1",
         "chrono-node": "2.2.4",

+ 5 - 1
resources/css/common.css

@@ -102,6 +102,8 @@ html[data-theme='dark'] {
   --ls-error-background-color: var(--color-red-900);
   --ls-warning-text-color: var(--color-yellow-100);
   --ls-warning-background-color: var(--color-yellow-900);
+  --ls-success-text-color: var(--color-green-100);
+  --ls-success-background-color: var(--color-green-900);
   --ls-focus-ring-color: rgba(18, 98, 119, 0.5);
   --ls-header-button-background: #dee4ea;
   --color-level-1: var(--ls-secondary-background-color);
@@ -177,6 +179,8 @@ html[data-theme='light'] {
   --ls-error-background-color: var(--color-red-100);
   --ls-warning-text-color: var(--color-yellow-800);
   --ls-warning-background-color: var(--color-yellow-100);
+  --ls-success-text-color: var(--color-green-800);
+  --ls-success-background-color: var(--color-green-100);
   --ls-focus-ring-color: rgba(66, 133, 244, 0.5);
   --ls-header-button-background: rgba(15, 20, 25, 1);
   --color-level-1: var(--ls-secondary-background-color);
@@ -633,7 +637,7 @@ span.warning, div.warning:not(.admonitionblock), p.warning {
 }
 
 .bg-warning {
-  background: var(--ls-waring-background-color);
+  background: var(--ls-warning-background-color);
 }
 
 a.error,

+ 1 - 1
resources/package.json

@@ -1,6 +1,6 @@
 {
   "name": "Logseq",
-  "version": "0.8.9",
+  "version": "0.8.10",
   "main": "electron.js",
   "author": "Logseq",
   "license": "AGPL-3.0",

+ 5 - 4
src/electron/electron/core.cljs

@@ -94,8 +94,7 @@
       (let [static-dir (path/join root-dir "static")
             assets-from-dir (path/join repo-path "assets")
             assets-to-dir (path/join root-dir "assets")
-            index-html-path (path/join root-dir "index.html")
-            export-or-custom-css-path (if (fs/existsSync export-css-path) export-css-path custom-css-path)]
+            index-html-path (path/join root-dir "index.html")]
         (p/let [_ (. fs ensureDir static-dir)
                 _ (. fs ensureDir assets-to-dir)
                 _ (p/all (concat
@@ -119,8 +118,10 @@
                            (fn [part]
                              (. fs copy (path/join app-path part) (path/join static-dir part)))
                            ["css" "fonts" "icons" "img" "js"])))
-                export-css (. fs readFile export-or-custom-css-path)
-                _ (. fs writeFile (path/join static-dir "css" "export.css") export-css)
+                export-css (if (fs/existsSync export-css-path) (. fs readFile export-css-path) "")
+                _ (. fs writeFile (path/join static-dir "css" "export.css")  export-css)
+                custom-css (if (fs/existsSync custom-css-path) (. fs readFile custom-css-path) "")
+                _ (. fs writeFile (path/join static-dir "css" "custom.css") custom-css)
                 js-files ["main.js" "code-editor.js" "excalidraw.js" "tldraw.js"]
                 _ (p/all (map (fn [file]
                                 (. fs removeSync (path/join static-dir "js" file)))

+ 11 - 4
src/main/frontend/components/block.cljs

@@ -37,13 +37,13 @@
             [frontend.format.block :as block]
             [frontend.format.mldoc :as mldoc]
             [frontend.fs :as fs]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.block :as block-handler]
             [frontend.handler.common :as common-handler]
             [frontend.handler.dnd :as dnd]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.file-sync :as file-sync]
             [frontend.handler.plugin :as plugin-handler]
-            [frontend.handler.assets :as assets-handler]
             [frontend.handler.query :as query-handler]
             [frontend.handler.repeated :as repeated]
             [frontend.handler.route :as route-handler]
@@ -72,6 +72,7 @@
             [logseq.graph-parser.util :as gp-util]
             [logseq.graph-parser.util.block-ref :as block-ref]
             [logseq.graph-parser.util.page-ref :as page-ref]
+            [logseq.graph-parser.whiteboard :as gp-whiteboard]
             [medley.core :as medley]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
@@ -1654,6 +1655,9 @@
 (defn- bullet-on-click
   [e block uuid]
   (cond
+    (gp-whiteboard/shape-block? block)
+    (route-handler/redirect-to-whiteboard! (get-in block [:block/page :block/name]) {:block-id uuid})
+
     (gobj/get e "shiftKey")
     (do
       (state/sidebar-add-block!
@@ -2701,6 +2705,7 @@
         doc-mode? (:document/mode? config)
         embed? (:embed? config)
         reference? (:reference? config)
+        whiteboard-block? (gp-whiteboard/shape-block? block)
         block-id (str "ls-block-" blocks-container-id "-" uuid)
         has-child? (first (:block/_parent (db/entity (:db/id block))))
         attrs (on-drag-and-mouse-attrs block uuid top? block-id *move-to)
@@ -2711,7 +2716,7 @@
         edit? (state/sub [:editor/editing? edit-input-id])
         card? (string/includes? data-refs-self "\"card\"")
         review-cards? (:review-cards? config)
-        selected? (state/sub-block-selected? uuid)]
+        selected? (when-not slide? (state/sub-block-selected? uuid))]
     [:div.ls-block
      (cond->
        {:id block-id
@@ -2723,7 +2728,7 @@
                     (when (and card? (not review-cards?)) " shadow-md")
                     (when selected? " selected noselect"))
         :blockid (str uuid)
-        :haschild (str has-child?)}
+        :haschild (str (boolean has-child?))}
 
        level
        (assoc :level level)
@@ -2767,7 +2772,9 @@
       (when @*show-left-menu?
         (block-left-menu config block))
 
-      (block-content-or-editor config block edit-input-id block-id edit? false)
+      (if whiteboard-block?
+        (block-reference {} (str uuid) nil)
+        (block-content-or-editor config block edit-input-id block-id edit? false))
 
       (when @*show-right-menu?
         (block-right-menu config block edit?))]

+ 31 - 28
src/main/frontend/components/content.cljs

@@ -17,6 +17,7 @@
             [frontend.handler.image :as image-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
+            [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.mixins :as mixins]
             [frontend.state :as state]
             [frontend.ui :as ui]
@@ -380,36 +381,38 @@
                             block-id (d/attr target "blockid")
                             {:keys [block block-ref]} (state/sub :block-ref/context)
                             {:keys [page]} (state/sub :page-title/context)]
-                        (cond
-                          page
-                          (do
+                        ;; TODO: Find a better way to handle this on whiteboards
+                        (when-not (whiteboard-handler/inside-portal? target)
+                          (cond
+                            page
+                            (do
+                              (common-handler/show-custom-context-menu!
+                               e
+                               (page-title-custom-context-menu-content page))
+                              (state/set-state! :page-title/context nil))
+
+                            block-ref
+                            (do
+                              (common-handler/show-custom-context-menu!
+                               e
+                               (block-ref-custom-context-menu-content block block-ref))
+                              (state/set-state! :block-ref/context nil))
+
+                            (and (state/selection?) (not (d/has-class? target "bullet")))
                             (common-handler/show-custom-context-menu!
                              e
-                             (page-title-custom-context-menu-content page))
-                            (state/set-state! :page-title/context nil))
-
-                          block-ref
-                          (do
-                            (common-handler/show-custom-context-menu!
-                             e
-                             (block-ref-custom-context-menu-content block block-ref))
-                            (state/set-state! :block-ref/context nil))
-
-                          (and (state/selection?) (not (d/has-class? target "bullet")))
-                          (common-handler/show-custom-context-menu!
-                           e
-                           (custom-context-menu-content))
-
-                          (and block-id (parse-uuid block-id))
-                          (let [block (.closest target ".ls-block")]
-                            (when block
-                              (util/select-highlight! [block]))
-                            (common-handler/show-custom-context-menu!
-                            e
-                            (block-context-menu-content target (uuid block-id))))
-
-                          :else
-                          nil))))))
+                             (custom-context-menu-content))
+
+                            (and block-id (parse-uuid block-id))
+                            (let [block (.closest target ".ls-block")]
+                              (when block
+                                (util/select-highlight! [block]))
+                              (common-handler/show-custom-context-menu!
+                               e
+                               (block-context-menu-content target (uuid block-id))))
+
+                            :else
+                            nil)))))))
   [id {:keys [hiccup]}]
   [:div {:id id}
    (if hiccup

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

@@ -764,7 +764,7 @@
     [:br]
     "to our users, we need a little more time to test it. That’s why we decided to first roll it out only to our "
     [:br]
-    "charitable OpenCollective sponsors. We can notify you once it becomes available for you."]
+    "charitable OpenCollective sponsors and backers. We can notify you once it becomes available for you."]
 
    [:div.pt-6.flex.justify-end.space-x-2
     (ui/button "Close" :on-click close-fn :background "gray" :class "opacity-60")]])

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

@@ -199,7 +199,7 @@
       (when (and sync-enabled?
                  current-repo
                  (not (config/demo-graph? current-repo))
-                 (user-handler/alpha-user?))
+                 (user-handler/alpha-or-beta-user?))
         (fs-sync/indicator))
 
       (when (and (not= (state/get-current-route) :home)

+ 1 - 1
src/main/frontend/components/header.css

@@ -313,7 +313,7 @@ html.is-native-ipad {
 }
 
 html.is-native-iphone {
-  --ls-headbar-inner-top-padding: 36px;
+  --ls-headbar-inner-top-padding: 38px;
 
   .left-sidebar-inner {
     .create {

+ 5 - 5
src/main/frontend/components/page.cljs

@@ -76,8 +76,8 @@
                       (or (not= page-name old-page-name)
                           (not= hiccup old-hiccup)
                           (not= block-uuid old-block-uuid))))}
-  [page-name _blocks hiccup sidebar? _block-uuid]
-  [:div.page-blocks-inner {:style {:margin-left (if sidebar? 0 -20)}}
+  [page-name _blocks hiccup sidebar? whiteboard? _block-uuid]
+  [:div.page-blocks-inner {:style {:margin-left (if (or sidebar? whiteboard?) 0 -20)}}
    (rum/with-key
      (content/content page-name
                       {:hiccup   hiccup
@@ -124,7 +124,7 @@
                                   (date/journal-title->int (date/today))))
                      (state/pub-event! [:journal/insert-template page-name])))
                  state)}
-  [repo page-e {:keys [sidebar?] :as config}]
+  [repo page-e {:keys [sidebar? whiteboard?] :as config}]
   (when page-e
     (let [page-name (or (:block/name page-e)
                         (str (:block/uuid page-e)))
@@ -147,7 +147,7 @@
               hiccup-config (common-handler/config-with-document-mode hiccup-config)
               hiccup (component-block/->hiccup page-blocks hiccup-config {})]
           [:div
-           (page-blocks-inner page-name page-blocks hiccup sidebar? block-id)
+           (page-blocks-inner page-name page-blocks hiccup sidebar? whiteboard? block-id)
            (when-not config/publishing?
              (let [args (if block-id
                           {:block-uuid block-id}
@@ -435,7 +435,7 @@
                _ (and block? page (reset! *current-block-page (:block/name (:block/page page))))
                _ (when (and block? (not page))
                    (route-handler/redirect-to-page! @*current-block-page))]
-           (page-blocks-cp repo page {:sidebar? sidebar?}))]])
+           (page-blocks-cp repo page {:sidebar? sidebar? :whiteboard? whiteboard?}))]])
 
        (when today?
          (today-queries repo today? sidebar?))

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

@@ -293,6 +293,10 @@ a.page-title {
 .page-title-sizer-wrapper {
   @apply w-full;
 
+  :empty::before {
+    content: '\200b';
+  }
+
   > .title {
     @apply w-full pointer-events-none overflow-hidden overflow-ellipsis;
   }

+ 28 - 17
src/main/frontend/components/settings.cljs

@@ -687,28 +687,38 @@
      (zotero-settings-row)
      (encryption-row enable-encryption?)
 
+     (when-not web-platform?
+       [:div.mt-1.sm:mt-0.sm:col-span-2
+        [:hr]
+        (if logged-in?
+          [:div
+           (user-handler/email)
+           [:p (ui/button (t :logout) {:class "p-1"
+                                       :icon "logout"
+                                       :on-click user-handler/logout})]]
+          [:div
+           (ui/button (t :login) {:class "p-1"
+                                  :icon "login"
+                                  :on-click (fn []
+                                              (state/close-settings!)
+                                              (js/window.open config/LOGIN-URL))})
+           [:p.text-sm.opacity-50 (t :settings-page/login-prompt)]])])
+
+     (when-not web-platform?
+       [:<>
+        [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-start
+         [:label.flex.font-medium.leading-5.self-start.mt-1 (ui/icon  (if logged-in? "lock-open" "lock") {:class "mr-1"}) (t :settings-page/beta-features)]]
+        [:div.flex.flex-col.gap-4
+         {:class (when-not user-handler/alpha-or-beta-user? "opacity-50 pointer-events-none cursor-not-allowed")}
+         (sync-switcher-row enable-sync?)]])
+
      (when-not web-platform?
        [:<>
         [:hr]
         [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-start
-         [:label.flex.font-medium.leading-5.self-start.mt-1 (ui/icon  (if logged-in? "lock-open" "lock") {:class "mr-1"}) (t :settings-page/alpha-features)]
-         [:div.mt-1.sm:mt-0.sm:col-span-2
-          (if logged-in?
-            [:div
-              (user-handler/email)
-              [:p (ui/button (t :logout) {:class "p-1"
-                                          :icon "logout"
-                                          :on-click user-handler/logout})]]
-            [:div
-             (ui/button (t :login) {:class "p-1"
-                                    :icon "login"
-                                    :on-click (fn []
-                                                (state/close-settings!)
-                                                (js/window.open config/LOGIN-URL))})
-             [:p.text-sm.opacity-50 (t :settings-page/login-prompt)]])]]
+         [:label.flex.font-medium.leading-5.self-start.mt-1 (ui/icon  (if logged-in? "lock-open" "lock") {:class "mr-1"}) (t :settings-page/alpha-features)]]
         [:div.flex.flex-col.gap-4
          {:class (when-not user-handler/alpha-user? "opacity-50 pointer-events-none cursor-not-allowed")}
-         (sync-switcher-row enable-sync?)
          (whiteboards-switcher-row enable-whiteboards?)]])]))
 
 (rum/defcs settings
@@ -750,7 +760,8 @@
                ;;   [:assets "assets" (t :settings-page/tab-assets) (ui/icon "box")])
 
                [:advanced "advanced" (t :settings-page/tab-advanced) (ui/icon "bulb")]
-               [:features "features" (t :settings-page/tab-features) (ui/icon "app-feature" {:extension? true})]
+               [:features "features" (t :settings-page/tab-features) (ui/icon "app-feature" {:extension? true
+                                                                                             :style {:margin-left 2}})]
 
                (when plugins-of-settings
                  [:plugins-setting "plugins" (t :settings-of-plugins) (ui/icon "puzzle")])]]

+ 1 - 0
src/main/frontend/components/whiteboard.css

@@ -105,6 +105,7 @@ h1.title.whiteboard-dashboard-title {
 
 input.tl-text-input {
   border: none;
+  padding: 0;
 
   &:focus {
     box-shadow: none;

+ 3 - 2
src/main/frontend/dicts.cljc

@@ -243,7 +243,8 @@
         :settings-page/network-proxy "Network proxy"
         :settings-page/filename-format "Filename format"
         :settings-page/alpha-features "Alpha features"
-        :settings-page/login-prompt "To access new features before anyone else you must be a financial supporter or alpha tester of Logseq and therefore log in first."
+        :settings-page/beta-features "Beta features"
+        :settings-page/login-prompt "To access new features before anyone else you must be an Open Collective Sponsor or Backer of Logseq and therefore log in first."
         :settings-page/sync "Sync"
         :settings-page/enable-whiteboards "Whiteboards"
         :logseq "Logseq"
@@ -1409,7 +1410,7 @@
            :settings-page/network-proxy "网络代理"
            :settings-page/filename-format "文件名格式"
            :settings-page/edit-setting "编辑"
-           :settings-page/login-prompt "你必须是 Logseq 的 Open Collective Sponsor 才能提前使用新功能(仍在测试中),因此需要登录。"
+           :settings-page/login-prompt "你必须是 Logseq 的 Open Collective Sponsor 或者 Backer 才能提前使用新功能(仍在测试中),因此需要登录。"
            :settings-page/alpha-features "Alpha 功能"
            :settings-page/custom-global-configuration "自定义全局配置"
            :settings-page/edit-global-config-edn "编辑全局 config.edn"

+ 17 - 8
src/main/frontend/extensions/slide.cljs

@@ -3,6 +3,7 @@
             [cljs-bean.core :as bean]
             [frontend.loader :as loader]
             [frontend.ui :as ui]
+            [frontend.util :as util]
             [frontend.config :as config]
             [frontend.components.block :as block]
             [clojure.string :as string]
@@ -37,17 +38,17 @@
                 :controls true
                 :history false
                 :center true
-                :transition "slide"}))]
+                :transition "slide"
+                :keyboardCondition "focused"}))]
     (.initialize deck)))
 
 ;; reveal.js doesn't support multiple nested sections yet.
 ;; https://github.com/hakimel/reveal.js/issues/1440
 (rum/defc block-container
   [config block level]
-  (let [deep-level? (>= level 2)
-        children (:block/children block)
+  (let [children (:block/children block)
         has-children? (seq children)
-        children (when (and has-children? (not deep-level?))
+        children (when has-children?
                    (map (fn [block]
                           (block-container config block (inc level))) children))
         block-el (block/block-container config (dissoc block :block/children))
@@ -55,9 +56,7 @@
     (if has-children?
       [:section dom-attrs
        [:section.relative
-        block-el
-        (when deep-level?
-          [:span.opacity-30.text-xl "Hidden children"])]
+        block-el]
        children]
       [:section dom-attrs block-el])))
 
@@ -93,11 +92,21 @@
         page (db/entity [:block/name page-name])
         journal? (:journal? page)
         repo (state/get-current-repo)
-        blocks (-> (db/get-paginated-blocks repo (:db/id page))
+        blocks (-> (db/get-paginated-blocks repo (:db/id page)
+                                            {:limit 1000})
                    (outliner-tree/blocks->vec-tree page-name))
         blocks (if journal?
                  (rest blocks)
                  blocks)
+        blocks (map (fn [block]
+                      (update block :block/children
+                              (fn [children]
+                                (->>
+                                 (mapcat
+                                  (fn [x]
+                                    (tree-seq map? :block/children x))
+                                  children)
+                                 (map #(dissoc % :block/children)))))) blocks)
         config {:id          "slide-reveal-js"
                 :slide?      true
                 :sidebar?    true

+ 18 - 16
src/main/frontend/fs/capacitor_fs.cljs

@@ -219,27 +219,29 @@
                       (log/error :write-file-failed error)))))))))
 
 (defn get-file-path [dir path]
-  (let [dir (some-> dir (string/replace #"/+$" ""))
-        dir (if (and (not-empty dir) (string/starts-with? dir "/"))
-              (do
-                (js/console.trace "WARN: detect absolute path, use URL instead")
-                (str "file://" (js/encodeURI dir)))
-              dir)
-        path (some-> path (string/replace #"^/+" ""))]
-    (cond (nil? path)
-          dir
+  (let [dir        (some-> dir (string/replace #"/+$" ""))
+        dir        (if (and (not-empty dir) (string/starts-with? dir "/"))
+                     (do
+                       (js/console.trace "WARN: detect absolute path, use URL instead")
+                       (str "file://" (js/encodeURI dir)))
+                     dir)
+        path       (some-> path (string/replace #"^/+" ""))
+        encode-url #(let [encoded-chars?
+                          (and (string? %) (boolean (re-find #"(?i)%[0-9a-f]{2}" %)))]
+                      (cond-> %
+                        (not encoded-chars?)
+                        (js/encodeURI path)))]
+    (cond (string/blank? path)
+          (encode-url dir)
 
-          (nil? dir)
-          path
+          (string/blank? dir)
+          (encode-url path)
 
           (string/starts-with? path dir)
-          path
+          (encode-url path)
 
           :else
-          (let [encoded-chars? (boolean (re-find #"(?i)%[0-9a-f]{2}" path))
-                path' (cond-> path
-                        (not encoded-chars?)
-                        (js/encodeURI path))]
+          (let [path' (encode-url path)]
             (str dir "/" path')))))
 
 (defn- local-container-path?

+ 35 - 20
src/main/frontend/fs/sync.cljs

@@ -1481,9 +1481,10 @@
               true
               r)))))))
 
+(declare sync-state-reset-full-remote->local-files)
 (defn apply-filetxns-partitions
   "won't call <update-graphs-txid! when *txid is nil"
-  [*sync-state user-uuid graph-uuid base-path filetxns-partitions repo *txid *stopped *paused]
+  [*sync-state user-uuid graph-uuid base-path filetxns-partitions repo *txid *stopped *paused full-sync?]
   (assert (some? *sync-state))
 
   (go-loop [filetxns-partitions* filetxns-partitions]
@@ -1495,6 +1496,8 @@
         (let [filetxns                        (first filetxns-partitions*)
               paths                           (map relative-path filetxns)
               recent-remote->local-file-items (filetxns=>recent-remote->local-files filetxns)
+              _ (when-not full-sync?
+                  (swap! *sync-state #(sync-state-reset-full-remote->local-files % recent-remote->local-file-items)))
               ;; update recent-remote->local-files
               _                               (swap! *sync-state sync-state--add-recent-remote->local-files
                                                      recent-remote->local-file-items)
@@ -1952,6 +1955,7 @@
 (def app-state-changed-cursor (rum/cursor state/state :mobile/app-state-change))
 (add-watch app-state-changed-cursor "sync"
            (fn [_ _ _ {:keys [is-active?]}]
+             (prn "is-active? " is-active?)
              (offer! pause-resume-chan is-active?)))
 
 (def recent-edited-chan
@@ -2147,13 +2151,15 @@
                                           :epoch      (tc/to-epoch (t/now))}})
                 (<! (apply-filetxns-partitions
                      *sync-state user-uuid graph-uuid base-path partitioned-filetxns repo
-                     nil *stopped *paused))))]
+                     nil *stopped *paused true))))]
         (cond
           (instance? ExceptionInfo r) {:unknown r}
           @*stopped                   {:stop true}
           @*paused                    {:pause true}
           :else
-          (do (<! (<update-graphs-txid! latest-txid graph-uuid user-uuid repo))
+          (do
+            (swap! *sync-state #(sync-state-reset-full-remote->local-files % []))
+            (<! (<update-graphs-txid! latest-txid graph-uuid user-uuid repo))
               (reset! *txid latest-txid)
               {:succ true})))))
 
@@ -2175,18 +2181,21 @@
                                                             (completing (fn [r i] (conj r (reverse i)))) ;reverse
                                                             '()
                                                             (reverse diff-txns))]
+                        ;; (swap! *sync-state #(sync-state-reset-full-remote->local-files % files))
                         (put-sync-event! {:event :start
                                           :data  {:type       :remote->local
                                                   :graph-uuid graph-uuid
                                                   :full-sync? false
                                                   :epoch      (tc/to-epoch (t/now))}})
                         (if (empty? (flatten partitioned-filetxns))
-                          (do (<! (<update-graphs-txid! latest-txid graph-uuid user-uuid repo))
-                              (reset! *txid latest-txid)
-                              {:succ true})
+                          (do
+                            (swap! *sync-state #(sync-state-reset-full-remote->local-files % []))
+                            (<! (<update-graphs-txid! latest-txid graph-uuid user-uuid repo))
+                            (reset! *txid latest-txid)
+                            {:succ true})
                           (<! (apply-filetxns-partitions
                                *sync-state user-uuid graph-uuid base-path
-                               partitioned-filetxns repo *txid *stopped *paused)))))))))]
+                               partitioned-filetxns repo *txid *stopped *paused false)))))))))]
         (cond
           (instance? ExceptionInfo r)       {:unknown r}
           @*stopped                         {:stop true}
@@ -2645,7 +2654,7 @@
           (.schedule this next-state nil nil)))))
 
   (pause [this]
-    (<! (<rsapi-cancel-all-requests))
+    (go (<! (<rsapi-cancel-all-requests)))
     (put-sync-event! {:event :pause
                       :data  {:graph-uuid graph-uuid
                               :epoch      (tc/to-epoch (t/now))}})
@@ -2702,11 +2711,13 @@
         (s/assert ::sync-local->remote-all-files!-result r)
         (cond
           succ
-          (do (put-sync-event! {:event :finished-local->remote
-                                :data  {:graph-uuid graph-uuid
-                                        :full-sync? true
-                                        :epoch      (tc/to-epoch (t/now))}})
-              (.schedule this ::idle nil nil))
+          (do
+            (swap! *sync-state #(sync-state-reset-full-local->remote-files % []))
+            (put-sync-event! {:event :finished-local->remote
+                              :data  {:graph-uuid graph-uuid
+                                      :full-sync? true
+                                      :epoch      (tc/to-epoch (t/now))}})
+            (.schedule this ::idle nil nil))
           need-sync-remote
           (do (util/drain-chan ops-chan)
               (>! ops-chan {:remote->local true})
@@ -2810,12 +2821,14 @@
                     (or need-sync-remote graph-has-been-deleted unknown pause stop) r))))]
         (cond
           succ
-          (do (put-sync-event! {:event :finished-local->remote
-                                :data  {:graph-uuid         graph-uuid
-                                        :full-sync?         false
-                                        :file-change-events distincted-local-changes
-                                        :epoch              (tc/to-epoch (t/now))}})
-              (.schedule this ::idle nil nil))
+          (do
+            (swap! *sync-state #(sync-state-reset-full-local->remote-files % []))
+            (put-sync-event! {:event :finished-local->remote
+                              :data  {:graph-uuid         graph-uuid
+                                      :full-sync?         false
+                                      :file-change-events distincted-local-changes
+                                      :epoch              (tc/to-epoch (t/now))}})
+            (.schedule this ::idle nil nil))
 
           need-sync-remote
           (do (util/drain-chan ops-chan)
@@ -2874,7 +2887,9 @@
         local->remote-syncer (->Local->RemoteSyncer user-uuid graph-uuid
                                                     base-path
                                                     repo *sync-state remoteapi-with-stop
-                                                    20000
+                                                    (if (mobile-util/native-platform?)
+                                                      2000
+                                                      20000)
                                                     *txid nil (chan) *stopped? *paused?
                                                     (chan 1) (chan 1))
         remote->local-syncer (->Remote->LocalSyncer user-uuid graph-uuid base-path

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

@@ -3089,9 +3089,15 @@
   (when (state/editing?)
     (keydown-backspace-handler false e)))
 
+(defn- slide-focused?
+  []
+  (some-> (first (dom/by-class "reveal"))
+          (dom/has-class? "focused")))
+
 (defn shortcut-up-down [direction]
   (fn [e]
-    (when-not (auto-complete?)
+    (when (and (not (auto-complete?))
+               (not (slide-focused?)))
       (util/stop e)
       (cond
         (state/editing?)

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

@@ -83,7 +83,7 @@
         (map? result)
         (do
           (state/set-state! :user/info result)
-          (let [status (if (user-handler/alpha-user?) :welcome :unavailable)]
+          (let [status (if (user-handler/alpha-or-beta-user?) :welcome :unavailable)]
             (when (and (= status :welcome) (user-handler/logged-in?))
               (async/<! (file-sync-handler/load-session-graphs))
               (p/let [repos (repo-handler/refresh-repos!)]

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

@@ -172,7 +172,7 @@
           (:GraphName graph)
           " to "
           (config/get-string-repo-dir (config/get-local-dir local)))
-     :warning)
+     :success)
     (init-graph (:GraphUUID graph))
     (state/close-modal!)))
 

+ 7 - 4
src/main/frontend/handler/user.cljs

@@ -183,7 +183,10 @@
   (or config/dev?
       (contains? (state/user-groups) "alpha-tester")))
 
-(comment
-  (defn beta-user?
-   []
-   (contains? (state/user-groups) "beta-tester")))
+(defn beta-user?
+  []
+  (contains? (state/user-groups) "beta-tester"))
+
+(defn alpha-or-beta-user?
+  []
+  (or (alpha-user?) (beta-user?)))

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

@@ -153,7 +153,7 @@
    By default it will be placed next to the given shape id"
   [block-uuid source-shape & {:keys [link? bottom?]}]
   (let [app (state/active-tldraw-app)
-        api (.-api app)
+        ^js api (.-api app)
         point (-> (.getShapeById app source-shape)
                   (.-bounds)
                   ((fn [bounds] (if bottom?

+ 1 - 1
src/main/frontend/mobile/record.cljs

@@ -44,7 +44,7 @@
 
 (defn- embed-audio [database64]
   (p/let [page (or (state/get-current-page) (string/lower-case (date/journal-name)))
-          filename (str (date/get-date-time-string-2) ".m4a")
+          filename (str (date/get-date-time-string-2) ".aac")
           edit-block (state/get-edit-block)
           format (or (:block/format edit-block) (db/get-page-format page))
           path (editor-handler/get-asset-path filename)

+ 2 - 0
src/main/frontend/mobile/util.cljs

@@ -51,6 +51,8 @@
          [414 896] "iPhone11"
          [428 926] "iPhone13ProMax"
          [476 847] "iPhone7Plus"
+         [393 852] "iPhone14Pro"
+         [430 932] "iPhone14ProMax"
          [744 1133] "iPadmini8.3"
          [768 1024] "iPad9.7"
          [810 1080] "iPad10.2"

+ 2 - 0
src/main/frontend/modules/outliner/file.cljs

@@ -23,6 +23,7 @@
     :block/format
     :block/created-at
     :block/updated-at
+    :block/collapsed?
     {:block/page      [:block/uuid]}
     {:block/left      [:block/uuid]}
     {:block/parent    [:block/uuid]}])
@@ -33,6 +34,7 @@
     (dissoc block
             :db/id
             :block/uuid ;; shape block uuid is read from properties
+            :block/collapsed?
             :block/content
             :block/format
             :block/left

+ 1 - 3
src/main/frontend/modules/shortcut/before.cljs

@@ -33,7 +33,5 @@
   [f]
   (fn [e]
     (when (or (contains? #{:srs :page-histories} (state/get-modal-id))
-              (not (state/block-component-editing?))
-              ;; when in whiteboard mode and editing a logseq block
-              (and (state/active-tldraw-app) (state/tldraw-editing-logseq-block?)))
+              (not (state/block-component-editing?)))
       (f e))))

+ 1 - 0
src/main/frontend/publishing/html.cljs

@@ -19,6 +19,7 @@
              :name "viewport"}]
            [:link {:type "text/css", :href "static/css/tabler-icons.min.css", :rel "stylesheet"}]
            [:link {:type "text/css", :href "static/css/style.css", :rel "stylesheet"}]
+           [:link {:type "text/css", :href "static/css/custom.css", :rel "stylesheet"}]
            [:link {:type "text/css", :href "static/css/export.css", :rel "stylesheet"}]
            [:link
             {:href icon

+ 8 - 2
src/main/frontend/state.cljs

@@ -1429,7 +1429,8 @@ Similar to re-frame subscriptions"
 
 (defn active-tldraw-app
   []
-  ^js js/window.tln)
+  (when-let [tldraw-el (.closest js/document.activeElement ".logseq-tldraw[data-tlapp]")]
+    (gobj/get js/window.tlapps (.. tldraw-el -dataset -tlapp))))
 
 (defn tldraw-editing-logseq-block?
   []
@@ -1622,9 +1623,14 @@ Similar to re-frame subscriptions"
   [args]
   (set-state! :editor/args args))
 
+(defn whiteboard-active-but-not-editing-portal?
+  []
+  (and (active-tldraw-app) (not (tldraw-editing-logseq-block?))))
+
 (defn block-component-editing?
   []
-  (:block/component-editing-mode? @state))
+  (or (:block/component-editing-mode? @state)
+      (whiteboard-active-but-not-editing-portal?)))
 
 (defn set-block-component-editing-mode!
   [value]

+ 1 - 1
src/main/frontend/util.cljc

@@ -723,7 +723,7 @@
 
 #?(:cljs
    (defn get-blocks-noncollapse []
-     (->> (d/by-class "ls-block")
+     (->> (d/sel "div:not(.reveal) .ls-block")
           (filter (fn [b] (some? (gobj/get b "offsetParent")))))))
 
 #?(:cljs

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

@@ -1,3 +1,3 @@
 (ns ^:no-doc frontend.version)
 
-(defonce version "0.8.9")
+(defonce version "0.8.10")

+ 16 - 8
tldraw/apps/tldraw-logseq/src/app.tsx

@@ -7,6 +7,7 @@ import {
   TLReactCallbacks,
   TLReactComponents,
   TLReactToolConstructor,
+  useApp,
 } from '@tldraw/react'
 import * as React from 'react'
 import { AppUI } from './components/AppUI'
@@ -61,6 +62,20 @@ interface LogseqTldrawProps {
   onPersist?: TLReactCallbacks<Shape>['onPersist']
 }
 
+const AppImpl = () => {
+  const ref = React.useRef<HTMLDivElement>(null)
+  const app = useApp()
+  return (
+    <ContextMenu collisionRef={ref}>
+      <div ref={ref} className="logseq-tldraw logseq-tldraw-wrapper" data-tlapp={app.uuid}>
+        <AppCanvas components={components}>
+          <AppUI />
+        </AppCanvas>
+      </div>
+    </ContextMenu>
+  )
+}
+
 const AppInner = ({
   onPersist,
   model,
@@ -69,7 +84,6 @@ const AppInner = ({
   const onDrop = useDrop()
   const onPaste = usePaste()
   const onQuickAdd = useQuickAdd()
-  const ref = React.useRef<HTMLDivElement>(null)
 
   const onPersistOnDiff: TLReactCallbacks<Shape>['onPersist'] = React.useCallback(
     (app, info) => {
@@ -91,13 +105,7 @@ const AppInner = ({
       model={model}
       {...rest}
     >
-      <ContextMenu collisionRef={ref}>
-        <div ref={ref} className="logseq-tldraw logseq-tldraw-wrapper">
-          <AppCanvas components={components}>
-            <AppUI />
-          </AppCanvas>
-        </div>
-      </ContextMenu>
+      <AppImpl />
     </AppProvider>
   )
 }

+ 2 - 2
tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx

@@ -72,7 +72,7 @@ const LogseqTypeTag = ({
 
 const LogseqPortalShapeHeader = observer(
   ({ type, fill, children }: { type: 'P' | 'B'; fill: string; children: React.ReactNode }) => {
-    return <div className="tl-logseq-portal-header" style={{background: `var(--ls-highlight-color-${fill})`}}>{children}</div>
+    return <div className={`tl-logseq-portal-header tl-logseq-portal-header-${type === "P" ? "page" : "block"}`} style={{background: `var(--ls-highlight-color-${fill})`}}>{children}</div>
   }
 )
 
@@ -882,7 +882,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
   validateProps = (props: Partial<LogseqPortalShapeProps>) => {
     if (props.size !== undefined) {
       const scale = levelToScale[this.props.scaleLevel ?? 'md']
-      props.size[0] = Math.max(props.size[0], 240 * scale)
+      props.size[0] = Math.max(props.size[0], 60 * scale)
       props.size[1] = Math.max(props.size[1], HEADER_HEIGHT * scale)
     }
     return withClampedStyles(this, props)

+ 1 - 0
tldraw/apps/tldraw-logseq/src/lib/tools/LogseqPortalTool/states/CreatingState.tsx

@@ -68,5 +68,6 @@ export class CreatingState extends TLToolState<
       this.app.deleteShapes([this.creatingShape.id])
       this.app.setEditingShape()
     }
+    this.creatingShape = undefined
   }
 }

+ 10 - 9
tldraw/apps/tldraw-logseq/src/styles.css

@@ -492,7 +492,7 @@ button.tl-select-input-trigger {
     transform: translateY(-100%);
   }
 
-  &[data-active='false']:hover {
+  &[data-active='false']:hover:not([data-recently-changed='true']) {
     .tie {
       transform: translateY(0);
 
@@ -515,7 +515,7 @@ button.tl-select-input-trigger {
       }
     }
 
-    &:hover {
+    &:hover:not([data-recently-changed='true']) {
       color: var(--ls-primary-text-color);
       background-color: var(--ls-secondary-background-color);
 
@@ -534,12 +534,6 @@ button.tl-select-input-trigger {
     transition-delay: 0;
   }
 
-  &[data-recently-changed='true'] {
-    i.tie {
-      transition-delay: 0.5s;
-    }
-  }
-
   .tl-circle-button-icons-wrapper[data-icons-count='2'] {
     position: relative;
     width: 22px;
@@ -680,18 +674,25 @@ button.tl-select-input-trigger {
 
   height: 40px;
   flex-shrink: 0;
-  background: linear-gradient(0deg, transparent, var(--ls-tertiary-background-color));
+
   color: var(--ls-title-text-color);
   border-top-left-radius: 8px;
   border-top-right-radius: 8px;
+  background: var(--ls-tertiary-background-color);
   padding: 0 1rem;
   gap: 0.5em;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
 
+  &.tl-logseq-portal-header-block {
+    background: linear-gradient(0deg, transparent, var(--ls-tertiary-background-color));
+  }
+
+
   .page-ref {
     color: var(--ls-title-text-color);
+    background: var(--ls-tertiary-background-color));
   }
 
   .breadcrumb {

+ 10 - 9
tldraw/packages/core/src/lib/TLApp/TLApp.ts

@@ -7,30 +7,29 @@ import { action, computed, makeObservable, observable, toJS, transaction } from
 import { GRID_SIZE } from '../../constants'
 import type {
   TLAsset,
+  TLCallback,
   TLEventMap,
+  TLEvents,
   TLShortcut,
+  TLStateEvents,
   TLSubscription,
-  TLSubscriptionEventName,
-  TLCallback,
   TLSubscriptionEventInfo,
-  TLStateEvents,
-  TLEvents,
-  TLHandle,
+  TLSubscriptionEventName,
 } from '../../types'
 import { AlignType, DistributeType } from '../../types'
-import { KeyUtils, BoundsUtils, isNonNullable, createNewLineBinding } from '../../utils'
+import { BoundsUtils, createNewLineBinding, isNonNullable, KeyUtils, uniqueId } from '../../utils'
 import type { TLShape, TLShapeConstructor, TLShapeModel } from '../shapes'
 import { TLApi } from '../TLApi'
 import { TLCursors } from '../TLCursors'
 
 import { TLHistory } from '../TLHistory'
 import { TLInputs } from '../TLInputs'
-import { type TLPageModel, TLPage } from '../TLPage'
+import { TLPage, type TLPageModel } from '../TLPage'
 import { TLSettings } from '../TLSettings'
 import { TLRootState } from '../TLState'
 import type { TLToolConstructor } from '../TLTool'
 import { TLViewport } from '../TLViewport'
-import { TLSelectTool, TLMoveTool } from '../tools'
+import { TLMoveTool, TLSelectTool } from '../tools'
 
 export interface TLDocumentModel<S extends TLShape = TLShape, A extends TLAsset = TLAsset> {
   // currentPageId: string
@@ -70,7 +69,8 @@ export class TLApp<
   }
 
   keybindingRegistered = false
-
+  uuid = uniqueId()
+  
   static id = 'app'
   static initial = 'select'
 
@@ -171,6 +171,7 @@ export class TLApp<
         keys: ['del', 'backspace'],
         fn: () => {
           this.api.deleteShapes()
+          this.selectedTool.transition('idle')
         },
       },
     ]

+ 8 - 3
tldraw/packages/react/src/hooks/useSetup.ts

@@ -2,7 +2,7 @@ import * as React from 'react'
 import type { TLAppPropsWithApp, TLAppPropsWithoutApp } from '../components'
 import type { TLReactApp, TLReactShape } from '../lib'
 
-declare const window: Window & { tln?: TLReactApp<any> }
+declare const window: Window & { tlapps?: Record<string, TLReactApp<any>> }
 
 export function useSetup<
   S extends TLReactShape = TLReactShape,
@@ -27,11 +27,16 @@ export function useSetup<
     const unsubs: (() => void)[] = []
     if (!app) return
     app.history.reset()
-    if (typeof window !== undefined) window['tln'] = app
+    if (typeof window !== undefined) {
+      window['tlapps'] = window['tlapps'] || {}
+      window['tlapps'][app.uuid] = app
+    }
     if (onMount) onMount(app, null)
     return () => {
       unsubs.forEach(unsub => unsub())
-      window['tln'] = undefined
+      if (typeof window !== undefined && window['tlapps']) {
+        delete window['tlapps'][app.uuid]
+      }
     }
   }, [app])
 

+ 8 - 8
yarn.lock

@@ -482,10 +482,10 @@
   resolved "https://registry.yarnpkg.com/@kanru/rage-wasm/-/rage-wasm-0.3.0.tgz#de96b1fda1f781ff401d43b50d0f95b7338c4399"
   integrity sha512-2LMRS27nNJPqFNpRQL7kXG0kgBeIPo63KM6u0Xu6Es5XIS7LP4MFtdHkCg8Pt7IhMM7GuOa2YnzAZgKBxE1lcw==
 
-"@logseq/[email protected]2":
-  version "0.0.12"
-  resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.12.tgz#26ab202d9925acaad42d38c58708c3adae39d79f"
-  integrity sha512-qYCvBI6XvaLbqYPxyqD02lRFoJ2MlOHX2Bp5+rDb1SGgfJW0kIstCTZ2B7Sb8tng7ZN1b6kb9fvLRGD2zviuMQ==
+"@logseq/[email protected]3":
+  version "0.0.13"
+  resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.13.tgz#cf249fd2e091566b453212558137885a30869131"
+  integrity sha512-jtXgI0fx4IagqPO+frEvSIRddRe0W/DpmaoUJguKrQ9aIH+ebtbkActUQEDX7jxo4w3VtsYJn21+qLtnAAH1pQ==
 
 "@logseq/[email protected]":
   version "1.3.1-1"
@@ -1599,10 +1599,10 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001370:
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356"
   integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==
 
-capacitor-voice-recorder@2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/capacitor-voice-recorder/-/capacitor-voice-recorder-2.1.0.tgz#142e7bfa62e88530279f478b79735a0dc68a7d1a"
-  integrity sha512-H0c/sUVD7cduVS5VqutKk00whyqXZUFi56ChRMl9Ke/LBU71HhHwzonPmheT8i9gQmgOaplc3TOpaKqckXb+3A==
+capacitor-voice-recorder@4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/capacitor-voice-recorder/-/capacitor-voice-recorder-4.0.0.tgz#41939aa21e68eb58301e781c217ad17dd48d2a34"
+  integrity sha512-J5RfSOnTFm0nOJlW46wSNUVY331SHF0jGc+pi5X0/6NsNM6tJPhZtg4dajIY0zPRR94eirE3Z/h6R+RW3EmSQg==
   dependencies:
     get-blob-duration "^1.2.0"