Bläddra i källkod

refactor(fs): handle global file write

Andelf 2 år sedan
förälder
incheckning
1cd7f89cd9

+ 1 - 0
src/main/frontend/components/file.cljs

@@ -129,6 +129,7 @@
      (cond
        ;; image type
        (and format (contains? (gp-config/img-formats) format))
+       ;; FIXME(andelf): bad path op
        [:img {:src (util/node-path.join "file://" path)}]
 
        (and format

+ 14 - 8
src/main/frontend/config.cljs

@@ -8,8 +8,7 @@
             [frontend.util :as util]
             [logseq.graph-parser.config :as gp-config]
             [logseq.graph-parser.util :as gp-util]
-            [shadow.resource :as rc]
-            [frontend.fs2.path :as path]))
+            [shadow.resource :as rc]))
 
 (goog-define DEV-RELEASE false)
 (defonce dev-release? DEV-RELEASE)
@@ -493,14 +492,21 @@
      (fs2-path/path-join repo-dir app-name  export-css-file))))
 
 (defn expand-relative-assets-path
+  ;; resolve all relative links in custom.css to assets:// URL
   ;; ../assets/xxx -> {assets|file}://{current-graph-root-path}/xxx
   [source]
-  (when-let [protocol (and (string? source)
-                           (not (string/blank? source))
-                           (if (util/electron?) "assets" "file"))]
-    (js/console.error "BUG: assets:// url handling")
-    (string/replace
-     source "../assets" (util/format "%s://%s/assets" protocol (get-repo-dir (state/get-current-repo))))))
+  (prn ::expand-relative-assets-path source)
+  (let [protocol (and (string? source)
+                      (not (string/blank? source))
+                      (if (util/electron?) "assets://" "file://"))
+             ;; BUG: use "assets" as fake current directory
+        assets-link-fn (fn [_]
+                        (str (fs2-path/path-join protocol
+                                                 (get-repo-dir (state/get-current-repo)) "assets"))
+                        "/")]
+    (when (not-empty source)
+      (string/replace source #"\\.\\./assets/"
+                      assets-link-fn))))
 
 (defn get-current-repo-assets-root
   []

+ 18 - 15
src/main/frontend/fs.cljs

@@ -23,12 +23,28 @@
 (defonce node-backend (node/->Node))
 (defonce mobile-backend (capacitor-fs/->Capacitorfs))
 
+(defn- get-native-backend
+  "Native FS backend of current platform"
+  []
+  (cond
+    (util/electron?)
+    node-backend
+
+    (mobile-util/native-platform?)
+    mobile-backend
+
+    :else
+    nfs-backend))
 
 (defn get-fs
   [dir]
-  (let [bfs-local? (or (string/starts-with? dir "/local")
-                       (string/starts-with? dir "local"))]
+  (let [bfs-local? (and dir
+                        (or (string/starts-with? dir "/local")
+                            (string/starts-with? dir "local")))]
     (cond
+      (nil? dir) ;; global file op, use native backend
+      (get-native-backend)
+
       (string/starts-with? dir "memory://")
       memory-backend
 
@@ -144,19 +160,6 @@
    (let [fpath (fs2-path/path-join dir path)]
      (protocol/stat (get-fs dir) fpath))))
 
-(defn- get-native-backend
-  "Native FS backend of current platform"
-  []
-  (cond
-    (util/electron?)
-    node-backend
-
-    (mobile-util/native-platform?)
-    mobile-backend
-
-    :else
-    nfs-backend))
-
 (defn open-dir
   [dir]
   (let [record (get-native-backend)]

+ 3 - 1
src/main/frontend/fs/node.cljs

@@ -106,7 +106,9 @@
     ;; Too dangerious!!! We'll never implement this.
     nil)
   (read-file [_this dir path _options]
-    (let [path (fs2-path/path-join dir path)]
+    (let [path (if (nil? dir)
+                 path
+                 (fs2-path/path-join dir path))]
       (ipc/ipc "readFile" path)))
   (write-file! [this repo dir path content opts]
     (p/let [fpath (fs2-path/path-join dir path)

+ 21 - 17
src/main/frontend/fs2/path.cljs

@@ -153,9 +153,14 @@
 (defn path-join
   "Join path segments, or URL base and path segments"
   [base & segments]
-  (when (string/blank? base)
-    (js/console.error "BUG: SHOULD-NOT-JOIN-EMPTY")
-    (js/console.trace))
+
+  (cond 
+    (nil? base)
+    (println "path join global directory" segments)
+    (= base "")
+    (js/console.error "BUG: should not join with empty dir" segments)
+    :else
+    nil)
 
   (if (is-file-url base)
     (apply url-join base segments)
@@ -184,20 +189,6 @@
     (url-normalize path)
     (path-normalize-internal path)))
 
-(defn trim-dir-prefix
-  "Trim dir prefix from path"
-  [base-path sub-path]
-  (let [base-path (path-normalize base-path)
-        sub-path (path-normalize sub-path)
-        is-url? (is-file-url base-path)]
-    (if (string/starts-with? sub-path base-path)
-      (if is-url?
-        (gp-util/safe-decode-uri-component (string/replace (subs sub-path (count base-path)) #"^/+", ""))
-        (string/replace (subs sub-path (count base-path)) #"^/+", ""))
-      (do
-        (js/console.error "unhandled trim-base" base-path sub-path)
-        sub-path))))
-
 (defn url-to-path
   "Extract path part of a URL, decoded.
    
@@ -214,6 +205,19 @@
       path)
     original-url))
 
+(defn trim-dir-prefix
+  "Trim dir prefix from path"
+  [base-path sub-path]
+  (let [base-path (path-normalize base-path)
+        sub-path (path-normalize sub-path)
+        is-url? (is-file-url base-path)]
+    (if (string/starts-with? sub-path base-path)
+      (if is-url?
+        (gp-util/safe-decode-uri-component (string/replace (subs sub-path (count base-path)) #"^/+", ""))
+        (string/replace (subs sub-path (count base-path)) #"^/+", ""))
+      (do
+        (js/console.error "unhandled trim-base" base-path sub-path)
+        nil))))
 
 (defn relative-path
   "Get relative path from base path.

+ 25 - 12
src/main/frontend/handler/code.cljs

@@ -1,12 +1,15 @@
 (ns frontend.handler.code
   "Codemirror editor related."
-  (:require [frontend.state :as state]
-            [goog.object :as gobj]
+  (:require [clojure.string :as string]
+            [frontend.config :as config]
             [frontend.db :as db]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.file :as file-handler]
+            [frontend.state :as state]
+            [goog.object :as gobj]
             [logseq.graph-parser.utf8 :as utf8]
-            [clojure.string :as string]))
+            [frontend.fs2.path :as fs2-path]
+            [frontend.components.content :as content]))
 
 (defn save-code-editor!
   []
@@ -20,6 +23,7 @@
             default-value (gobj/get textarea "defaultValue")]
         (when (not= value default-value)
           (cond
+            ;; save block content
             (:block/uuid config)
             (let [block (db/pull [:block/uuid (:block/uuid config)])
                   content (:block/content block)
@@ -34,16 +38,25 @@
               (state/set-edit-content! (state/get-edit-input-id) new-content)
               (editor-handler/save-block-if-changed! block new-content))
 
-            (:file-path config)
+            (not-empty (:file-path config))
             (let [path (:file-path config)
-                  content (or (db/get-file path) "")]
-              (when (and
-                     (not (string/blank? value))
-                     (not= (string/trim value) (string/trim content)))
-                (file-handler/alter-file (state/get-current-repo)
-                                         path
-                                         (str (string/trim value) "\n")
-                                         {:re-render-root? true})))
+                  repo (state/get-current-repo)
+                  repo-dir (config/get-repo-dir repo)
+                  rpath (fs2-path/trim-dir-prefix repo-dir path)
+                  ;; old-content (db/get-file rpath)
+                  _ (prn ::calc rpath)]
+              (if rpath
+                ;; in-db file
+                (let [old-content (db/get-file rpath)]
+                  (when (and
+                         (not (string/blank? value))
+                         (not= (string/trim value) (string/trim old-content)))
+                    (file-handler/alter-file (state/get-current-repo)
+                                             rpath
+                                             (str (string/trim value) "\n")
+                                             {:re-render-root? true})))
+                ;; global file
+                (file-handler/alter-global-file path (str (string/trim value) "\n"))))
 
             :else
             nil))))))

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

@@ -26,8 +26,8 @@
 (defn set-config!
   ([k v]
    (set-config! (state/get-current-repo) k v))
-  ([repo k v]
-   (let [path (config/get-repo-config-path repo)]
+  ([_repo k v]
+   (let [path "logseq/config.edn"]
      (repo-config-set-key-value path k v))))
 
 (defn toggle-ui-show-brackets! []

+ 18 - 7
src/main/frontend/handler/file.cljs

@@ -115,17 +115,28 @@
 (defn- write-file-aux!
   [repo path content write-file-options]
   (let [original-content (db/get-file repo path)
-        path-dir (if (and
-                      (config/global-config-enabled?)
-                      ;; Hack until we better understand failure in error handler
-                      (global-config-handler/global-config-dir-exists?)
-                      (= (path/dirname path) (global-config-handler/global-config-dir)))
-                   (global-config-handler/global-config-dir)
-                   (config/get-repo-dir repo))
+        path-dir (config/get-repo-dir repo)
+        ;;path-dir (if (and
+        ;;              (config/global-config-enabled?)
+         ;;             ;; Hack until we better understand failure in error handler
+          ;;            (global-config-handler/global-config-dir-exists?)
+          ;;            (= (path/dirname path) (global-config-handler/global-config-dir)))
+           ;;        (global-config-handler/global-config-dir)
+          ;;         (config/get-repo-dir repo))
         write-file-options' (merge write-file-options
                                    (when original-content {:old-content original-content}))]
     (fs/write-file! repo path-dir path content write-file-options')))
 
+(defn alter-global-file
+  "Write global file, e.g. global config"
+  [path content]
+  (p/let [_ (fs/write-file! "" nil path content {:skip-compare? true})]
+    (cond
+      (and (config/global-config-enabled?)
+           (= path (global-config-handler/global-config-path)))
+      (p/let [_ (global-config-handler/restore-global-config!)]
+        (state/pub-event! [:shortcut/refresh])))))
+
 (defn alter-file
   [repo path content {:keys [reset? re-render-root? from-disk? skip-compare? new-graph? verbose
                              skip-db-transact? extracted-block-ids]

+ 3 - 3
src/main/frontend/handler/plugin.cljs

@@ -529,8 +529,8 @@
               exist? (fs/file-exists? path dirname)
               _      (when-not exist? (fs/mkdir! (util/node-path.join path dirname)))
               path   (util/node-path.join path dirname (str key ".json"))
-              _      (fs/create-if-not-exists repo "" path (or default "{}"))
-              json   (fs/read-file "" path)]
+              _      (fs/create-if-not-exists repo nil path (or default "{}"))
+              json   (fs/read-file nil path)]
         [path (js/JSON.parse json)]))))
 
 (defn make-fn-to-save-dotdir-json
@@ -540,7 +540,7 @@
       (p/let [repo ""
               path (get-ls-dotdir-root)
               path (util/node-path.join path dirname (str key ".json"))]
-        (fs/write-file! repo "" path content {:skip-compare? true})))))
+        (fs/write-file! repo nil path content {:skip-compare? true})))))
 
 (defn make-fn-to-unlink-dotdir-json
   [dirname]

+ 3 - 4
src/main/frontend/handler/plugin_config.cljs

@@ -37,16 +37,14 @@ when a plugin is installed, updated or removed"
                               rewrite/parse-string
                               (rewrite/assoc (keyword id) (select-keys plugin common-plugin-keys))
                               str)]
-         ;; fs protocols require repo and dir when they aren't necessary. For this component,
-         ;; neither is needed so these are nil and blank respectively
-         (fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
+    (fs/write-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
 
 (defn remove-plugin
   "Removes a plugin from plugin.edn"
   [plugin-id]
   (p/let [content (fs/read-file "" (plugin-config-path))
           updated-content (-> content rewrite/parse-string (rewrite/dissoc (keyword plugin-id)) str)]
-         (fs/write-file! nil "" (plugin-config-path) updated-content {:skip-compare? true})))
+    (fs/write-file! "" nil (plugin-config-path) updated-content {:skip-compare? true})))
 
 (defn- create-plugin-config-file-if-not-exists
   []
@@ -54,6 +52,7 @@ when a plugin is installed, updated or removed"
                     (update-vals #(select-keys % common-plugin-keys))
                     pprint/pprint
                     with-out-str)]
+    (prn ::plugin-dir @global-config-handler/root-dir (plugin-config-path))
     (fs/create-if-not-exists nil @global-config-handler/root-dir (plugin-config-path) content)))
 
 (defn- determine-plugins-to-change

+ 9 - 7
src/main/logseq/api.cljs

@@ -175,17 +175,18 @@
 
 (def ^:export load_plugin_config
   (fn [path]
-    (fs/read-file "" (util/node-path.join path "package.json"))))
+    (fs/read-file nil (util/node-path.join path "package.json"))))
 
 (def ^:export load_plugin_readme
   (fn [path]
-    (fs/read-file "" (util/node-path.join path "readme.md"))))
+    (fs/read-file nil (util/node-path.join path "readme.md"))))
 
 (def ^:export save_plugin_config
   (fn [path ^js data]
     (let [repo ""
+          
           path (util/node-path.join path "package.json")]
-      (fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
+      (fs/write-file! repo nil path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
 
 (def ^:export save_focused_code_editor_content
   (fn []
@@ -205,7 +206,7 @@
           user-path-root (util/node-path.dirname user-path)
           exist?         (fs/file-exists? user-path-root "")
           _              (when-not exist? (fs/mkdir-recur! user-path-root))
-          _              (fs/write-file! repo "" user-path content {:skip-compare? true})]
+          _              (fs/write-file! repo nil user-path content {:skip-compare? true})]
     user-path))
 
 (defn ^:private write_dotdir_file
@@ -325,9 +326,10 @@
   (fn []
     (p/let [repo ""
             path (plugin-handler/get-ls-dotdir-root)
+            _ (prn ::dotdir path)
             path (util/node-path.join path "preferences.json")
-            _    (fs/create-if-not-exists repo "" path)
-            json (fs/read-file "" path)
+            _    (fs/create-if-not-exists repo nil path)
+            json (fs/read-file nil path)
             json (if (string/blank? json) "{}" json)]
       (js/JSON.parse json))))
 
@@ -337,7 +339,7 @@
       (p/let [repo ""
               path (plugin-handler/get-ls-dotdir-root)
               path (util/node-path.join path "preferences.json")]
-        (fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true})))))
+        (fs/write-file! repo nil path (js/JSON.stringify data nil 2) {:skip-compare? true})))))
 
 (def ^:export load_plugin_user_settings
   ;; results [path data]