Browse Source

Merge branch 'master' into feature/lang-tasks-and-ci

Gabriel Horner 4 years ago
parent
commit
04241dfe96
73 changed files with 552 additions and 1907 deletions
  1. 11 0
      .carve/config.edn
  2. 68 0
      .carve/ignore
  3. 1 2
      .clj-kondo/config.edn
  4. 0 1
      .github/ISSUE_TEMPLATE/bug_report.yaml
  5. 18 4
      .github/workflows/build.yml
  6. 23 0
      docs/dev-practices.md
  7. 2 1
      ios/App/App/DownloadiCloudFiles.m
  8. 32 19
      ios/App/App/DownloadiCloudFiles.swift
  9. 0 1
      package.json
  10. 43 0
      scripts/carve.clj
  11. 0 6
      src/electron/electron/configs.cljs
  12. 0 2
      src/electron/electron/core.cljs
  13. 0 5
      src/electron/electron/git.cljs
  14. 0 3
      src/electron/electron/search.cljs
  15. 0 28
      src/main/frontend/commands.cljs
  16. 5 22
      src/main/frontend/components/block.cljs
  17. 0 19
      src/main/frontend/components/export.cljs
  18. 0 11
      src/main/frontend/components/page.cljs
  19. 8 5
      src/main/frontend/components/search.cljs
  20. 0 24
      src/main/frontend/components/settings.cljs
  21. 0 14
      src/main/frontend/components/sidebar.cljs
  22. 0 344
      src/main/frontend/components/svg.cljs
  23. 0 53
      src/main/frontend/config.cljs
  24. 0 6
      src/main/frontend/context/i18n.cljs
  25. 0 18
      src/main/frontend/date.cljs
  26. 1 2
      src/main/frontend/db.cljs
  27. 1 85
      src/main/frontend/db/model.cljs
  28. 1 16
      src/main/frontend/db/outliner.cljs
  29. 1 6
      src/main/frontend/db/react.cljs
  30. 0 19
      src/main/frontend/diff.cljs
  31. 0 2
      src/main/frontend/extensions/excalidraw.cljs
  32. 0 4
      src/main/frontend/extensions/graph.cljs
  33. 0 2
      src/main/frontend/extensions/graph/pixi.cljs
  34. 0 2
      src/main/frontend/extensions/pdf/assets.cljs
  35. 0 4
      src/main/frontend/extensions/pdf/utils.cljs
  36. 0 24
      src/main/frontend/format/block.cljs
  37. 1 1
      src/main/frontend/fs/capacitor_fs.cljs
  38. 0 61
      src/main/frontend/git.cljs
  39. 0 19
      src/main/frontend/github.cljs
  40. 0 2
      src/main/frontend/handler.cljs
  41. 11 11
      src/main/frontend/handler/block.cljs
  42. 7 4
      src/main/frontend/handler/dnd.cljs
  43. 10 83
      src/main/frontend/handler/editor.cljs
  44. 1 93
      src/main/frontend/handler/export.cljs
  45. 41 39
      src/main/frontend/handler/extract.cljs
  46. 0 24
      src/main/frontend/handler/file.cljs
  47. 0 4
      src/main/frontend/handler/notification.cljs
  48. 5 12
      src/main/frontend/handler/repo.cljs
  49. 0 8
      src/main/frontend/handler/ui.cljs
  50. 0 12
      src/main/frontend/mixins.cljs
  51. 10 5
      src/main/frontend/mobile/core.cljs
  52. 13 8
      src/main/frontend/mobile/util.cljs
  53. 12 8
      src/main/frontend/modules/outliner/core.cljs
  54. 40 26
      src/main/frontend/modules/outliner/datascript.cljc
  55. 0 12
      src/main/frontend/modules/outliner/utils.cljs
  56. 1 6
      src/main/frontend/modules/shortcut/before.cljs
  57. 1 3
      src/main/frontend/publishing.cljs
  58. 0 5
      src/main/frontend/rum.cljs
  59. 0 4
      src/main/frontend/search/db.cljs
  60. 2 10
      src/main/frontend/spec.cljs
  61. 180 330
      src/main/frontend/state.cljs
  62. 0 16
      src/main/frontend/storage.cljs
  63. 1 7
      src/main/frontend/text.cljs
  64. 0 49
      src/main/frontend/tools/html_export.cljs
  65. 0 11
      src/main/frontend/ui.cljs
  66. 1 7
      src/main/frontend/ui/date_picker.cljs
  67. 0 14
      src/main/frontend/utf8.cljs
  68. 0 226
      src/main/frontend/util.cljc
  69. 0 11
      src/main/frontend/util/cursor.cljs
  70. 0 5
      src/main/frontend/util/pool.cljs
  71. 0 5
      src/main/frontend/util/property.cljs
  72. 0 7
      src/test/frontend/react.cljc
  73. 0 5
      yarn.lock

+ 11 - 0
.carve/config.edn

@@ -0,0 +1,11 @@
+{;; Only lint production namespaces as most dev
+ ;; namespaces are unused
+ :paths ["src/main" "src/electron" "src/test"]
+ :api-namespaces [
+                  ;; Ignore b/c too many false positives
+                  frontend.db
+                  ;; Used for debugging
+                  frontend.db.debug
+                  ;; namespace fns are lazily loaded
+                  frontend.extensions.age-encryption]
+ :report {:format :ignore}}

+ 68 - 0
.carve/ignore

@@ -0,0 +1,68 @@
+;; Used by shadow-cljs
+electron.core/main
+electron.core/start
+electron.core/stop
+;; repl fn
+electron.search/query
+frontend.blob/blob
+;; Used by shadow-cljs
+frontend.core/stop
+;; For repl
+frontend.db.utils/q
+;; For debugging
+frontend.debug/defn
+frontend.debug/print
+;; Lazily loaded
+frontend.extensions.code/editor
+;; Lazily loaded
+frontend.extensions.excalidraw/draw
+;; Referenced in commented TODO
+frontend.extensions.pdf.utils/get-page-bounding
+;; For repl
+frontend.extensions.zotero.api/item
+;; For repl
+frontend.external.roam/reset-state!
+;; For repl
+frontend.format.mldoc/ast-export-markdown
+;; Protocol fn wrapper that could be used
+frontend.fs/readdir
+;; Referenced in TODO
+frontend.handler.metadata/update-properties!
+;; Referenced in comment
+frontend.handler.route/toggle-between-page-and-file!
+;; Referenced in comment
+frontend.handler.shell/run-pandoc-command!
+;; Referenced in comment
+frontend.image/get-orientation
+;; For debugging
+frontend.mixins/perf-measure-mixin
+;; Previously useful fn
+frontend.mobile.util/get-idevice-statusbar-height
+;; Used in macro
+frontend.modules.outliner.datascript/transact!
+;; Referenced in comment
+frontend.page/route-view
+;; placeholder fn
+frontend.publishing/stop
+;; Referenced in comment
+frontend.state/set-db-persisted!
+;; Future use
+frontend.storage/get-transit
+;; repl fn
+frontend.state/remove-watch-state
+;; Future use?
+frontend.state/get-visual-viewport-state
+;; Future use?
+frontend.ui/reset-ios-whole-page-offset!
+;; For debugging
+frontend.util/d
+;; Future use?
+frontend.util/safe-search-normalize
+;; For debugging
+frontend.util/trace!
+;; Repl fn
+frontend.util.pool/terminate-pool!
+;; Repl fn
+frontend.util.property/add-page-properties
+;; Used by shadow
+frontend.worker.parser/init

+ 1 - 2
.clj-kondo/config.edn

@@ -27,5 +27,4 @@
            frontend.namespaces/import-vars potemkin/import-vars
            ;; src/test
            frontend.react/defc clojure.core/defn}
- :skip-comments true
- :output {:progress true}}
+ :skip-comments true}

+ 0 - 1
.github/ISSUE_TEMPLATE/bug_report.yaml

@@ -1,6 +1,5 @@
 name: Bug Report
 description: Report a bug encountered while using Logseq
-labels: awaiting-response
 body:
   - type: textarea
     id: problem

+ 18 - 4
.github/workflows/build.yml

@@ -61,13 +61,11 @@ jobs:
             ~/.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: Run clj-kondo lint
-        run: clojure -M:clj-kondo --lint src
-
       - name: Fetch yarn deps
         run: yarn install
 
@@ -83,15 +81,31 @@ jobs:
       - name: Checkout
         uses: actions/checkout@v2
 
+      - name: Set up Java
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: ${{ env.JAVA_VERSION }}
+
+      - name: Set up Clojure
+        uses: DeLaGuardo/setup-clojure@master
+        with:
+          cli: ${{ env.CLOJURE_VERSION }}
+
       - name: Setup Babashka
         uses: turtlequeue/[email protected]
         with:
           babashka-version: ${{ env.BABASHKA_VERSION }}
 
+      - name: Run clj-kondo lint
+        run: clojure -M:clj-kondo --parallel --lint src
+
+      - name: Carve lint for unused vars
+        run: scripts/carve.clj
+
       - name: Lint invalid dictionary keys
         run: bb lang:invalid-dicts
 
-
   e2e-test:
     runs-on: ubuntu-latest
 

+ 23 - 0
docs/dev-practices.md

@@ -4,6 +4,8 @@ This page describes development practices for this codebase.
 
 ## Linting
 
+### Clojure code
+
 To lint:
 ```
 clojure -M:clj-kondo --lint src
@@ -16,6 +18,27 @@ There are outstanding linting items that are currently ignored to allow linting
 * Comments starting with `TODO:lint`
 * Code marked with `#_:clj-kondo/ignore` require a good understanding of the context to address as they usually involve something with a side effect or require changing multiple fns up the call stack.
 
+### Unused vars
+
+We use https://github.com/borkdude/carve to detect unused vars in our codebase.
+Before running it, please install https://github.com/babashka/babashka.
+
+To run this linter:
+```
+scripts/carve.clj
+```
+
+By default, the script runs in CI mode which prints unused vars if they are
+found. The script can be run in an interactive mode which prompts for keeping
+(ignoring) an unused var or removing it. Run this mode with:
+
+```
+scripts/carve.clj '{:interactive true}'
+```
+
+When a var is ignored, it is added to `.carve/ignore`. Please add a comment for
+why a var is ignored to help others understand why it's unused.
+
 ## Testing
 
 We have unit and end to end tests as described in https://github.com/logseq/logseq#5-run-tests.

+ 2 - 1
ios/App/App/DownloadiCloudFiles.m

@@ -9,5 +9,6 @@
 #import <Capacitor/Capacitor.h>
 
 CAP_PLUGIN(DownloadiCloudFiles, "DownloadiCloudFiles",
-           CAP_PLUGIN_METHOD(downloadFilesFromiCloud, CAPPluginReturnPromise);
+           CAP_PLUGIN_METHOD(iCloudSync, CAPPluginReturnPromise);
+           CAP_PLUGIN_METHOD(syncGraph, CAPPluginReturnPromise);
            )

+ 32 - 19
ios/App/App/DownloadiCloudFiles.swift

@@ -19,49 +19,62 @@ public class DownloadiCloudFiles: CAPPlugin,  UIDocumentPickerDelegate  {
         return fileManager.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
     }
     
-    @objc func downloadFilesFromiCloud(_ call: CAPPluginCall) {
-        
-        self._call = call
+    var isDirectory: ObjCBool = false
+    var downloaded = false
+    
+    @objc func syncGraph(_ call: CAPPluginCall) {
         
-        var downloaded = false
+        guard let graph = call.options["graph"] as? String else {
+            call.reject("Missing graph name")
+            return
+        }
+ 
+        let ignores = [".git", ".trash", "bak", ".recycle"]
         
+        if let url = self.containerUrl?.appendingPathComponent(graph) {
+            do {
+                downloaded = try self.downloadAllFilesFromCloud(at: url, ignorePattern: ignores)
+            } catch {
+                print(error.localizedDescription)
+            }
+        }
+        call.resolve(["success": downloaded])
+    }
+    
+    @objc func iCloudSync(_ call: CAPPluginCall) {
+
         if let url = self.containerUrl, fileManager.fileExists(atPath: url.path) {
-            
             do {
-                print("Download started!")
-                downloaded = try self.downloadAllFilesFromCloud(at: url)
-                print("All files has been downloaded!", downloaded)
+                downloaded = try self.downloadAllFilesFromCloud(at: url, ignorePattern: [".git", ".Trash", "bak", ".recycle"])
             } catch {
-                print("Can't download logseq's files from iCloud to local device.")
                 print(error.localizedDescription)
             }
         }
         
-        self._call?.resolve(["success": downloaded])
+        call.resolve(["success": downloaded])
     }
     
-    func downloadAllFilesFromCloud(at url: URL) throws -> Bool {
+    func downloadAllFilesFromCloud(at url: URL, ignorePattern ignores: [String] = []) throws -> Bool {
 
-        guard url.hasDirectoryPath else { return true }
         let files = try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [])
 
-        var completed = false
-        
         for file in files {
             if file.pathExtension.lowercased() == "icloud" {
-                
                 do {
                     try fileManager.startDownloadingUbiquitousItem(at: file)
                 } catch {
                     print("Unexpected error: \(error).")
                 }
-
             } else {
-                if try downloadAllFilesFromCloud(at: file) {
-                    completed = true
+                if fileManager.fileExists(atPath: file.path, isDirectory:&isDirectory) {
+                    if isDirectory.boolValue && !ignores.contains(file.lastPathComponent) {
+                        if try downloadAllFilesFromCloud(at: file, ignorePattern: ignores) {
+                            downloaded = true
+                        }
+                    }
                 }
             }
         }
-        return completed
+        return downloaded
     }
 }

+ 0 - 1
package.json

@@ -83,7 +83,6 @@
         "codemirror": "5.58.1",
         "d3-force": "3.0.0",
         "diff": "5.0.0",
-        "diff-match-patch": "1.0.5",
         "electron": "15.1.2",
         "fs": "0.0.1-security",
         "fs-extra": "9.1.0",

+ 43 - 0
scripts/carve.clj

@@ -0,0 +1,43 @@
+#!/usr/bin/env bb
+;; This file is copied from
+;; https://github.com/borkdude/carve/blob/df552797a198b6701fb2d92390fce7c59205ea77/carve.clj
+;; and thus this file is under the same EPL license.
+;; The script is modified to run latest clj-kondo and carve versions and to add
+;; a more friendly commandline interface through -main
+
+(require '[babashka.pods :as pods])
+
+(pods/load-pod 'clj-kondo/clj-kondo "2021.12.19")
+(require '[pod.borkdude.clj-kondo :as clj-kondo])
+;; define clj-kondo.core ns which is used by carve
+(intern (create-ns 'clj-kondo.core) 'run! clj-kondo/run!)
+
+(require '[babashka.deps :as deps])
+(deps/add-deps '{:deps {borkdude/carve ;; {:local/root "."}
+                        {:git/url "https://github.com/borkdude/carve"
+                         :git/sha "df552797a198b6701fb2d92390fce7c59205ea77"}
+                        borkdude/spartan.spec {:git/url "https://github.com/borkdude/spartan.spec"
+                                               :sha "12947185b4f8b8ff8ee3bc0f19c98dbde54d4c90"}}})
+
+(require '[spartan.spec]) ;; defines clojure.spec
+
+(with-out-str ;; silence warnings about spartan.spec + with-gen
+  (binding [*err* *out*]
+    (require '[carve.api :as carve])))
+
+;; again to make clj-kondo happy
+(require '[carve.main])
+(require '[clojure.edn :as edn])
+
+(defn -main
+  "Wrapper around carve.main that defaults to .carve/config.edn and merges
+in an optional string of options"
+  [args]
+  (let [default-opts (slurp ".carve/config.edn")
+         opts (if-let [more-opts (first args)]
+                (pr-str (merge (select-keys (edn/read-string default-opts) [:paths :api-namespaces])
+                               (edn/read-string more-opts)))
+                default-opts)]
+    (apply carve.main/-main ["--opts" opts])))
+
+(-main *command-line-args*)

+ 0 - 6
src/electron/electron/configs.cljs

@@ -32,12 +32,6 @@
         cfg (assoc cfg k v)]
     (write-cfg! cfg)))
 
-(defn del-item!
-  [k]
-  (when-let [cfg (and k (ensure-cfg))]
-    (let [cfg (dissoc cfg k)]
-      (write-cfg! cfg))))
-
 (defn get-item
   [k]
   (when-let [cfg (and k (ensure-cfg))]

+ 0 - 2
src/electron/electron/core.cljs

@@ -24,8 +24,6 @@
 (defonce STATIC_URL (str LSP_PROTOCOL "logseq.com/"))
 (defonce PLUGINS_ROOT (.join path (.homedir os) ".logseq/plugins"))
 
-(def ROOT_PATH (path/join js/__dirname ".."))
-
 (defonce *setup-fn (volatile! nil))
 (defonce *teardown-fn (volatile! nil))
 (defonce *quit-dirty? (volatile! true))

+ 0 - 5
src/electron/electron/git.cljs

@@ -20,11 +20,6 @@
       (. fs ensureDirSync dir)
       dir)))
 
-(defn dot-git-exists?
-  []
-  (let [p (.join path (state/get-graph-path) ".git")]
-    (fs/existsSync p)))
-
 (defn run-git!
   [commands]
   (when-let [path (state/get-graph-path)]

+ 0 - 3
src/electron/electron/search.cljs

@@ -3,13 +3,10 @@
             ["fs-extra" :as fs]
             ["better-sqlite3" :as sqlite3]
             [clojure.string :as string]
-            [electron.utils :refer [logger] :as utils]
             ["electron" :refer [app]]))
 
 (defonce version "0.0.1")
 
-(def error (partial (.-error logger) "[Search]"))
-
 (defonce databases (atom nil))
 
 (defn close!

+ 0 - 28
src/main/frontend/commands.cljs

@@ -416,26 +416,6 @@
     (when check-fn
       (check-fn new-value (dec (count prefix)) new-pos))))
 
-(defn insert-before!
-  [id value
-   {:keys [backward-pos forward-pos check-fn]
-    :as _option}]
-  (let [input (gdom/getElement id)
-        edit-content (gobj/get input "value")
-        current-pos (cursor/pos input)
-        suffix (subs edit-content 0 current-pos)
-        new-value (str value
-                       suffix
-                       (subs edit-content current-pos))
-        new-pos (- (+ (count suffix)
-                      (count value)
-                      (or forward-pos 0))
-                   (or backward-pos 0))]
-    (state/set-block-content-and-last-pos! id new-value new-pos)
-    (cursor/move-cursor-to input new-pos)
-    (when check-fn
-      (check-fn new-value (dec (count suffix)) new-pos))))
-
 (defn simple-replace!
   [id value selected
    {:keys [backward-pos forward-pos check-fn]
@@ -482,14 +462,6 @@
                         :extract-fn first
                         :limit 50)))
 
-(defn get-command-input
-  [edit-content]
-  (when-not (string/blank? edit-content)
-    (let [result (last (util/split-last (state/get-editor-command-trigger) edit-content))]
-      (if (string/blank? result)
-        nil
-        result))))
-
 (defmulti handle-step first)
 
 (defmethod handle-step :editor/hook [[_ event {:keys [pid uuid] :as payload}] format]

+ 5 - 22
src/main/frontend/components/block.cljs

@@ -708,13 +708,6 @@
     (let [inline-list (mldoc/inline->edn v (mldoc/default-config format))]
       [:div.inline.mr-1 (map-inline {} inline-list)])))
 
-(defn selection-range-in-block? []
-  (and (= "Range" (. (js/window.getSelection) -type))
-       (-> (js/window.getSelection)
-           (.-anchorNode)
-           (.-parentNode)
-           (.closest ".block-content"))))
-
 (defn- render-macro
   [config name arguments macro-content format]
   (if macro-content
@@ -1338,8 +1331,6 @@
     :else
     ""))
 
-(declare blocks-cp)
-
 (rum/defc block-child
   [block]
   block)
@@ -1891,11 +1882,7 @@
                                ;; clear highlighted text
                                (util/clear-selection!)))}
        (not slide?)
-       (merge attrs)
-
-       ;; not playwright ci
-       (not js/window.navigator.webdriver)
-       (assoc :class "select-none"))
+       (merge attrs))
 
      [:span
       [:div.flex.flex-row.justify-between
@@ -2194,8 +2181,7 @@
              (assoc state ::control-show? (atom false))))
    :should-update (fn [old-state new-state]
                     (let [compare-keys [:block/uuid :block/content :block/parent :block/collapsed? :block/children
-                                        :block/properties
-                                        :block/_refs]
+                                        :block/properties :block/left :block/children :block/_refs]
                           config-compare-keys [:show-cloze?]
                           b1 (second (:rum/args old-state))
                           b2 (second (:rum/args new-state))
@@ -2871,16 +2857,13 @@
         custom-query? (:custom-query? config)]
     (or custom-query? ref?)))
 
-
 ;; TODO: virtual tree for better UX and memory usage reduce
-(def initial-blocks-length 200)
-(def step-loading-blocks 50)
 
 (defn- get-segment
   [flat-blocks idx blocks->vec-tree]
-  (let [new-idx (if (< idx initial-blocks-length)
-                  initial-blocks-length
-                  (+ idx step-loading-blocks))
+  (let [new-idx (if (< idx block-handler/initial-blocks-length)
+                  block-handler/initial-blocks-length
+                  (+ idx block-handler/step-loading-blocks))
         max-idx (count flat-blocks)
         idx (min max-idx new-idx)
         blocks (util/safe-subvec flat-blocks 0 idx)]

+ 0 - 19
src/main/frontend/components/export.cljs

@@ -43,25 +43,6 @@
        [:a#convert-markdown-to-unordered-list-or-heading.hidden]])))
 
 
-(rum/defc export-page
-  []
-  #_:clj-kondo/ignore
-  (when-let [current-repo (state/get-current-repo)]
-    (when-let [page (state/get-current-page)]
-      (rum/with-context [[t] i18n/*tongue-context*]
-        [:div.export
-         [:h1.title "Export"]
-         [:ul.mr-1
-          [:li.mb-4
-           [:a.font-medium {:on-click #(export/export-page-as-markdown! page)}
-            (t :export-markdown)]]
-          [:li.mb-4
-           [:a.font-medium {:on-click #(export/export-page-as-opml! page)}
-            (t :export-opml)]]]
-         [:a#export-page-as-markdown.hidden]
-         [:a#export-page-as-opml.hidden]
-         [:a#convert-markdown-to-unordered-list-or-heading.hidden]]))))
-
 (def *export-block-type (atom :text))
 
 (def text-indent-style-options [{:label "dashes"

+ 0 - 11
src/main/frontend/components/page.cljs

@@ -78,15 +78,6 @@
 
 (declare page)
 
-(defn- get-page-format
-  [page-name]
-  (let [block? (util/uuid-string? page-name)
-        block-id (and block? (uuid page-name))
-        page (if block-id
-               (:block/name (:block/page (db/entity [:block/uuid block-id])))
-               page-name)]
-    (db/get-page-format page)))
-
 (rum/defc dummy-block
   [page-name]
   [:div.ls-block.flex-1.flex-col.rounded-sm {:style {:width "100%"}}
@@ -341,8 +332,6 @@
 
 (defonce layout (atom [js/window.innerWidth js/window.innerHeight]))
 
-(defonce show-journal? (atom false))
-
 ;; scrollHeight
 (rum/defcs graph-filter-section < (rum/local false ::open?)
   [state title content {:keys [search-filters]}]

+ 8 - 5
src/main/frontend/components/search.cljs

@@ -5,6 +5,7 @@
             [frontend.components.svg :as svg]
             [frontend.handler.route :as route]
             [frontend.handler.page :as page-handler]
+            [frontend.handler.block :as block-handler]
             [frontend.db :as db]
             [frontend.db.model :as model]
             [frontend.handler.search :as search-handler]
@@ -133,13 +134,15 @@
                                           :path-params {:path data}})
 
                         :block
-                        (let [block-uuid (uuid (:block/uuid data))
-                              collapsed? (db/parents-collapsed? (state/get-current-repo) block-uuid)
-                              page (:block/name (:block/page (db/entity [:block/uuid block-uuid])))]
+                        (let [repo (state/get-current-repo)
+                              block-uuid (uuid (:block/uuid data))
+                              collapsed? (db/parents-collapsed? repo block-uuid)
+                              page (:block/page (db/entity [:block/uuid block-uuid]))
+                              long-page? (block-handler/long-page? repo (:db/id page))]
                           (if page
-                            (if collapsed?
+                            (if (or collapsed? long-page?)
                              (route/redirect-to-page! block-uuid)
-                             (route/redirect-to-page! page (str "ls-block-" (:block/uuid data))))
+                             (route/redirect-to-page! (:block/name page) (str "ls-block-" (:block/uuid data))))
                             ;; search indice outdated
                             (println "[Error] Block page missing: "
                                      {:block-id block-uuid

+ 0 - 24
src/main/frontend/components/settings.cljs

@@ -50,30 +50,6 @@
 
       [:span.pl-1.opacity-70 "Git commit requires the email address."]]]))
 
-(rum/defcs set-cors < (rum/local "" ::cors)
-  [state]
-  (let [cors (get state ::cors)]
-    [:div.p-8.flex.items-center.justify-center
-     [:div.w-full.mx-auto
-      [:div
-       [:div
-        [:h1.title.mb-1
-         "Your cors address:"]
-        [:div.mt-2.mb-4.relative.rounded-md.max-w-xs
-         [:input#.form-input.is-small
-          {:autoFocus true
-           :on-change (fn [e]
-                        (reset! cors (util/evalue e)))}]]]]
-      (ui/button
-       "Submit"
-       :on-click
-       (fn []
-         (user-handler/set-cors! @cors)))
-
-      [:hr]
-
-      [:span.pl-1.opacity-70 "Git commit requires the cors address."]]]))
-
 (defn toggle
   [label-for name state on-toggle & [detail-text]]
   [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-start

+ 0 - 14
src/main/frontend/components/sidebar.cljs

@@ -34,20 +34,6 @@
             [frontend.mobile.util :as mobile-util]
             [frontend.handler.mobile.swipe :as swipe]))
 
-(defn nav-item
-  [title href svg-d _active? close-modal-fn]
-  [:a.mb-1.group.flex.items-center.pl-4.py-2.text-base.leading-6.font-medium.hover:text-gray-200.transition.ease-in-out.duration-150.nav-item
-   {:href href
-    :on-click close-modal-fn}
-   [:svg.mr-4.h-6.w-6.group-hover:text-gray-200.group-focus:text-gray-200.transition.ease-in-out.duration-150
-    {:viewBox "0 0 24 24", :fill "none", :stroke "currentColor"}
-    [:path
-     {:d svg-d
-      :stroke-width "2"
-      :stroke-linejoin "round"
-      :stroke-linecap "round"}]]
-   title])
-
 (rum/defc nav-content-item
   [name {:keys [class]} child]
 

+ 0 - 344
src/main/frontend/components/svg.cljs

@@ -29,54 +29,6 @@
     {:d         "M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z"
      :fill-rule "evenodd"}]])
 
-(rum/defc arrow-left
-  []
-  [:svg.w-6.h-6
-   {:viewBox "0 0 24 24", :stroke "currentColor", :fill "none"}
-   [:path
-    {:d               "M15 19l-7-7 7-7",
-     :stroke-width    "2",
-     :stroke-linejoin "round",
-     :stroke-linecap  "round"}]])
-
-(rum/defc arrow-right
-  []
-  [:svg.w-6.h-6
-   {:viewBox "0 0 24 24", :stroke "currentColor", :fill "none"}
-   [:path
-    {:d               "M9 5l7 7-7 7",
-     :stroke-width    "2",
-     :stroke-linejoin "round",
-     :stroke-linecap  "round"}]])
-
-(rum/defc big-arrow-right
-  []
-  [:svg
-   {:fill "none", :view-box "0 0 24 24", :height "24", :width "24"}
-   [:path
-    {:stroke-linejoin "round"
-     :stroke-linecap  "round"
-     :stroke-width    "2"
-     :stroke          "currentColor"
-     :d               "M14 5L21 12M21 12L14 19M21 12L3 12"}]])
-
-(rum/defc big-arrow-left
-  []
-  [:svg
-   {:fill "none", :view-box "0 0 24 24", :height "24", :width "24"}
-   [:path
-    {:stroke-linejoin "round"
-     :stroke-linecap  "round"
-     :stroke-width    "2"
-     :stroke          "currentColor"
-     :d               "M10 19L3 12M3 12L10 5M3 12L21 12"}]])
-
-(def arrow-narrow-left
-  [:svg.h-6.w-6 {:xmlns "http://www.w3.org/2000/svg" :fill "none" :view-box "0 0 24 24" :stroke "currentColor"} [:path {:stroke-linecap "round" :stroke-linejoin "round" :stroke-width "2" :d "M7 16l-4-4m0 0l4-4m-4 4h18"}]])
-
-(def arrow-narrow-right
-  [:svg.h-6.w-6 {:xmlns "http://www.w3.org/2000/svg" :fill "none" :view-box "0 0 24 24" :stroke "currentColor"} [:path {:stroke-linecap "round" :stroke-linejoin "round" :stroke-width "2" :d "M17 8l4 4m0 0l-4 4m4-4H3"}]])
-
 (defonce arrow-right-v2
          [:svg.h-3.w-3
           {:version  "1.1"
@@ -109,22 +61,6 @@
           [:path.opacity-75 {:fill "currentColor"
                              :d    "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"}]])
 
-(defonce minus
-         [:svg.w-6.h-6
-          {:viewBox "0 0 24 24", :stroke "currentColor", :fill "none"}
-          [:path
-           {:d               "M20 12H4"
-            :stroke-width    "2"
-            :stroke-linejoin "round"
-            :stroke-linecap  "round"}]])
-
-(defonce rectangle
-         [:svg.w-6.h-6
-          {:viewBox "0 0 24 24", :stroke "currentColor", :fill "none"}
-          [:path
-           {:d            "M3.16580358,18.5038125 L20.5529464,18.5038125 C22.6525178,18.5038125 23.7072321,17.4593839 23.7072321,15.3902411 L23.7072321,3.12495537 C23.7072321,1.0558125 22.6525178,0.0113839219 20.5529464,0.0113839219 L3.16580358,0.0113839219 C1.07651787,0.0118125 0.0115178672,1.04638392 0.0115178672,3.12495537 L0.0115178672,15.3906696 C0.0115178672,17.4696696 1.07651787,18.5042411 3.16580358,18.5042411 L3.16580358,18.5038125 Z M3.19580358,16.8868125 C2.19123216,16.8868125 1.62894642,16.3545268 1.62894642,15.3096696 L1.62894642,3.20638392 C1.62894642,2.16152679 2.19123213,1.62924108 3.19580358,1.62924108 L20.5229464,1.62924108 C21.5172321,1.62924108 22.0898036,2.16152679 22.0898036,3.20638392 L22.0898036,15.3092411 C22.0898036,16.3540982 21.5172322,16.8863839 20.5229464,16.8863839 L3.19580358,16.8868125 Z"
-            :stroke-width "2"}]])
-
 (defn- hero-icon
   ([d]
    (hero-icon d {}))
@@ -142,93 +78,14 @@
   (hero-icon "M4 4V9H4.58152M19.9381 11C19.446 7.05369 16.0796 4 12 4C8.64262 4 5.76829 6.06817 4.58152 9M4.58152 9H9M20 20V15H19.4185M19.4185 15C18.2317 17.9318 15.3574 20 12 20C7.92038 20 4.55399 16.9463 4.06189 13M19.4185 15H15"
              {:fill "none"}))
 
-(def user
-  [:svg
-   {:stroke-linejoin "round"
-    :stroke-linecap  "round"
-    :fill            "none"
-    :stroke          "currentColor"
-    :stroke-width    "2"
-    :view-box        "0 0 24 24"
-    :height          "24"
-    :width           "24"}
-   [:path {:d "M0 0h24v24H0z", :stroke "none"}]
-   [:circle {:r "4", :cy "7", :cx "12"}]
-   [:path {:d "M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"}]])
-
 (def close (hero-icon "M6 18L18 6M6 6L18 18"))
-(def plus (hero-icon "M12 4v16m8-8H4"))
-
-(def plus-circle
-  [:svg.add-button
-   {:viewBox "0 0 20 20"}
-   [:circle.circle {:fill "#dce0e2", :r "9", :cy "10.5", :cx "10.5"}]
-   [:line
-    {:stroke-width "1"
-     :stroke       "#868c90"
-     :y2           "10.5"
-     :x2           "15"
-     :y1           "10.5"
-     :x1           "6"}]
-   [:line
-    {:stroke-width "1"
-     :stroke       "#868c90"
-     :y2           "15"
-     :x2           "10.5"
-     :y1           "6"
-     :x1           "10.5"}]])
-
-(def graph-sm [:div {:style {:transform "rotate(90deg)"}} (hero-icon "M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" {:height "16" :width "16"})])
-
-(def folder-add
-  [:svg
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none" :width 24 :height 24 :display "inline-block"}
-   [:path
-    {:d
-                      "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def folder-add-large
-  [:svg
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none" :width 64 :height 64 :display "inline-block"}
-   [:path
-    {:d
-                      "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
 (def folder (hero-icon "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"))
-(def folder-sm (hero-icon "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" {:height "16" :width "16"}))
-(def pages-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
-               [:path {:d "M9 2a2 2 0 00-2 2v8a2 2 0 002 2h6a2 2 0 002-2V6.414A2 2 0 0016.414 5L14 2.586A2 2 0 0012.586 2H9z"}]
-               [:path {:d "M3 8a2 2 0 012-2v10h8a2 2 0 01-2 2H5a2 2 0 01-2-2V8z"}]])
-(def repos-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
-               [:path {:d "M3 12v3c0 1.657 3.134 3 7 3s7-1.343 7-3v-3c0 1.657-3.134 3-7 3s-7-1.343-7-3z"}]
-               [:path {:d "M3 7v3c0 1.657 3.134 3 7 3s7-1.343 7-3V7c0 1.657-3.134 3-7 3S3 8.657 3 7z"}]
-               [:path {:d "M17 5c0 1.657-3.134 3-7 3S3 6.657 3 5s3.134-3 7-3 7 1.343 7 3z"}]])
 (def settings-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "20", :width "20"}
                   [:path {:fill-rule "evenodd", :d "M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z", :clip-rule "evenodd"}]])
-(def calendar-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
-                  [:path {:fill-rule "evenodd", :d "M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z", :clip-rule "evenodd"}]])
-(def import-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
-                [:path {:fill-rule "evenodd", :d "M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM6.293 6.707a1 1 0 010-1.414l3-3a1 1 0 011.414 0l3 3a1 1 0 01-1.414 1.414L11 5.414V13a1 1 0 11-2 0V5.414L7.707 6.707a1 1 0 01-1.414 0z", :clip-rule "evenodd"}]])
 (def logout-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "18", :width "18"}
                 [:path {:fill-rule "evenodd", :d "M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z", :clip-rule "evenodd"}]])
 (def trash-sm [:svg {:viewBox "0 0 20 20", :fill "currentColor", :height "16", :width "16"}
                [:path {:fill-rule "evenodd", :d "M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z", :clip-rule "evenodd"}]])
-(def sort-asc-sm [:svg {:viewBox "0 0 16 16", :fill "currentColor"}
-                  [:path {:d "M3 3a1 1 0 000 2h11a1 1 0 100-2H3zM3 7a1 1 0 000 2h5a1 1 0 000-2H3zM3 11a1 1 0 100 2h4a1 1 0 100-2H3zM13 16a1 1 0 102 0v-5.586l1.293 1.293a1 1 0 001.414-1.414l-3-3a1 1 0 00-1.414 0l-3 3a1 1 0 101.414 1.414L13 10.414V16z"}]])
-(defn vertical-dots
-  [options]
-  (hero-icon "M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" options))
-
-(defn horizontal-dots
-  [options]
-  (hero-icon "M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" options))
-
 (def external-link
   [:svg {:fill   "none", :view-box "0 0 24 24", :height "21", :width "21"
          :stroke "currentColor"}
@@ -237,16 +94,6 @@
      :stroke-linecap  "round"
      :stroke-width    "2"
      :d               "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}]])
-(def save
-  [:svg
-   {:fill "currentColor", :view-box "0 0 448 512", :height "24", :width "24"}
-   [:path
-    {:stroke-linejoin "round"
-     :stroke-linecap  "round"
-     :stroke-width    "2"
-     :stroke          "currentColor"
-     :d               "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"}]])
-
 (rum/defc note
   []
   [:svg.h-8.w-8.svg-shadow.note
@@ -348,54 +195,6 @@
     {:d         "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
      :fill-rule "evenodd"}]])
 
-(rum/defc menu
-  [class]
-  [:svg
-   {:fill  "none", :view-box "0 0 20 20", :height "20", :width "20"
-    :class class}
-   [:path
-    {:fill      "currentColor"
-     :d
-                "M3 5C3 4.44772 3.44772 4 4 4H16C16.5523 4 17 4.44772 17 5C17 5.55228 16.5523 6 16 6H4C3.44772 6 3 5.55228 3 5Z"
-     :clip-rule "evenodd"
-     :fill-rule "evenodd"}]
-   [:path
-    {:fill      "currentColor"
-     :d
-                "M3 10C3 9.44772 3.44772 9 4 9H16C16.5523 9 17 9.44772 17 10C17 10.5523 16.5523 11 16 11H4C3.44772 11 3 10.5523 3 10Z"
-     :clip-rule "evenodd"
-     :fill-rule "evenodd"}]
-   [:path
-    {:fill      "currentColor"
-     :d
-                "M3 15C3 14.4477 3.44772 14 4 14H16C16.5523 14 17 14.4477 17 15C17 15.5523 16.5523 16 16 16H4C3.44772 16 3 15.5523 3 15Z"
-     :clip-rule "evenodd"
-     :fill-rule "evenodd"}]])
-
-(defn excalidraw-logo
-  []
-  [:svg
-   {:preserve-aspect-ratio "xMidYMid meet"
-    :view-box              "0 0 109.000000 269.000000"
-    :height                24
-    :width                 24
-    :version               "1.0"
-    :style                 {:display "inline"}}
-   [:g
-    {:stroke "none"
-     :fill   "currentColor"
-     :transform
-             "translate(0.000000,269.000000) scale(0.100000,-0.100000)"}
-    [:path
-     {:d
-      "M393 2643 c-74 -59 -188 -159 -278 -245 l-71 -67 13 -88 c7 -48 20 -142 28 -208 9 -66 18 -128 21 -137 4 -12 0 -18 -11 -18 -19 0 -20 5 32 -160 19 -63 37 -121 39 -127 2 -7 10 -10 19 -7 9 4 14 12 11 19 -3 8 2 16 10 19 11 4 10 12 -7 41 -27 45 -96 429 -100 553 -3 88 -3 89 34 139 36 49 119 123 247 217 36 27 72 57 82 67 15 18 22 13 148 -121 73 -77 154 -156 180 -176 l48 -36 -37 -78 c-20 -42 -101 -204 -181 -358 -167 -324 -133 -293 -327 -296 l-126 -1 -42 -48 c-44 -51 -50 -70 -29 -102 8 -11 14 -29 14 -40 0 -18 7 -21 47 -23 25 -1 48 -4 51 -7 3 -3 7 -65 10 -138 l4 -132 -67 -144 c-111 -240 -155 -350 -155 -386 0 -19 4 -35 8 -35 10 0 10 1 417 850 189 394 368 765 398 826 30 61 57 117 59 125 2 9 -67 78 -177 175 -99 88 -186 168 -194 177 -23 28 -57 19 -118 -30z m34 -1150 c-46 -89 -48 -90 -174 -96 -111 -6 -113 -5 -113 16 0 12 -4 28 -9 36 -6 9 -2 25 12 47 l22 34 100 0 c55 1 118 5 140 9 22 4 41 6 43 5 2 -1 -8 -24 -21 -51z m-84 -160 c-8 -21 -29 -65 -46 -98 -28 -56 -31 -58 -38 -35 -4 14 -7 55 -8 92 -1 73 -3 72 81 77 l27 1 -16 -37z"}]
-    [:path
-     {:d
-      "M423 2405 c-18 -13 -23 -26 -23 -59 0 -39 3 -45 30 -56 27 -11 34 -10 65 11 41 28 42 35 12 80 -26 39 -52 46 -84 24z m57 -36 c16 -28 6 -49 -24 -49 -27 0 -39 27 -24 54 12 22 35 20 48 -5z"}]
-    [:path
-     {:d
-      "M1050 2180 c0 -5 -6 -10 -13 -10 -6 0 -23 -28 -36 -62 -40 -104 -440 -895 -441 -870 0 13 -6 22 -16 22 -14 0 -16 -8 -10 -47 6 -45 2 -55 -140 -331 -80 -157 -166 -321 -191 -365 -26 -46 -46 -96 -48 -117 -3 -36 1 -41 88 -116 50 -44 114 -99 142 -124 126 -115 185 -161 201 -158 24 4 395 393 396 415 0 10 -18 162 -40 338 -38 300 -74 651 -70 685 3 21 -12 127 -23 173 -9 36 -5 51 67 215 42 97 97 216 121 264 23 48 43 90 43 93 0 3 -7 5 -15 5 -8 0 -15 -4 -15 -10z m-230 -747 c11 -70 33 -238 49 -373 31 -248 67 -523 77 -593 6 -35 2 -42 -63 -114 -113 -127 -233 -252 -274 -284 l-38 -30 -195 182 c-180 166 -195 183 -184 203 6 11 57 104 113 206 56 102 130 238 164 302 35 65 67 121 73 124 7 4 9 -97 7 -312 -4 -321 -3 -322 29 -315 4 0 7 162 7 359 l0 358 105 210 c58 116 106 209 108 208 2 -1 12 -60 22 -131z"}]]])
-
 (rum/defc logo
   [_dark?]
   [:svg
@@ -416,105 +215,6 @@
      :ry "6.13006"
      :rx "7.78547"}]])
 
-(def discord
-  [:svg
-   {:view-box              "0 0 448 512"
-    :height                15
-    :width                 15
-    :preserve-aspect-ratio "xMidYMid meet"
-    :style
-                           {"msTransform"     "rotate(360deg)"
-                            "WebkitTransform" "rotate(360deg)"
-                            "transform"       "rotate(360deg)"}
-    :focusable             "false"
-    :aria-hidden           "true"
-    :fill                  "currentColor"}
-   [:path
-    {:d
-     "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416c-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416c.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248c-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512c-60.811-33.329-132.244-33.335-191.232-7.424c-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248c0 0 21.504 37.12 78.08 38.912c0 0 9.472-11.52 17.152-21.248c-32.512-9.728-44.8-30.208-44.8-30.208c3.766 2.636 9.976 6.053 10.496 6.4c43.21 24.198 104.588 32.126 159.744 8.96c8.96-3.328 18.944-8.192 29.44-15.104c0 0-12.8 20.992-46.336 30.464c7.68 9.728 16.896 20.736 16.896 20.736c56.576-1.792 78.336-38.912 78.336-38.912z"}]])
-
-(def slideshow
-  [:svg
-   {:view-box "0 0 24 24"
-    :height   24
-    :width    24
-    :fill     "currentColor"}
-   [:path
-    {:d "M10 8v8l5-4-5-4zm9-5H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"}]])
-
-(def indent-block
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M4.293 15.707a1 1 0 010-1.414L8.586 10 4.293 5.707a1 1 0 011.414-1.414l5 5a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]
-   [:path
-    {:d               "M10.293 15.707a1 1 0 010-1.414L14.586 10l-4.293-4.293a1 1 0 111.414-1.414l5 5a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def outdent-block
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M15.707 15.707a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 010 1.414zm-6 0a1 1 0 01-1.414 0l-5-5a1 1 0 010-1.414l5-5a1 1 0 011.414 1.414L5.414 10l4.293 4.293a1 1 0 010 1.414z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def move-up-block
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def move-down-block
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def multi-line-input
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
-(def checkbox
-  [:svg.h-6.w-6
-   {:stroke "currentColor", :view-box "0 0 24 24", :fill "none"}
-   [:path
-    {:d               "M11.167 16.167l-4.167-4.416 1.166-1.192 2.978 3.113 5.477-5.839 1.213 1.169-6.667 7.164zm9.167-12.5v16.667h-16.667v-16.667h16.667zm1.667-1.667h-20v20h20v-20z"
-     :fill-rule       "evenodd"
-     :clip-rule       "evenodd"
-     :stroke-width    "2"
-     :stroke-linejoin "round"
-     :stroke-linecap  "round"}]])
-
 (def page
   [:svg.h-5.w-4 {:viewBox "0 0 24 24", :fill "none", :xmlns "http://www.w3.org/2000/svg"}
    [:path {:d "M2 0.5H6.78272L13.5 7.69708V18C13.5 18.8284 12.8284 19.5 12 19.5H2C1.17157 19.5 0.5 18.8284 0.5 18V2C0.5 1.17157 1.17157 0.5 2 0.5Z", :fill "var(--ls-active-primary-color)"}]
@@ -529,12 +229,6 @@
      "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z",
      :fill-rule "evenodd"}]])
 
-(def online
-  (hero-icon "M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"))
-
-(def collapse-right
-  (hero-icon "M4 6h16M4 12h16m-7 6h7"))
-
 (def search
   [:svg.h-5.w-5
    {:view-box "0 0 20 20", :fill "currentColor"}
@@ -566,10 +260,6 @@
             :height  "20"} opts)
     [:path {:d "M512 12.63616c-282.74688 0-512 229.21216-512 512 0 226.22208 146.69824 418.14016 350.12608 485.82656 25.57952 4.73088 35.00032-11.10016 35.00032-24.63744 0-12.20608-0.47104-52.55168-0.69632-95.31392-142.4384 30.96576-172.50304-60.416-172.50304-60.416-23.28576-59.16672-56.85248-74.91584-56.85248-74.91584-46.44864-31.78496 3.50208-31.1296 3.50208-31.1296 51.4048 3.60448 78.47936 52.75648 78.47936 52.75648 45.6704 78.27456 119.76704 55.64416 149.01248 42.55744 4.58752-33.09568 17.85856-55.68512 32.50176-68.46464-113.72544-12.94336-233.2672-56.85248-233.2672-253.0304 0-55.88992 20.00896-101.5808 52.75648-137.4208-5.3248-12.9024-22.85568-64.96256 4.95616-135.49568 0 0 43.008-13.74208 140.84096 52.49024 40.83712-11.34592 84.64384-17.03936 128.16384-17.24416 43.49952 0.2048 87.32672 5.87776 128.24576 17.24416 97.73056-66.2528 140.65664-52.49024 140.65664-52.49024 27.87328 70.53312 10.3424 122.59328 5.03808 135.49568 32.82944 35.86048 52.69504 81.53088 52.69504 137.4208 0 196.64896-119.78752 239.94368-233.79968 252.6208 18.37056 15.89248 34.73408 47.04256 34.73408 94.80192 0 68.5056-0.59392 123.63776-0.59392 140.51328 0 13.6192 9.216 29.5936 35.16416 24.576 203.32544-67.76832 349.83936-259.62496 349.83936-485.76512 0-282.78784-229.23264-512-512-512z"}]]))
 
-(def git
-  [:svg.icon.git {:width 24 :height 24 :viewbox "0 0 24 24" :stroke-width "2" :stroke "currentColor" :fill "none" :stroke-linecap "round" :stroke-linejoin "round"} [:path {:stroke "none" :d "M0 0h24v24H0z" :fill "none"}] [:circle {:cx "12" :cy "18" :r "2"}] [:circle {:cx "7" :cy "6" :r "2"}] [:circle {:cx "17" :cy "6" :r "2"}] [:path {:d "M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2"}] [:line {:x1 "12" :y1 "12" :x2 "12" :y2 "16"}]])
-
-
 (defn info []
   [:svg {:class "info" :view-box "0 0 16 16" :width "16px" :height "16px"}
    [:g [:path {:style {:transform "scale(0.25)"} :d "m32 2c-16.568 0-30 13.432-30 30s13.432 30 30 30 30-13.432 30-30-13.432-30-30-30m5 49.75h-10v-24h10v24m-5-29.5c-2.761 0-5-2.238-5-5s2.239-5 5-5c2.762 0 5 2.238 5 5s-2.238 5-5 5"}]]])
@@ -592,10 +282,6 @@
      :stroke-linejoin "round"
      :stroke-linecap  "round"}]])
 
-(def home
-  [:svg.h-6.w-6 {:fill "none" :viewBox "0 0 24 24" :stroke "currentColor"}
-   [:path {:stroke-linecap "round" :stroke-linejoin "round" :stroke-width "2" :d "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"}]])
-
 (defn zoom-in
   ([] (zoom-in 16))
   ([size]
@@ -621,25 +307,6 @@
     [:path {:d "M512 981.333333C253.866667 981.333333 42.666667 770.133333 42.666667 512S253.866667 42.666667 512 42.666667s469.333333 211.2 469.333333 469.333333-211.2 469.333333-469.333333 469.333333z m0-844.8c-206.506667 0-375.466667 168.96-375.466667 375.466667 0 206.506667 168.96 375.466667 375.466667 375.466667 206.506667 0 375.466667-168.96 375.466667-375.466667 0-206.506667-168.96-375.466667-375.466667-375.466667z" :fill "currentColor"}]
     [:path {:d "M512 796.714667a46.08 46.08 0 0 1-46.933333-46.933334v-269.056c0-26.624 20.352-46.933333 46.933333-46.933333 26.581333 0 46.933333 20.309333 46.933333 46.933333v269.056c0 26.624-20.352 46.933333-46.933333 46.933334zM512 364.928a46.08 46.08 0 0 1-46.933333-46.933333V274.218667c0-26.624 20.352-46.933333 46.933333-46.933334 26.581333 0 46.933333 20.309333 46.933333 46.933334v43.776c0 26.624-21.888 46.933333-46.933333 46.933333z" :fill "currentColor"}]]))
 
-(defn icon-cmd
-  ([] (icon-cmd 16))
-  ([size]
-   [:svg.cmd {:viewBox "0 0 1024 1024" :width size :height size}
-    [:path {:d "M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H184V184h656v656z" :fill "currentColor"}]
-    [:path {:d "M370.8 554.4c-54.6 0-98.8 44.2-98.8 98.8s44.2 98.8 98.8 98.8 98.8-44.2 98.8-98.8v-42.4h84.7v42.4c0 54.6 44.2 98.8 98.8 98.8s98.8-44.2 98.8-98.8-44.2-98.8-98.8-98.8h-42.4v-84.7h42.4c54.6 0 98.8-44.2 98.8-98.8 0-54.6-44.2-98.8-98.8-98.8s-98.8 44.2-98.8 98.8v42.4h-84.7v-42.4c0-54.6-44.2-98.8-98.8-98.8S272 316.2 272 370.8s44.2 98.8 98.8 98.8h42.4v84.7h-42.4z m42.4 98.8c0 23.4-19 42.4-42.4 42.4s-42.4-19-42.4-42.4 19-42.4 42.4-42.4h42.4v42.4z m197.6-282.4c0-23.4 19-42.4 42.4-42.4s42.4 19 42.4 42.4-19 42.4-42.4 42.4h-42.4v-42.4z m0 240h42.4c23.4 0 42.4 19 42.4 42.4s-19 42.4-42.4 42.4-42.4-19-42.4-42.4v-42.4zM469.6 469.6h84.7v84.7h-84.7v-84.7z m-98.8-56.4c-23.4 0-42.4-19-42.4-42.4s19-42.4 42.4-42.4 42.4 19 42.4 42.4v42.4h-42.4z" :fill "currentColor"}]]))
-
-(defn icon-editor
-  ([] (icon-editor 16))
-  ([size]
-   [:svg {:viewBox "0 0 1024 1024" :width size :height size}
-    [:path {:d "M934.443 258.719L496.176 696.983h-157.92V539.059L776.523 100.8c6.165-6.165 14.235-9.175 22.315-9.175 8.1 0 16.185 3.01 22.35 9.175l113.255 113.247c6.17 6.17 9.175 14.24 9.175 22.335 0 8.072-3.005 16.17-9.175 22.337z m-135.585-74.977L417.216 565.378v52.65h52.64l381.642-381.647-52.64-52.639z m-289.519 39.485H180.337v631.676h631.681V525.899c0-21.79 17.665-39.475 39.48-39.475 21.805 0 39.48 17.685 39.48 39.475v355.324c0 29.075-23.57 52.645-52.64 52.645H154.017c-29.07 0-52.64-23.57-52.64-52.645V196.902c0-29.07 23.57-52.64 52.64-52.64h355.322c21.805 0 39.48 17.685 39.48 39.48s-17.675 39.485-39.48 39.485z" :fill "currentColor"}]]))
-
-(defn icon-cli
-  ([] (icon-cli 16))
-  ([size]
-   [:svg {:viewBox "0 0 1024 1024" :width size :height size}
-    [:path {:d "M324.608 312.32l-60.416 60.416 140.288 140.288-139.264 139.264 60.416 60.416 199.68-199.68-200.704-200.704z m193.536 345.088h235.52v97.28h-235.52v-97.28zM28.672 76.8v870.4h967.68v-870.4H28.672z m870.4 774.144H124.928V173.056h774.144v677.888z" :fill "currentColor"}]]))
-
 (defn view-list
   ([] (view-list 16))
   ([size]
@@ -692,14 +359,6 @@
     [:path {:stroke "none" :d "M0 0h24v24H0z" :fill "none"}]
     [:path {:d "M4.05 11a8 8 0 1 1 .5 4m-.5 5v-5h5"}]]))
 
-(defn settings
-  ([] (settings 16))
-  ([size]
-   [:svg.icon-settings {:width size :height size :viewBox "0 0 24 24" :stroke-width "2" :stroke "currentColor" :fill "none" :stroke-linecap "round" :stroke-linejoin "round"}
-    [:path {:stroke "none" :d "M0 0h24v24H0z" :fill "none"}]
-    [:path {:d "M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"}]
-    [:circle {:cx "12" :cy "12" :r "3"}]]))
-
 (defn offline
   ([] (offline 16))
   ([size]
@@ -748,6 +407,3 @@
     [:circle {:cx "12" :cy "12" :r "9"}]
     [:line {:x1 "12" :y1 "17" :x2 "12" :y2 "17.01"}]
     [:path {:d "M12 13.5a1.5 1.5 0 0 1 1 -1.5a2.6 2.6 0 1 0 -3 -4"}]]))
-
-(def arrow-expand
-  (hero-icon "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"))

+ 0 - 53
src/main/frontend/config.cljs

@@ -60,10 +60,6 @@
   []
   (or 10 (get-in @state/state [:config :git-push-secs])))
 
-(defn git-repo-status-secs
-  []
-  (or 10 (get-in @state/state [:config :git-push-secs])))
-
 (defn text-formats
   []
   (let [config-formats (some->> (get-in @state/state [:config :text-formats])
@@ -185,14 +181,6 @@
       "`"
       "")))
 
-(defn get-subscript
-  [_format]
-  "_")
-
-(defn get-superscript
-  [_format]
-  "^")
-
 (defn get-empty-link-and-forward-pos
   [format]
   (case format
@@ -235,13 +223,6 @@
      (+ 3 (count label))]
     ["" 0]))
 
-(defn properties-wrapper
-  [format]
-  (case format
-    :markdown
-    "---\n\n---"
-    ""))
-
 (defn properties-wrapper-pattern
   [format]
   (case format
@@ -256,34 +237,6 @@
     "md"
     (name format)))
 
-(defn get-file-format
-  [extension]
-  (case (keyword extension)
-    :markdown
-    :markdown
-    :md
-    :markdown
-    (keyword extension)))
-
-(defn default-empty-block
-  ([format]
-   (default-empty-block format 2))
-  ([format n]
-   (let [block-pattern (get-block-pattern format)]
-     (apply str (repeat n block-pattern)))))
-
-(defn with-code-wrapper
-  [format mode code]
-  (let [mode (if-not (string/blank? mode)
-               (str mode " ")
-               "")]
-    (case format
-      :markdown
-      (util/format "```%s\n%s\n```" mode code)
-      :org
-      (util/format "#+BEGIN_SRC%s\n%s\n#+END_SRC" mode code)
-      code)))
-
 (defonce default-journals-directory "journals")
 (defonce default-pages-directory "pages")
 (defonce default-draw-directory "draws")
@@ -436,9 +389,3 @@
 (defn get-block-hidden-properties
   []
   (get-in @state/state [:config (state/get-current-repo) :block-hidden-properties]))
-
-(defn get-static-path
-  []
-  (if (and (util/electron?) dev?)
-    "static/"
-    ""))

+ 0 - 6
src/main/frontend/context/i18n.cljs

@@ -38,9 +38,3 @@
       :ok)
     (rum/bind-context [*tongue-context* [t preferred-language set-preferred-language]]
                       children)))
-
-(rum/defc use-tongue []
-  (rum/with-context [value *tongue-context*]
-    (if (nil? value)
-      (throw "use-i18n must be used within a i18n-provider")
-      value)))

+ 0 - 18
src/main/frontend/date.cljs

@@ -77,14 +77,6 @@
     (catch js/Error _e
       nil)))
 
-(defn ISO-string
-  []
-  (.toISOString (js/Date.)))
-
-(defn get-local-date-time-string
-  []
-  (get-date-time-string (tl/local-now)))
-
 (def custom-formatter-2 (tf/formatter "yyyy-MM-dd-HH-mm-ss"))
 (defn get-date-time-string-2 []
   (tf/unparse custom-formatter-2 (tl/local-now)))
@@ -145,12 +137,6 @@
   []
   (journal-name (t/minus (t/today) (t/days 1))))
 
-(defn get-month-last-day
-  []
-  (let [today (js/Date.)
-        date (js/Date. (.getFullYear today) (inc (.getMonth today)) 0)]
-    (.getDate date)))
-
 (defn ymd
   ([]
    (ymd (js/Date.)))
@@ -249,10 +235,6 @@
   [journal-title]
   (journal-title-> journal-title format))
 
-(defn int->local-time
-  [n]
-  (get-date-time-string (t/to-default-time-zone (tc/from-long n))))
-
 (defn int->local-time-2
   [n]
   (tf/unparse

+ 1 - 2
src/main/frontend/db.cljs

@@ -89,8 +89,7 @@
     (when conn
       (let [db (d/db conn)
             db-str (if db (db->string db) "")]
-        (p/let [_ (db-persist/save-graph! key db-str)]
-          (state/set-last-persist-transact-id! repo false (get-max-tx-id db)))))))
+        (p/let [_ (db-persist/save-graph! key db-str)])))))
 
 (defonce persistent-jobs (atom {}))
 

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

@@ -15,7 +15,6 @@
             [frontend.format :as format]
             [frontend.state :as state]
             [frontend.util :as util :refer [react]]
-            [medley.core :as medley]
             [frontend.db.rules :refer [rules]]
             [frontend.db.default :as default-db]))
 
@@ -272,12 +271,6 @@
       conn)
      (flatten))))
 
-(defn get-file-by-path
-  [file-path]
-  (when-let [repo (state/get-current-repo)]
-    (when-let [conn (conn/get-conn repo)]
-      (d/pull conn '[*] [:file/path file-path]))))
-
 (defn get-custom-css
   []
   (when-let [repo (state/get-current-repo)]
@@ -351,16 +344,6 @@
      (->> (db-utils/pull-many repo '[:block/name] ids)
           (map :block/name)))))
 
-(defn get-page-ids-by-names
-  ([names]
-   (get-page-ids-by-names (state/get-current-repo) names))
-  ([repo names]
-   (when repo
-     (let [lookup-refs (map (fn [name]
-                              [:block/name (util/page-name-sanity-lc name)]) names)]
-       (->> (db-utils/pull-many repo '[:db/id] lookup-refs)
-            (mapv :db/id))))))
-
 (defn get-page-alias-names
   [repo page-name]
   (let [alias-ids (page-alias-set repo page-name)]
@@ -613,7 +596,7 @@
 (defn get-block-parents-v2
   [repo block-id]
   (d/pull (conn/get-conn repo)
-          '[:db/id :block/properties {:block/parent ...}]
+          '[:db/id :block/collapsed? :block/properties {:block/parent ...}]
           [:block/uuid block-id]))
 
 (defn parents-collapsed?
@@ -936,15 +919,6 @@
                                db-utils/seq-flatten)]
       (mapv (fn [page] [page (get-page-alias repo page)]) mentioned-pages))))
 
-(defn remove-children!
-  [blocks]
-  (let [parents (->> (mapcat :block/parent blocks)
-                     (map :db/id)
-                     (set))]
-    (if (seq parents)
-      (filter (fn [block] (contains? parents (:db/id block))) blocks)
-      blocks)))
-
 (defn has-children?
   ([block-id]
    (has-children? (state/get-current-repo) block-id))
@@ -955,27 +929,6 @@
        (let [result (d/datoms db :avet :block/parent (:db/id block))]
          (boolean (seq result)))))))
 
-;; TODO: improve perf
-(defn with-children-refs
-  [repo blocks]
-  (when-let [conn (conn/get-conn repo)]
-    (when (seq blocks)
-      (let [block-ids (set (map :db/id blocks))
-            refs (d/q
-                  '[:find ?p ?ref
-                    :in $ % ?block-ids
-                    :where
-                    (parent ?p ?b)
-                    [(contains? ?block-ids ?p)]
-                    [?b :block/refs ?ref]]
-                  conn
-                  rules
-                  block-ids)
-            refs (->> (group-by first refs)
-                      (medley/map-vals #(set (map (fn [[_ id]] {:db/id id}) %))))]
-        (map (fn [block] (assoc block :block/children-refs
-                                (get refs (:db/id block)))) blocks)))))
-
 (defn get-page-referenced-blocks-no-cache
   [page-id]
   (when-let [repo (state/get-current-repo)]
@@ -1025,7 +978,6 @@
                          (sort-by-left-recursive)
                          (remove (fn [block]
                                    (= page-id (:db/id (:block/page block)))))
-                         ;; (with-children-refs repo)
                          db-utils/group-by-page
                          (map (fn [[k blocks]]
                                 (let [k (if (contains? aliases (:db/id k))
@@ -1227,11 +1179,6 @@
   [repo]
   (db-utils/get-key-value repo :db/type))
 
-(defn db-graph?
-  "Is current graph a database graph instead of a graph on plain-text files?"
-  []
-  (= :database (get-db-type (state/get-current-repo))))
-
 (defn get-public-pages
   [db]
   (-> (d/q
@@ -1436,19 +1383,6 @@
     (when (seq pages)
       (mapv (fn [page] [:db.fn/retractEntity [:block/name page]]) (map util/page-name-sanity-lc pages)))))
 
-(defn remove-all-aliases!
-  [repo]
-  (let [page-ids (->>
-                  (d/q '[:find ?e
-                         :where
-                         [?e :block/alias]]
-                       (conn/get-conn repo))
-                  (apply concat)
-                  (distinct))
-        tx-data (map (fn [page-id] [:db/retract page-id :block/alias]) page-ids)]
-    (when (seq tx-data)
-      (db-utils/transact! repo tx-data))))
-
 (defn set-file-content!
   [repo path content]
   (when (and repo path)
@@ -1526,18 +1460,6 @@
                                 {:block/file [:db/id :file/path]}]
                               ids))))))
 
-(defn get-latest-changed-pages
-  [repo]
-  (->>
-   (d/q
-     '[:find [(pull ?page [:block/name :block/file :block/updated-at]) ...]
-       :where
-       [?page :block/name]]
-     (conn/get-conn repo))
-   (filter :block/file)
-   (sort-by :block/updated-at >)
-   (take 200)))
-
 (defn get-orphaned-pages
   [{:keys [repo pages empty-ref-f]
           :or {repo (state/get-current-repo)
@@ -1571,12 +1493,6 @@
                         (remove nil?))]
     orphaned-pages))
 
-(defn remove-orphaned-pages!
-  ([repo] (remove-orphaned-pages! repo (get-orphaned-pages {})))
-  ([repo orphaned-pages]
-   (let [transaction (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)]
-     (db-utils/transact! repo transaction))))
-
 (defn get-block-last-direct-child
   [db-id]
   (when-let [block (db-utils/entity db-id)]

+ 1 - 16
src/main/frontend/db/outliner.cljs

@@ -1,8 +1,5 @@
 (ns frontend.db.outliner
-  (:require [datascript.core :as d]
-            [frontend.db :as db]
-            [frontend.db.utils :as db-utils]
-            [frontend.util :as util]))
+  (:require [datascript.core :as d]))
 
 (defn get-by-id
   [conn id]
@@ -28,14 +25,6 @@
     :where
     [?a :block/parent ?id]])
 
-(defn save-block
-  [conn block-m]
-  (let [tx (-> (dissoc block-m :block/children :block/level :block/meta)
-             (util/remove-nils))
-        block-id (:block/uuid block-m)]
-    (d/transact! conn [tx])
-    (db-utils/pull [:block/uuid block-id])))
-
 (defn del-block
   [conn id-or-look-ref]
   (d/transact! conn [[:db.fn/retractEntity id-or-look-ref]]))
@@ -53,7 +42,3 @@
                  [?a :block/journal? true]]
                @conn)]
     (flatten r)))
-
-(defn remove-non-existed-refs!
-  [refs]
-  (filter db/entity refs))

+ 1 - 6
src/main/frontend/db/react.cljs

@@ -12,8 +12,7 @@
             [frontend.db.utils :as db-utils]
             [frontend.state :as state]
             [frontend.util :as util :refer [react]]
-            [frontend.util.marker :as marker]
-            [frontend.db.rules :as rules]))
+            [frontend.util.marker :as marker]))
 
 ;; Query atom of map of Key ([repo q inputs]) -> atom
 ;; TODO: replace with LRUCache, only keep the latest 20 or 50 items?
@@ -136,10 +135,6 @@
          (set! (.-state result-atom) result)
          (add-q! k nil nil result-atom identity identity identity))))))
 
-(defn add-rules-to-inputs
-  [inputs]
-  (conj (vec inputs) rules/rules))
-
 (defn q
   [repo k {:keys [use-cache? transform-fn query-fn inputs-fn disable-reactive?]
            :or {use-cache? true

+ 0 - 19
src/main/frontend/diff.cljs

@@ -1,36 +1,17 @@
 (ns frontend.diff
   (:require [clojure.string :as string]
             ["diff" :as jsdiff]
-            ["diff-match-patch" :as diff-match-patch]
             [goog.object :as gobj]
             [lambdaisland.glogi :as log]
             [cljs-bean.core :as bean]
             [frontend.util :as util]
             [frontend.text :as text]))
 
-;; TODO: replace with diff-match-patch
 (defn diff
   [s1 s2]
   (-> ((gobj/get jsdiff "diffLines") s1 s2)
       bean/->clj))
 
-(defonce dmp (diff-match-patch.))
-
-(defn diffs
-  [s1 s2]
-  (.diff_main dmp s1 s2 true))
-
-(defn get-patches
-  [s1 s2 diffs]
-  (.patch_make dmp s1 s2 diffs))
-
-(defn apply-patches!
-  [text patches]
-  (if (seq patches)
-    (let [result (.patch_apply dmp patches text)]
-      (nth result 0))
-    text))
-
 (def inline-special-chars
   #{\* \_ \/ \` \+ \^ \~ \$})
 

+ 0 - 2
src/main/frontend/extensions/excalidraw.cljs

@@ -27,8 +27,6 @@
          (util/format "Could not load this invalid excalidraw file")
          :error)))))
 
-(defonce *bounding-width (atom nil))
-
 (defn- update-draw-content-width
   [state]
   (let [el ^js (rum/dom-node state)

+ 0 - 4
src/main/frontend/extensions/graph.cljs

@@ -44,10 +44,6 @@
         (.unhoverNode ^js graph node)
         (route-handler/redirect-to-page! page-name)))))
 
-(defn reset-graph!
-  [^js graph]
-  (.resetView graph))
-
 (rum/defcs graph-2d <
   (rum/local nil :ref)
   {:did-update pixi/render!

+ 0 - 2
src/main/frontend/extensions/graph/pixi.cljs

@@ -97,8 +97,6 @@
     (reset! *graph-instance nil)
     (reset! *simulation nil)))
 
-(defonce *dark? (atom nil))
-
 (defn- update-position!
   [node obj]
   (.updatePosition node #js {:x (.-x obj)

+ 0 - 2
src/main/frontend/extensions/pdf/assets.cljs

@@ -14,8 +14,6 @@
             [reitit.frontend.easy :as rfe]
             [rum.core :as rum]))
 
-(defonce *asset-uploading? (atom false))
-
 (defn hls-file?
   [filename]
   (and filename (string? filename) (string/starts-with? filename "hls__")))

+ 0 - 4
src/main/frontend/extensions/pdf/utils.cljs

@@ -113,10 +113,6 @@
   (when (sequential? its)
     (mapv #(if (map? %) % (bean/->clj %)) its)))
 
-(defn gen-id []
-  (str (.toString (js/Date.now) 36)
-       (.. (js/Math.random) (toString 36) (substr 2 4))))
-
 (defn gen-uuid []
   (front-db/new-block-id))
 

+ 0 - 24
src/main/frontend/format/block.cljs

@@ -136,38 +136,18 @@
                (util/uuid-string? block-id))
       block-id)))
 
-;; FIXME:
-(defn extract-title
-  [block]
-  (-> (:title (second block))
-      first
-      second))
-
 (defn paragraph-block?
   [block]
   (and
    (vector? block)
    (= "Paragraph" (first block))))
 
-(defn hiccup-block?
-  [block]
-  (and
-   (vector? block)
-   (= "Hiccup" (first block))))
-
 (defn timestamp-block?
   [block]
   (and
    (vector? block)
    (= "Timestamp" (first block))))
 
-(defn definition-list-block?
-  [block]
-  (and
-   (vector? block)
-   (= "List" (first block))
-   (:name (first (second block)))))
-
 ;; TODO: we should move this to mldoc
 (defn extract-properties
   [properties]
@@ -418,10 +398,6 @@
                                 [:block/name (util/page-name-sanity-lc tag)])) tags))
     block))
 
-(defn src-block?
-  [block]
-  (some (fn [x] (and (vector? x) (= "Src" (first x)))) (:body block)))
-
 (defn- get-block-content
   [utf8-content block format block-content]
   (let [meta (:meta block)

+ 1 - 1
src/main/frontend/fs/capacitor_fs.cljs

@@ -251,7 +251,7 @@
                   (.pickFolder mobile-util/folder-picker)
                   #(js->clj % :keywordize-keys true)
                   :path)
-            _ (when (mobile-util/native-ios?) (.downloadFilesFromiCloud mobile-util/download-icloud-files))
+            _ (when (mobile-util/native-ios?) (mobile-util/sync-icloud-repo path))
             files (readdir path)
             files (js->clj files :keywordize-keys true)]
       (into [] (concat [{:path path}] files))))

+ 0 - 61
src/main/frontend/git.cljs

@@ -4,7 +4,6 @@
             [frontend.util :as util]
             [frontend.config :as config]
             [clojure.string :as string]
-            [clojure.set :as set]
             [frontend.state :as state]
             [cljs-bean.core :as bean]))
 
@@ -65,20 +64,6 @@
   (js/window.workerThread.checkout (config/get-repo-dir repo-url)
                                    (state/get-default-branch repo-url)))
 
-(defn log
-  [repo-url depth]
-  (js/window.workerThread.log (config/get-repo-dir repo-url)
-                              (state/get-default-branch repo-url)
-                              depth))
-
-(defn pull
-  [repo-url token]
-  (js/window.workerThread.pull (config/get-repo-dir repo-url)
-                               (get-cors-proxy repo-url)
-                               (state/get-default-branch repo-url)
-                               (get-username)
-                               token))
-
 (defn add
   [repo-url file]
   (when js/window.git
@@ -131,16 +116,6 @@
                      (add repo-url file)))]
     changed-files))
 
-(defn commit-non-empty
-  "Equivalent to `git add --all` and then `git commit` without `--allow-empty`."
-  ([repo-url message]
-   (commit-non-empty repo-url message nil))
-  ([repo-url message parent]
-   (p/let [changed-files (add-all repo-url)]
-     (if (not-empty changed-files)
-       (commit repo-url message parent)
-       (p/resolved nil)))))
-
 (defn read-commit
   [repo-url oid]
   (js/window.workerThread.readCommit (config/get-repo-dir repo-url)
@@ -175,18 +150,6 @@
                                 (get-username)
                                 token)))
 
-(defn add-commit
-  [repo-url file message commit-ok-handler commit-error-handler]
-  (util/p-handle
-   (add repo-url file)
-   (fn [_]
-     (util/p-handle
-      (commit repo-url message)
-      (fn []
-        (commit-ok-handler))
-      (fn [error]
-        (commit-error-handler error))))))
-
 (defn get-diffs
   [repo-url hash-1 hash-2]
   (and js/window.git
@@ -198,30 +161,6 @@
                               (update diff :path #(subs % 1))) diffs)]
            diffs))))
 
-(defn find-common-base
-  ([repo-url remote-id local-id]
-   (find-common-base repo-url remote-id local-id (atom [local-id]) (atom [remote-id])))
-  ([repo-url remote-id local-id local-commits remote-commits]
-   ;; FIXME: p/plet not working
-   (p/let
-    [local-commit (read-commit repo-url local-id)]
-     (p/let [remote-commit (read-commit repo-url remote-id)]
-       (let [local-parent (first (get-in (bean/->clj local-commit) [:commit :parent]))
-
-             remote-parent (first (get-in (bean/->clj remote-commit) [:commit :parent]))]
-         (swap! local-commits conj local-parent)
-         (swap! remote-commits conj remote-parent)
-         (let [commons (set/intersection (set @local-commits)
-                                         (set @remote-commits))]
-           (if (seq commons)
-             (first commons)
-             (find-common-base repo-url local-parent remote-parent local-commits remote-commits))))))))
-
-(defn read-blob
-  [repo-url oid path]
-  (js/window.workerThread.readBlob (config/get-repo-dir repo-url)
-                                   oid
-                                   path))
 ;; (resolve-ref (state/get-current-repo) "refs/remotes/origin/master")
 (defn resolve-ref
   [repo-url ref]

+ 0 - 19
src/main/frontend/github.cljs

@@ -1,6 +1,5 @@
 (ns frontend.github
   (:require [frontend.util :as util]
-            [cljs-bean.core :as bean]
             [goog.crypt.base64 :as b64]))
 
 (defonce API "https://api.github.com/")
@@ -30,21 +29,3 @@
                         :content content}))
                     (fn [error]
                       (error-handler error)))))
-
-;; GET /repos/:owner/:repo/collaborators/:username/permission
-(defn get-repo-permission
-  [token repo-url current-user-name true-handler false-handler]
-  (let [[owner repo-name] (util/get-git-owner-and-repo repo-url)
-        token (str "Basic " (b64/encodeString (str owner ":" token)))
-        url (util/format (str API "repos/%s/%s/collaborators/%s/permission")
-                         owner
-                         repo-name
-                         current-user-name)]
-    (util/fetch url
-                (bean/->js {:method "get"
-                            :headers {:Accept "application/json"
-                                      :Content-Type "application/json"
-                                      :Authorization token}})
-                (fn [result] (true-handler result))
-                (fn [_error]
-                  (false-handler)))))

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

@@ -2,7 +2,6 @@
   (:require [cljs-bean.core :as bean]
             [electron.ipc :as ipc]
             [electron.listener :as el]
-            [frontend.components.editor :as editor]
             [frontend.components.page :as page]
             [frontend.config :as config]
             [frontend.db :as db]
@@ -206,7 +205,6 @@
 (defn- register-components-fns!
   []
   (state/set-page-blocks-cp! page/page-blocks-cp)
-  (state/set-editor-cp! editor/box)
   (command-palette/register-global-shortcut-commands))
 
 (defn start!

+ 11 - 11
src/main/frontend/handler/block.cljs

@@ -4,17 +4,17 @@
             [frontend.db :as db]
             [frontend.format.block :as block]))
 
-(defn get-block-ids
-  [block]
-  (let [ids (atom [])
-        _ (walk/prewalk
-           (fn [form]
-             (when (map? form)
-               (when-let [id (:block/uuid form)]
-                 (swap! ids conj id)))
-             form)
-           block)]
-    @ids))
+;; lazy loading
+
+(def initial-blocks-length 200)
+
+(def step-loading-blocks 50)
+
+;;  Fns
+
+(defn long-page?
+  [repo page-id]
+  (>= (db/get-page-blocks-count repo page-id) initial-blocks-length))
 
 (defn get-block-refs-with-children
   [block]

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

@@ -6,7 +6,6 @@
             [frontend.state :as state]
             [frontend.util :as util]))
 
-
 (defn- moveable?
   [current-block target-block]
   (let [current-block-uuid (:block/uuid current-block)]
@@ -27,9 +26,7 @@
   2. Move a block between two different files.
 
   Notes:
-  1. Those two blocks might have different formats, e.g. one is `org` and another is `markdown`,
-     we don't handle this now. TODO: transform between different formats in mldoc.
-  2. Sometimes we might need to move a parent block to it's own child.
+  Sometimes we might need to move a parent block to it's own child.
   "
   [^js event current-block target-block move-to]
   (let [top? (= move-to :top)
@@ -37,6 +34,12 @@
         alt-key? (and event (.-altKey event))
         repo (state/get-current-repo)]
     (cond
+      (not= (:block/format current-block) (:block/format target-block))
+      (state/pub-event! [:notification/show
+                         {:content [:div "Those two pages have different formats."]
+                          :status :warning
+                          :clear? true}])
+
       alt-key?
       (do
         (editor-handler/set-block-property! (:block/uuid current-block)

+ 10 - 83
src/main/frontend/handler/editor.cljs

@@ -16,7 +16,6 @@
             [frontend.db.model :as db-model]
             [frontend.db.utils :as db-utils]
             [frontend.diff :as diff]
-            [frontend.extensions.html-parser :as html-parser]
             [frontend.format.block :as block]
             [frontend.format.mldoc :as mldoc]
             [frontend.fs :as fs]
@@ -256,16 +255,6 @@
          (clear-selection!)
          (state/set-editing! edit-input-id content block text-range move-cursor?))))))
 
-(defn edit-last-block-for-new-page!
-  [last-block pos]
-  (when-let [first-block (util/get-first-block-by-id (:block/uuid last-block))]
-    (edit-block!
-     last-block
-     pos
-     (string/replace (gobj/get first-block "id")
-                     "ls-block"
-                     "edit-block"))))
-
 (defn- another-block-with-same-id-exists?
   [current-id block-id]
   (and (string? block-id)
@@ -293,12 +282,14 @@
                                              (mapv (fn [attribute]
                                                      [:db/retract id attribute])
                                                    [:block/properties :block/tags :block/alias]))
+                        tags (->> (map str->page tags) (remove nil?))
+                        alias (->> (map str->page alias) (remove nil?))
                         tx (cond-> {:db/id id
                                     :block/properties page-properties}
                              (seq tags)
-                             (assoc :block/tags (map str->page tags))
+                             (assoc :block/tags tags)
                              (seq alias)
-                             (assoc :block/alias (map str->page alias)))]
+                             (assoc :block/alias alias))]
                     (conj retract-attributes tx))]
       (assoc block
              :block/refs refs
@@ -307,9 +298,11 @@
 
 (defn- remove-non-existed-refs!
   [refs]
-  (remove (fn [x] (and (vector? x)
-                       (= :block/uuid (first x))
-                       (nil? (db/entity x)))) refs))
+  (remove (fn [x] (or
+                   (and (vector? x)
+                        (= :block/uuid (first x))
+                        (nil? (db/entity x)))
+                   (nil? x))) refs))
 
 (defn- with-marker-time
   [content block format new-marker old-marker]
@@ -1445,18 +1438,6 @@
   (let [block (state/drop-last-selection-block!)]
     (util/select-unhighlight! [block])))
 
-(defn input-start-or-end?
-  ([input]
-   (input-start-or-end? input nil))
-  ([input up?]
-   (let [value (gobj/get input "value")
-         start (util/get-selection-start input)
-         end (util/get-selection-end input)]
-     (if (nil? up?)
-       (or (= start 0) (= end (count value)))
-       (or (and (= start 0) up?)
-           (and (= end (count value)) (not up?)))))))
-
 (defn highlight-selection-area!
   [end-block]
   (when-let [start-block (state/get-selection-start-block)]
@@ -1773,10 +1754,6 @@
          "$" "$"
          ":" ":"))
 
-(def reversed-delete-map
-  (zipmap (vals delete-map)
-          (keys delete-map)))
-
 (defn autopair
   [input-id prefix _format _option]
   (let [value (get autopair-map prefix)
@@ -1899,22 +1876,6 @@
       (state/get-editor-show-template-search?)
       (state/get-editor-show-date-picker?)))
 
-(defn get-previous-input-char
-  [input]
-  (when-let [pos (cursor/pos input)]
-    (let [value (gobj/get input "value")]
-      (when (and (>= (count value) pos)
-                 (>= pos 1))
-        (util/nth-safe value (- pos 1))))))
-
-(defn get-previous-input-chars
-  [input length]
-  (when-let [pos (cursor/pos input)]
-    (let [value (gobj/get input "value")]
-      (when (and (>= (count value) pos)
-                 (>= pos 1))
-        (subs value (- pos length) pos)))))
-
 (defn get-current-input-char
   [input]
   (when-let [pos (cursor/pos input)]
@@ -1923,15 +1884,6 @@
                  (>= pos 1))
         (util/nth-safe value pos)))))
 
-(defn append-paste-doc!
-  [format event]
-  (let [[html text] (util/get-clipboard-as-html event)]
-    (when-not (util/starts-with? (string/trim text) "http")
-      (let [doc-text (html-parser/parse format html)]
-        (when-not (string/blank? doc-text)
-          (util/stop event)
-          (state/append-current-edit-content! doc-text))))))
-
 (defn- reorder-selected-blocks
   [blocks]
   (let [repo (state/get-current-repo)
@@ -2067,14 +2019,6 @@
           (state/set-editor-show-page-search! false)
           (state/set-editor-show-page-search-hashtag! false))))))
 
-(defn save!
-  []
-  (when-let [repo (state/get-current-repo)]
-    (save-current-block!)
-
-    (when (string/starts-with? repo "https://") ; git repo
-      (repo-handler/auto-push!))))
-
 (defn resize-image!
   [block-id metadata full_text size]
   (let [new-meta (merge metadata size)
@@ -3552,7 +3496,7 @@
         :skip-transact? false}
        (doseq [block-id block-ids]
          (when-let [block (db/entity [:block/uuid block-id])]
-          (let [current-value (boolean (util/collapsed? block))]
+           (let [current-value (:block/collapsed? block)]
             (when-not (= current-value value)
               (let [block (outliner-core/block {:block/uuid block-id
                                                 :block/collapsed? value})]
@@ -3665,23 +3609,6 @@
    (let [blocks (all-blocks-with-level {:root-block block-id})]
      (set-blocks-collapsed! (map :block/uuid blocks) false))))
 
-(defn- get-block-with-its-children
-  [block-uuid]
-  (let [repo (state/get-current-repo)
-        children (db/get-block-children repo block-uuid)
-        block (db/pull [:block/uuid block-uuid])]
-    (cons block (seq children))))
-
-(defn expand-all?
-  [block-uuid]
-  (let [blocks (get-block-with-its-children block-uuid)]
-    (some util/collapsed? blocks)))
-
-(defn collapse-all?
-  [block-uuid]
-  (let [blocks (get-block-with-its-children block-uuid)]
-    (some #(collapsable? (:block/uuid %)) blocks)))
-
 (defn toggle-open! []
   (let [all-collapsed?
         (->> (all-blocks-with-level {:collapse? true})

+ 1 - 93
src/main/frontend/handler/export.cljs

@@ -10,7 +10,6 @@
             [frontend.external.roam-export :as roam-export]
             [frontend.format :as f]
             [frontend.format.protocol :as fp]
-            [frontend.handler.file :as file-handler]
             [frontend.modules.file.core :as outliner-file]
             [frontend.modules.outliner.tree :as outliner-tree]
             [frontend.publishing.html :as html]
@@ -59,17 +58,6 @@
    (outliner-tree/blocks->vec-tree (str (:block/uuid block)))
    (outliner-file/tree->file-content {:init-level 1})))
 
-
-(defn export-repo-as-json!
-  [repo]
-  (when-let [db (db/get-conn repo)]
-    (let [db-json (db/db->json db)
-          data-str (str "data:text/json;charset=utf-8," (js/encodeURIComponent db-json))]
-      (when-let [anchor (gdom/getElement "download-as-json")]
-        (.setAttribute anchor "href" data-str)
-        (.setAttribute anchor "download" (str (last (string/split repo #"/")) ".json"))
-        (.click anchor)))))
-
 (defn download-file!
   [file-path]
   (when-let [repo (state/get-current-repo)]
@@ -90,7 +78,7 @@
                                            (db/filter-only-public-pages-and-blocks db))
           db-str       (db/db->string db)
           state        (select-keys @state/state
-                                    [:ui/theme :ui/cycle-collapse
+                                    [:ui/theme
                                      :ui/sidebar-collapsed-blocks
                                      :ui/show-recent?
                                      :config])
@@ -141,20 +129,6 @@
           (.setAttribute anchor "download" (.-name zipfile))
           (.click anchor))))))
 
-(defn export-git-repo-as-zip!
-  [repo]
-  (p/let [files (file-handler/load-files repo)
-          contents (file-handler/load-multiple-files repo files)
-          files (zipmap files contents)
-          [owner repo-name] (util/get-git-owner-and-repo repo)
-          repo-name (str owner "-" repo-name)]
-    (when (seq files)
-      (p/let [zipfile (zip/make-zip repo-name files repo)]
-        (when-let [anchor (gdom/getElement "download")]
-          (.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile))
-          (.setAttribute anchor "download" (.-name zipfile))
-          (.click anchor))))))
-
 (defn get-md-file-contents
   [repo]
   #_:clj-kondo/ignore
@@ -391,16 +365,6 @@
                                     (f/get-default-config %2)
                                     (js/JSON.stringify (clj->js %3)))))
 
-(defn- convert-md-files-unordered-list-or-heading
-  [files heading-to-list?]
-  (->> files
-       (mapv (fn [{:keys [path content names format]}]
-               (when (first names)
-                 [path (fp/exportMarkdown f/mldoc-record content
-                                          (f/get-default-config format {:export-heading-to-list? heading-to-list? :export-keep-properties? true})
-                                          nil)])))
-       (remove nil?)))
-
 (defn- get-file-contents-with-suffix
   [repo]
   (let [conn (db/get-conn repo)
@@ -430,25 +394,6 @@
           (.setAttribute anchor "download" (.-name zipfile))
           (.click anchor))))))
 
-(defn export-page-as-markdown!
-  [page-name]
-  (when-let [repo (state/get-current-repo)]
-    (when-let [file (db/get-page-file page-name)]
-      (when-let [path (:file/path file)]
-        (when-let [content (get-page-content repo page-name)]
-          (let [names [page-name]
-                format (f/get-format path)
-                files [{:path path :content content :names names :format format}]
-                files
-                (export-files-as-markdown repo files (state/export-heading-to-list?))
-                data (js/Blob. [(second (first files))]
-                               (clj->js {:type "text/plain;charset=utf-8,"}))
-                anchor (gdom/getElement "export-page-as-markdown")
-                url (js/window.URL.createObjectURL data)]
-            (.setAttribute anchor "href" url)
-            (.setAttribute anchor "download" path)
-            (.click anchor)))))))
-
 (defn export-repo-as-opml!
   #_:clj-kondo/ignore
   [repo]
@@ -462,43 +407,6 @@
                  (.setAttribute anchor "download" (.-name zipfile))
                  (.click anchor)))))))
 
-(defn export-page-as-opml!
-  [page-name]
-  (when-let [repo (state/get-current-repo)]
-    (when-let [file (db/get-page-file page-name)]
-      (when-let [path (:file/path file)]
-        (when-let [content (get-page-content repo page-name)]
-          (let [names [page-name]
-                format (f/get-format path)
-                files [{:path path :content content :names names :format format}]
-                files (export-files-as-opml repo files)
-                data (js/Blob. [(second (first files))]
-                               (clj->js {:type "text/plain;charset=utf-8,"}))
-                anchor (gdom/getElement "export-page-as-opml")
-                url (js/window.URL.createObjectURL data)
-                opml-path (string/replace (string/lower-case path) #"(.+)\.(md|org|markdown)$" "$1.opml")]
-            (.setAttribute anchor "href" url)
-            (.setAttribute anchor "download" opml-path)
-            (.click anchor)))))))
-
-(defn convert-page-markdown-unordered-list-or-heading!
-  [page-name]
-  (when-let [repo (state/get-current-repo)]
-    (when-let [file (db/get-page-file page-name)]
-      (when-let [path (:file/path file)]
-        (when-let [content (get-page-content repo page-name)]
-          (let [names [page-name]
-                format (f/get-format path)
-                files [{:path path :content content :names names :format format}]
-                files (convert-md-files-unordered-list-or-heading files (state/export-heading-to-list?))
-                data (js/Blob. [(second (first files))]
-                               (clj->js {:type "text/plain;charset=utf-8,"}))
-                anchor (gdom/getElement "convert-markdown-to-unordered-list-or-heading")
-                url (js/window.URL.createObjectURL data)]
-            (.setAttribute anchor "href" url)
-            (.setAttribute anchor "download" path)
-            (.click anchor)))))))
-
 (defn- dissoc-properties [m ks]
   (if (:block/properties m)
     (update m :block/properties

+ 41 - 39
src/main/frontend/handler/extract.cljs

@@ -66,48 +66,50 @@
                                      :block/page [:block/name page-name]
                                      :block/refs block-ref-pages
                                      :block/path-refs block-path-ref-pages))))
-                      blocks)
+                   blocks)
           page-entity (let [alias (:alias properties)
                             alias (if (string? alias) [alias] alias)
                             aliases (and alias
                                          (seq (remove #(= page-name (util/page-name-sanity-lc %))
-                                                      alias)))]
+                                                      alias)))
+                            aliases (->>
+                                     (map
+                                       (fn [alias]
+                                         (let [page-name (util/page-name-sanity-lc alias)
+                                               aliases (distinct
+                                                        (conj
+                                                         (remove #{alias} aliases)
+                                                         page))
+                                               aliases (when (seq aliases)
+                                                         (map
+                                                           (fn [alias]
+                                                             {:block/name (util/page-name-sanity-lc alias)})
+                                                           aliases))]
+                                           (if (seq aliases)
+                                             {:block/name page-name
+                                              :block/alias aliases}
+                                             {:block/name page-name})))
+                                       aliases)
+                                     (remove nil?))]
                         (cond->
-                         (util/remove-nils
-                          (assoc
-                           (block/page-name->map page false)
-                           :block/file {:file/path (util/path-normalize file)}))
-                         (seq properties)
-                         (assoc :block/properties properties)
+                          (util/remove-nils
+                           (assoc
+                            (block/page-name->map page false)
+                            :block/file {:file/path (util/path-normalize file)}))
+                          (seq properties)
+                          (assoc :block/properties properties)
 
-                         aliases
-                         (assoc :block/alias
-                                (map
-                                 (fn [alias]
-                                   (let [page-name (util/page-name-sanity-lc alias)
-                                         aliases (distinct
-                                                  (conj
-                                                   (remove #{alias} aliases)
-                                                   page))
-                                         aliases (when (seq aliases)
-                                                   (map
-                                                    (fn [alias]
-                                                      {:block/name (util/page-name-sanity-lc alias)})
-                                                    aliases))]
-                                     (if (seq aliases)
-                                       {:block/name page-name
-                                        :block/alias aliases}
-                                       {:block/name page-name})))
-                                 aliases))
+                          (seq aliases)
+                          (assoc :block/alias aliases)
 
-                         (:tags properties)
-                         (assoc :block/tags (let [tags (:tags properties)
-                                                  tags (if (string? tags) [tags] tags)
-                                                  tags (remove string/blank? tags)]
-                                              (swap! ref-tags set/union (set tags))
-                                              (map (fn [tag] {:block/name (util/page-name-sanity-lc tag)
-                                                              :block/original-name tag})
-                                                   tags)))))
+                          (:tags properties)
+                          (assoc :block/tags (let [tags (:tags properties)
+                                                   tags (if (string? tags) [tags] tags)
+                                                   tags (remove string/blank? tags)]
+                                               (swap! ref-tags set/union (set tags))
+                                               (map (fn [tag] {:block/name (util/page-name-sanity-lc tag)
+                                                               :block/original-name tag})
+                                                 tags)))))
           namespace-pages (let [page (:block/original-name page-entity)]
                             (when (text/namespace-page? page)
                               (->> (util/split-namespace-pages page)
@@ -118,10 +120,10 @@
                       [page-entity]
                       @ref-pages
                       (map
-                       (fn [page]
-                         {:block/original-name page
-                          :block/name (util/page-name-sanity-lc page)})
-                       @ref-tags)
+                        (fn [page]
+                          {:block/original-name page
+                           :block/name (util/page-name-sanity-lc page)})
+                        @ref-tags)
                       namespace-pages)
                      ;; remove block references
                      (remove vector?)

+ 0 - 24
src/main/frontend/handler/file.cljs

@@ -16,7 +16,6 @@
             [frontend.git :as git]
             [frontend.handler.common :as common-handler]
             [frontend.handler.extract :as extract-handler]
-            [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.state :as state]
             [frontend.utf8 :as utf8]
@@ -234,18 +233,6 @@
   (alter-file repo path new-content {:reset? false
                                      :re-render-root? false}))
 
-(defn create!
-  ([path]
-   (create! path ""))
-  ([path content]
-   (when-let [repo (state/get-current-repo)]
-     (when (and path content)
-       (p/let [_ (alter-file repo path content {:reset? false
-                                                :re-render-root? false
-                                                :update-status? true})]
-         (route-handler/redirect! {:to :file
-                                   :path-params {:path path}}))))))
-
 (defn alter-files
   [repo files {:keys [reset? update-db?]
                :or {reset? false
@@ -388,14 +375,3 @@
             new-result (rewrite/assoc-in result ks v)
             new-content (str new-result)]
         (set-file-content! repo path new-content)))))
-
-;; TODO:
-;; (defn compare-latest-pages
-;;   []
-;;   (when-let [repo (state/get-current-repo)]
-;;     (doseq [{:block/keys [file name]} (db/get-latest-changed-pages repo)]
-;;       (when-let [path (:file/path (db/pull (:db/id file)))]
-;;         (p/let [content (load-file repo path)]
-;;           (when (not= (string/trim content) (string/trim (or (db/get-file repo path) "")))
-;;             ;; notify
-;;             ))))))

+ 0 - 4
src/main/frontend/handler/notification.cljs

@@ -7,10 +7,6 @@
   (let [contents (state/get-notification-contents)]
     (state/set-state! :notification/contents (dissoc contents uid))))
 
-(defn clear-all!
-  []
-  (state/set-state! :notification/contents nil))
-
 (defn show!
   ([content status]
    (show! content status true nil))

+ 5 - 12
src/main/frontend/handler/repo.cljs

@@ -29,7 +29,7 @@
             [promesa.core :as p]
             [shadow.resource :as rc]
             [clojure.set :as set]
-            [frontend.mobile.util :as mobile]
+            [frontend.mobile.util :as mobile-util]
             [frontend.db.persist :as db-persist]
             [electron.ipc :as ipc]))
 
@@ -632,10 +632,11 @@
   [nfs-rebuild-index! ok-handler]
   (route-handler/redirect-to-home!)
   (when-let [repo (state/get-current-repo)]
-    (let [local? (config/local-db? repo)]
+    (let [local? (config/local-db? repo)
+          repo-dir (config/get-repo-dir repo)]
       (if local?
-        (p/let [_ (when (mobile/native-ios?)
-                    (.downloadFilesFromiCloud mobile/download-icloud-files))
+        (p/let [_ (when (mobile-util/native-ios?)
+                    (mobile-util/sync-icloud-repo repo-dir))
                 _ (metadata-handler/set-pages-metadata! repo)]
           (nfs-rebuild-index! repo ok-handler))
         (rebuild-index! repo))
@@ -649,11 +650,3 @@
   (when-let [repo (state/get-current-repo)]
     (push repo {:commit-message commit-message
                 :custom-commit? true})))
-
-(defn get-repo-name
-  [url]
-  (last (string/split url #"/")))
-
-(defn auto-push!
-  []
-  (git-commit-and-push! "Logseq auto save"))

+ 0 - 8
src/main/frontend/handler/ui.cljs

@@ -22,14 +22,6 @@
   (when-let [elem (gdom/getElement "close-left-bar")]
     (.click elem)))
 
-(defn hide-right-sidebar
-  []
-  (state/hide-right-sidebar!))
-
-(defn show-right-sidebar
-  []
-  (state/open-right-sidebar!))
-
 (defn toggle-right-sidebar!
   []
   (state/toggle-sidebar-open?!))

+ 0 - 12
src/main/frontend/mixins.cljs

@@ -77,12 +77,6 @@
       ;; TODO: Unable to find node on an unmounted component.
       nil)))
 
-(defn resize-layout
-  [state ref]
-  (listen state js/window "resize"
-          (fn [_e]
-            (reset! ref [js/window.innerWidth js/window.innerHeight]))))
-
 (defn on-enter
   [state & {:keys [on-enter node]}]
   (let [node (or node (rum/dom-node state))]
@@ -157,12 +151,6 @@
               :toggle-fn (fn []
                            (swap! open? not)))))))
 
-(defn will-mount-effect
-  [handler]
-  {:will-mount (fn [state]
-                 (handler (:rum/args state))
-                 state)})
-
 (def component-editing-mode
   {:will-mount
    (fn [state]

+ 10 - 5
src/main/frontend/mobile/core.cljs

@@ -12,7 +12,8 @@
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.notification :as notification]
             [promesa.core :as p]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [frontend.config :as config]))
 
 (defn init!
   []
@@ -50,12 +51,16 @@
   (when (mobile-util/is-native-platform?)
     (.addEventListener js/window "statusTap"
                        #(util/scroll-to-top true))
-    
+
     (.addListener App "appStateChange"
                   (fn [^js state]
                     (when-let [repo (state/get-current-repo)]
-                      (let [is-active? (.-isActive state)]
+                      (let [is-active? (.-isActive state)
+                            repo-dir (config/get-repo-dir repo)]
                         (if is-active?
-                          (p/do! (nfs-handler/refresh! repo repo/refresh-cb)
-                                 (notification/show! "Notes updated!" :success true))
+                          (p/do!
+                           (when (mobile-util/native-ios?)
+                               (mobile-util/sync-icloud-repo repo-dir))
+                           (nfs-handler/refresh! repo repo/refresh-cb)
+                           (notification/show! "Notes updated!" :success true))
                           (editor-handler/save-current-block!))))))))

+ 13 - 8
src/main/frontend/mobile/util.cljs

@@ -1,7 +1,7 @@
 (ns frontend.mobile.util
   (:require ["@capacitor/core" :refer [Capacitor registerPlugin]]
             ["@capacitor/splash-screen" :refer [SplashScreen]]
-            [clojure.string :as str]))
+            [clojure.string :as string]))
 
 (defn platform []
   (.getPlatform Capacitor))
@@ -20,15 +20,20 @@
 (defn convert-file-src [path-str]
   (.convertFileSrc Capacitor path-str))
 
-(defn is-plugin-available? [name]
-  (.isPluginAvailable Capacitor name))
-
 (defonce folder-picker (registerPlugin "FolderPicker"))
 (when (native-ios?)
  (defonce download-icloud-files (registerPlugin "DownloadiCloudFiles")))
 (when (native-ios?)
   (defonce ios-file-container (registerPlugin "FileContainer")))
 
+(defn sync-icloud-repo [repo-dir]
+  (let [repo-name (-> (string/split repo-dir "Documents/")
+                      last
+                      string/trim
+                      js/decodeURI)]
+    (.syncGraph download-icloud-files
+                       (clj->js {:graph repo-name}))))
+
 (defn hide-splash []
   (.hide SplashScreen))
 
@@ -101,18 +106,18 @@
 (defn native-iphone-without-notch?
   []
   (when-let [model (get-idevice-model)]
-    (str/starts-with? (first model) "iPhone8")))
+    (string/starts-with? (first model) "iPhone8")))
 
 (defn native-iphone?
   []
   (when-let [model (get-idevice-model)]
-    (and (str/starts-with? (first model) "iPhone")
-         (not (str/starts-with? (first model) "iPhone8")))))
+    (and (string/starts-with? (first model) "iPhone")
+         (not (string/starts-with? (first model) "iPhone8")))))
 
 (defn native-ipad?
   []
   (when-let [model (get-idevice-model)]
-    (str/starts-with? (first model) "iPad")))
+    (string/starts-with? (first model) "iPad")))
 
 (defn get-idevice-statusbar-height
   []

+ 12 - 8
src/main/frontend/modules/outliner/core.cljs

@@ -625,13 +625,15 @@
   [root target-node sibling?]
   {:pre [(every? tree/satisfied-inode? [root target-node])
          (boolean? sibling?)]}
-  (let [target-node-id (tree/-get-id target-node)]
-    (when-not (or (and sibling?
-                       (= (tree/-get-left-id root) target-node-id)
-                       (not= (tree/-get-parent-id root) target-node-id))
-                  (and (not sibling?)
-                       (= (tree/-get-left-id root) target-node-id)
-                       (= (tree/-get-parent-id root) target-node-id)))
+  (if-let [target-node-id (tree/-get-id target-node)]
+    (when-not (and
+               (or (and sibling?
+                        (= (tree/-get-left-id root) target-node-id)
+                        (not= (tree/-get-parent-id root) target-node-id))
+                   (and (not sibling?)
+                        (= (tree/-get-left-id root) target-node-id)
+                        (= (tree/-get-parent-id root) target-node-id)))
+               (= target-node-id (tree/-get-id root)))
       (let [root-page (:db/id (:block/page (:data root)))
             target-page (:db/id (:block/page (:data target-node)))
             not-same-page? (not= root-page target-page)
@@ -649,7 +651,9 @@
            (let [new-root (first (if sibling?
                                    (insert-node-as-sibling txs-state root target-node)
                                    (insert-node-as-first-child txs-state root target-node)))]
-             (set-nodes-page new-root target-node txs-state))))))))
+             (when (not= root-page target-page)
+               (set-nodes-page new-root target-node txs-state)))))))
+    (js/console.trace)))
 
 (defn get-right-node
   [node]

+ 40 - 26
src/main/frontend/modules/outliner/datascript.cljc

@@ -7,7 +7,9 @@
                      [frontend.modules.editor.undo-redo :as undo-redo]
                      [frontend.state :as state]
                      [frontend.config :as config]
-                     [lambdaisland.glogi :as log])))
+                     [lambdaisland.glogi :as log]
+                     [frontend.util :as util]
+                     [medley.core :as medley])))
 
 #?(:cljs
    (defn new-outliner-txs-state [] (atom [])))
@@ -32,34 +34,46 @@
      (pipelines/invoke-hooks tx-report)
      (undo-redo/listen-outliner-operation tx-report)))
 
+#?(:cljs
+   (defn- remove-nil-from-transaction
+     [txs]
+     (some->> (util/remove-nils txs)
+              (map (fn [x]
+                     (if (map? x)
+                       (medley/map-vals (fn [v] (if (vector? v)
+                                                  (remove nil? v)
+                                                  v)) x)
+                       x))))))
+
 #?(:cljs
    (defn transact!
      [txs opts]
-     ;; (util/pprint txs)
-     (when (and (seq txs)
-                (not (:skip-transact? opts)))
-       (try
-         (let [conn (conn/get-conn false)
-               editor-cursor (state/get-current-edit-block-and-position)
-               meta (merge opts {:editor-cursor editor-cursor})
-               rs (d/transact! conn txs meta)]
-           (when true                 ; TODO: add debug flag
-             (let [eids (distinct (mapv first (:tx-data rs)))
-                   left&parent-list (->>
-                                     (d/q '[:find ?e ?l ?p
-                                            :in $ [?e ...]
-                                            :where
-                                            [?e :block/left ?l]
-                                            [?e :block/parent ?p]] @conn eids)
-                                     (vec)
-                                     (map next))]
-               (assert (= (count left&parent-list) (count (distinct left&parent-list))) eids)))
-           (when-not config/test?
-             (after-transact-pipelines rs))
-           rs)
-         (catch js/Error e
-           (log/error :exception e)
-           (throw e))))))
+     (let [txs (remove-nil-from-transaction txs)]
+       ;; (util/pprint txs)
+       (when (and (seq txs)
+                 (not (:skip-transact? opts)))
+        (try
+          (let [conn (conn/get-conn false)
+                editor-cursor (state/get-current-edit-block-and-position)
+                meta (merge opts {:editor-cursor editor-cursor})
+                rs (d/transact! conn txs meta)]
+            (when true                 ; TODO: add debug flag
+              (let [eids (distinct (mapv first (:tx-data rs)))
+                    left&parent-list (->>
+                                      (d/q '[:find ?e ?l ?p
+                                             :in $ [?e ...]
+                                             :where
+                                             [?e :block/left ?l]
+                                             [?e :block/parent ?p]] @conn eids)
+                                      (vec)
+                                      (map next))]
+                (assert (= (count left&parent-list) (count (distinct left&parent-list))) eids)))
+            (when-not config/test?
+              (after-transact-pipelines rs))
+            rs)
+          (catch js/Error e
+            (log/error :exception e)
+            (throw e)))))))
 
 #?(:clj
    (defmacro auto-transact!

+ 0 - 12
src/main/frontend/modules/outliner/utils.cljs

@@ -62,15 +62,3 @@
     id
 
     :else nil))
-
-(defn ->db-id
-  [x]
-  (cond
-    (map? x)
-    (:db/id x)
-
-    (number? x)
-    x
-
-    :else
-    (throw (js/Error. (util/format "Unknown db/id format: %s" x)))))

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

@@ -1,6 +1,5 @@
 (ns frontend.modules.shortcut.before
-  (:require [frontend.config :as config]
-            [frontend.state :as state]
+  (:require [frontend.state :as state]
             [frontend.util :as util]))
 
 ;; before function
@@ -32,7 +31,3 @@
   (fn [e]
     (when-not (state/block-component-editing?)
       (f e))))
-
-(defn only-enable-when-dev!
-  [_]
-  (boolean config/dev?))

+ 1 - 3
src/main/frontend/publishing.cljs

@@ -12,7 +12,6 @@
             [reitit.frontend.easy :as rfe]
             [cljs.reader :as reader]
             [frontend.components.page :as component-page]
-            [frontend.components.editor :as component-editor]
             [frontend.modules.shortcut.core :as shortcut]
             [frontend.handler.events :as events]))
 
@@ -62,8 +61,7 @@
 
 (defn- register-components-fns!
   []
-  (state/set-page-blocks-cp! component-page/page-blocks-cp)
-  (state/set-editor-cp! component-editor/box))
+  (state/set-page-blocks-cp! component-page/page-blocks-cp))
 
 (defn ^:export init []
   ;; init is called ONCE when the page loads

+ 0 - 5
src/main/frontend/rum.cljs

@@ -86,11 +86,6 @@
   [a]
   (use-atom-fn a identity (fn [_ v] v)))
 
-(defn use-atom-in
-  "(use-atom my-atom [:path :to :data])"
-  [a path]
-  (use-atom-fn a #(get-in % path) #(assoc-in %1 path %2)))
-
 (defn use-mounted
   []
   (let [*mounted (rum/use-ref false)]

+ 0 - 4
src/main/frontend/search/db.cljs

@@ -12,10 +12,6 @@
 
 (defonce indices (atom nil))
 
-(defn empty?
-  [repo]
-  (nil? (get @indices repo)))
-
 (defn block->content
   "Convert a block to the display contents for searching"
   [{:block/keys [content format]}]

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

@@ -37,14 +37,6 @@
 
 (s/def :me/repos (s/* :repos/repo))
 
-
-;; project
-
-(s/def :projects/name string?)
-(s/def :projects/repo string?)
-(s/def :projects/project (s/keys :req-un [:projects/name :projects/repo]))
-(s/def :me/projects (s/* :projects/project))
-
 ;; me
 
 (s/def :me/name string?)
@@ -57,9 +49,9 @@
 
 ;; state
 
-(s/def :state/me (s/keys :req-un [:me/name :me/email :me/avatar :me/repos :me/projects :me/preferred_format
+(s/def :state/me (s/keys :req-un [:me/name :me/email :me/avatar :me/repos :me/preferred_format
                                   :me/preferred_workflow :me/cors_proxy]))
 
 
 (comment
-  (validate :user/repo 1))
+  (validate :user/repo 1))

+ 180 - 330
src/main/frontend/state.cljs

@@ -23,190 +23,186 @@
                        (when graph (ipc/ipc "setCurrentGraph" graph))
                        graph)]
    (atom
-     {:route-match                           nil
-      :today                                 nil
-      :system/events                         (async/chan 100)
-      :db/batch-txs                          (async/chan 100)
-      :file/writes                           (async/chan 100)
-      :notification/show?                    false
-      :notification/content                  nil
-      :repo/cloning?                         false
-      :repo/loading-files?                   {}
-      :repo/importing-to-db?                 nil
-      :repo/sync-status                      {}
-      :repo/changed-files                    nil
-      :nfs/user-granted?                     {}
-      :nfs/refreshing?                       nil
-      :instrument/disabled?                  (storage/get "instrument-disabled")
-      ;; TODO: how to detect the network reliably?
-      :network/online?                       true
-      :indexeddb/support?                    true
-      :me                                    nil
-      :git/current-repo                      current-graph
-      :git/status                            {}
-      :format/loading                        {}
-      :draw?                                 false
-      :db/restoring?                         nil
-
-      :journals-length                       2
-
-      :search/q                              ""
-      :search/mode                           :global
-      :search/result                         nil
-      :search/graph-filters                  []
-
-      ;; modals
-      :modal/label                           ""
-      :modal/show?                           false
-      :modal/panel-content                   nil
-      :modal/fullscreen?                     false
-      :modal/close-btn?                      nil
-      :modal/subsets                         []
-
-      ;; right sidebar
-      :ui/fullscreen?                        false
-      :ui/settings-open?                     false
-      :ui/sidebar-open?                      false
-      :ui/left-sidebar-open?                 (boolean (storage/get "ls-left-sidebar-open?"))
-      :ui/theme                              (or (storage/get :ui/theme) (if (mobile-util/is-native-platform?) "light" "dark"))
-      :ui/system-theme?                      ((fnil identity (or util/mac? util/win32? false)) (storage/get :ui/system-theme?))
-      :ui/wide-mode?                         false
-      ;; :show-all, :hide-block-body, :hide-block-children
-      :ui/cycle-collapse                     :show-all
-
-      ;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
-      ;; 1. right sidebar
-      ;; 2. zoom-in view
-      ;; 3. queries
-      ;; 4. references
-      ;; graph => {:block-id bool}
-      :ui/collapsed-blocks                   {}
-      :ui/sidebar-collapsed-blocks           {}
-      :ui/root-component                     nil
-      :ui/file-component                     nil
-      :ui/custom-query-components            {}
-      :ui/show-recent?                       false
-      :ui/command-palette-open?              false
-      :ui/developer-mode?                    (or (= (storage/get "developer-mode") "true")
-                                                 false)
-      ;; remember scroll positions of visited paths
-      :ui/paths-scroll-positions             {}
-      :ui/shortcut-tooltip?                  (if (false? (storage/get :ui/shortcut-tooltip?))
-                                               false
-                                               true)
-      :ui/visual-viewport-pending?           false
-      :ui/visual-viewport-state              nil
-
-      :document/mode?                        document-mode?
-
-      :github/contents                       {}
-      :config                                {}
-      :block/component-editing-mode?         false
-      :editor/draw-mode?                     false
-      :editor/show-page-search?              false
-      :editor/show-page-search-hashtag?      false
-      :editor/show-date-picker?              false
-      ;; With label or other data
-      :editor/show-input                     nil
-      :editor/show-zotero                    false
-      :editor/last-saved-cursor              nil
-      :editor/editing?                       nil
-      :editor/last-edit-block-input-id       nil
-      :editor/in-composition?                false
-      :editor/content                        {}
-      :editor/block                          nil
-      :editor/block-dom-id                   nil
-      :editor/set-timestamp-block            nil
-      :editor/last-input-time                nil
-      :editor/pos                            nil
-      :editor/document-mode?                 document-mode?
-      :editor/args                           nil
-      :editor/on-paste?                      false
-      :editor/last-key-code                  nil
-
-      :db/last-transact-time                 {}
-      :db/last-persist-transact-ids          {}
-      ;; whether database is persisted
-      :db/persisted?                         {}
-      :db/latest-txs                         (or (storage/get-transit :db/latest-txs) {})
-      :cursor-range                          nil
-
-      :selection/mode                        false
-      :selection/blocks                      []
-      :selection/start-block                 nil
-      ;; either :up or :down, defaults to down
-      ;; used to determine selection direction when two or more blocks are selected
-      :selection/direction                   :down
-      :custom-context-menu/show?             false
-      :custom-context-menu/links             nil
-
-      ;; pages or blocks in the right sidebar
-      ;; It is a list of `[repo db-id block-type block-data]` 4-tuple
-      :sidebar/blocks                        '()
-
-      :preferred-language                    (storage/get :preferred-language)
-
-      ;; electron
-      :electron/auto-updater-downloaded      false
-      :electron/updater-pending?             false
-      :electron/updater                      {}
-      :electron/user-cfgs                    nil
-
-      ;; plugin
-      :plugin/enabled                        (and (util/electron?)
-                                                  ;; true false :theme-only
-                                                  ((fnil identity true) (storage/get :lsp-core-enabled)))
-      :plugin/indicator-text                 nil
-      :plugin/installed-plugins              {}
-      :plugin/installed-themes               []
-      :plugin/installed-commands             {}
-      :plugin/installed-ui-items             {}
-      :plugin/simple-commands                {}
-      :plugin/selected-theme                 nil
-      :plugin/selected-unpacked-pkg          nil
-      :plugin/marketplace-pkgs               nil
-      :plugin/marketplace-stats              nil
-      :plugin/installing                     nil
-      :plugin/active-readme                  nil
-      :plugin/updates-pending                {}
-      :plugin/updates-coming                 {}
-      :plugin/updates-downloading?           false
-      :plugin/updates-unchecked              #{}
-
-      ;; pdf
-      :pdf/current                           nil
-      :pdf/ref-highlight                     nil
-
-      ;; all notification contents as k-v pairs
-      :notification/contents                 {}
-      :graph/syncing?                        false
-
-      ;; copied blocks
-      :copy/blocks                           {:copy/content nil :copy/block-tree nil}
-
-      :copy/export-block-text-indent-style   (or (storage/get :copy/export-block-text-indent-style)
-                                                 "dashes")
-      :copy/export-block-text-remove-options (or (storage/get :copy/export-block-text-remove-options)
-                                                 #{})
-      :date-picker/date                      nil
-
-      :youtube/players                       {}
-
-      ;; command palette
-      :command-palette/commands              []
-
-      :view/components                       {}
-
-      :debug/write-acks                      {}
-
-      :encryption/graph-parsing?             false
-
-      :favorites/dragging                    nil
-
-      :srs/mode?                             false
-
-      :srs/cards-due-count                   nil
-      })))
+    {:route-match                           nil
+     :today                                 nil
+     :system/events                         (async/chan 100)
+     :db/batch-txs                          (async/chan 100)
+     :file/writes                           (async/chan 100)
+     :notification/show?                    false
+     :notification/content                  nil
+     :repo/cloning?                         false
+     :repo/loading-files?                   {}
+     :repo/importing-to-db?                 nil
+     :repo/changed-files                    nil
+     :nfs/user-granted?                     {}
+     :nfs/refreshing?                       nil
+     :instrument/disabled?                  (storage/get "instrument-disabled")
+     ;; TODO: how to detect the network reliably?
+     :network/online?                       true
+     :indexeddb/support?                    true
+     :me                                    nil
+     :git/current-repo                      current-graph
+     :git/status                            {}
+     :format/loading                        {}
+     :draw?                                 false
+     :db/restoring?                         nil
+
+     :journals-length                       2
+
+     :search/q                              ""
+     :search/mode                           :global
+     :search/result                         nil
+     :search/graph-filters                  []
+
+     ;; modals
+     :modal/label                           ""
+     :modal/show?                           false
+     :modal/panel-content                   nil
+     :modal/fullscreen?                     false
+     :modal/close-btn?                      nil
+     :modal/subsets                         []
+
+     ;; right sidebar
+     :ui/fullscreen?                        false
+     :ui/settings-open?                     false
+     :ui/sidebar-open?                      false
+     :ui/left-sidebar-open?                 (boolean (storage/get "ls-left-sidebar-open?"))
+     :ui/theme                              (or (storage/get :ui/theme) (if (mobile-util/is-native-platform?) "light" "dark"))
+     :ui/system-theme?                      ((fnil identity (or util/mac? util/win32? false)) (storage/get :ui/system-theme?))
+     :ui/wide-mode?                         false
+
+     ;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
+     ;; 1. right sidebar
+     ;; 2. zoom-in view
+     ;; 3. queries
+     ;; 4. references
+     ;; graph => {:block-id bool}
+     :ui/collapsed-blocks                   {}
+     :ui/sidebar-collapsed-blocks           {}
+     :ui/root-component                     nil
+     :ui/file-component                     nil
+     :ui/custom-query-components            {}
+     :ui/show-recent?                       false
+     :ui/command-palette-open?              false
+     :ui/developer-mode?                    (or (= (storage/get "developer-mode") "true")
+                                                false)
+     ;; remember scroll positions of visited paths
+     :ui/paths-scroll-positions             {}
+     :ui/shortcut-tooltip?                  (if (false? (storage/get :ui/shortcut-tooltip?))
+                                              false
+                                              true)
+     :ui/visual-viewport-pending?           false
+     :ui/visual-viewport-state              nil
+
+     :document/mode?                        document-mode?
+
+     :github/contents                       {}
+     :config                                {}
+     :block/component-editing-mode?         false
+     :editor/draw-mode?                     false
+     :editor/show-page-search?              false
+     :editor/show-page-search-hashtag?      false
+     :editor/show-date-picker?              false
+     ;; With label or other data
+     :editor/show-input                     nil
+     :editor/show-zotero                    false
+     :editor/last-saved-cursor              nil
+     :editor/editing?                       nil
+     ;; This key is not currently used but may be useful later?
+     :editor/last-edit-block-input-id       nil
+     :editor/in-composition?                false
+     :editor/content                        {}
+     :editor/block                          nil
+     :editor/block-dom-id                   nil
+     :editor/set-timestamp-block            nil
+     :editor/last-input-time                nil
+     :editor/pos                            nil
+     :editor/document-mode?                 document-mode?
+     :editor/args                           nil
+     :editor/on-paste?                      false
+     :editor/last-key-code                  nil
+
+     :db/last-transact-time                 {}
+     ;; whether database is persisted
+     :db/persisted?                         {}
+     :cursor-range                          nil
+
+     :selection/mode                        false
+     :selection/blocks                      []
+     :selection/start-block                 nil
+     ;; either :up or :down, defaults to down
+     ;; used to determine selection direction when two or more blocks are selected
+     :selection/direction                   :down
+     :custom-context-menu/show?             false
+     :custom-context-menu/links             nil
+
+     ;; pages or blocks in the right sidebar
+     ;; It is a list of `[repo db-id block-type block-data]` 4-tuple
+     :sidebar/blocks                        '()
+
+     :preferred-language                    (storage/get :preferred-language)
+
+     ;; electron
+     :electron/auto-updater-downloaded      false
+     :electron/updater-pending?             false
+     :electron/updater                      {}
+     :electron/user-cfgs                    nil
+
+     ;; plugin
+     :plugin/enabled                        (and (util/electron?)
+                                                 ;; true false :theme-only
+                                                 ((fnil identity true) (storage/get :lsp-core-enabled)))
+     :plugin/indicator-text                 nil
+     :plugin/installed-plugins              {}
+     :plugin/installed-themes               []
+     :plugin/installed-commands             {}
+     :plugin/installed-ui-items             {}
+     :plugin/simple-commands                {}
+     :plugin/selected-theme                 nil
+     :plugin/selected-unpacked-pkg          nil
+     :plugin/marketplace-pkgs               nil
+     :plugin/marketplace-stats              nil
+     :plugin/installing                     nil
+     :plugin/active-readme                  nil
+     :plugin/updates-pending                {}
+     :plugin/updates-coming                 {}
+     :plugin/updates-downloading?           false
+     :plugin/updates-unchecked              #{}
+
+     ;; pdf
+     :pdf/current                           nil
+     :pdf/ref-highlight                     nil
+
+     ;; all notification contents as k-v pairs
+     :notification/contents                 {}
+     :graph/syncing?                        false
+
+     ;; copied blocks
+     :copy/blocks                           {:copy/content nil :copy/block-tree nil}
+
+     :copy/export-block-text-indent-style   (or (storage/get :copy/export-block-text-indent-style)
+                                                "dashes")
+     :copy/export-block-text-remove-options (or (storage/get :copy/export-block-text-remove-options)
+                                                #{})
+     :date-picker/date                      nil
+
+     :youtube/players                       {}
+
+     ;; command palette
+     :command-palette/commands              []
+
+     :view/components                       {}
+
+     :debug/write-acks                      {}
+
+     :encryption/graph-parsing?             false
+
+     :favorites/dragging                    nil
+
+     :srs/mode?                             false
+
+     :srs/cards-due-count                   nil
+     })))
 
 ;; block uuid -> {content(String) -> ast}
 (def blocks-ast-cache (atom {}))
@@ -230,10 +226,6 @@
     (util/react (rum/cursor-in state ks))
     (util/react (rum/cursor state ks))))
 
-(defn sub-current-route
-  []
-  (get-in (sub :route-match) [:data :name]))
-
 (defn get-route-match
   []
   (:route-match @state))
@@ -454,10 +446,6 @@
     "LATER"
     "TODO"))
 
-(defn hide-file?
-  []
-  (:hide-file-in-page? (get-config)))
-
 (defn page-name-order
   "Decide whether to use file name or :title as page name. If it returns \"file\", use the file
   name unless it is missing."
@@ -512,22 +500,6 @@
   (when (= (get-current-repo) (:url repo))
     (set-current-repo! (:url (first (get-repos))))))
 
-(defn next-collapse-mode
-  []
-  (case (:ui/cycle-collapse @state)
-    :show-all
-    :hide-block-body
-
-    :hide-block-body
-    :hide-block-children
-
-    :hide-block-children
-    :show-all))
-
-(defn cycle-collapse!
-  []
-  (set-state! :ui/cycle-collapse (next-collapse-mode)))
-
 (defn set-timestamp-block!
   [value]
   (set-state! :editor/set-timestamp-block value))
@@ -564,10 +536,6 @@
   (when-let [id (get-edit-input-id)]
     (gdom/getElement id)))
 
-(defn get-last-edit-input-id
-  []
-  (:editor/last-edit-block-input-id @state))
-
 (defn editing?
   []
   (let [input (get-input)]
@@ -661,11 +629,6 @@
   [value]
   (set-state! :editor/show-zotero value))
 
-(defn get-editor-show-zotero
-  []
-  (get @state :editor/show-zotero))
-
-
 (defn set-edit-input-id!
   [input-id]
   (swap! state update :editor/editing?
@@ -706,10 +669,6 @@
          :selection/blocks nil
          :selection/direction :down))
 
-(defn clear-selection-blocks!
-  []
-  (swap! state assoc :selection/blocks nil))
-
 (defn get-selection-blocks
   []
   (util/sort-by-height (:selection/blocks @state)))
@@ -755,17 +714,6 @@
          :custom-context-menu/show? false
          :custom-context-menu/links nil))
 
-(defn set-github-token!
-  [repo token-result]
-  (when token-result
-    (let [{:keys [token expires_at]} token-result]
-      (swap! state update-in [:me :repos]
-             (fn [repos]
-               (map (fn [r]
-                      (if (= repo (:url r))
-                        (merge r {:token token :expires_at expires_at})
-                        repo)) repos))))))
-
 (defn set-github-installation-tokens!
   [tokens]
   (when (seq tokens)
@@ -835,10 +783,6 @@
   [idx]
   (some #(= (second %) idx) (:sidebar/blocks @state)))
 
-(defn get-sidebar-blocks
-  []
-  (:sidebar/blocks @state))
-
 (defn clear-sidebar-blocks!
   []
   (set-state! :sidebar/blocks '()))
@@ -977,12 +921,6 @@
         theme' (if (= theme "dark") "white" "dark")]
     (use-theme-mode! theme')))
 
-(defn update-sync-status!
-  [status]
-  (when (seq status)
-    (when-let [current-repo (get-current-repo)]
-      (set-state! [:repo/sync-status current-repo] status))))
-
 (defn set-root-component!
   [component]
   (set-state! :ui/root-component component))
@@ -1096,10 +1034,6 @@
   []
   (some? (get-name)))
 
-(defn set-draw!
-  [value]
-  (set-state! :draw? value))
-
 (defn in-draw-mode?
   []
   (:draw? @state))
@@ -1118,33 +1052,6 @@
              :branch)
     "master"))
 
-(defn get-current-project
-  []
-  (when-let [project (get-in (get-config) [:project :name])]
-    (when-not (string/blank? project)
-      project)))
-
-(defn update-current-project
-  [& kv]
-  {:pre [(even? (count kv))]}
-  (when-let [current-repo (get-current-repo)]
-    (let [new-kvs (apply array-map (vec kv))
-          projects (:projects (get-me))
-          new-projects (reduce (fn [acc project]
-                                 (if (= (:repo project) current-repo)
-                                   (conj acc (merge project new-kvs))
-                                   (conj acc project)))
-                               []
-                               projects)]
-      (set-state! [:me :projects] new-projects))))
-
-(defn remove-current-project
-  []
-  (when-let [current-repo (get-current-repo)]
-    (update-state! [:me :projects]
-                   (fn [projects]
-                     (remove #(= (:repo %) current-repo) projects)))))
-
 (defn set-indexedb-support!
   [value]
   (set-state! :indexeddb/support? value))
@@ -1319,10 +1226,6 @@
   [repo changed-files]
   (set-state! [:repo/changed-files repo] changed-files))
 
-(defn get-changed-files
-  []
-  (get-in @state [:repo/changed-files (get-current-repo)]))
-
 (defn get-wide-mode?
   []
   (:ui/wide-mode? @state))
@@ -1335,10 +1238,6 @@
   [value]
   (set-state! :network/online? value))
 
-(defn online?
-  []
-  (:network/online? @state))
-
 (defn get-commands
   []
   (:commands (get-config)))
@@ -1398,15 +1297,6 @@
   ;; THINK: new block, indent/outdent, drag && drop, etc.
   (set-editor-last-input-time! repo time))
 
-(defn set-published-pages
-  [pages]
-  (when-let [repo (get-current-repo)]
-    (set-state! [:me :published-pages repo] pages)))
-
-(defn reset-published-pages
-  []
-  (set-published-pages []))
-
 (defn set-db-persisted!
   [repo value]
   (swap! state assoc-in [:db/persisted? repo] value))
@@ -1428,34 +1318,6 @@
       ;; not in editing mode
       (not (get-edit-input-id)))))
 
-(defn set-last-persist-transact-id!
-  [_repo files? id]
-  (swap! state assoc-in [:db/last-persist-transact-ids :repo files?] id))
-
-(defn get-last-persist-transact-id
-  [_repo files?]
-  (get-in @state [:db/last-persist-transact-ids :repo files?]))
-
-(defn persist-transaction!
-  [repo files? tx-id tx-data]
-  (when (seq tx-data)
-    (let [latest-txs (:db/latest-txs @state)
-          last-persist-tx-id (get-last-persist-transact-id repo files?)
-          latest-txs (if last-persist-tx-id
-                       (update-in latest-txs [repo files?]
-                                  (fn [result]
-                                    (remove (fn [tx] (<= (:tx-id tx) last-persist-tx-id)) result)))
-                       latest-txs)
-          new-txs (update-in latest-txs [repo files?] (fn [result]
-                                                        (vec (conj result {:tx-id   tx-id
-                                                                           :tx-data tx-data}))))]
-      (storage/set-transit! :db/latest-txs new-txs)
-      (set-state! :db/latest-txs new-txs))))
-
-(defn get-repo-latest-txs
-  [repo file?]
-  (get-in (:db/latest-txs @state) [repo file?]))
-
 (defn set-nfs-refreshing!
   [value]
   (set-state! :nfs/refreshing? value))
@@ -1627,14 +1489,6 @@
   []
   (get-in @state [:view/components :page-blocks]))
 
-(defn set-editor-cp!
-  [value]
-  (set-state! [:view/components :editor] value))
-
-(defn get-editor-cp
-  []
-  (get-in @state [:view/components :editor]))
-
 (defn exit-editing-and-set-selected-blocks!
   ([blocks]
    (exit-editing-and-set-selected-blocks! blocks :down))
@@ -1645,10 +1499,6 @@
    (set-selection-blocks! blocks direction)
    (util/select-highlight! blocks)))
 
-(defn get-favorites-name
-  []
-  (or (:name/favorites (get-config)) "Favorites"))
-
 (defn add-watch-state [key f]
   (add-watch state key f))
 

+ 0 - 16
src/main/frontend/storage.cljs

@@ -20,22 +20,6 @@
   (when-not util/node-test?
     (dt/read-transit-str ^js (.getItem js/localStorage (name key)))))
 
-(defn set-transit!
-  [key value]
-  (when-not util/node-test?
-    (.setItem ^js js/localStorage (name key) (dt/write-transit-str value))))
-
-(defn get-json
-  [key]
-  (when-not util/node-test?
-    (when-let [value (.getItem js/localStorage (name key))]
-      (js/JSON.parse value))))
-
-(defn set-json
-  [key value]
-  (when-not util/node-test?
-    (.setItem ^js js/localStorage (name key) (js/JSON.stringify value))))
-
 (defn remove
   [key]
   (when-not util/node-test?

+ 1 - 7
src/main/frontend/text.cljs

@@ -221,12 +221,6 @@
        :else
        (remove-level-space-aux! text (config/get-block-pattern format) space? trim-left?)))))
 
-(defn remove-lines-level-spaces
-  [text format]
-  (->> (string/split-lines text)
-       (map #(remove-level-spaces (string/triml %) format true false))
-       (string/join "\n")))
-
 (defn build-data-value
   [col]
   (let [items (map (fn [item] (str "\"" item "\"")) col)]
@@ -376,7 +370,7 @@
       (= v "false")
       false
 
-      (util/safe-re-find #"^\d+$" v)
+      (and (not= k "alias") (util/safe-re-find #"^\d+$" v))
       (util/safe-parse-int v)
 
       (util/wrapped-by-quotes? v) ; wrapped in ""

+ 0 - 49
src/main/frontend/tools/html_export.cljs

@@ -1,49 +0,0 @@
-(ns frontend.tools.html-export
-  (:require-macros [hiccups.core :as hiccups :refer [html]])
-  (:require [clojure.set :as set]
-            [clojure.walk :as walk]
-            [frontend.components.block :as block]
-            [frontend.db :as db]
-            [medley.core :as medley]
-            [frontend.format.block :as format-block]))
-
-;; Consider generate a db index so that search can still works
-
-;; Or maybe TiddlyWiki
-
-;; It could be better that we can reuse some parts of this module in a nodejs tool,
-;; so users don't have to use the web for exporting to htmls or publishing.
-
-(defn- build-block
-  [config block]
-  (let [block (format-block/parse-title-and-body block)
-        body (:block/body block)
-        block (block/build-block-title config block)]
-    [:div.block
-     block
-     (when (seq body)
-       (for [child body]
-         (block/markup-element-cp config child)))]))
-
-(defn export-page
-  [page-name blocks show-notification!]
-  (let [{:keys [slide]} (db/get-page-properties page-name)
-        slide? slide
-        blocks (if (:block/pre-block? (first blocks))
-                 (rest blocks)
-                 blocks)]
-    (if (seq blocks)
-      (let [config {:html-export? true :slide? slide?}
-            hiccup [:div.page
-                    (for [block blocks]
-                      (build-block config block))]
-            remove-attrs #{:on-click :on-change}
-            hiccup (walk/postwalk (fn [f]
-                                    (if (and (map? f)
-                                             (seq (set/intersection remove-attrs (set (keys f)))))
-
-                                      (medley/remove-keys remove-attrs f)
-                                      f))
-                                  hiccup)]
-        (html hiccup))
-      (show-notification! "The published content can't be empty." :error))))

+ 0 - 11
src/main/frontend/ui.cljs

@@ -249,16 +249,6 @@
   [:input.form-checkbox.h-4.w-4.transition.duration-150.ease-in-out
    (merge {:type "checkbox"} option)])
 
-(defn badge
-  [text option]
-  [:span.inline-flex.items-center.px-2.5.py-0.5.rounded-full.text-xs.font-medium.leading-4.bg-purple-100.text-purple-800
-   option
-   text])
-
-;; scroll
-(defn get-doc-scroll-top []
-  (.-scrollTop js/document.documentElement))
-
 (defn main-node
   []
   (gdom/getElement "main-content-container"))
@@ -493,7 +483,6 @@
         binding         (or custom-binding default-binding)]
     (shortcut-helper/decorate-binding binding)))
 
-(defonce modal-show? (atom false))
 (rum/defc modal-overlay
   [state close-fn]
   [:div.ui__modal-overlay

+ 1 - 7
src/main/frontend/ui/date_picker.cljs

@@ -1,6 +1,6 @@
 (ns frontend.ui.date-picker
   (:require [cljs-time.core       :refer [after? before? day day-of-week days first-day-of-the-month minus month months plus year]]
-            [cljs-time.format     :refer [formatter formatters parse unparse]]
+            [cljs-time.format     :refer [formatter unparse]]
             [frontend.modules.shortcut.core :as shortcut]
             [frontend.state :as state]
             [frontend.util  :as util    :refer [deref-or-value now->utc]]
@@ -18,12 +18,6 @@
 
 (def ^:const week-format (formatter "ww"))
 
-(def ^:const date-format (formatter "yyyy MMM dd"))
-
-(defn iso8601->date [iso8601]
-  (when (seq iso8601)
-    (parse (formatters :basic-date) iso8601)))
-
 (defn- month-label [date] (unparse month-format date))
 
 (defn- dec-month [date] (minus date (months 1)))

+ 0 - 14
src/main/frontend/utf8.cljs

@@ -26,17 +26,3 @@
 (defn length
   [arr]
   (gobj/get arr "length"))
-
-;; start-pos inclusive
-;; end-pos exclusive
-(defn insert!
-  [s start-pos end-pos content]
-  (let [arr (encode s)
-        end-pos (or end-pos (length arr))]
-    (str (substring arr 0 start-pos)
-         content
-         (substring arr end-pos))))
-
-(defn delete!
-  [s start-pos end-pos]
-  (insert! s start-pos end-pos ""))

+ 0 - 226
src/main/frontend/util.cljc

@@ -142,28 +142,10 @@
      (p/do!
       (.setStyle StatusBar (clj->js {:style (.-Dark Style)})))))
 
-(defn indexed
-  [coll]
-  (map-indexed vector coll))
-
 (defn find-first
   [pred coll]
   (first (filter pred coll)))
 
-(defn dissoc-in
-  "Dissociates an entry from a nested associative structure returning a new
-  nested structure. keys is a sequence of keys. Any empty maps that result
-  will not be present in the new structure."
-  [m [k & ks]]
-  (if ks
-    (if-let [nextmap (get m k)]
-      (let [newmap (dissoc-in nextmap ks)]
-        (if (seq newmap)
-          (assoc m k newmap)
-          (dissoc m k)))
-      m)
-    (dissoc m k)))
-
 ;; (defn format
 ;;   [fmt & args]
 ;;   (apply gstring/format fmt args))
@@ -194,24 +176,6 @@
   [nm]
   (into {} (remove (comp nil? second)) nm))
 
-(defn remove-nils-or-empty
-  [nm]
-  (walk/postwalk
-   (fn [el]
-     (if (map? el)
-       (not-empty (into {} (remove (comp #(or
-                                           (nil? %)
-                                           (and (coll? %)
-                                                (empty? %))) second)) el))
-       el))
-   nm))
-
-(defn index-by
-  [col k]
-  (->> (map (fn [entry] [(get entry k) entry])
-            col)
-       (into {})))
-
 (defn ext-of-image? [s]
   (some #(string/ends-with? s %)
         [".png" ".jpg" ".jpeg" ".bmp" ".gif" ".webp" ".svg"]))
@@ -276,15 +240,6 @@
             on-ok
             on-failed)))
 
-#?(:cljs
-   (defn patch
-     [url body on-ok on-failed]
-     (fetch url {:method "patch"
-                 :headers {:Content-Type "application/json"}
-                 :body (js/JSON.stringify (clj->js body))}
-            on-ok
-            on-failed)))
-
 #?(:cljs
    (defn delete
      [url on-ok on-failed]
@@ -420,13 +375,6 @@
         last-newline-pos (or (string/last-index-of value \newline (dec pos)) -1)]
     (- pos last-newline-pos 1)))
 
-(defn minimize-html
-  [s]
-  (->> s
-       (string/split-lines)
-       (map string/trim)
-       (string/join "")))
-
 #?(:cljs
    (defn stop [e]
      (when e (doto e (.preventDefault) (.stopPropagation)))))
@@ -436,20 +384,10 @@
      (when e (.stopPropagation e))))
 
 
-(def speed 500)
-(def moving-frequency 15)
-
 #?(:cljs
    (defn cur-doc-top []
      (.. js/document -documentElement -scrollTop)))
 
-#?(:cljs
-   (defn lock-global-scroll
-     ([] (lock-global-scroll true))
-     ([v] (js-invoke (.-classList (app-scroll-container-node))
-                     (if v "add" "remove")
-                     "locked-scroll"))))
-
 #?(:cljs
    (defn element-top [elem top]
      (when elem
@@ -472,15 +410,6 @@
                                   (- top 80)))
                          :behavior "smooth"}))))))
 
-#?(:cljs
-   (defn scroll-to-element-v2
-     [elem-id]
-     (when elem-id
-       (when-let [elem (gdom/getElement elem-id)]
-         (.scroll (app-scroll-container-node)
-                  #js {:top (element-top elem 0)
-                       :behavior "auto"})))))
-
 #?(:cljs
    (defn scroll-to
      ([pos]
@@ -509,13 +438,6 @@
      ([animate?]
       (scroll-to (app-scroll-container-node) 0 animate?))))
 
-#?(:cljs
-   (defn scroll-to-bottom
-     [node]
-     (when-let [node ^js (or node (app-scroll-container-node))]
-       (let [bottom (.-scrollHeight node)]
-         (scroll-to node bottom false)))))
-
 #?(:cljs
    (defn url-encode
      [string]
@@ -574,11 +496,6 @@
   [s substr]
   (string/starts-with? s substr))
 
-(defn drop-first-line
-  [s]
-  (let [lines (string/split-lines s)]
-    [(first lines)]))
-
 (defn distinct-by
   [f col]
   (reduce
@@ -608,12 +525,6 @@
   [repo-url]
   (take-last 2 (string/split repo-url #"/")))
 
-(defn safe-split-first [pattern s]
-  (if-let [first-index (string/index-of s pattern)]
-    [(subs s 0 first-index)
-     (subs s (+ first-index (count pattern)) (count s))]
-    [s ""]))
-
 (defn safe-lower-case
   [s]
   (if (string? s)
@@ -638,12 +549,6 @@
   [s]
   (.replace s #"[ \t\r]+$" ""))
 
-(defn trim-only-newlines
-  [s]
-  (-> s
-      (.replace #"[\n]+$" "")
-      (.replace #"^[\n]+" "")))
-
 (defn triml-without-newlines
   [s]
   (.replace s #"^[ \t\r]+" ""))
@@ -660,16 +565,6 @@
            (when-not not-space? " ")
            (triml-without-newlines right)))))
 
-#?(:cljs
-   (defn join-newline
-     [& col]
-     (let [col (remove nil? col)]
-       (reduce (fn [acc s]
-                 (if (or (= acc "") (= "\n" (last acc)))
-                   (str acc s)
-                   (str acc "\n"
-                        (.replace s #"^[\n]+" "")))) "" col))))
-
 ;; Add documentation
 (defn replace-first [pattern s new-value]
   (if-let [first-index (string/index-of s pattern)]
@@ -699,16 +594,6 @@
                     old-value)]
     (string/replace s (re-pattern (str "(?i)" old-value)) new-value)))
 
-(defn replace-first-ignore-case
-  [s old-value new-value & [escape-chars]]
-  (let [escape-chars (or escape-chars default-escape-chars)
-        old-value (if (string? escape-chars)
-                    (reduce (fn [acc escape-char]
-                              (string/replace acc escape-char (str "\\" escape-char)))
-                            old-value escape-chars)
-                    old-value)]
-    (string/replace-first s (re-pattern (str "(?i)" old-value)) new-value)))
-
 ;; copy from https://stackoverflow.com/questions/18735665/how-can-i-get-the-positions-of-regex-matches-in-clojurescript
 #?(:cljs
    (defn re-pos [re s]
@@ -874,16 +759,6 @@
        (and node
             (rec-get-blocks-content-section (gobj/get node "parentNode"))))))
 
-#?(:cljs
-   (defn node-in-viewpoint?
-     [node]
-     (let [rect (.getBoundingClientRect node)
-           height (or (.-innerHeight js/window)
-                      (.. js/document -documentElement -clientHeight))]
-       (and
-        (> (.-top rect) (.-clientHeight (d/by-id "head")))
-        (<= (.-bottom rect) height)))))
-
 #?(:cljs
    (defn get-blocks-noncollapse []
      (->> (d/by-class "ls-block")
@@ -917,12 +792,6 @@
        (catch js/Error _e
          nil))))
 
-#?(:cljs
-   (defn input-selected?
-     [input]
-     (not= (get-selection-start input)
-           (get-selection-end input))))
-
 #?(:cljs
    (defn get-selected-text
      []
@@ -943,10 +812,6 @@
   [s]
   (safe-re-find exactly-uuid-pattern s))
 
-(defn extract-uuid
-  [s]
-  (safe-re-find (re-pattern uuid-pattern) s))
-
 (defn drop-nth [n coll]
   (keep-indexed #(when (not= %1 n) %2) coll))
 
@@ -955,10 +820,6 @@
            (map string/capitalize)
            (string/join " ")))
 
-(defn file-page?
-  [page-name]
-  (when page-name (safe-re-find #"\." page-name)))
-
 #?(:cljs
    (defn react
      [ref]
@@ -993,40 +854,6 @@
      [title]
      (set! (.-title js/document) title)))
 
-#?(:cljs
-   (defn get-prev-block-with-same-level
-     [block]
-     (let [id (gobj/get block "id")
-           prefix (safe-re-find #"ls-block-[\d]+" id)]
-       (when-let [blocks (d/by-class "ls-block")]
-         (when-let [index (.indexOf blocks block)]
-           (let [level (d/attr block "level")]
-             (when (> index 0)
-               (loop [idx (dec index)]
-                 (if (>= idx 0)
-                   (let [block (nth blocks idx)
-                         prefix-match? (starts-with? (gobj/get block "id") prefix)]
-                     (if (and prefix-match?
-                              (= level (d/attr block "level")))
-                       block
-                       (recur (dec idx))))
-                   nil)))))))))
-
-#?(:cljs
-   (defn get-next-block-with-same-level
-     [block]
-     (when-let [blocks (d/by-class "ls-block")]
-       (when-let [index (.indexOf blocks block)]
-         (let [level (d/attr block "level")]
-           (when (> (count blocks) (inc index))
-             (loop [idx (inc index)]
-               (if (< idx (count blocks))
-                 (let [block (nth blocks idx)]
-                   (if (= level (d/attr block "level"))
-                     block
-                     (recur (inc idx))))
-                 nil))))))))
-
 #?(:cljs
    (defn get-block-container
      [block-element]
@@ -1078,17 +905,6 @@
                  (recur (inc idx))
                  block))))))))
 
-(defn sort-by-value
-  [order m]
-  (into (sorted-map-by
-         (fn [k1 k2]
-           (let [v1 (get m k1)
-                 v2 (get m k2)]
-             (if (= order :desc)
-               (compare [v2 k2] [v1 k1])
-               (compare [v1 k1] [v2 k2])))))
-        m))
-
 (defn rand-str
   [n]
   #?(:cljs (-> (.toString (js/Math.random) 36)
@@ -1106,23 +922,6 @@
   (when (string? tag-name)
     (not (safe-re-find #"[# \t\r\n]+" tag-name))))
 
-#?(:cljs
-   (defn encode-str
-     [s]
-     (if (tag-valid? s)
-       s
-       (url-encode s))))
-
-#?(:cljs
-   (defn get-clipboard-as-html
-     [event]
-     (if-let [c (gobj/get event "clipboardData")]
-       [(.getData c "text/html") (.getData c "text")]
-       (if-let [c (gobj/getValueByKeys event "originalEvent" "clipboardData")]
-         [(.getData c "text/html") (.getData c "text")]
-         (when-let [c (gobj/get js/window "clipboardData")]
-           [(.getData c "Text") (.getData c "Text")])))))
-
 (defn pp-str [x]
   #_:clj-kondo/ignore
   (with-out-str (clojure.pprint/pprint x)))
@@ -1170,14 +969,6 @@
        (catch js/Error _
          (utils/win32 path)))))
 
-(defn ->system-modifier
-  [keyboard-shortcut]
-  (if mac?
-    (-> keyboard-shortcut
-        (string/replace "ctrl" "meta")
-        (string/replace "alt" "meta"))
-    keyboard-shortcut))
-
 (defn default-content-with-title
   [text-format]
   (case (name text-format)
@@ -1234,12 +1025,6 @@
      [s]
      (removeAccents (.normalize (string/lower-case s) "NFKC"))))
 
-#?(:cljs
-   (defn safe-search-normalize
-  [s]
-  (if (string? s)
-        (removeAccents (.normalize (string/lower-case s) "NFKC")) s)))
-
 (defn page-name-sanity
   "Sanitize the page-name for file name (strict), for file writting"
   ([page-name]
@@ -1402,11 +1187,6 @@
      []
      (contains? (set (system-locales)) "zh-CN")))
 
-#?(:cljs
-   (defn get-element-width
-     [id]
-     (when-let [element (gdom/getElement id)]
-       (gobj/get element "offsetWidth"))))
 (comment
   (= (get-relative-path "journals/2020_11_18.org" "pages/grant_ideas.org")
      "../pages/grant_ideas.org")
@@ -1579,12 +1359,6 @@
   [v]
   (string/trim (subs v 1 (dec (count v)))))
 
-(defn unquote-string-if-wrapped
-  [v]
-  (if (wrapped-by-quotes? v)
-    (unquote-string v)
-    v))
-
 #?(:cljs
    (defn right-click?
      [e]

+ 0 - 11
src/main/frontend/util/cursor.cljs

@@ -115,13 +115,6 @@
         (when-let [pre-char (subs content (dec pos) pos)]
           (= pre-char \newline)))))
 
-(defn end-of-line?
-  [input]
-  (let [[content pos] (get-input-content&pos input)]
-    (or (= pos (count content))
-        (when-let [next-char (subs content pos (inc pos))]
-          (= next-char \newline)))))
-
 (defn move-cursor-to-line-end
   [input]
   (move-cursor-to input (line-end-pos input)))
@@ -130,10 +123,6 @@
   [input]
   (move-cursor-to input (line-beginning-pos input)))
 
-(defn move-cursor-to-beginning
-  [input]
-  (move-cursor-to input 0))
-
 (defn move-cursor-to-end
   [input]
   (let [pos (count (gobj/get input "value"))]

+ 0 - 5
src/main/frontend/util/pool.cljs

@@ -51,11 +51,6 @@
   (p/let [_ (.completed pool)]
     (.terminate pool)))
 
-(defn terminate-parser-pool!
-  []
-  (when-let [pool @parser-pool]
-    (terminate-pool! pool)))
-
 (defn add-parse-job!
   [content config]
   (when-let [pool @parser-pool]

+ 0 - 5
src/main/frontend/util/property.cljs

@@ -122,11 +122,6 @@
   (let [key (string/upper-case key)]
     (contains? (set (util/remove-first #{key} (get-property-keys format content))) key)))
 
-(defn goto-properties-beginning
-  [_format input]
-  (cursor/move-cursor-to-thing input properties-start 0)
-  (cursor/move-cursor-forward input (count properties-start)))
-
 (defn goto-properties-end
   [_format input]
   (cursor/move-cursor-to-thing input properties-start 0)

+ 0 - 7
src/test/frontend/react.cljc

@@ -67,10 +67,3 @@
           [key & body]
           `(binding [*with-key* ~key]
              ~@body)))
-
-#?(:clj (defmacro auto-clean-state
-          [& body]
-          `(do (reset! react-components {})
-               (let [result# ~@body]
-                 (reset! react-components {})
-                 result#))))

+ 0 - 5
yarn.lock

@@ -2763,11 +2763,6 @@ didyoumean@^1.2.1:
   resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
   integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
 
[email protected]:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
-  integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
-
 diff-sequences@^27.4.0:
   version "27.4.0"
   resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5"