Преглед изворни кода

Merge branch 'master' into feat/whiteboards-onboarding

Konstantinos Kaloutas пре 3 година
родитељ
комит
612950d75c
49 измењених фајлова са 381 додато и 167 уклоњено
  1. 67 0
      .github/workflows/build-ios-release.yml
  2. 2 2
      android/app/build.gradle
  3. 5 0
      docs/dev-practices.md
  4. 4 4
      ios/App/App.xcodeproj/project.pbxproj
  5. 8 0
      ios/App/fastlane/Appfile
  6. 44 0
      ios/App/fastlane/Fastfile
  7. 32 0
      ios/App/fastlane/README.md
  8. 0 1
      package.json
  9. 0 1
      public/index.html
  10. 0 1
      resources/electron.html
  11. 0 1
      resources/index.html
  12. 1 1
      resources/package.json
  13. 29 0
      scripts/build-ios.sh
  14. 0 6
      shadow-cljs.edn
  15. 1 1
      src/electron/electron/core.cljs
  16. 11 11
      src/main/frontend/components/sidebar.cljs
  17. 1 0
      src/main/frontend/dicts.cljc
  18. 2 10
      src/main/frontend/encrypt.cljs
  19. 0 23
      src/main/frontend/extensions/age_encryption.cljs
  20. 1 1
      src/main/frontend/extensions/pdf/highlights.cljs
  21. 10 8
      src/main/frontend/extensions/tldraw.cljs
  22. 41 16
      src/main/frontend/fs/sync.cljs
  23. 1 1
      src/main/frontend/handler/common/file.cljs
  24. 14 5
      src/main/frontend/handler/conversion.cljs
  25. 18 9
      src/main/frontend/handler/events.cljs
  26. 1 1
      src/main/frontend/handler/page.cljs
  27. 22 2
      src/main/frontend/handler/repo.cljs
  28. 8 7
      src/main/frontend/mobile/camera.cljs
  29. 14 12
      src/main/frontend/search/agency.cljs
  30. 10 10
      src/main/frontend/ui.cljs
  31. 2 1
      src/main/frontend/util/fs.cljs
  32. 1 1
      src/main/frontend/version.cljs
  33. 1 1
      src/test/frontend/db/name_sanity_test.cljs
  34. 3 3
      tldraw/apps/tldraw-logseq/src/app.tsx
  35. 6 1
      tldraw/apps/tldraw-logseq/src/components/BlockLink/BlockLink.tsx
  36. 1 1
      tldraw/apps/tldraw-logseq/src/lib/logseq-context.ts
  37. 1 1
      tldraw/apps/tldraw-logseq/src/lib/shapes/LineShape.tsx
  38. 2 2
      tldraw/apps/tldraw-logseq/src/lib/shapes/PencilShape.tsx
  39. 1 1
      tldraw/apps/tldraw-logseq/src/styles.css
  40. 2 2
      tldraw/demo/src/App.jsx
  41. 3 3
      tldraw/packages/core/src/types/types.ts
  42. 1 1
      tldraw/packages/react/src/components/BacklinksCountContainer/BacklinksCountContainer.tsx
  43. 1 0
      tldraw/packages/react/src/components/BacklinksCountContainer/index.ts
  44. 5 5
      tldraw/packages/react/src/components/Canvas/Canvas.tsx
  45. 0 0
      tldraw/packages/react/src/components/QuickLinksContainer/QuickLinksContainer.tsx
  46. 0 0
      tldraw/packages/react/src/components/QuickLinksContainer/index.ts
  47. 0 1
      tldraw/packages/react/src/components/ReferencesCountContainer/index.ts
  48. 4 4
      tldraw/packages/react/src/types/component-props.ts
  49. 0 5
      yarn.lock

+ 67 - 0
.github/workflows/build-ios-release.yml

@@ -0,0 +1,67 @@
+# This workflow build iOS App as a .ipa file and upload it to TestFlight.
+
+name: Build-iOS
+
+on:
+  workflow_dispatch:
+    inputs:
+      git-ref:
+        description: "Release Git Ref (Which branch or tag to build?)"
+        required: true
+        default: "master"
+
+env:
+  CLOJURE_VERSION: '1.10.1.763'
+  NODE_VERSION: '16'
+  JAVA_VERSION: '11'
+
+jobs:
+  build-app:
+    runs-on: macos-latest
+    steps:
+      - name: Check out Git repository
+        uses: actions/checkout@v2
+        with:
+          ref: ${{ github.event.inputs.git-ref }}
+
+      - name: Install Node.js, NPM and Yarn
+        uses: actions/setup-node@v2
+        with:
+          node-version: ${{ env.NODE_VERSION }}
+
+      - name: Setup Java JDK
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: ${{ env.JAVA_VERSION }}
+
+      - name: Setup clojure
+        uses: DeLaGuardo/[email protected]
+        with:
+          cli: ${{ env.CLOJURE_VERSION }}
+
+      - name: Setup build tools
+        run: brew install fastlane
+
+      - name: Set Build Environment Variables
+        run: |
+          echo "ENABLE_FILE_SYNC_PRODUCTION=true" >> $GITHUB_ENV
+
+      - name: Compile CLJS
+        run: yarn install && yarn release-app
+
+      - name: Sync static build files
+        run: rsync -avz --exclude node_modules --exclude '*.js.map' --exclude android ./static/ ./public/static/
+
+      - name: Prepare iOS build
+        run: npx cap sync ios
+
+      - name: Build and upload iOS app
+        run: fastlane beta
+        working-directory: ./ios/App
+        env:
+          APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }}
+          APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
+          APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
+          APP_STORE_CONNECT_API_KEY_IS_KEY_CONTENT_BASE64: true
+          SLACK_URL: ${{ secrets.SLACK_URL }}

+ 2 - 2
android/app/build.gradle

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

+ 5 - 0
docs/dev-practices.md

@@ -89,6 +89,11 @@ yarn electron-watch
 yarn e2e-test # or npx playwright test
 yarn e2e-test # or npx playwright test
 ```
 ```
 
 
+If e2e failed after first running:
+- `rm -rdf ~/.logseq`
+- `rm -rdf <repo dir>/tmp/`  
+- `rm -rdf <appData dir>/Electron`  (Reference: https://www.electronjs.org/de/docs/latest/api/app#appgetpathname)
+
 ### Unit Testing
 ### Unit Testing
 
 
 Our unit tests use the [shadow-cljs test-runner](https://shadow-cljs.github.io/docs/UsersGuide.html#_testing). To run them:
 Our unit tests use the [shadow-cljs test-runner](https://shadow-cljs.github.io/docs/UsersGuide.html#_testing). To run them:

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

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

+ 8 - 0
ios/App/fastlane/Appfile

@@ -0,0 +1,8 @@
+app_identifier("com.logseq.logseq") # The bundle identifier of your app
+apple_id("[email protected]") # Your Apple Developer Portal username
+
+itc_team_id("123783177") # App Store Connect Team ID
+team_id("K378MFWK59") # Developer Portal Team ID
+
+# For more information about the Appfile, see:
+#     https://docs.fastlane.tools/advanced/#appfile

+ 44 - 0
ios/App/fastlane/Fastfile

@@ -0,0 +1,44 @@
+# This file contains the fastlane.tools configuration
+# You can find the documentation at https://docs.fastlane.tools
+#
+# For a list of all available actions, check out
+#
+#     https://docs.fastlane.tools/actions
+#
+# For a list of all available plugins, check out
+#
+#     https://docs.fastlane.tools/plugins/available-plugins
+#
+
+# Uncomment the line if you want fastlane to automatically update itself
+# update_fastlane
+
+default_platform(:ios)
+
+platform :ios do
+  desc "Push a new beta build to TestFlight"
+  lane :beta do
+    # Set from env
+    app_store_connect_api_key
+
+    increment_build_number(
+      xcodeproj: "App.xcodeproj",
+      build_number: latest_testflight_build_number + 1,
+      skip_info_plist: true
+    )
+
+    build_app(
+      workspace: "App.xcworkspace",
+      configuration: "Release",
+      destination: "generic/platform=iOS",
+      scheme: "Logseq"
+    )
+
+    upload_to_testflight(
+      skip_submission: true,
+      skip_waiting_for_build_processing: true,
+    )
+
+    slack(message: "App successfully uploaded to TestFlight 🎉!")
+  end
+end

+ 32 - 0
ios/App/fastlane/README.md

@@ -0,0 +1,32 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+## iOS
+
+### ios beta
+
+```sh
+[bundle exec] fastlane ios beta
+```
+
+Push a new beta build to TestFlight
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

+ 0 - 1
package.json

@@ -91,7 +91,6 @@
         "@capawesome/capacitor-background-task": "^2.0.0",
         "@capawesome/capacitor-background-task": "^2.0.0",
         "@excalidraw/excalidraw": "0.12.0",
         "@excalidraw/excalidraw": "0.12.0",
         "@hugotomazi/capacitor-navigation-bar": "^2.0.0",
         "@hugotomazi/capacitor-navigation-bar": "^2.0.0",
-        "@kanru/rage-wasm": "^0.3.0",
         "@logseq/capacitor-file-sync": "0.0.14",
         "@logseq/capacitor-file-sync": "0.0.14",
         "@logseq/react-tweet-embed": "1.3.1-1",
         "@logseq/react-tweet-embed": "1.3.1-1",
         "@sentry/react": "^6.18.2",
         "@sentry/react": "^6.18.2",

+ 0 - 1
public/index.html

@@ -53,7 +53,6 @@
 <script defer src="/static/js/main.js"></script>
 <script defer src="/static/js/main.js"></script>
 <script defer src="/static/js/tabler.min.js"></script>
 <script defer src="/static/js/tabler.min.js"></script>
 <script defer src="/static/js/code-editor.js"></script>
 <script defer src="/static/js/code-editor.js"></script>
-<script defer src="/static/js/age-encryption.js"></script>
 <script defer src="/static/js/tldraw.js"></script>
 <script defer src="/static/js/tldraw.js"></script>
 <script defer src="/static/js/excalidraw.js"></script>
 <script defer src="/static/js/excalidraw.js"></script>
 </body>
 </body>

+ 0 - 1
resources/electron.html

@@ -54,7 +54,6 @@ const portal = new MagicPortal(worker);
 <script defer src="./js/main.js"></script>
 <script defer src="./js/main.js"></script>
 <script defer src="./js/tabler.min.js"></script>
 <script defer src="./js/tabler.min.js"></script>
 <script defer src="./js/code-editor.js"></script>
 <script defer src="./js/code-editor.js"></script>
-<script defer src="./js/age-encryption.js"></script>
 <script defer src="./js/excalidraw.js"></script>
 <script defer src="./js/excalidraw.js"></script>
 <script defer src="./js/tldraw.js"></script>
 <script defer src="./js/tldraw.js"></script>
 </body>
 </body>

+ 0 - 1
resources/index.html

@@ -53,7 +53,6 @@ const portal = new MagicPortal(worker);
 <script defer src="./js/main.js"></script>
 <script defer src="./js/main.js"></script>
 <script defer src="./js/tabler.min.js"></script>
 <script defer src="./js/tabler.min.js"></script>
 <script defer src="./js/code-editor.js"></script>
 <script defer src="./js/code-editor.js"></script>
-<script defer src="./js/age-encryption.js"></script>
 <script defer src="./js/excalidraw.js"></script>
 <script defer src="./js/excalidraw.js"></script>
 <script defer src="./js/tldraw.js"></script>
 <script defer src="./js/tldraw.js"></script>
 </body>
 </body>

+ 1 - 1
resources/package.json

@@ -1,7 +1,7 @@
 {
 {
   "name": "Logseq",
   "name": "Logseq",
   "productName": "Logseq",
   "productName": "Logseq",
-  "version": "0.8.11",
+  "version": "0.8.12",
   "main": "electron.js",
   "main": "electron.js",
   "author": "Logseq",
   "author": "Logseq",
   "license": "AGPL-3.0",
   "license": "AGPL-3.0",

+ 29 - 0
scripts/build-ios.sh

@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -ex
+
+unset LOGSEQ_APP_SERVER_URL
+export ENABLE_FILE_SYNC_PRODUCTION=true
+
+# yarn clean
+PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 yarn install --force
+
+rm -rv public/static || true
+rm -rv ios/App/App/public || true
+
+yarn release-app
+
+rsync -avz --exclude node_modules --exclude '*.js.map' --exclude android ./static/ ./public/static/
+
+npx cap sync ios
+
+npx cap open ios
+
+echo "step 1(Xcode). Product > Archive (device should be Any iOS Device)"
+
+echo "step 2(Archive). Distribute App"
+
+echo "  - App Store Connect"
+echo "  - Upload"
+echo "  - (Default config, all checked)"
+echo "  - Upload"

+ 0 - 6
shadow-cljs.edn

@@ -16,9 +16,6 @@
                         :code-editor
                         :code-editor
                         {:entries    [frontend.extensions.code]
                         {:entries    [frontend.extensions.code]
                          :depends-on #{:main}}
                          :depends-on #{:main}}
-                        :age-encryption
-                        {:entries    [frontend.extensions.age-encryption]
-                         :depends-on #{:main}}
                         :excalidraw
                         :excalidraw
                         {:entries    [frontend.extensions.excalidraw]
                         {:entries    [frontend.extensions.excalidraw]
                          :depends-on #{:main}}
                          :depends-on #{:main}}
@@ -83,9 +80,6 @@
                                :code-editor
                                :code-editor
                                {:entries    [frontend.extensions.code]
                                {:entries    [frontend.extensions.code]
                                 :depends-on #{:main}}
                                 :depends-on #{:main}}
-                               :age-encryption
-                               {:entries    [frontend.extensions.age-encryption]
-                                :depends-on #{:main}}
                                :excalidraw
                                :excalidraw
                                {:entries    [frontend.extensions.excalidraw]
                                {:entries    [frontend.extensions.excalidraw]
                                 :depends-on #{:main}}
                                 :depends-on #{:main}}

+ 1 - 1
src/electron/electron/core.cljs

@@ -137,7 +137,7 @@
                 ;; TODO: ugly, replace with ls-files and filter with ".map"
                 ;; TODO: ugly, replace with ls-files and filter with ".map"
                 _ (p/all (map (fn [file]
                 _ (p/all (map (fn [file]
                                 (. fs removeSync (path/join static-dir "js" (str file ".map"))))
                                 (. fs removeSync (path/join static-dir "js" (str file ".map"))))
-                              ["main.js" "code-editor.js" "excalidraw.js" "age-encryption.js"]))]
+                              ["main.js" "code-editor.js" "excalidraw.js"]))]
 
 
           (send-to-renderer
           (send-to-renderer
            :notification
            :notification

+ 11 - 11
src/main/frontend/components/sidebar.cljs

@@ -360,7 +360,16 @@
                                      (route-handler/sidebar-journals!)
                                      (route-handler/sidebar-journals!)
                                      (route-handler/go-to-journals!)))
                                      (route-handler/go-to-journals!)))
                :icon             "calendar"})))
                :icon             "calendar"})))
-
+         
+         (when enable-whiteboards?
+           (sidebar-item
+            {:class           "whiteboard"
+             :title           (t :right-side-bar/whiteboards)
+             :href            (rfe/href :whiteboards)
+             :active          (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
+             :icon            "whiteboard"
+             :icon-extension? true}))
+         
          (when (state/enable-flashcards? (state/get-current-repo))
          (when (state/enable-flashcards? (state/get-current-repo))
            [:div.flashcards-nav
            [:div.flashcards-nav
             (flashcards srs-open?)])
             (flashcards srs-open?)])
@@ -377,16 +386,7 @@
            :title  (t :right-side-bar/all-pages)
            :title  (t :right-side-bar/all-pages)
            :href   (rfe/href :all-pages)
            :href   (rfe/href :all-pages)
            :active (and (not srs-open?) (= route-name :all-pages))
            :active (and (not srs-open?) (= route-name :all-pages))
-           :icon   "files"})
-
-         (when enable-whiteboards?
-           (sidebar-item
-            {:class           "whiteboard"
-             :title           (t :right-side-bar/whiteboards)
-             :href            (rfe/href :whiteboards)
-             :active          (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
-             :icon            "whiteboard"
-             :icon-extension? true}))]]
+           :icon   "files"})]]
 
 
        [:div.nav-contents-container.flex.flex-col.gap-1.pt-1
        [:div.nav-contents-container.flex.flex-col.gap-1.pt-1
         {:on-scroll on-contents-scroll}
         {:on-scroll on-contents-scroll}

+ 1 - 0
src/main/frontend/dicts.cljc

@@ -1650,6 +1650,7 @@
            :settings-page/custom-date-format "首选日期页面格式"
            :settings-page/custom-date-format "首选日期页面格式"
            :settings-page/preferred-file-format "首选文件格式"
            :settings-page/preferred-file-format "首选文件格式"
            :settings-page/preferred-workflow "首选工作流"
            :settings-page/preferred-workflow "首选工作流"
+           :settings-page/preferred-pasting-file "保存链接为文件"
            :settings-page/enable-timetracking "开启 timetracking"
            :settings-page/enable-timetracking "开启 timetracking"
            :settings-page/enable-tooltip "开启提示框"
            :settings-page/enable-tooltip "开启提示框"
            :settings-page/enable-journals "开启日记"
            :settings-page/enable-journals "开启日记"

+ 2 - 10
src/main/frontend/encrypt.cljs

@@ -4,7 +4,6 @@
             [frontend.util :as util]
             [frontend.util :as util]
             [promesa.core :as p]
             [promesa.core :as p]
             [electron.ipc :as ipc]
             [electron.ipc :as ipc]
-            [shadow.loader :as loader]
             [frontend.mobile.util :as mobile-util]))
             [frontend.mobile.util :as mobile-util]))
 
 
 (defn encrypt-with-passphrase
 (defn encrypt-with-passphrase
@@ -22,10 +21,7 @@
              :data)
              :data)
 
 
     :else
     :else
-    (p/let [lazy-encrypt-with-user-passphrase (resolve 'frontend.extensions.age-encryption/encrypt-with-user-passphrase)
-            content (utf8/encode content)
-            encrypted (@lazy-encrypt-with-user-passphrase passphrase content true)]
-      (utf8/decode encrypted))))
+    nil))
 
 
 (defn decrypt-with-passphrase
 (defn decrypt-with-passphrase
   [passphrase content]
   [passphrase content]
@@ -42,8 +38,4 @@
              :data)
              :data)
 
 
     :else
     :else
-    (p/let [_ (loader/load :age-encryption)
-            lazy-decrypt-with-user-passphrase (resolve 'frontend.extensions.age-encryption/decrypt-with-user-passphrase)
-            content (utf8/encode content)
-            decrypted (lazy-decrypt-with-user-passphrase passphrase content)]
-      (utf8/decode decrypted))))
+    nil))

+ 0 - 23
src/main/frontend/extensions/age_encryption.cljs

@@ -1,23 +0,0 @@
-(ns frontend.extensions.age-encryption
-  (:require ["regenerator-runtime/runtime"] ;; required for async npm module
-            ["@kanru/rage-wasm" :as rage]))
-
-(defn keygen
-  []
-  (rage/keygen))
-
-(defn encrypt-with-x25519
-  [public-key content armor]
-  (rage/encrypt_with_x25519 public-key content armor))
-
-(defn decrypt-with-x25519
-  [secret-key content]
-  (rage/decrypt_with_x25519 secret-key content))
-
-(defn encrypt-with-user-passphrase
-  [passphrase content armor]
-  (rage/encrypt_with_user_passphrase passphrase content armor))
-
-(defn decrypt-with-user-passphrase
-  [passphrase content]
-  (rage/decrypt_with_user_passphrase passphrase content))

+ 1 - 1
src/main/frontend/extensions/pdf/highlights.cljs

@@ -178,7 +178,7 @@
                     (action-fn! action true)))}
                     (action-fn! action true)))}
 
 
      [:li.item-colors
      [:li.item-colors
-      (for [it ["yellow", "blue", "green", "red", "purple"]]
+      (for [it ["yellow", "red", "green", "blue", "purple"]]
         [:a {:key it :data-color it :data-action it} it])]
         [:a {:key it :data-color it :data-action it} it])]
 
 
 
 

+ 10 - 8
src/main/frontend/extensions/tldraw.cljs

@@ -39,7 +39,6 @@
 
 
 (rum/defc block-reference
 (rum/defc block-reference
   [props]
   [props]
-  (println "page-name-linkpage-name-linkpage-name-linkpage-name-link" props)
   (block/block-reference {} (gobj/get props "blockId") nil))
   (block/block-reference {} (gobj/get props "blockId") nil))
 
 
 (rum/defc page-name-link
 (rum/defc page-name-link
@@ -73,7 +72,7 @@
                        :Block block-cp
                        :Block block-cp
                        :Breadcrumb breadcrumb
                        :Breadcrumb breadcrumb
                        :PageName page-name-link
                        :PageName page-name-link
-                       :ReferencesCount references-count
+                       :BacklinksCount references-count
                        :BlockReference block-reference})
                        :BlockReference block-reference})
 
 
 (defn get-tldraw-handlers [current-whiteboard-name]
 (defn get-tldraw-handlers [current-whiteboard-name]
@@ -91,13 +90,16 @@
                                                 (:db/id (model/get-page uuid))
                                                 (:db/id (model/get-page uuid))
                                                 (keyword type)))
                                                 (keyword type)))
    :redirectToPage (fn [page-name-or-uuid]
    :redirectToPage (fn [page-name-or-uuid]
-                     (let [page-name (if (util/uuid-string? page-name-or-uuid)
-                                       (:block/name (model/get-block-parent (parse-uuid page-name-or-uuid)))
-                                       page-name-or-uuid)
+                     (let [page-name (or (when (util/uuid-string? page-name-or-uuid)
+                                           (:block/name (model/get-block-page (state/get-current-repo)
+                                                                              (parse-uuid page-name-or-uuid))))
+                                         page-name-or-uuid)
+                           page-exists? (model/page-exists? page-name)
                            whiteboard? (model/whiteboard-page? page-name)]
                            whiteboard? (model/whiteboard-page? page-name)]
-                       (if whiteboard? (route-handler/redirect-to-whiteboard!
-                                        page-name {:block-id page-name-or-uuid})
-                           (route-handler/redirect-to-page! page-name-or-uuid))))})
+                       (when page-exists?
+                         (if whiteboard? (route-handler/redirect-to-whiteboard!
+                                          page-name {:block-id page-name-or-uuid})
+                             (route-handler/redirect-to-page! page-name-or-uuid)))))})
 
 
 (rum/defc tldraw-app
 (rum/defc tldraw-app
   [page-name block-id]
   [page-name block-id]

+ 41 - 16
src/main/frontend/fs/sync.cljs

@@ -494,7 +494,7 @@
         reserved-paths (filter f paths)]
         reserved-paths (filter f paths)]
     (when (seq reserved-paths)
     (when (seq reserved-paths)
       (let [paths (if path-string? reserved-paths (map -relative-path reserved-paths))]
       (let [paths (if path-string? reserved-paths (map -relative-path reserved-paths))]
-        (state/pub-event! [:ui/notify-files-with-reserved-chars paths])
+        (state/pub-event! [:ui/notify-outdated-filename-format paths])
         (prn "Skipped uploading those file paths with reserved chars: " paths)))
         (prn "Skipped uploading those file paths with reserved chars: " paths)))
     (vec (remove f paths))))
     (vec (remove f paths))))
 
 
@@ -728,6 +728,12 @@
   (<get-graph-encrypt-keys [this graph-uuid])
   (<get-graph-encrypt-keys [this graph-uuid])
   (<upload-graph-encrypt-keys [this graph-uuid public-key encrypted-private-key]))
   (<upload-graph-encrypt-keys [this graph-uuid public-key encrypted-private-key]))
 
 
+
+(defprotocol IRemoteControlAPI
+  "api functions provided for outside the sync process"
+  (<delete-remote-files-control [this graph-uuid filepaths])
+  )
+
 (defprotocol IToken
 (defprotocol IToken
   (<get-token [this]))
   (<get-token [this]))
 
 
@@ -1360,6 +1366,20 @@
                                                       :public-key            public-key
                                                       :public-key            public-key
                                                       :encrypted-private-key encrypted-private-key})))))
                                                       :encrypted-private-key encrypted-private-key})))))
 
 
+(extend-type RemoteAPI
+  IRemoteControlAPI
+  (<delete-remote-files-control [this graph-uuid filepaths]
+    (user/<wrap-ensure-id&access-token
+     (let [current-txid (:TXId (<! (<get-remote-graph this nil graph-uuid)))
+           files (<! (<encrypt-fnames rsapi graph-uuid filepaths))]
+       (<! (.<request this "delete_files" {:GraphUUID graph-uuid :TXId current-txid :Files files}))))))
+
+(comment
+  (declare remoteapi)
+  (<delete-remote-files-control remoteapi (second @graphs-txid) ["pages/aa.md"])
+
+  )
+
 (def remoteapi (->RemoteAPI nil))
 (def remoteapi (->RemoteAPI nil))
 
 
 
 
@@ -2633,7 +2653,7 @@
 ;;; ### put all stuff together
 ;;; ### put all stuff together
 
 
 (defrecord ^:large-vars/cleanup-todo
 (defrecord ^:large-vars/cleanup-todo
-  SyncManager [graph-uuid base-path *sync-state
+  SyncManager [user-uuid graph-uuid base-path *sync-state
                ^Local->RemoteSyncer local->remote-syncer ^Remote->LocalSyncer remote->local-syncer remoteapi
                ^Local->RemoteSyncer local->remote-syncer ^Remote->LocalSyncer remote->local-syncer remoteapi
                ^:mutable ratelimit-local-changes-chan
                ^:mutable ratelimit-local-changes-chan
                *txid ^:mutable state ^:mutable remote-change-chan ^:mutable *ws *stopped? *paused?
                *txid ^:mutable state ^:mutable remote-change-chan ^:mutable *ws *stopped? *paused?
@@ -2798,7 +2818,8 @@
           (do
           (do
             (state/pub-event! [:instrument {:type :sync/wrong-ops-chan-when-idle
             (state/pub-event! [:instrument {:type :sync/wrong-ops-chan-when-idle
                                             :payload {:ops-chan-result result
                                             :payload {:ops-chan-result result
-                                                      :state state}}])
+                                                      :user-id user-uuid
+                                                      :graph-id graph-uuid}}])
             nil)))))
             nil)))))
 
 
   (full-sync [this]
   (full-sync [this]
@@ -2829,9 +2850,10 @@
           unknown
           unknown
           (do
           (do
             (state/pub-event! [:instrument {:type :sync/unknown
             (state/pub-event! [:instrument {:type :sync/unknown
-                                            :event :local->remote-full-sync-failed
-                                            :graph-uuid graph-uuid
-                                            :payload {:error unknown}}])
+                                            :payload {:error unknown
+                                                      :event :local->remote-full-sync-failed
+                                                      :user-id user-uuid
+                                                      :graph-uuid graph-uuid}}])
             (put-sync-event! {:event :local->remote-full-sync-failed
             (put-sync-event! {:event :local->remote-full-sync-failed
                               :data  {:graph-uuid graph-uuid
                               :data  {:graph-uuid graph-uuid
                                       :epoch      (tc/to-epoch (t/now))}})
                                       :epoch      (tc/to-epoch (t/now))}})
@@ -2856,9 +2878,10 @@
           unknown
           unknown
           (do
           (do
             (state/pub-event! [:instrument {:type :sync/unknown
             (state/pub-event! [:instrument {:type :sync/unknown
-                                            :event :remote->local-full-sync-failed
-                                            :graph-uuid graph-uuid
-                                            :payload {:error unknown}}])
+                                            :payload {:event :remote->local-full-sync-failed
+                                                      :graph-uuid graph-uuid
+                                                      :user-id user-uuid
+                                                      :error unknown}}])
             (put-sync-event! {:event :remote->local-full-sync-failed
             (put-sync-event! {:event :remote->local-full-sync-failed
                               :data  {:graph-uuid graph-uuid
                               :data  {:graph-uuid graph-uuid
                                       :exp        unknown
                                       :exp        unknown
@@ -2900,9 +2923,10 @@
             unknown
             unknown
             (do (prn "remote->local err" unknown)
             (do (prn "remote->local err" unknown)
                 (state/pub-event! [:instrument {:type :sync/unknown
                 (state/pub-event! [:instrument {:type :sync/unknown
-                                                :event :remote->local
-                                                :graph-uuid graph-uuid
-                                                :payload {:error unknown}}])
+                                                :payload {:event :remote->local
+                                                          :user-id user-uuid
+                                                          :graph-uuid graph-uuid
+                                                          :error unknown}}])
                 (.schedule this ::idle nil nil)))))))
                 (.schedule this ::idle nil nil)))))))
 
 
   (local->remote [this {local-changes :local}]
   (local->remote [this {local-changes :local}]
@@ -2963,9 +2987,10 @@
           (do
           (do
             (debug/pprint "local->remote" unknown)
             (debug/pprint "local->remote" unknown)
             (state/pub-event! [:instrument {:type :sync/unknown
             (state/pub-event! [:instrument {:type :sync/unknown
-                                            :event :local->remote
-                                            :graph-uuid graph-uuid
-                                            :payload {:error unknown}}])
+                                            :payload {:event :local->remote
+                                                      :user-id user-uuid
+                                                      :graph-uuid graph-uuid
+                                                      :error unknown}}])
             (.schedule this ::idle nil nil))))))
             (.schedule this ::idle nil nil))))))
   IStoppable
   IStoppable
   (-stop! [_]
   (-stop! [_]
@@ -3015,7 +3040,7 @@
     (.set-remote->local-syncer! local->remote-syncer remote->local-syncer)
     (.set-remote->local-syncer! local->remote-syncer remote->local-syncer)
     (.set-local->remote-syncer! remote->local-syncer local->remote-syncer)
     (.set-local->remote-syncer! remote->local-syncer local->remote-syncer)
     (swap! *sync-state sync-state--update-current-syncing-graph-uuid graph-uuid)
     (swap! *sync-state sync-state--update-current-syncing-graph-uuid graph-uuid)
-    (->SyncManager graph-uuid base-path *sync-state local->remote-syncer remote->local-syncer remoteapi-with-stop
+    (->SyncManager user-uuid graph-uuid base-path *sync-state local->remote-syncer remote->local-syncer remoteapi-with-stop
                    nil *txid nil nil nil *stopped? *paused? nil (chan 1) (chan 1) (chan 1) (chan 1) (chan 1))))
                    nil *txid nil nil nil *stopped? *paused? nil (chan 1) (chan 1) (chan 1) (chan 1) (chan 1))))
 
 
 (defn sync-manager-singleton
 (defn sync-manager-singleton

+ 1 - 1
src/main/frontend/handler/common/file.cljs

@@ -27,7 +27,7 @@
                        (distinct))]
                        (distinct))]
     (when-let [current-file (page-exists-in-another-file repo-url first-page file)]
     (when-let [current-file (page-exists-in-another-file repo-url first-page file)]
       (when (not= file current-file)
       (when (not= file current-file)
-        (let [error (str "Page already exists with another file: " current-file ", current file: " file)]
+        (let [error (str "Page already exists with another file: " current-file ", current file: " file ". Please keep only one of them and re-index your graph.")]
           (state/pub-event! [:notification/show
           (state/pub-event! [:notification/show
                              {:content error
                              {:content error
                               :status :error
                               :status :error

+ 14 - 5
src/main/frontend/handler/conversion.cljs

@@ -59,8 +59,6 @@
 ;;   - the special rule in `is-manual-title-prop?`
 ;;   - the special rule in `is-manual-title-prop?`
 (defonce supported-filename-formats [:triple-lowbar :legacy])
 (defonce supported-filename-formats [:triple-lowbar :legacy])
 
 
-;; In case of recovering this check in future
-#_:clj-kondo/ignore
 (defn- is-manual-title-prop?
 (defn- is-manual-title-prop?
   "If it's an user defined title property instead of the generated one"
   "If it's an user defined title property instead of the generated one"
   [format file-body prop-title]
   [format file-body prop-title]
@@ -104,6 +102,17 @@
   [page path old-format new-format]
   [page path old-format new-format]
   (let [prop-title (get-in page [:block/properties :title])
   (let [prop-title (get-in page [:block/properties :title])
         file-body  (gp-util/path->file-body path)
         file-body  (gp-util/path->file-body path)
-        journal?   (:block/journal? page)]
-    (when (not journal?)
-      (calc-rename-target-impl old-format new-format file-body prop-title))))
+        journal?   (:block/journal? page)
+        manual-prop-title? (is-manual-title-prop? old-format file-body prop-title)]
+    (cond
+      (and (not journal?)
+           (not manual-prop-title?))
+      (calc-rename-target-impl old-format new-format file-body prop-title)
+
+      (and (not journal?)
+           manual-prop-title?
+           (fs-util/include-reserved-chars? file-body))
+      {:status        :informal
+       :target        (fs-util/file-name-sanity file-body new-format)
+       :old-title     prop-title
+       :changed-title prop-title})))

+ 18 - 9
src/main/frontend/handler/events.cljs

@@ -361,7 +361,11 @@
       (when-not dir-exists?
       (when-not dir-exists?
         (state/pub-event! [:graph/dir-gone dir]))))
         (state/pub-event! [:graph/dir-gone dir]))))
   ;; FIXME: an ugly implementation for redirecting to page on new window is restored
   ;; FIXME: an ugly implementation for redirecting to page on new window is restored
-  (repo-handler/graph-ready! repo))
+  (repo-handler/graph-ready! repo)
+  (when (and (util/electron?)
+             (not (config/demo-graph?))
+             (= :legacy (state/get-filename-format)))
+    (state/pub-event! [:ui/notify-outdated-filename-format []])))
 
 
 (defmethod handle :notification/show [[_ {:keys [content status clear?]}]]
 (defmethod handle :notification/show [[_ {:keys [content status clear?]}]]
   (notification/show! content status clear?))
   (notification/show! content status clear?))
@@ -401,7 +405,9 @@
 (defmethod handle :redirect-to-home [_]
 (defmethod handle :redirect-to-home [_]
   (page-handler/create-today-journal!))
   (page-handler/create-today-journal!))
 
 
-(defmethod handle :instrument [[_ {:keys [type payload]}]]
+(defmethod handle :instrument [[_ {:keys [type payload] :as opts}]]
+  (when-not (empty? (dissoc opts :type :payload))
+    (js/console.error "instrument data-map should only contains [:type :payload]"))
   (posthog/capture type payload))
   (posthog/capture type payload))
 
 
 (defmethod handle :exec-plugin-cmd [[_ {:keys [pid cmd action]}]]
 (defmethod handle :exec-plugin-cmd [[_ {:keys [pid cmd action]}]]
@@ -746,7 +752,8 @@
     (when (= dir (config/get-repo-dir repo))
     (when (= dir (config/get-repo-dir repo))
       (fs/watch-dir! dir))))
       (fs/watch-dir! dir))))
 
 
-(defmethod handle :ui/notify-files-with-reserved-chars [[_ paths]]
+(defmethod handle :ui/notify-outdated-filename-format [[_ paths]]
+  ;; paths - the affected paths that contains reserved characters
   (notification/show!
   (notification/show!
    [:div
    [:div
     [:div.mb-4
     [:div.mb-4
@@ -754,9 +761,10 @@
 
 
      [:div
      [:div
       [:p
       [:p
-       "We suggest you upgrade now to avoid some potential bugs."]
-      [:p
-       "For example, the files below have reserved characters can't be synced on some platforms."]]
+       "We suggest you upgrade now to avoid potential bugs."]
+      (when (seq paths)
+        [:p
+         "For example, the files below have reserved characters that can't be synced on some platforms."])]
      ]
      ]
     (ui/button
     (ui/button
       "Update filename format"
       "Update filename format"
@@ -765,9 +773,10 @@
                   (state/set-modal!
                   (state/set-modal!
                   (fn [_] (conversion-component/files-breaking-changed))
                   (fn [_] (conversion-component/files-breaking-changed))
                   {:id :filename-format-panel :center? true})))
                   {:id :filename-format-panel :center? true})))
-    [:ol.my-2
-     (for [path paths]
-       [:li path])]]
+    (when (seq paths)
+      [:ol.my-2
+       (for [path paths]
+         [:li path])])]
    :warning
    :warning
    false))
    false))
 
 

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

@@ -100,7 +100,7 @@
 (defn- create-title-property?
 (defn- create-title-property?
   [journal? page-name]
   [journal? page-name]
   (and (not journal?)
   (and (not journal?)
-       (not= (state/get-filename-format) :triple-lowbar)
+       (= (state/get-filename-format) :legacy) ;; reduce title computation
        (fs-util/create-title-property? page-name)))
        (fs-util/create-title-property? page-name)))
 
 
 (defn- build-page-tx [format properties page journal? whiteboard?]
 (defn- build-page-tx [format properties page journal? whiteboard?]

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

@@ -181,7 +181,9 @@
         chan (async/to-chan! indexed-files)
         chan (async/to-chan! indexed-files)
         graph-added-chan (async/promise-chan)
         graph-added-chan (async/promise-chan)
         total (count supported-files)
         total (count supported-files)
-        large-graph? (> total 1000)]
+        large-graph? (> total 1000)
+        *page-names (atom #{})
+        *page-name->path (atom {})]
     (when (seq delete-data) (db/transact! repo-url delete-data))
     (when (seq delete-data) (db/transact! repo-url delete-data))
     (state/set-current-repo! repo-url)
     (state/set-current-repo! repo-url)
     (state/set-parsing-state! {:total (count supported-files)})
     (state/set-parsing-state! {:total (count supported-files)})
@@ -215,7 +217,25 @@
                           (assoc opts' :skip-db-transact? false)
                           (assoc opts' :skip-db-transact? false)
                           opts')
                           opts')
                   result (parse-and-load-file! repo-url file opts')
                   result (parse-and-load-file! repo-url file opts')
-                  tx' (if whiteboard? tx (concat tx result))
+                  page-name (some (fn [x] (when (and (map? x) (:block/original-name x )
+                                                     (= (:file/path file) (:file/path (:block/file x))))
+                                            (:block/name x))) result)
+                  page-exists? (and page-name (get @*page-names page-name))
+                  tx' (cond
+                        whiteboard? tx
+                        page-exists? (do
+                                       (state/pub-event! [:notification/show
+                                                          {:content [:div
+                                                                     (util/format "The file \"%s\" will be skipped because another file \"%s\" has the same page title."
+                                                                                  (:file/path file)
+                                                                                  (get @*page-name->path page-name))]
+                                                           :status :warning
+                                                           :clear? false}])
+                                       tx)
+                        :else (concat tx result))
+                  _ (when (and page-name (not page-exists?))
+                      (swap! *page-names conj page-name)
+                      (swap! *page-name->path assoc page-name (:file/path file)))
                   tx' (if (or whiteboard? (zero? (rem (inc idx) 100)))
                   tx' (if (or whiteboard? (zero? (rem (inc idx) 100)))
                         (do (db/transact! repo-url tx' {:from-disk? true})
                         (do (db/transact! repo-url tx' {:from-disk? true})
                             [])
                             [])

+ 8 - 7
src/main/frontend/mobile/camera.cljs

@@ -23,13 +23,14 @@
                       (log/error :photo/get-failed {:error error})))
                       (log/error :photo/get-failed {:error error})))
           filename (str (date/get-date-time-string-2) ".jpeg")
           filename (str (date/get-date-time-string-2) ".jpeg")
           path (editor-handler/get-asset-path filename)
           path (editor-handler/get-asset-path filename)
-          _file (p/catch
-                    (.writeFile Filesystem (clj->js {:data (.-base64String photo)
-                                                     :path path
-                                                     :recursive true}))
-                    (fn [error]
-                      (log/error :file/write-failed {:path path
-                                                     :error error})))]
+          _file (when photo
+                  (p/catch
+                     (.writeFile Filesystem (clj->js {:data (.-base64String photo)
+                                                      :path path
+                                                      :recursive true}))
+                     (fn [error]
+                       (log/error :file/write-failed {:path path
+                                                      :error error}))))]
     (p/resolved filename)))
     (p/resolved filename)))
 
 
 (defn embed-photo [id]
 (defn embed-photo [id]

+ 14 - 12
src/main/frontend/search/agency.cljs

@@ -9,13 +9,17 @@
 
 
 (defn get-registered-engines
 (defn get-registered-engines
   [repo]
   [repo]
-  (-> (if (util/electron?)
-        (search-node/->Node repo)
-        (search-browser/->Browser repo))
-      (cons
-       [(when state/lsp-enabled?
-          (for [s (state/get-all-plugin-services-with-type :search)]
-            (search-plugin/->Plugin s repo)))])))
+  [(if (util/electron?)
+     (search-node/->Node repo)
+     (search-browser/->Browser repo))
+   (when state/lsp-enabled?
+     (for [s (state/get-all-plugin-services-with-type :search)]
+       (search-plugin/->Plugin s repo)))])
+
+(defn- get-flatten-registered-engines
+  [repo]
+  (->> (flatten (get-registered-engines repo))
+       (remove nil?)))
 
 
 (deftype Agency [repo]
 (deftype Agency [repo]
   protocol/Engine
   protocol/Engine
@@ -36,17 +40,15 @@
 
 
   (transact-blocks! [_this data]
   (transact-blocks! [_this data]
     (println "D:Search > Transact blocks!:" repo)
     (println "D:Search > Transact blocks!:" repo)
-    (doseq [e (flatten (get-registered-engines repo))]
+    (doseq [e (get-flatten-registered-engines repo)]
       (protocol/transact-blocks! e data)))
       (protocol/transact-blocks! e data)))
 
 
   (truncate-blocks! [_this]
   (truncate-blocks! [_this]
     (println "D:Search > Truncate blocks!" repo)
     (println "D:Search > Truncate blocks!" repo)
-    (doseq [e (flatten (get-registered-engines repo))]
+    (doseq [e (get-flatten-registered-engines repo)]
       (protocol/truncate-blocks! e)))
       (protocol/truncate-blocks! e)))
 
 
   (remove-db! [_this]
   (remove-db! [_this]
     (println "D:Search > Remove Db!" repo)
     (println "D:Search > Remove Db!" repo)
-    (doseq [e (flatten (get-registered-engines repo))]
+    (doseq [e (get-flatten-registered-engines repo)]
       (protocol/remove-db! e))))
       (protocol/remove-db! e))))
-
-

+ 10 - 10
src/main/frontend/ui.cljs

@@ -56,13 +56,13 @@
 (defonce icon-size (if (mobile-util/native-platform?) 26 20))
 (defonce icon-size (if (mobile-util/native-platform?) 26 20))
 
 
 (def block-background-colors
 (def block-background-colors
-  ["gray"
+  ["yellow"
    "red"
    "red"
-   "yellow"
+   "pink"
    "green"
    "green"
    "blue"
    "blue"
    "purple"
    "purple"
-   "pink"])
+   "gray"])
 
 
 (rum/defc ls-textarea
 (rum/defc ls-textarea
   < rum/reactive
   < rum/reactive
@@ -246,7 +246,7 @@
            [:div.flex-shrink-0
            [:div.flex-shrink-0
             svg]
             svg]
            [:div.ml-3.w-0.flex-1
            [:div.ml-3.w-0.flex-1
-            [:div.text-sm.leading-5.font-medium.whitespace-pre-line {:style {:margin 0}}
+            [:div.text-sm.leading-6.font-medium.whitespace-pre-line {:style {:margin 0}}
              content]]
              content]]
            [:div.ml-4.flex-shrink-0.flex
            [:div.ml-4.flex-shrink-0.flex
             [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150.notification-close-button
             [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150.notification-close-button
@@ -942,24 +942,24 @@
   (memoize (fn [klass] (r/adapt-class klass))))
   (memoize (fn [klass] (r/adapt-class klass))))
 
 
 (defn icon
 (defn icon
-  ([class] (icon class nil))
-  ([class {:keys [extension? font?] :as opts}]
-   (when-not (string/blank? class)
+  ([name] (icon name nil))
+  ([name {:keys [extension? font? class] :as opts}]
+   (when-not (string/blank? name)
      (let [^js jsTablerIcons (gobj/get js/window "tablerIcons")]
      (let [^js jsTablerIcons (gobj/get js/window "tablerIcons")]
        (if (or extension? font? (not jsTablerIcons))
        (if (or extension? font? (not jsTablerIcons))
          [:span.ui__icon (merge {:class
          [:span.ui__icon (merge {:class
                                  (util/format
                                  (util/format
-                                  (str "%s-" class
+                                  (str "%s-" name
                                        (when (:class opts)
                                        (when (:class opts)
                                          (str " " (string/trim (:class opts)))))
                                          (str " " (string/trim (:class opts)))))
                                   (if extension? "tie tie" "ti ti"))}
                                   (if extension? "tie tie" "ti ti"))}
                                 (dissoc opts :class :extension? :font?))]
                                 (dissoc opts :class :extension? :font?))]
 
 
          ;; tabler svg react
          ;; tabler svg react
-         (when-let [klass (gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase class)))]
+         (when-let [klass (gobj/get js/tablerIcons (str "Icon" (csk/->PascalCase name)))]
            (let [f (get-adapt-icon-class klass)]
            (let [f (get-adapt-icon-class klass)]
              [:span.ui__icon.ti
              [:span.ui__icon.ti
-              {:class (str "ls-icon-" class)}
+              {:class (str "ls-icon-" name " " class)}
               (f (merge {:size 18} (r/map-keys->camel-case (dissoc opts :class))))])))))))
               (f (merge {:size 18} (r/map-keys->camel-case (dissoc opts :class))))])))))))
 
 
 (defn button
 (defn button

+ 2 - 1
src/main/frontend/util/fs.cljs

@@ -179,7 +179,8 @@
    (when (string? title)
    (when (string? title)
      (case file-name-format
      (case file-name-format
        :triple-lowbar (tri-lb-file-name-sanity title)
        :triple-lowbar (tri-lb-file-name-sanity title)
-       :legacy-dot    (legacy-dot-file-name-sanity title) ;; The earliest file name rule (before May 2022). For file name check in the conversion logic only. Don't allow users to use this.
+       ;; The earliest file name rule (before May 2022). For file name check in the conversion logic only. Don't allow users to use this or show up in config, as it's not handled.
+       :legacy-dot    (legacy-dot-file-name-sanity title)
        (legacy-url-file-name-sanity title)))))
        (legacy-url-file-name-sanity title)))))
 
 
 (defn create-title-property?
 (defn create-title-property?

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

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

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

@@ -74,7 +74,7 @@
     "aaa__bbb__cccon" "aaa/bbb/cccon"  true
     "aaa__bbb__cccon" "aaa/bbb/cccon"  true
     "aaa.bbb.ccc"     "adbcde/aks/sdf" true
     "aaa.bbb.ccc"     "adbcde/aks/sdf" true
     "a__.bbb.ccc"     "adbcde/aks/sdf" true
     "a__.bbb.ccc"     "adbcde/aks/sdf" true
-    ))
+    "aaa__bbb__ccc" nil false))
 
 
 (deftest rename-previous-tests
 (deftest rename-previous-tests
   (are [x y] (= y (#'conversion-handler/calc-previous-name :legacy :triple-lowbar x))
   (are [x y] (= y (#'conversion-handler/calc-previous-name :legacy :triple-lowbar x))

+ 3 - 3
tldraw/apps/tldraw-logseq/src/app.tsx

@@ -57,12 +57,12 @@ interface LogseqTldrawProps {
   onPersist?: TLReactCallbacks<Shape>['onPersist']
   onPersist?: TLReactCallbacks<Shape>['onPersist']
 }
 }
 
 
-const ReferencesCount: LogseqContextValue['renderers']['ReferencesCount'] = props => {
+const BacklinksCount: LogseqContextValue['renderers']['BacklinksCount'] = props => {
   const { renderers } = React.useContext(LogseqContext)
   const { renderers } = React.useContext(LogseqContext)
 
 
   const options = { 'portal?': false }
   const options = { 'portal?': false }
 
 
-  return <renderers.ReferencesCount {...props} options={options} />
+  return <renderers.BacklinksCount {...props} options={options} />
 }
 }
 
 
 const AppImpl = () => {
 const AppImpl = () => {
@@ -71,7 +71,7 @@ const AppImpl = () => {
   const components = React.useMemo(
   const components = React.useMemo(
     () => ({
     () => ({
       ContextBar,
       ContextBar,
-      ReferencesCount,
+      BacklinksCount,
       QuickLinks,
       QuickLinks,
     }),
     }),
     []
     []

+ 6 - 1
tldraw/apps/tldraw-logseq/src/components/BlockLink/BlockLink.tsx

@@ -13,7 +13,12 @@ export const BlockLink = ({ id }: { id: string }) => {
   let linkType = validUUID(id) ? 'B' : 'P'
   let linkType = validUUID(id) ? 'B' : 'P'
 
 
   if (validUUID(id)) {
   if (validUUID(id)) {
-    if (queryBlockByUUID(id)?.properties?.['ls-type'] === 'whiteboard-shape') {
+    const block = queryBlockByUUID(id)
+    if (!block) {
+      return <span className='p-2'>Invalid reference. Did you remove it?</span>
+    }
+
+    if (block.properties?.['ls-type'] === 'whiteboard-shape') {
       iconName = 'link-to-whiteboard'
       iconName = 'link-to-whiteboard'
     } else {
     } else {
       iconName = 'link-to-block'
       iconName = 'link-to-block'

+ 1 - 1
tldraw/apps/tldraw-logseq/src/lib/logseq-context.ts

@@ -25,7 +25,7 @@ export interface LogseqContextValue {
     BlockReference: React.FC<{
     BlockReference: React.FC<{
       blockId: string
       blockId: string
     }>
     }>
-    ReferencesCount: React.FC<{
+    BacklinksCount: React.FC<{
       id: string
       id: string
       className?: string
       className?: string
       options?: {
       options?: {

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

@@ -161,7 +161,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
       <>
       <>
         <Arrow
         <Arrow
           style={{
           style={{
-            stroke: getComputedColor(stroke, 'stroke'),
+            stroke: getComputedColor(stroke, 'text'),
             fill,
             fill,
             strokeWidth,
             strokeWidth,
             strokeType,
             strokeType,

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

@@ -131,8 +131,8 @@ export class PencilShape extends TLDrawShape<PencilShapeProps> {
         strokeWidth={strokeWidth / 2}
         strokeWidth={strokeWidth / 2}
         strokeLinejoin="round"
         strokeLinejoin="round"
         strokeLinecap="round"
         strokeLinecap="round"
-        stroke={getComputedColor(stroke, 'stroke')}
-        fill={getComputedColor(stroke, 'stroke')}
+        stroke={getComputedColor(stroke, 'text')}
+        fill={getComputedColor(stroke, 'text')}
         strokeDasharray={strokeType === 'dashed' ? '12 4' : undefined}
         strokeDasharray={strokeType === 'dashed' ? '12 4' : undefined}
       />
       />
     )
     )

+ 1 - 1
tldraw/apps/tldraw-logseq/src/styles.css

@@ -7,7 +7,7 @@
   --ls-wb-stroke-color-purple: var(--color-purple-500, purple);
   --ls-wb-stroke-color-purple: var(--color-purple-500, purple);
   --ls-wb-stroke-color-pink: var(--color-pink-500, pink);
   --ls-wb-stroke-color-pink: var(--color-pink-500, pink);
   --ls-wb-stroke-color-default: var(--ls-secondary-border-color);
   --ls-wb-stroke-color-default: var(--ls-secondary-border-color);
-  --ls-wb-text-color-default: var(--ls-secondary-text-color);
+  --ls-wb-text-color-default: var(--ls-primary-text-color);
   --ls-wb-background-color-default: var(--ls-tertiary-background-color);
   --ls-wb-background-color-default: var(--ls-tertiary-background-color);
 }
 }
 
 

+ 2 - 2
tldraw/demo/src/App.jsx

@@ -87,7 +87,7 @@ const PageName = props => {
   )
   )
 }
 }
 
 
-const ReferencesCount = props => {
+const BacklinksCount = props => {
   return (
   return (
     <div className={props.className}>
     <div className={props.className}>
       <div className={'open-page-ref-link rounded bg-gray-400 p-0.5 '}>3</div>
       <div className={'open-page-ref-link rounded bg-gray-400 p-0.5 '}>3</div>
@@ -222,7 +222,7 @@ export default function App() {
           Block,
           Block,
           Breadcrumb,
           Breadcrumb,
           PageName,
           PageName,
-          ReferencesCount,
+          BacklinksCount,
           BlockReference,
           BlockReference,
         }}
         }}
         handlers={{
         handlers={{

+ 3 - 3
tldraw/packages/core/src/types/types.ts

@@ -4,13 +4,13 @@ import type { TLEventMap } from './TLEventMap'
 import type { TLHandle } from './TLHandle'
 import type { TLHandle } from './TLHandle'
 
 
 export enum Color {
 export enum Color {
-  Gray = 'gray',
-  Red = 'red',
   Yellow = 'yellow',
   Yellow = 'yellow',
+  Red = 'red',
+  Pink = 'pink',
   Green = 'green',
   Green = 'green',
   Blue = 'blue',
   Blue = 'blue',
   Purple = 'purple',
   Purple = 'purple',
-  Pink = 'pink',
+  Gray = 'gray',
   Default = '',
   Default = '',
 }
 }
 
 

+ 1 - 1
tldraw/packages/react/src/components/ReferencesCountContainer/ReferencesCountContainer.tsx → tldraw/packages/react/src/components/BacklinksCountContainer/BacklinksCountContainer.tsx

@@ -24,7 +24,7 @@ export const BacklinksCountContainer = observer(function BacklinksCountContainer
 
 
   const app = useApp<S>()
   const app = useApp<S>()
 
 
-  if (!BacklinksCount) throw Error('Expected a ReferencesCount component.')
+  if (!BacklinksCount) throw Error('Expected a BacklinksCount component.')
 
 
   const stop: React.EventHandler<any> = e => e.stopPropagation()
   const stop: React.EventHandler<any> = e => e.stopPropagation()
 
 

+ 1 - 0
tldraw/packages/react/src/components/BacklinksCountContainer/index.ts

@@ -0,0 +1 @@
+export * from './BacklinksCountContainer'

+ 5 - 5
tldraw/packages/react/src/components/Canvas/Canvas.tsx

@@ -22,8 +22,8 @@ import { Container } from '../Container'
 import { ContextBarContainer } from '../ContextBarContainer'
 import { ContextBarContainer } from '../ContextBarContainer'
 import { HTMLLayer } from '../HTMLLayer'
 import { HTMLLayer } from '../HTMLLayer'
 import { Indicator } from '../Indicator'
 import { Indicator } from '../Indicator'
-import { QuickLinksContainer } from '../ReferencesCountContainer copy'
-import { BacklinksCountContainer } from '../ReferencesCountContainer'
+import { QuickLinksContainer } from '../QuickLinksContainer'
+import { BacklinksCountContainer } from '../BacklinksCountContainer'
 import { SelectionDetailContainer } from '../SelectionDetailContainer'
 import { SelectionDetailContainer } from '../SelectionDetailContainer'
 import { Shape } from '../Shape'
 import { Shape } from '../Shape'
 import { SVGContainer } from '../SVGContainer'
 import { SVGContainer } from '../SVGContainer'
@@ -158,11 +158,11 @@ export const Canvas = observer(function Renderer<S extends TLReactShape>({
           {hoveredShape && (
           {hoveredShape && (
             <Indicator key={'hovered_indicator_' + hoveredShape.id} shape={hoveredShape} />
             <Indicator key={'hovered_indicator_' + hoveredShape.id} shape={hoveredShape} />
           )}
           )}
-          {selectedOrHooveredShape && components.BacklinksCount && (
+          {singleSelectedShape && components.BacklinksCount && (
             <BacklinksCountContainer
             <BacklinksCountContainer
               hidden={false}
               hidden={false}
-              bounds={selectedOrHooveredShape.bounds}
-              shape={selectedOrHooveredShape}
+              bounds={singleSelectedShape.bounds}
+              shape={singleSelectedShape}
             />
             />
           )}
           )}
           {hoveredShape && hoveredShape !== singleSelectedShape && components.QuickLinks && (
           {hoveredShape && hoveredShape !== singleSelectedShape && components.QuickLinks && (

+ 0 - 0
tldraw/packages/react/src/components/ReferencesCountContainer copy/QuickLinksContainer.tsx → tldraw/packages/react/src/components/QuickLinksContainer/QuickLinksContainer.tsx


+ 0 - 0
tldraw/packages/react/src/components/ReferencesCountContainer copy/index.ts → tldraw/packages/react/src/components/QuickLinksContainer/index.ts


+ 0 - 1
tldraw/packages/react/src/components/ReferencesCountContainer/index.ts

@@ -1 +0,0 @@
-export * from './ReferencesCountContainer'

+ 4 - 4
tldraw/packages/react/src/types/component-props.ts

@@ -72,14 +72,14 @@ export type TLHandleComponent<
   H extends TLHandle = TLHandle
   H extends TLHandle = TLHandle
 > = (props: TLHandleComponentProps<S, H>) => JSX.Element | null
 > = (props: TLHandleComponentProps<S, H>) => JSX.Element | null
 
 
-export interface TLReferencesCountComponentProps<S extends TLReactShape = TLReactShape> {
+export interface TLBacklinksCountComponentProps<S extends TLReactShape = TLReactShape> {
   shape: S
   shape: S
   id: string
   id: string
   className?: string
   className?: string
 }
 }
 
 
-export type TLReferencesCountComponent<S extends TLReactShape = TLReactShape> = (
-  props: TLReferencesCountComponentProps<S>
+export type TLBacklinksCountComponent<S extends TLReactShape = TLReactShape> = (
+  props: TLBacklinksCountComponentProps<S>
 ) => JSX.Element | null
 ) => JSX.Element | null
 
 
 export interface TLQuickLinksComponentProps<S extends TLReactShape = TLReactShape> {
 export interface TLQuickLinksComponentProps<S extends TLReactShape = TLReactShape> {
@@ -102,7 +102,7 @@ export type TLReactComponents<S extends TLReactShape = TLReactShape> = {
   SelectionBackground?: TLBoundsComponent<S> | null
   SelectionBackground?: TLBoundsComponent<S> | null
   SelectionForeground?: TLBoundsComponent<S> | null
   SelectionForeground?: TLBoundsComponent<S> | null
   SelectionDetail?: TLSelectionDetailComponent<S> | null
   SelectionDetail?: TLSelectionDetailComponent<S> | null
-  BacklinksCount?: TLReferencesCountComponent<S> | null
+  BacklinksCount?: TLBacklinksCountComponent<S> | null
   QuickLinks?: TLQuickLinksComponent<S> | null
   QuickLinks?: TLQuickLinksComponent<S> | null
   DirectionIndicator?: TLDirectionIndicatorComponent<S> | null
   DirectionIndicator?: TLDirectionIndicatorComponent<S> | null
   Handle?: TLHandleComponent<S> | null
   Handle?: TLHandleComponent<S> | null

+ 0 - 5
yarn.lock

@@ -487,11 +487,6 @@
     "@jridgewell/resolve-uri" "^3.0.3"
     "@jridgewell/resolve-uri" "^3.0.3"
     "@jridgewell/sourcemap-codec" "^1.4.10"
     "@jridgewell/sourcemap-codec" "^1.4.10"
 
 
-"@kanru/rage-wasm@^0.3.0":
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/@kanru/rage-wasm/-/rage-wasm-0.3.0.tgz#de96b1fda1f781ff401d43b50d0f95b7338c4399"
-  integrity sha512-2LMRS27nNJPqFNpRQL7kXG0kgBeIPo63KM6u0Xu6Es5XIS7LP4MFtdHkCg8Pt7IhMM7GuOa2YnzAZgKBxE1lcw==
-
 "@logseq/[email protected]":
 "@logseq/[email protected]":
   version "0.0.14"
   version "0.0.14"
   resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.14.tgz#f358f42e95e0578c2853477a66491c8f221a7c15"
   resolved "https://registry.yarnpkg.com/@logseq/capacitor-file-sync/-/capacitor-file-sync-0.0.14.tgz#f358f42e95e0578c2853477a66491c8f221a7c15"