浏览代码

Merge branch 'master' into feat/hnswlib+transformer-js

Tienson Qin 3 月之前
父节点
当前提交
2d50ca5ce2
共有 100 个文件被更改,包括 661 次插入723 次删除
  1. 26 13
      .clj-kondo/config.edn
  2. 13 0
      .clj-kondo/hooks/def_thread_api.clj
  3. 5 5
      .cljfmt.edn
  4. 3 0
      .github/ISSUE_TEMPLATE/config.yml
  5. 6 6
      .github/workflows/build-android.yml
  6. 0 68
      .github/workflows/build-demo.yml
  7. 40 87
      .github/workflows/build-desktop-release.yml
  8. 5 6
      .github/workflows/build-ios-release.yml
  9. 2 5
      .github/workflows/build-ios.yml
  10. 0 71
      .github/workflows/build-stage.yml
  11. 12 109
      .github/workflows/build.yml
  12. 94 0
      .github/workflows/clj-e2e.yml
  13. 97 0
      .github/workflows/clj-rtc-e2e.yml
  14. 4 4
      .github/workflows/db.yml
  15. 0 70
      .github/workflows/deploy-db-pages.yml
  16. 4 4
      .github/workflows/deploy-db-test-pages.yml
  17. 0 165
      .github/workflows/e2e.yml
  18. 5 5
      .github/workflows/graph-parser.yml
  19. 1 1
      .github/workflows/logseq-common.yml
  20. 2 2
      .github/workflows/outliner.yml
  21. 1 1
      .github/workflows/publishing.yml
  22. 7 3
      .gitignore
  23. 4 1
      .projectile
  24. 2 1
      CODEBASE_OVERVIEW.md
  25. 14 0
      README.md
  26. 13 8
      android/app/build.gradle
  27. 7 6
      android/app/capacitor.build.gradle
  28. 3 8
      android/app/src/main/AndroidManifest.xml
  29. 4 4
      android/app/src/main/assets/capacitor.plugins.json
  30. 2 4
      android/app/src/main/java/com/logseq/app/MainActivity.java
  31. 88 0
      android/app/src/main/java/com/logseq/app/UILocal.kt
  32. 二进制
      android/app/src/main/res/drawable-land-hdpi/splash.png
  33. 二进制
      android/app/src/main/res/drawable-land-ldpi/splash.png
  34. 二进制
      android/app/src/main/res/drawable-land-mdpi/splash.png
  35. 二进制
      android/app/src/main/res/drawable-land-night-hdpi/splash.png
  36. 二进制
      android/app/src/main/res/drawable-land-night-ldpi/splash.png
  37. 二进制
      android/app/src/main/res/drawable-land-night-mdpi/splash.png
  38. 二进制
      android/app/src/main/res/drawable-land-night-xhdpi/splash.png
  39. 二进制
      android/app/src/main/res/drawable-land-night-xxhdpi/splash.png
  40. 二进制
      android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png
  41. 二进制
      android/app/src/main/res/drawable-land-xhdpi/splash.png
  42. 二进制
      android/app/src/main/res/drawable-land-xxhdpi/splash.png
  43. 二进制
      android/app/src/main/res/drawable-land-xxxhdpi/splash.png
  44. 二进制
      android/app/src/main/res/drawable-night/splash.png
  45. 二进制
      android/app/src/main/res/drawable-port-hdpi/splash.png
  46. 二进制
      android/app/src/main/res/drawable-port-ldpi/splash.png
  47. 二进制
      android/app/src/main/res/drawable-port-mdpi/splash.png
  48. 二进制
      android/app/src/main/res/drawable-port-night-hdpi/splash.png
  49. 二进制
      android/app/src/main/res/drawable-port-night-ldpi/splash.png
  50. 二进制
      android/app/src/main/res/drawable-port-night-mdpi/splash.png
  51. 二进制
      android/app/src/main/res/drawable-port-night-xhdpi/splash.png
  52. 二进制
      android/app/src/main/res/drawable-port-night-xxhdpi/splash.png
  53. 二进制
      android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png
  54. 二进制
      android/app/src/main/res/drawable-port-xhdpi/splash.png
  55. 二进制
      android/app/src/main/res/drawable-port-xxhdpi/splash.png
  56. 二进制
      android/app/src/main/res/drawable-port-xxxhdpi/splash.png
  57. 二进制
      android/app/src/main/res/drawable/splash.png
  58. 7 4
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  59. 6 3
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  60. 二进制
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  61. 二进制
      android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
  62. 二进制
      android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
  63. 二进制
      android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  64. 二进制
      android/app/src/main/res/mipmap-ldpi/ic_launcher.png
  65. 二进制
      android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png
  66. 二进制
      android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png
  67. 二进制
      android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png
  68. 二进制
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  69. 二进制
      android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
  70. 二进制
      android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
  71. 二进制
      android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  72. 二进制
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  73. 二进制
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
  74. 二进制
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
  75. 二进制
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  76. 二进制
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  77. 二进制
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
  78. 二进制
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
  79. 二进制
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  80. 二进制
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  81. 二进制
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
  82. 二进制
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
  83. 二进制
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  84. 29 0
      android/app/src/main/res/raw/logseq_local.pem
  85. 16 0
      android/app/src/main/res/xml/network_security_config.xml
  86. 6 2
      android/build.gradle
  87. 3 3
      android/capacitor.settings.gradle
  88. 二进制
      android/gradle/wrapper/gradle-wrapper.jar
  89. 3 1
      android/gradle/wrapper/gradle-wrapper.properties
  90. 31 13
      android/gradlew
  91. 21 16
      android/gradlew.bat
  92. 11 11
      android/variables.gradle
  93. 二进制
      assets/icon.png
  94. 二进制
      assets/splash.png
  95. 13 1
      bb.edn
  96. 11 12
      capacitor.config.ts
  97. 3 0
      clj-e2e/.clj-kondo/config.edn
  98. 4 0
      clj-e2e/.cljfmt.edn
  99. 31 0
      clj-e2e/.gitignore
  100. 2 0
      clj-e2e/.lsp/config.edn

+ 26 - 13
.clj-kondo/config.edn

@@ -1,10 +1,17 @@
-{:ns-groups [{:pattern "frontend.components.*" :name all-components}]
+{:ns-groups [{:pattern "frontend.components.*" :name all-components}
+             {:pattern "frontend.*" :name all-frontend}]
 
  :config-in-ns
  ;; :used-underscored-binding is turned off for components because of false positive
  ;; for rum/defcs and _state.
  {all-components
   {:linters {:used-underscored-binding {:level :off}}}
+
+  all-frontend
+  {:linters {:discouraged-namespace
+             {logseq.db.common.sqlite-cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}
+              logseq.outliner.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}}}}
+
   ;; false positive with match/match and _
   frontend.handler.paste {:linters {:used-underscored-binding {:level :off}}}
   frontend.db {:linters {:aliased-namespace-symbol
@@ -32,16 +39,13 @@
                                 ;; TODO:lint: Fix when fixing all type hints
                                 object]}
 
-  :discouraged-namespace
-  {logseq.db.sqlite.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}
-   logseq.outliner.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}}
   :discouraged-var
   {rum.core/use-effect! {:message "Use frontend.hooks/use-effect! instead" :level :info}
    rum.core/use-memo {:message "Use frontend.hooks/use-memo instead" :level :info}
    rum.core/use-layout-effect! {:message "Use frontend.hooks/use-layout-effect! instead" :level :info}
    rum.core/use-callback {:message "Use frontend.hooks/use-callback instead" :level :info}}
   :unused-namespace {:level :warning
-                     :exclude [logseq.db.frontend.entity-plus]}
+                     :exclude [logseq.db.common.entity-plus]}
 
   ;; TODO:lint: Remove node-path excludes once we have a cleaner api
   :unresolved-var {:exclude [frontend.util/node-path.basename
@@ -55,6 +59,7 @@
   :consistent-alias
   {:aliases {"/electron/utils" js-utils
              "path" node-path
+             borkdude.rewrite-edn rewrite
              cljs-time.coerce tc
              cljs-time.core t
              cljs.reader reader
@@ -81,6 +86,7 @@
              frontend.config config
              frontend.date date
              frontend.db db
+             frontend.db.file-based.model file-model
              frontend.db-mixins db-mixins
              frontend.db.query-custom query-custom
              frontend.db.query-dsl query-dsl
@@ -93,15 +99,14 @@
              frontend.format.block block
              frontend.format.mldoc mldoc
              frontend.fs fs
-             frontend.fs.capacitor-fs capacitor-fs
              frontend.fs.memory-fs memory-fs
-             frontend.fs.nfs nfs
              frontend.handler.common common-handler
              frontend.handler.common.developer dev-common-handler
              frontend.handler.common.page page-common-handler
              frontend.handler.common.plugin plugin-common-handler
              frontend.handler.config config-handler
              frontend.handler.db-based.editor db-editor-handler
+             frontend.handler.db-based.export db-export-handler
              frontend.handler.db-based.page db-page-handler
              frontend.handler.db-based.property db-property-handler
              frontend.handler.db-based.property.util db-pu
@@ -109,6 +114,7 @@
              frontend.handler.events events
              frontend.handler.extract extract
              frontend.handler.file-based.file file-handler
+             frontend.handler.file-based.native-fs nfs-handler
              frontend.handler.file-based.page file-page-handler
              frontend.handler.file-based.page-property file-page-property
              frontend.handler.file-based.property file-property-handler
@@ -152,6 +158,8 @@
              frontend.util.text text-util
              frontend.util.thingatpt thingatpt
              frontend.util.url url-util
+             frontend.util.ref ref
+             frontend.worker.shared-service shared-service
              frontend.worker.handler.page worker-page
              frontend.worker.pipeline worker-pipeline
              frontend.worker.state worker-state
@@ -167,17 +175,20 @@
              logseq.common.util.namespace ns-util
              logseq.common.util.page-ref page-ref
              logseq.db ldb
+             logseq.db.common.entity-plus entity-plus
              logseq.db.common.entity-util common-entity-util
+             logseq.db.common.initial-data common-initial-data
              logseq.db.common.order db-order
              logseq.db.common.property-util db-property-util
-             logseq.db.common.sqlite sqlite-common-db
+             logseq.db.common.sqlite common-sqlite
+             logseq.db.common.view db-view
              logseq.db.file-based.rules file-rules
              logseq.db.file-based.schema file-schema
              logseq.db.file-based.entity-util file-entity-util
              logseq.db.frontend.class db-class
              logseq.db.frontend.content db-content
+             logseq.db.frontend.db db-db
              logseq.db.frontend.db-ident db-ident
-             logseq.db.frontend.entity-plus entity-plus
              logseq.db.frontend.entity-util entity-util
              logseq.db.frontend.inputs db-inputs
              logseq.db.frontend.property db-property
@@ -187,7 +198,7 @@
              logseq.db.frontend.schema db-schema
              logseq.db.frontend.validate db-validate
              logseq.db.sqlite.build sqlite-build
-             logseq.db.sqlite.cli sqlite-cli
+             logseq.db.common.sqlite-cli sqlite-cli
              logseq.db.sqlite.create-graph sqlite-create-graph
              logseq.db.sqlite.export sqlite-export
              logseq.db.sqlite.util sqlite-util
@@ -216,7 +227,8 @@
                         rum.core/defcs hooks.rum/defcs
                         clojure.string/join hooks.path-invalid-construct/string-join
                         clojure.string/replace hooks.regex-checks/double-escaped-regex
-                        logseq.common.defkeywords/defkeywords hooks.defkeywords/defkeywords}}
+                        logseq.common.defkeywords/defkeywords hooks.defkeywords/defkeywords
+                        frontend.common.thread-api/def-thread-api hooks.def-thread-api/def-thread-api}}
  :lint-as {promesa.core/let clojure.core/let
            promesa.core/loop clojure.core/loop
            promesa.core/recur clojure.core/recur
@@ -232,7 +244,8 @@
            frontend.test.helper/deftest-async clojure.test/deftest
            frontend.worker.rtc.idb-keyval-mock/with-reset-idb-keyval-mock cljs.test/async
            frontend.react/defc clojure.core/defn
-           logseq.common.defkeywords/defkeyword cljs.spec.alpha/def}
+           logseq.common.defkeywords/defkeyword cljs.spec.alpha/def
+           frontend.common.thread-api/defkeyword cljs.spec.alpha/def}
  :skip-comments true
  :output {:progress true
-          :exclude-files ["src/test/docs-0.10.9/"]}}
+          :exclude-files ["src/test/docs-0.10.12/"]}}

+ 13 - 0
.clj-kondo/hooks/def_thread_api.clj

@@ -0,0 +1,13 @@
+(ns hooks.def-thread-api
+  (:require [clj-kondo.hooks-api :as api]))
+
+(defn def-thread-api
+  [{:keys [node]}]
+  (let [[_ kw & others] (:children node)
+        new-node (api/list-node
+                  [(api/token-node 'do)
+                   (api/list-node [(api/token-node 'frontend.common.thread-api/defkeyword) kw])
+                   (api/list-node
+                    (cons (api/token-node 'fn) others))])
+        new-node* (with-meta new-node (meta node))]
+    {:node new-node*}))

+ 5 - 5
.cljfmt.edn

@@ -1,5 +1,5 @@
- {:extra-indents {missionary.core/sp [[:block 0]]
-                  missionary.core/ap [[:block 0]]
-                  frontend.worker-common.util/profile [[:inner 0]]
-                  frontend.util/profile [[:inner 0]]}
-  :sort-ns-references? true}
+{:extra-indents {missionary.core/sp [[:block 0]]
+                 missionary.core/ap [[:block 0]]
+                 frontend.util/profile [[:inner 0]]
+                 frontend.common.missionary/run-task [[:inner 0]]}
+ :sort-ns-references? true}

+ 3 - 0
.github/ISSUE_TEMPLATE/config.yml

@@ -1,4 +1,7 @@
 contact_links:
+  - name: Database Version Issue
+    url: https://github.com/logseq/db-test/issues
+    about: For issues related to unreleased Database Version
   - name: Feature request
     url: https://discuss.logseq.com/new-topic?category=feature-requests
     about: Suggest an idea for Logseq

+ 6 - 6
.github/workflows/build-android.yml

@@ -129,17 +129,17 @@ jobs:
       - name: Prepare public Directory
         run: |
           cp -r static public/
-          rm -rvf public/static/js/publishing
-          rm -rvf public/static/js/*.js.map || true
-          rm -rvf public/static/*.*
-          rm -rvf public/static/ios
+          rm -rvf public/js/publishing
+          rm -rvf public/js/*.js.map || true
+          rm -rvf public/*.*
+          rm -rvf public/ios
           rm -rvf android/app/src/main/assets/public || true
 
       - name: Sync public to Android Project
         run: npx cap sync android
 
       - name: Setup Android SDK
-        uses: android-actions/setup-android@v2
+        uses: android-actions/setup-android@v3.2.2
 
       - name: Build Android
         run: |
@@ -152,7 +152,7 @@ jobs:
       - name: Sign Android APK
         run: |
           echo ${{ secrets.ANDROID_KEYSTORE }} | base64 -d > keystore.jks
-          /usr/local/lib/android/sdk/build-tools/33.0.0/apksigner sign \
+          $ANDROID_SDK_ROOT/build-tools/34.0.0/apksigner sign \
             --ks keystore.jks --ks-pass "pass:${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" \
             --in app/build/outputs/apk/release/app-release-unsigned.apk \
             --out app-signed.apk

+ 0 - 68
.github/workflows/build-demo.yml

@@ -1,68 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: Build-Demo
-
-on:
-  workflow_dispatch:
-    inputs:
-      git-ref:
-        description: "Release Git Ref (Which branch or tag to build?)"
-        required: true
-        default: "master"
-      cloudflare-project-name:
-        description: "Cloudflare pages project name"
-        required: true
-        default: "logseq-demo"
-
-  release:
-    types: [released]
-
-env:
-  CLOJURE_VERSION: '1.11.1.1413'
-  NODE_VERSION: '20'
-  JAVA_VERSION: '17'
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-    env:
-      asset-path: ${GITHUB_REF##*/}/static/js/
-
-    steps:
-      - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
-        with:
-          ref: ${{ github.event.inputs.git-ref }}
-
-      - name: Setup Java JDK
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: ${{ env.JAVA_VERSION }}
-
-      - name: Install Node.js, NPM and Yarn
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-
-      - name: Setup clojure
-        uses: DeLaGuardo/[email protected]
-        with:
-          cli: ${{ env.CLOJURE_VERSION }}
-
-      - name: Fetch yarn deps
-        run: yarn cache clean && yarn install --frozen-lockfile
-
-      - name: Build Released-Web
-        run: |
-          yarn gulp:build && clojure -M:cljs release app  --config-merge '{:asset-path "${{env.asset-path}}" :compiler-options {:source-map-include-sources-content false :source-map-detail-level :symbols}}'
-          ls -ah ./public
-
-      - name: Publish to Cloudflare Pages
-        uses: cloudflare/pages-action@1
-        with:
-          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
-          accountId: 2553ea8236c11ea0f88de28fce1cbfee
-          projectName: ${{ github.event.inputs.cloudflare-project-name || 'logseq-demo' }}
-          directory: 'static'
-          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
-          branch: 'production'

+ 40 - 87
.github/workflows/build-desktop-release.yml

@@ -38,13 +38,13 @@ on:
         type: boolean
         required: true
         default: true
-      build-android:
-        description: 'Build Android App'
-        type: boolean
-        required: true
-        default: true
-  schedule: # Every workday at the 2 P.M. (UTC) we run a scheduled nightly build
-    - cron: '0 14 * * MON-FRI'
+      # build-android:
+      #   description: 'Build Android App'
+      #   type: boolean
+      #   required: true
+      #   default: true
+  # schedule: # Every workday at the 2 P.M. (UTC) we run a scheduled nightly build
+  #   - cron: '0 14 * * MON-FRI'
 
 env:
   CLOJURE_VERSION: '1.11.1.1413'
@@ -170,58 +170,6 @@ jobs:
         with:
           name: static
           path: static
-
-  e2e-test:
-    name: E2E Test Shard ${{ matrix.shard }}
-    runs-on: ubuntu-22.04
-    strategy:
-      matrix:
-        shard: [1, 2, 3]
-    needs: [ compile-cljs ]
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-
-      - name: Download The Static Asset
-        uses: actions/download-artifact@v4
-        with:
-          name: static
-          path: static
-
-      - name: Set up Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-          cache: 'yarn'
-          cache-dependency-path: |
-            yarn.lock
-            static/yarn.lock
-
-      - name: Fetch yarn deps for E2E test
-        run: |
-          yarn install
-          (cd static && yarn install && yarn rebuild:all)
-        env:
-          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
-
-      - name: Install Fluxbox
-        run: sudo apt-get update && sudo apt-get install -y fluxbox
-
-      # Emulate a virtual framebuffer on machines with no display hardware
-      - name: Run XVFB
-        run: Xvfb :1 -screen 0 1024x768x24 >/dev/null 2>&1 &
-
-      # Start a lightweight window manager to simulate window actions (maximize,restore etc)
-      - name: Start Fluxbox
-        run:  DISPLAY=:1.0 fluxbox >/dev/null 2>&1 &
-
-      - name: Run Playwright test
-        run: DISPLAY=:1.0 npx playwright test --reporter github --shard=${{ matrix.shard }}/3
-        env:
-          LOGSEQ_CI: true
-          DEBUG: "pw:api"
-          RELEASE: true # skip dev only test
-
   build-linux-x64:
     runs-on: ubuntu-22.04
     needs: [ compile-cljs ]
@@ -359,6 +307,8 @@ jobs:
       - name: Build/Release Electron app
         run: yarn electron:make
         working-directory: ./static
+        env:
+          DEBUG: electron-packager
         #env:
         #  CODE_SIGN_CERTIFICATE_FILE: ../codesign.pfx
         #  CODE_SIGN_CERTIFICATE_PASSWORD: ${{ secrets.CODE_SIGN_CERTIFICATE_PASSWORD }}
@@ -445,7 +395,7 @@ jobs:
       #     key: ${{ runner.os }}-node-modules
 
       - name: Build/Release Electron App for x64
-        run: yarn install && yarn electron:make
+        run: yarn install && yarn rebuild:all && yarn electron:make
         working-directory: ./static
         env:
           APPLE_ID: ${{ secrets.APPLE_ID_EMAIL }}
@@ -518,7 +468,7 @@ jobs:
       #     key: ${{ runner.os }}-node-modules
 
       - name: Fetch deps and fix dugit arch for arm64
-        run: yarn install --ignore-platform && cd node_modules/dugite && npm_config_arch=arm64 node script/download-git.js
+        run: yarn install --ignore-platform && yarn rebuild:all && cd node_modules/dugite && npm_config_arch=arm64 node script/download-git.js
         working-directory: ./static
 
       - name: Build/Release Electron App for arm64
@@ -542,23 +492,26 @@ jobs:
           path: builds
 
   # reuse workflow via workflow_call
-  build-android:
-    uses: ./.github/workflows/build-android.yml
-    if: ${{ github.event_name == 'schedule' || github.event.inputs.build-android == 'true' }}
-    with:
-      build-target: "${{ github.event.inputs.build-target }}"
-      # if scheduled, use production mode
-      enable-file-sync-production: "${{ github.event_name == 'schedule' || github.event.inputs.enable-file-sync-production == 'true' }}"
-    secrets:
-      ANDROID_KEYSTORE: "${{ secrets.ANDROID_KEYSTORE }}"
-      ANDROID_KEYSTORE_PASSWORD: "${{ secrets.ANDROID_KEYSTORE_PASSWORD }}"
-      SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}"
+  # build-android:
+  #   uses: ./.github/workflows/build-android.yml
+  #   if: ${{ github.event_name == 'schedule' || github.event.inputs.build-android == 'true' }}
+  #   with:
+  #     build-target: "${{ github.event.inputs.build-target }}"
+  #     # if scheduled, use production mode
+  #     enable-file-sync-production: "${{ github.event_name == 'schedule' || github.event.inputs.enable-file-sync-production == 'true' }}"
+  #   secrets:
+  #     ANDROID_KEYSTORE: "${{ secrets.ANDROID_KEYSTORE }}"
+  #     ANDROID_KEYSTORE_PASSWORD: "${{ secrets.ANDROID_KEYSTORE_PASSWORD }}"
+  #     SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}"
 
   codesign-windows:
     if: ${{ github.event_name == 'schedule' || github.event.inputs.build-target == 'nightly' || github.event.inputs.build-target == 'beta' }}
     needs: [ build-windows ]
     runs-on: [self-hosted, macos, token]
     steps:
+      - name: Remove old builds
+        run: rm -rf ./builds && mkdir ./builds
+
       - name: Download Windows Artifact
         uses: actions/download-artifact@v4
         with:
@@ -580,7 +533,7 @@ jobs:
 
   nightly-release:
     if: ${{ github.event_name == 'schedule' || github.event.inputs.build-target == 'nightly' }}
-    needs: [ build-macos-x64, build-macos-arm64, build-linux-x64, build-linux-arm64, codesign-windows, build-android, e2e-test ]
+    needs: [ build-macos-x64, build-macos-arm64, build-linux-x64, build-linux-arm64, codesign-windows]
     runs-on: ubuntu-22.04
     steps:
       - name: Download MacOS x64 Artifacts
@@ -619,11 +572,11 @@ jobs:
           name: logseq-win64-builds
           path: ./
 
-      - name: Download Android Artifacts
-        uses: actions/download-artifact@v4
-        with:
-          name: logseq-android-builds
-          path: ./
+      # - name: Download Android Artifacts
+      #   uses: actions/download-artifact@v4
+      #   with:
+      #     name: logseq-android-builds
+      #     path: ./
 
       - name: Generate SHA256 checksums
         run: |
@@ -642,7 +595,7 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         with:
           tag_name: nightly
-          name: 'Desktop/Android APP Nightly Release $$'
+          name: 'Desktop app Nightly Release $$'
           draft: false
           prerelease: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.is-pre-release) || (github.event_name == 'schedule')}}
           body: |
@@ -660,7 +613,7 @@ jobs:
   release:
     # NOTE: For now, we only have beta channel to be released on Github
     if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.build-target == 'beta' }}
-    needs: [ build-macos-x64, build-macos-arm64, build-linux-x64, build-linux-arm64, codesign-windows, build-android, e2e-test ]
+    needs: [ build-macos-x64, build-macos-arm64, build-linux-x64, build-linux-arm64, codesign-windows]
     runs-on: ubuntu-22.04
     steps:
       - name: Download MacOS x64 Artifacts
@@ -699,12 +652,12 @@ jobs:
           name: logseq-win64-builds
           path: ./
 
-      - name: Download Android Artifacts
-        uses: actions/download-artifact@v4
-        if: ${{ github.event_name == 'schedule' || github.event.inputs.build-android == 'true' }}
-        with:
-          name: logseq-android-builds
-          path: ./
+      # - name: Download Android Artifacts
+      #   uses: actions/download-artifact@v4
+      #   if: ${{ github.event_name == 'schedule' || github.event.inputs.build-android == 'true' }}
+      #   with:
+      #     name: logseq-android-builds
+      #     path: ./
 
       - name: List files
         run: ls -rl
@@ -734,7 +687,7 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         with:
           tag_name: ${{ steps.ref.outputs.version }}
-          name: Desktop/Android APP ${{ steps.ref.outputs.version }} (Beta Testing)
+          name: Desktop APP ${{ steps.ref.outputs.version }} (Beta Testing)
           body: "TODO: Fill this changelog. Sorry for the inconvenience!"
           draft: ${{ github.event.inputs.is-draft }}
           prerelease: ${{ github.event.inputs.is-pre-release }}

+ 5 - 6
.github/workflows/build-ios-release.yml

@@ -17,13 +17,15 @@ env:
 
 jobs:
   build-app:
-    runs-on: macos-13
+    runs-on: macos-15
     steps:
       - name: Check out Git repository
         uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
         with:
           ref: ${{ github.event.inputs.git-ref }}
-
+      - uses: maxim-lobanov/setup-xcode@v1
+        with:
+          xcode-version: 16.1
       - name: Install Node.js, NPM and Yarn
         uses: actions/setup-node@v3
         with:
@@ -56,14 +58,11 @@ jobs:
           echo "ENABLE_FILE_SYNC_PRODUCTION=true" >> $GITHUB_ENV
 
       - name: Compile CLJS
-        run: yarn install && yarn release-app
+        run: yarn install && yarn release-mobile
         env:
           LOGSEQ_SENTRY_DSN: ${{ secrets.LOGSEQ_SENTRY_DSN }}
           LOGSEQ_POSTHOG_TOKEN: ${{ secrets.LOGSEQ_POSTHOG_TOKEN }}
 
-      - 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
 

+ 2 - 5
.github/workflows/build-ios.yml

@@ -22,7 +22,7 @@ env:
 
 jobs:
   build-app:
-    runs-on: macos-13
+    runs-on: macos-14
     steps:
       - name: Check out Git repository
         uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
@@ -69,10 +69,7 @@ jobs:
           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/
+        run: yarn install && yarn release-mobile
 
       - name: Prepare iOS build
         run: npx cap sync ios

+ 0 - 71
.github/workflows/build-stage.yml

@@ -1,71 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: Build-Stage
-
-on:
-  workflow_dispatch:
-    inputs:
-      git-ref:
-        description: "Release Git Ref (Which branch or tag to build?)"
-        required: true
-        default: "master"
-      cloudflare-project-name:
-        description: "Cloudflare pages project name"
-        required: true
-        default: "logseq-dev"
-
-  release:
-    types: [released]
-
-env:
-  CLOJURE_VERSION: '1.11.1.1413'
-  NODE_VERSION: '20'
-  JAVA_VERSION: '17'
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
-        with:
-          ref: ${{ github.event.inputs.git-ref }}
-
-      - name: Setup Java JDK
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: ${{ env.JAVA_VERSION }}
-
-      - name: Install Node.js, NPM and Yarn
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-
-      - name: Setup clojure
-        uses: DeLaGuardo/[email protected]
-        with:
-          cli: ${{ env.CLOJURE_VERSION }}
-
-      - name: Fetch yarn deps
-        run: yarn cache clean && yarn install --frozen-lockfile
-
-      - name: Set Build Environment Variables
-        run: |
-          echo "ENABLE_FILE_SYNC_PRODUCTION=false" >> $GITHUB_ENV
-
-      - name: Build Released-Web
-        run: |
-          yarn gulp:build && clojure -M:cljs release app  --config-merge '{:compiler-options {:source-map true :source-map-include-sources-content false :source-map-detail-level :symbols}}'
-          rsync -avz --exclude node_modules --exclude android --exclude ios ./static/ ./public/static/
-          ls -lR ./public
-
-      - name: Publish to Cloudflare Pages
-        uses: cloudflare/pages-action@1
-        with:
-          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
-          accountId: 2553ea8236c11ea0f88de28fce1cbfee
-          projectName: ${{ github.event.inputs.cloudflare-project-name || 'logseq-dev' }}
-          directory: 'public'
-          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
-          branch: 'production'

+ 12 - 109
.github/workflows/build.yml

@@ -6,7 +6,7 @@ on:
     paths-ignore:
       - '*.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths-ignore:
       - '*.md'
 
@@ -45,9 +45,7 @@ jobs:
         with:
           node-version: ${{ env.NODE_VERSION }}
           cache: 'yarn'
-          cache-dependency-path: |
-            yarn.lock
-            static/yarn.lock
+          cache-dependency-path: yarn.lock
 
       - name: Set up Java
         uses: actions/setup-java@v3
@@ -112,13 +110,13 @@ jobs:
         run: clojure -M:clj-kondo --parallel --lint src
 
       - name: Carve lint for unused vars
-        run: bb lint:carve 2>/dev/null
+        run: bb lint:carve
 
       - name: Lint for vars that are too large
-        run: bb lint:large-vars 2>/dev/null
+        run: bb lint:large-vars
 
       - name: Lint for namespaces that aren't documented
-        run: bb lint:ns-docstrings 2>/dev/null
+        run: bb lint:ns-docstrings
 
       - name: Lint invalid translation entries
         run: bb lang:validate-translations
@@ -165,115 +163,20 @@ jobs:
         run: cd scripts && yarn install --frozen-lockfile
 
       - name: Create DB graph with properties
-        run: cd scripts && yarn nbb-logseq src/logseq/tasks/db_graph/create_graph_with_properties.cljs ./db-graph-with-props
+        run: cd scripts && yarn nbb-logseq src/logseq/tasks/db_graph/create_graph_with_properties.cljs ./properties-graph
 
       # TODO: Use a smaller, test-focused graph to test classes
       - name: Create DB graph with classes
-        run: cd scripts && yarn nbb-logseq src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs ./db-graph-with-schema
+        run: cd scripts && yarn nbb-logseq src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs ./schema-graph
 
       - name: Fetch deps/db yarn deps
         run: cd deps/db && yarn install --frozen-lockfile
 
       - name: Validate created DB graphs
-        run: cd deps/db && yarn nbb-logseq script/validate_db.cljs ../../scripts/db-graph-with-props ../../scripts/db-graph-with-schema --closed-maps --group-errors
-
-  e2e-test:
-    # TODO: Re-enable when ready to enable tests for file graphs
-    if: false
-    runs-on: ubuntu-22.04
-
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v4
-
-      - name: Set up Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-          cache: 'yarn'
-          cache-dependency-path: |
-            yarn.lock
-            static/yarn.lock
-
-      - name: Set up Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: ${{ env.JAVA_VERSION }}
-
-      - name: Set up Clojure
-        uses: DeLaGuardo/[email protected]
-        with:
-          cli: ${{ env.CLOJURE_VERSION }}
-
-      - name: Clojure cache
-        uses: actions/cache@v3
-        id: clojure-deps
-        with:
-          path: |
-            ~/.m2/repository
-            ~/.gitlibs
-          key: ${{ runner.os }}-clojure-deps-${{ hashFiles('deps.edn') }}
-          restore-keys: ${{ runner.os }}-clojure-deps-
+        run: cd deps/db && yarn nbb-logseq script/validate_db.cljs ../../scripts/properties-graph ../../scripts/schema-graph --closed-maps --group-errors
 
-      - name: Fetch Clojure deps
-        if: steps.clojure-deps.outputs.cache-hit != 'true'
-        run: clojure -A:cljs -P
+      - name: Export a created DB graph
+        run: cd deps/db && yarn nbb-logseq script/export_graph.cljs ../../scripts/properties-graph -f properties.edn -T
 
-      - name: Shadow-cljs cache
-        uses: actions/cache@v3
-        with:
-          path: .shadow-cljs
-          # ensure update cache every time
-          key: ${{ runner.os }}-shadow-cljs-${{ github.sha }}
-          # will match most recent upload
-          restore-keys: |
-            ${{ runner.os }}-shadow-cljs-
-
-      - name: Fetch yarn deps
-        run: yarn install
-        env:
-          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
-
-      # NOTE: require the app to be build in debug mode(compile instead of build).
-      - name: Prepare E2E test build
-        run: |
-          yarn gulp:build && clojure -M:cljs compile app publishing electron
-          (cd static && yarn install && yarn rebuild:all)
-
-      # Exits with 0 if yarn.lock is up to date or 1 if we forgot to update it
-      - name: Ensure static yarn.lock is up to date
-        run: git diff --exit-code static/yarn.lock
-
-      - name: Install Fluxbox
-        run: sudo apt-get update && sudo apt-get install -y fluxbox
-
-      # Emulate a virtual framebuffer on machines with no display hardware
-      - name: Run XVFB
-        run: Xvfb :1 -screen 0 1024x768x24 >/dev/null 2>&1 &
-
-      # Start a lightweight window manager to simulate window actions (maximize,restore etc)
-      - name: Start Fluxbox
-        run:  DISPLAY=:1.0 fluxbox >/dev/null 2>&1 &
-
-      - name: Run Playwright test - 1/2
-        run: DISPLAY=:1.0 npx playwright test --reporter github --shard=1/2
-        env:
-          LOGSEQ_CI: true
-          DEBUG: "pw:api"
-          RELEASE: true # skip dev only test
-
-      - name: Run Playwright test - 2/2
-        run: DISPLAY=:1.0 npx playwright test --reporter github --shard=2/2
-        env:
-          LOGSEQ_CI: true
-          DEBUG: "pw:api"
-          RELEASE: true # skip dev only test
-
-      - name: Save test artifacts
-        if: ${{ failure() }}
-        uses: actions/upload-artifact@v4
-        with:
-          name: e2e-test-report
-          path: e2e-dump/*
-          retention-days: 1
+      - name: Create graph from the export and diff the two graphs
+        run: cd deps/db && yarn nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs ./properties-graph2 properties.edn -iv && yarn nbb-logseq script/diff_graphs.cljs ../../scripts/properties-graph ./properties-graph2 -T

+ 94 - 0
.github/workflows/clj-e2e.yml

@@ -0,0 +1,94 @@
+name: Clojure E2E
+
+on:
+  push:
+    branches: [master]
+    paths:
+      - 'clj-e2e/**'
+      - '.github/workflows/clj-e2e.yml'
+      - src/**
+      - deps/**
+      - packages/**
+  pull_request:
+    branches: [master]
+    paths:
+      - 'clj-e2e/**'
+      - '.github/workflows/clj-e2e.yml'
+      - src/**
+      - deps/**
+      - packages/**
+
+env:
+  CLOJURE_VERSION: '1.11.1.1413'
+  # This is the latest node version we can run.
+  NODE_VERSION: '22'
+  BABASHKA_VERSION: '1.0.168'
+
+jobs:
+  e2e-test-build:
+    name: Test
+    runs-on: ubuntu-22.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Set up Node
+        uses: actions/setup-node@v3
+        with:
+          node-version: ${{ env.NODE_VERSION }}
+          cache: 'yarn'
+          cache-dependency-path: |
+            yarn.lock
+
+      - name: Set up Clojure
+        uses: DeLaGuardo/[email protected]
+        with:
+          cli: ${{ env.CLOJURE_VERSION }}
+          bb: ${{ env.BABASHKA_VERSION }}
+
+      - name: Clojure cache
+        uses: actions/cache@v3
+        id: clojure-deps
+        with:
+          path: |
+            ~/.m2/repository
+            ~/.gitlibs
+          key: ${{ runner.os }}-clojure-deps-${{ hashFiles('deps.edn') }}
+          restore-keys: ${{ runner.os }}-clojure-deps-
+
+      - name: Fetch Clojure deps
+        if: steps.clojure-deps.outputs.cache-hit != 'true'
+        run: clojure -A:cljs -P
+
+      - name: Shadow-cljs cache
+        uses: actions/cache@v3
+        with:
+          path: .shadow-cljs
+          # ensure update cache every time
+          key: ${{ runner.os }}-shadow-cljs-${{ github.sha }}
+          # will match most recent upload
+          restore-keys: |
+            ${{ runner.os }}-shadow-cljs-
+
+      - name: Fetch yarn deps
+        run: yarn install
+        env:
+          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
+
+      # NOTE: require the app to be build with DEV-RELEASE flag
+      - name: Prepare E2E test build
+        run: |
+          yarn gulp:build && clojure -M:cljs release app --config-merge "{:closure-defines {frontend.config/DEV-RELEASE true}}" --debug
+
+      - name: Run e2e tests
+        run: cd clj-e2e && timeout 30m bb dev
+        # env:
+        #   DEBUG: "pw:api"
+
+      - name: Collect screenshots
+        if: ${{ failure() }}
+        uses: actions/upload-artifact@v4
+        with:
+          name: e2e-screenshots
+          path: clj-e2e/e2e-dump/*
+          retention-days: 1

+ 97 - 0
.github/workflows/clj-rtc-e2e.yml

@@ -0,0 +1,97 @@
+name: Clojure RTC E2E
+
+on:
+  push:
+    branches: [master]
+    paths:
+      - 'clj-e2e/**'
+      - '.github/workflows/clj-rtc-e2e.yml'
+      - src/**
+      - deps/**
+      - packages/**
+  pull_request:
+    branches: [master]
+    paths:
+      - 'clj-e2e/**'
+      - '.github/workflows/clj-rtc-e2e.yml'
+      - src/**
+      - deps/**
+      - packages/**
+
+env:
+  CLOJURE_VERSION: '1.11.1.1413'
+  # This is the latest node version we can run.
+  NODE_VERSION: '22'
+  BABASHKA_VERSION: '1.0.168'
+
+jobs:
+  rtc-e2e-test-build:
+    name: Test
+    runs-on: ubuntu-22.04
+    if: "contains(github.event.head_commit.message, 'rtc')"
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Set up Node
+        uses: actions/setup-node@v3
+        with:
+          node-version: ${{ env.NODE_VERSION }}
+          cache: 'yarn'
+          cache-dependency-path: |
+            yarn.lock
+
+      - name: Set up Clojure
+        uses: DeLaGuardo/[email protected]
+        with:
+          cli: ${{ env.CLOJURE_VERSION }}
+          bb: ${{ env.BABASHKA_VERSION }}
+
+      - name: Clojure cache
+        uses: actions/cache@v3
+        id: clojure-deps
+        with:
+          path: |
+            ~/.m2/repository
+            ~/.gitlibs
+          key: ${{ runner.os }}-clojure-deps-${{ hashFiles('deps.edn') }}
+          restore-keys: ${{ runner.os }}-clojure-deps-
+
+      - name: Fetch Clojure deps
+        if: steps.clojure-deps.outputs.cache-hit != 'true'
+        run: clojure -A:cljs -P
+
+      - name: Shadow-cljs cache
+        uses: actions/cache@v3
+        with:
+          path: .shadow-cljs
+          # ensure update cache every time
+          key: ${{ runner.os }}-shadow-cljs-${{ github.sha }}
+          # will match most recent upload
+          restore-keys: |
+            ${{ runner.os }}-shadow-cljs-
+
+      - name: Fetch yarn deps
+        run: yarn install
+        env:
+          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
+
+      # NOTE: require the app to be build with DEV-RELEASE flag
+      - name: Prepare E2E test build
+        run: |
+          yarn gulp:build && clojure -M:cljs release app --config-merge "{:closure-defines {frontend.config/DEV-RELEASE true}}" --debug
+          rsync -avz --exclude node_modules --exclude android --exclude ios ./static/ ./public/
+          ls -lR ./public
+
+      - name: Run e2e tests
+        run: cd clj-e2e && timeout 30m bb run-rtc-extra-test
+        # env:
+        # DEBUG: "pw:api"
+
+      - name: Collect screenshots
+        if: ${{ failure() }}
+        uses: actions/upload-artifact@v4
+        with:
+          name: e2e-screenshots
+          path: clj-e2e/e2e-dump/*
+          retention-days: 1

+ 4 - 4
.github/workflows/db.yml

@@ -9,7 +9,7 @@ on:
       - '.github/workflows/db.yml'
       - '!deps/db/**.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths:
       - 'deps/db/**'
       - '.github/workflows/db.yml'
@@ -86,13 +86,13 @@ jobs:
         run: clojure -M:clj-kondo --lint src test
 
       - name: Carve lint for unused vars
-        run: bb lint:carve 2>/dev/null
+        run: bb lint:carve
 
       - name: Lint for vars that are too large
-        run: bb lint:large-vars 2>/dev/null
+        run: bb lint:large-vars
 
       - name: Lint datalog rules
         run: bb lint:rules
 
       - name: Lint for namespaces that aren't documented
-        run: bb lint:ns-docstrings 2>/dev/null
+        run: bb lint:ns-docstrings

+ 0 - 70
.github/workflows/deploy-db-pages.yml

@@ -1,70 +0,0 @@
-name: Deploy DB Version to Cloud
-
-on:
-  push:
-    branches: ["feat/db"]
-
-env:
-  CLOJURE_VERSION: "1.11.1.1413"
-  NODE_VERSION: '20'
-  JAVA_VERSION: "11"
-
-jobs:
-  build-and-deploy:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: Setup Java JDK
-        uses: actions/setup-java@v3
-        with:
-          distribution: "zulu"
-          java-version: ${{ env.JAVA_VERSION }}
-
-      - name: Set up Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-
-      - name: Setup clojure
-        uses: DeLaGuardo/[email protected]
-        with:
-          cli: ${{ env.CLOJURE_VERSION }}
-
-      - name: Fetch yarn deps
-        run: yarn install --frozen-lockfile
-
-      - name: Set Build Environment Variables
-        run: |
-          echo "ENABLE_FILE_SYNC_PRODUCTION=false" >> $GITHUB_ENV
-
-      - name: Build Released-Web
-        run: |
-          yarn gulp:build && clojure -M:cljs release app  --config-merge '{:compiler-options {:source-map-include-sources-content true :source-map-detail-level :symbols}}'
-          rsync -avz --exclude node_modules --exclude android --exclude ios ./static/ ./public/static/
-          ls -lR ./public && mkdir r2 && mv ./public/static/js/main.js.map ./r2/db-demo.main.js.map
-          sed -i 's/=main.js.map/=https:\/\/assets.logseq.io\/db-demo.main.js.map/g' ./public/static/js/main.js
-        env:
-          LOGSEQ_SENTRY_DSN: ${{ secrets.LOGSEQ_SENTRY_DSN }}
-          LOGSEQ_POSTHOG_TOKEN: ${{ secrets.LOGSEQ_POSTHOG_TOKEN }}
-
-      - name: Upload to R2
-        uses: ryand56/r2-upload-action@latest
-        with:
-          r2-account-id: 2553ea8236c11ea0f88de28fce1cbfee
-          r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
-          r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
-          r2-bucket: ${{ secrets.R2_ASSETS_BUCKET }}
-          source-dir: r2
-          destination-dir: ./
-
-      - name: Publish to Cloudflare Pages
-        uses: cloudflare/pages-action@1
-        with:
-          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
-          accountId: 2553ea8236c11ea0f88de28fce1cbfee
-          projectName: "logseq-db-demo"
-          directory: "public"
-          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
-          branch: "main"

+ 4 - 4
.github/workflows/deploy-db-test-pages.yml

@@ -6,7 +6,7 @@ on:
 
 env:
   CLOJURE_VERSION: "1.11.1.1413"
-  NODE_VERSION: '20'
+  NODE_VERSION: '22'
   JAVA_VERSION: "11"
 
 jobs:
@@ -43,9 +43,9 @@ jobs:
       - name: Build Released-Web
         run: |
           yarn gulp:build && clojure -M:cljs release app  --config-merge '{:compiler-options {:source-map true :source-map-include-sources-content true :source-map-detail-level :symbols}}'
-          rsync -avz --exclude node_modules --exclude android --exclude ios ./static/ ./public/static/
-          ls -lR ./public && mkdir r2 && mv ./public/static/js/main.js.map ./r2/db-test.main.js.map
-          sed -i 's/=main.js.map/=https:\/\/assets.logseq.io\/db-test.main.js.map/g' ./public/static/js/main.js
+          rsync -avz --exclude node_modules --exclude android --exclude ios ./static/ ./public/
+          ls -lR ./public && mkdir r2 && mv ./public/js/main.js.map ./r2/db-test.main.js.map
+          sed -i 's/=main.js.map/=https:\/\/assets.logseq.io\/db-test.main.js.map/g' ./public/js/main.js
         env:
           LOGSEQ_SENTRY_DSN: ${{ secrets.LOGSEQ_SENTRY_DSN }}
           LOGSEQ_POSTHOG_TOKEN: ${{ secrets.LOGSEQ_POSTHOG_TOKEN }}

+ 0 - 165
.github/workflows/e2e.yml

@@ -1,165 +0,0 @@
-name: E2E
-
-# Running E2E test multiple times to confirm test stability.
-# E2E test could be randomly failed due to the batch update mechanism of React.
-# Robust E2E test could help improving dev experience.
-
-on:
-  push:
-    branches: [master]
-    paths:
-      - 'e2e-tests/**'
-  # TODO: Re-enable when ready to enable tests for file graphs
-  # pull_request:
-  #   branches: [master]
-  #   paths:
-  #     - 'e2e-tests/**'
-
-env:
-  CLOJURE_VERSION: '1.11.1.1413'
-  JAVA_VERSION: '11'
-  # This is the latest node version we can run.
-  NODE_VERSION: '20'
-  BABASHKA_VERSION: '1.0.168'
-
-jobs:
-  e2e-test-build:
-    name: Build Test Artifact
-    runs-on: ubuntu-22.04
-    steps:
-      - name: Checkout
-        uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
-
-      - name: Set up Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-          cache: 'yarn'
-          cache-dependency-path: |
-            yarn.lock
-            static/yarn.lock
-
-      - name: Set up Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: ${{ env.JAVA_VERSION }}
-
-      - name: Set up Clojure
-        uses: DeLaGuardo/[email protected]
-        with:
-          cli: ${{ env.CLOJURE_VERSION }}
-
-      - name: Clojure cache
-        uses: actions/cache@v3
-        id: clojure-deps
-        with:
-          path: |
-            ~/.m2/repository
-            ~/.gitlibs
-          key: ${{ runner.os }}-clojure-deps-${{ hashFiles('deps.edn') }}
-          restore-keys: ${{ runner.os }}-clojure-deps-
-
-      - name: Fetch Clojure deps
-        if: steps.clojure-deps.outputs.cache-hit != 'true'
-        run: clojure -A:cljs -P
-
-      - name: Shadow-cljs cache
-        uses: actions/cache@v3
-        with:
-          path: .shadow-cljs
-          # ensure update cache every time
-          key: ${{ runner.os }}-shadow-cljs-${{ github.sha }}
-          # will match most recent upload
-          restore-keys: |
-            ${{ runner.os }}-shadow-cljs-
-
-      - name: Fetch yarn deps
-        run: yarn install
-        env:
-          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
-
-      # NOTE: require the app to be build with DEV-RELEASE flag
-      - name: Prepare E2E test build
-        run: |
-          yarn gulp:build && clojure -M:cljs release app electron --config-merge "{:closure-defines {frontend.config/DEV-RELEASE true}}" --debug
-
-      # NOTE: should include .shadow-cljs if in dev mode(compile)
-      - name: Create Archive for build
-        run: tar czf static.tar.gz static
-
-      - name: Upload Artifact
-        uses: actions/upload-artifact@v4
-        with:
-          name: logseq-e2e-artifact
-          path: static.tar.gz
-          retention-days: 1
-
-  e2e-test-run:
-    needs: [ e2e-test-build ]
-    name: Test Shard ${{ matrix.shard }} Repeat ${{ matrix.repeat }}
-    runs-on: ubuntu-22.04
-    strategy:
-      matrix:
-        repeat: [1, 2]
-        shard: [1, 2, 3]
-
-    steps:
-      - name: Repeat message
-        run: echo ::info title=StartUp::E2E testing shard ${{ matrix.shard}}/3 repeat ${{ matrix.repeat }}
-
-      - name: Checkout
-        uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c  # v3.3.0
-
-      - name: Download test build artifact
-        uses: actions/download-artifact@v4
-        with:
-          name: logseq-e2e-artifact
-
-      - name: Extract test Artifact
-        run: tar xzf static.tar.gz
-
-      - name: Set up Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-          cache: 'yarn'
-          cache-dependency-path: |
-            yarn.lock
-            static/yarn.lock
-
-      - name: Fetch yarn deps for E2E test
-        run: |
-          yarn install
-          (cd static && yarn install && yarn rebuild:all)
-        env:
-          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
-
-      - name: Ensure static yarn.lock is up to date
-        run: git diff --exit-code static/yarn.lock
-
-      - name: Install Fluxbox
-        run: sudo apt-get update && sudo apt-get install -y fluxbox
-
-      # Emulate a virtual framebuffer on machines with no display hardware
-      - name: Run XVFB
-        run: Xvfb :1 -screen 0 1024x768x24 >/dev/null 2>&1 &
-
-      # Start a lightweight window manager to simulate window actions (maximize,restore etc)
-      - name: Start Fluxbox
-        run:  DISPLAY=:1.0 fluxbox >/dev/null 2>&1 &
-
-      - name: Run Playwright test
-        run: DISPLAY=:1.0 npx playwright test --reporter github --shard=${{ matrix.shard }}/3
-        env:
-          LOGSEQ_CI: true
-          DEBUG: "pw:api"
-          RELEASE: true # skip dev only test
-
-      - name: Save e2e artifacts
-        if: ${{ failure() }}
-        uses: actions/upload-artifact@v4
-        with:
-          name: e2e-repeat-report-${{ matrix.shard}}-${{ matrix.repeat }}
-          path: e2e-dump/*
-          retention-days: 1

+ 5 - 5
.github/workflows/graph-parser.yml

@@ -12,7 +12,7 @@ on:
       - '.github/workflows/graph-parser.yml'
       - '!deps/graph-parser/**.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths:
       - 'deps/graph-parser/**'
       - 'deps/db/**'
@@ -76,7 +76,7 @@ jobs:
         run: yarn install --frozen-lockfile
 
       - name: Run ClojureScript tests
-        run: clojure -M:test
+        run: REPEATABLE_IDENTS=true clojure -M:test
 
       - name: Run nbb-logseq tests
         run: yarn test
@@ -108,10 +108,10 @@ jobs:
         run: clojure -M:clj-kondo --parallel --lint src test
 
       - name: Carve lint for unused vars
-        run: bb lint:carve 2>/dev/null
+        run: bb lint:carve
 
       - name: Lint for vars that are too large
-        run: bb lint:large-vars 2>/dev/null
+        run: bb lint:large-vars
 
       - name: Lint for namespaces that aren't documented
-        run: bb lint:ns-docstrings 2>/dev/null
+        run: bb lint:ns-docstrings

+ 1 - 1
.github/workflows/logseq-common.yml

@@ -9,7 +9,7 @@ on:
       - '.github/workflows/logseq-common.yml'
       - '!deps/common/**.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths:
       - 'deps/common/**'
       - '.github/workflows/logseq-common.yml'

+ 2 - 2
.github/workflows/outliner.yml

@@ -12,7 +12,7 @@ on:
       - '.github/workflows/outliner.yml'
       - '!deps/outliner/**.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths:
       - 'deps/outliner/**'
       - 'deps/db/**'
@@ -28,7 +28,7 @@ env:
   # This is the same as 1.8.
   JAVA_VERSION: '11'
   # This is the latest node version we can run.
-  NODE_VERSION: '20'
+  NODE_VERSION: '22'
   BABASHKA_VERSION: '1.0.168'
 
 jobs:

+ 1 - 1
.github/workflows/publishing.yml

@@ -12,7 +12,7 @@ on:
       - '.github/workflows/publishing.yml'
       - '!deps/publishing/**.md'
   pull_request:
-    branches: [master, "feat/db"]
+    branches: [master]
     paths:
       - 'deps/publishing/**'
       - 'deps/db/**'

+ 7 - 3
.gitignore

@@ -1,4 +1,3 @@
-/e2e-dump
 /target
 /classes
 /checkouts
@@ -15,7 +14,6 @@ pom.xml.asc
 
 node_modules/
 static/**
-!static/yarn.lock
 tmp
 cljs-test-runner-out
 
@@ -49,6 +47,7 @@ charlie/
 docker
 android/app/src/main/assets/capacitor.plugin.json
 ios/App/App/capacitor.config.json
+ios/App/App/public
 
 startup.png
 
@@ -59,7 +58,7 @@ startup.png
 android/app/src/main/assets/capacitor.config.json
 
 *.sublime-*
-/public/static
+/public
 .yarn/
 .yarnrc.yml
 
@@ -68,3 +67,8 @@ deps/shui/.lsp
 deps/shui/.lsp-cache
 deps/shui/.clj-kondo
 tx-log*
+clj-e2e/.wally
+clj-e2e/resources
+clj-e2e/e2e-dump
+.dir-locals.el
+.projectile

+ 4 - 1
.projectile

@@ -11,7 +11,10 @@
 -/resources/static/js/katex.min.js
 -/resources/static/js/mhchem.min.js
 -/resources/static/js/mldoc.min.js
--/resources/static/js/reveal.js
 -/resources/static/js/sci.min.js
 -/resources/static/js/excalidraw.min.js
 -/resources/static/js/react-force-graph.min.js
+-/resources/js/lsplugin.user.js
+-/resources/js/pdf_viewer2.js
+-/deps/graph-parser/test/resources/
+-/ios/App/App/public

+ 2 - 1
CODEBASE_OVERVIEW.md

@@ -52,6 +52,7 @@ This is overview of this repository's most important directories and files.
     - `src/main/frontend/worker/` contains code for the separate worker asset.
     - `src/main/frontend/common/` contains common code shared by the worker asset and the frontend.
   - `src/main/logseq/` contains the api used by plugins.
+  - `src/main/mobile/` contains code for new mobile app.
   - `src/dev-cljs/` contains some development utilities.
 
 - `deps/` contains ClojureScript dependencies or libraries used by the frontend.
@@ -61,7 +62,7 @@ This is overview of this repository's most important directories and files.
   - `packages/ui/` - The frontend's component system based on shadcn
   - `packags/tldraw/` - Custom fork of tldraw which powers whiteboards
 - `scripts` - Dev scripts
-- `e2e-tests/` - end to end frontend tests
+- `clj-e2e/` - end to end clj frontend tests
 - `android/` -  Android app
 - `ios/` - iOS app
 

+ 14 - 0
README.md

@@ -54,6 +54,7 @@
 
 ## Table of Contents
 
+  * [<g-emoji class="g-emoji" alias="database" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png">🚀</g-emoji> Database Version](#-database-version)
   * [<g-emoji class="g-emoji" alias="thinking" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f914.png">🤔</g-emoji> Why Logseq?](#-why-logseq)
   * [<g-emoji class="g-emoji" alias="eyes" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f440.png">👀</g-emoji> How can I use it?](#-how-can-i-use-it)
   * [<g-emoji class="g-emoji" alias="books" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f4da.png">📚</g-emoji> Learn more](#-learn-more)
@@ -65,6 +66,19 @@
   * [<g-emoji class="g-emoji" alias="sparkles" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2728.png">✨</g-emoji> Inspiration](#-inspiration)
 * [<g-emoji class="g-emoji" alias="pray" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f64f.png">🙏</g-emoji> Thank You](#-thank-you)
 
+## 🚀 Database Version
+
+The Database version (DB version) of Logseq introduces DB graphs while maintaining support for file graphs. [See this page](https://github.com/logseq/docs/blob/master/db-version.md) to get an overview of the main features for DB graphs. If you are an existing user, [see changes with the DB version](https://github.com/logseq/docs/blob/master/db-version-changes.md). The DB version has its own new mobile app! To participate in the mobile app alpha, [please complete this brief form](https://forms.gle/nfefJv51jUuULbFB9). The DB version also has a new sync approach, RTC (Real Time Collaboration)! You can use it to sync graphs between multiple devices or collaborate with others. To participate in the RTC alpha, [please fill out this form](https://forms.gle/YSyF4WfKPSDuwyjH6).
+
+The DB version is in beta status while the new mobile app and RTC is in alpha. This means that **data loss is possible** so we recommend [automated backups](https://github.com/logseq/docs/blob/master/db-version.md#automated-backup) or [regular SQLite DB backups](https://github.com/logseq/docs/blob/master/db-version.md#graph-export). When using DB graphs, we recommend you create a dedicated test graph and choose one project that’s not crucial for you. When using file graphs, **data corruption is possible** as some file content can be duplicated. We only recommend using it with file graphs if you make regular backups with git.
+
+To get started with the DB version:
+* To try the latest web version, go to https://test.logseq.com/.
+* To try the latest desktop version, go to https://github.com/logseq/logseq/actions/workflows/build-desktop-release.yml and click on the latest release. Scroll to the bottom and under the `Artifacts` section download the artifact for your operating system.
+* To report bugs, please file them at https://github.com/logseq/db-test/issues.
+* For feature or enhancement requests, please file them on Discord on the `#db-feedback` channel.
+* For discussion, see the `#db-chat` channel in Discord.
+
 ## 🤔 Why Logseq?
 
 [Logseq](https://logseq.com) is a **knowledge management** and **collaboration** platform. It focuses on **privacy**, **longevity**, and [**user control**](https://www.gnu.org/philosophy/free-sw.en.html). Logseq offers a range of **powerful tools** for **knowledge management**, **collaboration**, **PDF annotation**, and **task management** with support for multiple file formats, including **Markdown** and **Org-mode**, and **various features** for organizing and structuring your notes.

+ 13 - 8
android/app/build.gradle

@@ -1,5 +1,8 @@
 apply plugin: 'com.android.application'
 
+apply from: 'capacitor.build.gradle'
+apply plugin: 'kotlin-android'
+
 android {
     namespace "com.logseq.app"
     compileSdkVersion rootProject.ext.compileSdkVersion
@@ -7,12 +10,12 @@ android {
         applicationId "com.logseq.app"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
-        versionCode 84
-        versionName "0.10.10"
+        versionCode 87
+        versionName "0.11.0"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         aaptOptions {
-             // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
-             // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
+            // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
+            // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
             ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
         }
     }
@@ -22,10 +25,14 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+
+    kotlinOptions {
+        jvmTarget = '21'
+    }
 }
 
 repositories {
-    flatDir{
+    flatDir {
         dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
     }
 }
@@ -43,13 +50,11 @@ dependencies {
     implementation project(':capacitor-cordova-android-plugins')
 }
 
-apply from: 'capacitor.build.gradle'
-
 try {
     def servicesJSON = file('google-services.json')
     if (servicesJSON.text) {
         apply plugin: 'com.google.gms.google-services'
     }
-} catch(Exception e) {
+} catch (Exception e) {
     logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
 }

+ 7 - 6
android/app/capacitor.build.gradle

@@ -1,14 +1,15 @@
 // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
 
 android {
-  compileOptions {
-      sourceCompatibility JavaVersion.VERSION_17
-      targetCompatibility JavaVersion.VERSION_17
-  }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_21
+        targetCompatibility JavaVersion.VERSION_21
+    }
 }
 
 apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
 dependencies {
+    implementation 'androidx.core:core-ktx:1.16.0'
     implementation project(':capacitor-action-sheet')
     implementation project(':capacitor-app')
     implementation project(':capacitor-camera')
@@ -21,13 +22,13 @@ dependencies {
     implementation project(':capacitor-status-bar')
     implementation project(':capawesome-capacitor-background-task')
     implementation project(':capgo-capacitor-navigation-bar')
-    implementation project(':logseq-capacitor-file-sync')
     implementation project(':capacitor-voice-recorder')
     implementation project(':send-intent')
+    implementation project(':jcesarmobile-ssl-skip')
 
 }
 
 
 if (hasProperty('postBuildExtras')) {
-  postBuildExtras()
+    postBuildExtras()
 }

+ 3 - 8
android/app/src/main/AndroidManifest.xml

@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8" ?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
-
     <!-- Permissions -->
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
@@ -12,6 +11,7 @@
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
     <application
+        android:networkSecurityConfig="@xml/network_security_config"
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
@@ -19,7 +19,6 @@
         android:supportsRtl="true"
         android:requestLegacyExternalStorage="true"
         android:theme="@style/AppTheme">
-
         <activity
             android:exported="true"
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation"
@@ -27,7 +26,6 @@
             android:label="@string/title_activity_main"
             android:theme="@style/AppTheme.NoActionBarLaunch"
             android:launchMode="singleTask">
-
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -48,7 +46,6 @@
                 <category android:name="android.intent.category.BROWSABLE" />
                 <data android:scheme="logseq" />
             </intent-filter>
-
         </activity>
 
         <provider
@@ -56,9 +53,7 @@
             android:authorities="${applicationId}.fileprovider"
             android:exported="false"
             android:grantUriPermissions="true">
-            <meta-data
-                android:name="android.support.FILE_PROVIDER_PATHS"
-                android:resource="@xml/file_paths" />
+            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
         </provider>
     </application>
 </manifest>

+ 4 - 4
android/app/src/main/assets/capacitor.plugins.json

@@ -47,10 +47,6 @@
 		"pkg": "@capgo/capacitor-navigation-bar",
 		"classpath": "ee.forgr.capacitor_navigation_bar.NavigationBarPlugin"
 	},
-	{
-		"pkg": "@logseq/capacitor-file-sync",
-		"classpath": "com.logseq.app.filesync.FileSyncPlugin"
-	},
 	{
 		"pkg": "capacitor-voice-recorder",
 		"classpath": "com.tchvu3.capacitorvoicerecorder.VoiceRecorder"
@@ -58,5 +54,9 @@
 	{
 		"pkg": "send-intent",
 		"classpath": "de.mindlib.sendIntent.SendIntent"
+	},
+	{
+		"pkg": "@jcesarmobile/ssl-skip",
+		"classpath": "com.jcesarmobile.sslskip.SslSkipPlugin"
 	}
 ]

+ 2 - 4
android/app/src/main/java/com/logseq/app/MainActivity.java

@@ -13,7 +13,8 @@ public class MainActivity extends BridgeActivity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         registerPlugin(FolderPicker.class);
-        registerPlugin(FsWatcher.class);
+        registerPlugin(UILocal.class);
+
         super.onCreate(savedInstanceState);
 
         new Timer().schedule(new TimerTask() {
@@ -27,7 +28,6 @@ public class MainActivity extends BridgeActivity {
                 });
             }
         }, 5000);
-
     }
 
     @Override
@@ -51,6 +51,4 @@ public class MainActivity extends BridgeActivity {
             });
         }
     }
-
-
 }

+ 88 - 0
android/app/src/main/java/com/logseq/app/UILocal.kt

@@ -0,0 +1,88 @@
+package com.logseq.app
+
+import android.app.AlertDialog
+import android.app.DatePickerDialog
+import android.os.Build
+import android.view.View
+import android.view.ViewGroup
+import android.widget.DatePicker
+import android.widget.FrameLayout
+import androidx.annotation.RequiresApi
+import com.getcapacitor.JSObject
+import com.getcapacitor.Plugin
+import com.getcapacitor.PluginCall
+import com.getcapacitor.PluginMethod
+import com.getcapacitor.annotation.CapacitorPlugin
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+@CapacitorPlugin(name = "UILocal")
+class UILocal : Plugin() {
+
+  @RequiresApi(Build.VERSION_CODES.O)
+  @PluginMethod
+  fun showDatePicker(call: PluginCall) {
+    val defaultDate = call.getString("defaultDate")
+    val calendar = Calendar.getInstance()
+
+    if (defaultDate.isNullOrEmpty()) {
+      try {
+        val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
+        val date = defaultDate?.let { sdf.parse(it) }
+        if (date != null) {
+          calendar.time = date
+        }
+      } catch (e: Exception) {
+        call.reject("Invalid default date format. Use YYYY-MM-DD", e)
+        return
+      }
+    }
+
+    val year = calendar.get(Calendar.YEAR)
+    val month = calendar.get(Calendar.MONTH)
+    val day = calendar.get(Calendar.DAY_OF_MONTH)
+
+    // create date picker dialog
+    val datePickerDialog = DatePickerDialog(
+      activity,
+      null,
+      year, month, day
+    )
+
+    datePickerDialog.datePicker.setOnDateChangedListener { _, selectedYear: Int, selectedMonth: Int, selectedDay: Int ->
+      // format selected date
+      val selectedDate = Calendar.getInstance().apply {
+        set(selectedYear, selectedMonth, selectedDay)
+      }
+
+      val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
+      val formattedDate = sdf.format(selectedDate.time)
+
+      // return to js
+      val res = JSObject()
+      res.put("value", formattedDate)
+      call.resolve(res)
+
+      // close dialog
+      datePickerDialog.dismiss()
+    }
+
+    datePickerDialog.setOnShowListener {
+      val parent = datePickerDialog.getButton(DatePickerDialog.BUTTON_POSITIVE).parent.parent
+      if (parent is ViewGroup) {
+        parent.visibility = View.GONE
+      }
+    }
+
+    if (call.getBoolean("restrictFuture", false) == true) {
+      datePickerDialog.datePicker.maxDate = System.currentTimeMillis()
+    }
+
+    try {
+      datePickerDialog.show()
+    } catch (e: Exception) {
+      call.reject("Error showing date picker", e)
+    }
+  }
+}

二进制
android/app/src/main/res/drawable-land-hdpi/splash.png


二进制
android/app/src/main/res/drawable-land-ldpi/splash.png


二进制
android/app/src/main/res/drawable-land-mdpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-hdpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-ldpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-mdpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-xhdpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-xxhdpi/splash.png


二进制
android/app/src/main/res/drawable-land-night-xxxhdpi/splash.png


二进制
android/app/src/main/res/drawable-land-xhdpi/splash.png


二进制
android/app/src/main/res/drawable-land-xxhdpi/splash.png


二进制
android/app/src/main/res/drawable-land-xxxhdpi/splash.png


二进制
android/app/src/main/res/drawable-night/splash.png


二进制
android/app/src/main/res/drawable-port-hdpi/splash.png


二进制
android/app/src/main/res/drawable-port-ldpi/splash.png


二进制
android/app/src/main/res/drawable-port-mdpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-hdpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-ldpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-mdpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-xhdpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-xxhdpi/splash.png


二进制
android/app/src/main/res/drawable-port-night-xxxhdpi/splash.png


二进制
android/app/src/main/res/drawable-port-xhdpi/splash.png


二进制
android/app/src/main/res/drawable-port-xxhdpi/splash.png


二进制
android/app/src/main/res/drawable-port-xxxhdpi/splash.png


二进制
android/app/src/main/res/drawable/splash.png


+ 7 - 4
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@color/ic_launcher_background"/>
-    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-    <monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
-</adaptive-icon>
+    <background>
+        <inset android:drawable="@mipmap/ic_launcher_background" android:inset="16.7%" />
+    </background>
+    <foreground>
+        <inset android:drawable="@mipmap/ic_launcher_foreground" android:inset="16.7%" />
+    </foreground>
+</adaptive-icon>

+ 6 - 3
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@color/ic_launcher_background"/>
-    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-    <monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
+    <background>
+        <inset android:drawable="@mipmap/ic_launcher_background" android:inset="16.7%" />
+    </background>
+    <foreground>
+        <inset android:drawable="@mipmap/ic_launcher_foreground" android:inset="16.7%" />
+    </foreground>
 </adaptive-icon>

二进制
android/app/src/main/res/mipmap-hdpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png


二进制
android/app/src/main/res/mipmap-ldpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-ldpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-ldpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png


二进制
android/app/src/main/res/mipmap-mdpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png


二进制
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


二进制
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


二进制
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


二进制
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png


二进制
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png


二进制
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 29 - 0
android/app/src/main/res/raw/logseq_local.pem

@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE+zCCA2OgAwIBAgIQTfWeF1QJkSfpzuDXGxklNTANBgkqhkiG9w0BAQsFADCB
+lTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTUwMwYDVQQLDCxjaGFy
+bGllQENoYXJsaWVzLU1hY0Jvb2stUHJvLmxvY2FsIChDaGFybGllKTE8MDoGA1UE
+AwwzbWtjZXJ0IGNoYXJsaWVAQ2hhcmxpZXMtTWFjQm9vay1Qcm8ubG9jYWwgKENo
+YXJsaWUpMB4XDTI1MDQwODAzMDQwM1oXDTM1MDQwODAzMDQwM1owgZUxHjAcBgNV
+BAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE1MDMGA1UECwwsY2hhcmxpZUBDaGFy
+bGllcy1NYWNCb29rLVByby5sb2NhbCAoQ2hhcmxpZSkxPDA6BgNVBAMMM21rY2Vy
+dCBjaGFybGllQENoYXJsaWVzLU1hY0Jvb2stUHJvLmxvY2FsIChDaGFybGllKTCC
+AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALtxgIn34fnuZu70fN5hT0rE
+T2PJDhJV9w5uFIYDEIprWf5jP9/bXeFJEYc6zhzk/lcFJtnPUkJVqYskNQEKEFmn
+nR5KhFbFfSD4jhw1/TSdgPy1RPDbLvuZzG7diox6YYu7cdrmgul0svnMoC95rlW+
+i86We1i3cR9TNSKK2NWwJubnqE3HEVLhRJOFEuLwj/BT+F9hKa+VVhrEY7cFQyBt
+Zr5Uoqxdhs0wMzp/RXruAVQzP7X3CEUiZ1uudFcquveq+gfGe0u852TPTsND0Ujc
+0UTI1GhT1Pxsrk64EkN1INwGCf5yFRiLXH6HHmMJ+dX/c8gOTC7xgEfAZt8NanBV
+dWjbLRbWEXF0OwmPMqnyxkOWxJI97XSokv9ytvM7jO9QOW6Dg+i8BPrgTWMXF+PI
+E34JAD3M1czrhMMwJZHCCHBLVXa8l7VXaQ5DJ3VQ8nU6bVubptDeG4rwqz3nKlIa
+wTULqteFolkCPeZE+VHdDEsAI/gXoDRE3wwOove4AwIDAQABo0UwQzAOBgNVHQ8B
+Af8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlcxmwwnvSm6A
+rd7inGI2JRe0Ca4wDQYJKoZIhvcNAQELBQADggGBAKzy5396m1qr7XJ66pjvQxWy
+bb4/eF0ldBrvOXjktjvDdrCnFMSTwliJp8XJq4ps1zBzRX1TjPOJCVPHzJ4o7eWN
+8rc2m+7w6/CaRb5SJ26fAw3LHodM0glKtmSw7RTafSQRh1mnmxfMJ8SjYNy+9QVK
+w3HNUcQe2HcAd+TmIMZVJLRX14g68OOLSOiOl2vZreVRbWPTcwqnvBtbw82ZgSaB
+NN9fgnoOcb8odQsov3mY07RR1KpSs3g1aGuncNco47fACY9xVVoeJAzCWMBJF7SI
+UpHRDX94OLs5Etk+SmCJ7L/nS3qT8bnKHZ4gycCPRoG01Lcf+BXNoPykkx2z8mEK
+JkXj+s85cykTNBOUY9a+bDr2qrynCsiaSXkGtyWSgdbAR7HHSOWIZX216aaTKdmm
+gt5r1+ZK0qcYx6SR8qvdJN+7WY+apQA1Z9kV3fMrHVnCxR8zp8Vjmk0R1TsV6uxi
+VGo45tVFDtL0EajZ7yxif/v29fs7/VtV8tXPytMzkQ==
+-----END CERTIFICATE-----

+ 16 - 0
android/app/src/main/res/xml/network_security_config.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config cleartextTrafficPermitted="true">
+        <domain includeSubdomains="true">logseq.local</domain>
+        <trust-anchors>
+            <certificates src="@raw/logseq_local" />
+        </trust-anchors>
+    </domain-config>
+    <!-- 如果需要允许所有域名(仅用于调试,生产环境不推荐) -->
+    <base-config cleartextTrafficPermitted="true">
+        <trust-anchors>
+            <certificates src="system" />
+            <certificates src="user" />
+        </trust-anchors>
+    </base-config>
+</network-security-config>

+ 6 - 2
android/build.gradle

@@ -2,14 +2,18 @@
 
 buildscript {
     
+    ext {
+        kotlin_version = '2.1.21'
+    }
     repositories {
         google()
         jcenter()
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:8.1.1'
-        classpath 'com.google.gms:google-services:4.3.15'
+        classpath 'com.android.tools.build:gradle:8.7.2'
+        classpath 'com.google.gms:google-services:4.4.2'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files

+ 3 - 3
android/capacitor.settings.gradle

@@ -38,11 +38,11 @@ project(':capawesome-capacitor-background-task').projectDir = new File('../node_
 include ':capgo-capacitor-navigation-bar'
 project(':capgo-capacitor-navigation-bar').projectDir = new File('../node_modules/@capgo/capacitor-navigation-bar/android')
 
-include ':logseq-capacitor-file-sync'
-project(':logseq-capacitor-file-sync').projectDir = new File('../node_modules/@logseq/capacitor-file-sync/android')
-
 include ':capacitor-voice-recorder'
 project(':capacitor-voice-recorder').projectDir = new File('../node_modules/capacitor-voice-recorder/android')
 
 include ':send-intent'
 project(':send-intent').projectDir = new File('../node_modules/send-intent/android')
+
+include ':jcesarmobile-ssl-skip'
+project(':jcesarmobile-ssl-skip').projectDir = new File('../node_modules/@jcesarmobile/ssl-skip/android')

二进制
android/gradle/wrapper/gradle-wrapper.jar


+ 3 - 1
android/gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
+networkTimeout=10000
+validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists

+ 31 - 13
android/gradlew

@@ -15,6 +15,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+# SPDX-License-Identifier: Apache-2.0
+#
 
 ##############################################################################
 #
@@ -55,7 +57,7 @@
 #       Darwin, MinGW, and NonStop.
 #
 #   (3) This script is generated from the Groovy template
-#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 #       within the Gradle project.
 #
 #       You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
     esac
 done
 
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
+# This is normally unused
+# shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
@@ -133,22 +134,29 @@ location of your Java installation."
     fi
 else
     JAVACMD=java
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
+    fi
 fi
 
 # Increase the maximum file descriptors if we can.
 if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
     case $MAX_FD in #(
       max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
         MAX_FD=$( ulimit -H -n ) ||
             warn "Could not query maximum file descriptor limit"
     esac
     case $MAX_FD in  #(
       '' | soft) :;; #(
       *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
         ulimit -n "$MAX_FD" ||
             warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
@@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
     done
 fi
 
-# Collect all arguments for the java command;
-#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-#     shell script including quotes and variable substitutions, so put them in
-#     double quotes to make sure that they get re-expanded; and
-#   * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +217,12 @@ set -- \
         org.gradle.wrapper.GradleWrapperMain \
         "$@"
 
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
 # Use "xargs" to parse quoted args.
 #
 # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

+ 21 - 16
android/gradlew.bat

@@ -13,8 +13,10 @@
 @rem See the License for the specific language governing permissions and
 @rem limitations under the License.
 @rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
 
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
 @rem ##########################################################################
 @rem
 @rem  Gradle startup script for Windows
@@ -25,7 +27,8 @@
 if "%OS%"=="Windows_NT" setlocal
 
 set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
 set APP_BASE_NAME=%~n0
 set APP_HOME=%DIRNAME%
 
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
 
 set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
 
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
 if exist "%JAVA_EXE%" goto execute
 
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
 :end
 @rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
 
 :fail
 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
 rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
 
 :mainEnd
 if "%OS%"=="Windows_NT" endlocal

+ 11 - 11
android/variables.gradle

@@ -1,16 +1,16 @@
 ext {
-    minSdkVersion = 22
-    compileSdkVersion = 33
-    targetSdkVersion = 33
-    androidxActivityVersion = '1.7.0'
-    androidxAppCompatVersion = '1.6.1'
+    minSdkVersion = 23
+    compileSdkVersion = 35
+    targetSdkVersion = 35
+    androidxActivityVersion = '1.9.2'
+    androidxAppCompatVersion = '1.7.0'
     androidxCoordinatorLayoutVersion = '1.2.0'
-    androidxCoreVersion = '1.10.0'
-    androidxFragmentVersion = '1.5.6'
+    androidxCoreVersion = '1.15.0'
+    androidxFragmentVersion = '1.8.4'
     junitVersion = '4.13.2'
-    androidxJunitVersion = '1.1.5'
-    androidxEspressoCoreVersion = '3.5.1'
+    androidxJunitVersion = '1.2.1'
+    androidxEspressoCoreVersion = '3.6.1'
     cordovaAndroidVersion = '10.1.1'
-    coreSplashScreenVersion = '1.0.0'
-    androidxWebkitVersion = '1.6.1'
+    coreSplashScreenVersion = '1.0.1'
+    androidxWebkitVersion = '1.12.1'
 }

二进制
assets/icon.png


二进制
assets/splash.png


+ 13 - 1
bb.edn

@@ -2,7 +2,7 @@
  :deps
  {metosin/malli
   {:mvn/version "0.16.1"}
-  borkdude/rewrite-edn {:mvn/version "0.4.8"}
+  borkdude/rewrite-edn {:mvn/version "0.4.9"}
   logseq/bb-tasks
   #_{:local/root "../bb-tasks"}
   {:git/url "https://github.com/logseq/bb-tasks"
@@ -85,6 +85,18 @@
    :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
                 "yarn -s nbb-logseq -cp src:../outliner/src:script script/create_graph.cljs" *command-line-args*)}
 
+  dev:db-export
+  {:doc "Export a DB graph to a sqlite.build EDN file"
+   :requires ([babashka.fs :as fs])
+   :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
+                "yarn -s nbb-logseq script/export_graph.cljs" *command-line-args*)}
+
+  dev:db-diff
+  {:doc "Diffs two DB graphs"
+   :requires ([babashka.fs :as fs])
+   :task (apply shell {:dir "deps/db" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
+                "yarn -s nbb-logseq script/diff_graphs.cljs" *command-line-args*)}
+
   dev:db-import
   {:doc "Import a file graph to db graph"
    :requires ([babashka.fs :as fs])

+ 11 - 12
capacitor.config.ts

@@ -1,19 +1,23 @@
 import { CapacitorConfig } from '@capacitor/cli'
-import fs from 'fs'
+import * as fs from 'fs'
 
 const version = fs.readFileSync('static/package.json', 'utf8').match(/"version": "(.*?)"/)?.at(1) ?? '0.0.0'
 
 const config: CapacitorConfig = {
   appId: 'com.logseq.app',
   appName: 'Logseq',
-  bundledWebRuntime: false,
-  webDir: 'public',
+  webDir: 'static/mobile',
   loggingBehavior: 'debug',
   server: {
-    // https://capacitorjs.com/docs/updating/5-0#update-androidscheme
-    androidScheme: 'http',
+      androidScheme: 'http',
   },
   plugins: {
+    StatusBar: {
+      overlaysWebView: true,
+      style: 'Light',
+      backgroundColor: '#ffffffff',
+    },
+
     SplashScreen: {
       launchShowDuration: 500,
       launchAutoHide: false,
@@ -32,18 +36,13 @@ const config: CapacitorConfig = {
   ios: {
     scheme: 'Logseq',
     appendUserAgent: `Logseq/${version} (iOS)`
-  },
-  cordova: {
-    staticPlugins: [
-      '@logseq/capacitor-file-sync', // AgeEncryption requires static link
-    ]
   }
 }
 
-if ("http://192.168.199.216:3001") {
+if (process.env.LOGSEQ_APP_SERVER_URL) {
   Object.assign(config, {
     server: {
-      url: "http://192.168.199.216:3001",
+      url: process.env.LOGSEQ_APP_SERVER_URL,
       cleartext: true
     }
   })

+ 3 - 0
clj-e2e/.clj-kondo/config.edn

@@ -0,0 +1,3 @@
+{:linters
+ {:unresolved-var {:exclude [wally.main/click
+                             wally.main/fill]}}}

+ 4 - 0
clj-e2e/.cljfmt.edn

@@ -0,0 +1,4 @@
+{:extra-indents {missionary.core/sp [[:block 0]]
+                 missionary.core/ap [[:block 0]]
+                 frontend.common.missionary/run-task [[:inner 0]]}
+ :sort-ns-references? true}

+ 31 - 0
clj-e2e/.gitignore

@@ -0,0 +1,31 @@
+.calva/output-window/
+.calva/repl.calva-repl
+.classpath
+.clj-kondo/.cache
+.cpcache
+.DS_Store
+.eastwood
+.factorypath
+.hg/
+.hgignore
+.java-version
+.lein-*
+.lsp/.cache
+.lsp/sqlite.db
+.nrepl-history
+.nrepl-port
+.portal
+.project
+.rebel_readline_history
+.settings
+.socket-repl-port
+.sw*
+.vscode
+*.class
+*.jar
+*.swp
+*~
+/checkouts
+/classes
+/target
+.wally/

+ 2 - 0
clj-e2e/.lsp/config.edn

@@ -0,0 +1,2 @@
+{:source-aliases #{:test}
+ :clean {:ns-inner-blocks-indentation :same-line}}

部分文件因为文件数量过多而无法显示