Prechádzať zdrojové kódy

fix: notify graph dir is gone when starting or running the apps

Also, disabled both re-index and refresh when logseq detects that
a graph's dir doesn't exists anymore.
Tienson Qin 3 rokov pred
rodič
commit
b7ae3684be

+ 46 - 43
src/electron/electron/fs_watcher.cljs

@@ -44,51 +44,54 @@
 
 (defn watch-dir!
   "Watch a directory if no such file watcher exists"
-  [_win dir]
-  (when (and (fs/existsSync dir)
-             (not (get @*file-watcher dir)))
-    (let [watcher-opts (clj->js
-                        {:ignored (fn [path]
-                                    (utils/ignored-path? dir path))
-                         :ignoreInitial false
-                         :ignorePermissionErrors true
-                         :interval polling-interval
-                         :binaryInterval polling-interval
-                         :persistent true
-                         :disableGlobbing true
-                         :usePolling false
-                         :awaitWriteFinish true})
-          dir-watcher (.watch watcher dir watcher-opts)
-          watcher-del-f #(.close dir-watcher)]
-      (swap! *file-watcher assoc dir [dir-watcher watcher-del-f])
-      ;; TODO: batch sender
-      (.on dir-watcher "unlinkDir"
-           (fn [path]
-             (when (= dir path)
-               (publish-file-event! dir dir "unlinkDir"))))
-      (.on dir-watcher "addDir"
-           (fn [path]
-             (when (= dir path)
-               (publish-file-event! dir dir "addDir"))))
-      (.on dir-watcher "add"
-           (fn [path]
-             (publish-file-event! dir path "add")))
-      (.on dir-watcher "change"
-           (fn [path]
-             (publish-file-event! dir path "change")))
-      (.on dir-watcher "unlink"
-           (fn [path]
-             (publish-file-event! dir path "unlink")))
-      (.on dir-watcher "error"
-           (fn [path]
-             (println "Watch error happened: "
-                      {:path path})))
+  [dir]
+  (when-not (get @*file-watcher dir)
+    (if (fs/existsSync dir)
+      (let [watcher-opts (clj->js
+                          {:ignored (fn [path]
+                                      (utils/ignored-path? dir path))
+                           :ignoreInitial false
+                           :ignorePermissionErrors true
+                           :interval polling-interval
+                           :binaryInterval polling-interval
+                           :persistent true
+                           :disableGlobbing true
+                           :usePolling false
+                           :awaitWriteFinish true})
+            dir-watcher (.watch watcher dir watcher-opts)
+            watcher-del-f #(.close dir-watcher)]
+        (swap! *file-watcher assoc dir [dir-watcher watcher-del-f])
+        ;; TODO: batch sender
+        (.on dir-watcher "unlinkDir"
+             (fn [path]
+               (when (= dir path)
+                 (publish-file-event! dir dir "unlinkDir"))))
+        (.on dir-watcher "addDir"
+             (fn [path]
+               (when (= dir path)
+                 (publish-file-event! dir dir "addDir"))))
+        (.on dir-watcher "add"
+             (fn [path]
+               (publish-file-event! dir path "add")))
+        (.on dir-watcher "change"
+             (fn [path]
+               (publish-file-event! dir path "change")))
+        (.on dir-watcher "unlink"
+             (fn [path]
+               (publish-file-event! dir path "unlink")))
+        (.on dir-watcher "error"
+             (fn [path]
+               (println "Watch error happened: "
+                        {:path path})))
 
-      ;; electron app extends `EventEmitter`
-      ;; TODO check: duplicated with the logic in "window-all-closed" ?
-      (.on app "quit" watcher-del-f)
+        ;; electron app extends `EventEmitter`
+        ;; TODO check: duplicated with the logic in "window-all-closed" ?
+        (.on app "quit" watcher-del-f)
 
-      true)))
+        true)
+      ;; retry if the `dir` not exists, which is useful when a graph's folder is
+      ;; back after refreshing the window
+      (js/setTimeout #(watch-dir! dir) 5000))))
 
 (defn close-watcher!
   "If no `dir` provided, close all watchers;

+ 3 - 5
src/electron/electron/handler.cljs

@@ -337,7 +337,8 @@
 (defn set-current-graph!
   [window graph-path]
   (let [old-path (state/get-window-graph-path window)]
-    (when old-path (close-watcher-when-orphaned! window old-path))
+    (when (and old-path graph-path (not= old-path graph-path))
+      (close-watcher-when-orphaned! window old-path))
     (swap! state/state assoc :graph/current graph-path)
     (swap! state/state assoc-in [:window/graph window] graph-path)
     nil))
@@ -397,10 +398,7 @@
   ;;    1. there is no one window on the same dir
   ;;    2. reset file watcher to resend `add` event on window refreshing
   (when dir
-    ;; adding dir watcher when the window has watcher already - must be cmd + r refreshing
-    ;; maintain only one file watcher when multiple windows on the same dir
-    (close-watcher-when-orphaned! window dir)
-    (watcher/watch-dir! window dir)))
+    (watcher/watch-dir! dir)))
 
 (defn open-new-window!
   "Persist db first before calling! Or may break db persistency"

+ 2 - 2
src/electron/electron/state.cljs

@@ -15,10 +15,10 @@
 
          ;; window -> current graph
          :window/graph {}
-         
+
          ;; job to do when persistGraph is done on renderer
          :window/once-persist-done nil
-         
+
          ;; job to do when graph is loaded on renderer
          :window/once-graph-ready nil}))
 

+ 4 - 0
src/main/frontend/fs.cljs

@@ -200,3 +200,7 @@
    (stat dir path)
    (fn [_stat] true)
    (fn [_e] false)))
+
+(defn dir-exists?
+  [dir]
+  (file-exists? dir ""))

+ 4 - 16
src/main/frontend/fs/watcher_handler.cljs

@@ -55,22 +55,10 @@
                  (not (:encryption/graph-parsing? @state/state)))
         (cond
           (and (= "unlinkDir" type) dir)
-          (do
-            (state/pub-event! [:notification/show
-                               {:content (str "The directory " dir " has been renamed or deleted, the editor will be disabled for this graph, you can unlink the graph.")
-                                :status :error
-                                :clear? false}])
-            (state/update-state! :file/unlinked-dirs (fn [dirs] (conj dirs dir))))
-
-          (= "addDir" type)
-          (when (contains? (:file/unlinked-dirs @state/state) dir)
-            (notification/clear-all!)
-            (state/pub-event! [:notification/show
-                               {:content (str "The directory " dir " has been back, you can edit your graph now.")
-                                :status :success
-                                :clear? true}])
-            (fs/watch-dir! dir)
-            (state/update-state! :file/unlinked-dirs (fn [dirs] (disj dirs dir))))
+          (state/pub-event! [:graph/dir-gone dir])
+
+          (and (= "addDir" type) dir)
+          (state/pub-event! [:graph/dir-back repo dir])
 
           (contains? (:file/unlinked-dirs @state/state) dir)
           nil

+ 23 - 0
src/main/frontend/handler/events.cljs

@@ -240,6 +240,11 @@
     (state/set-modal! #(git-component/file-specific-version path hash content))))
 
 (defmethod handle :graph/ready [[_ repo]]
+  (when (config/local-db? repo)
+    (p/let [dir (config/get-repo-dir repo)
+            dir-exists? (fs/dir-exists? dir)]
+      (when-not dir-exists?
+        (state/pub-event! [:graph/dir-gone dir]))))
   (search-handler/rebuild-indices-when-stale! repo)
   (repo-handler/graph-ready! repo))
 
@@ -428,6 +433,24 @@
            template
            {:target page}))))))
 
+(defmethod handle :graph/dir-gone [[_ dir]]
+  (state/pub-event! [:notification/show
+                     {:content (str "The directory " dir " has been renamed or deleted, the editor will be disabled for this graph, you can unlink the graph.")
+                      :status :error
+                      :clear? false}])
+  (state/update-state! :file/unlinked-dirs (fn [dirs] (conj dirs dir))))
+
+(defmethod handle :graph/dir-back [[_ repo dir]]
+  (when (contains? (:file/unlinked-dirs @state/state) dir)
+    (notification/clear-all!)
+    (state/pub-event! [:notification/show
+                       {:content (str "The directory " dir " has been back, you can edit your graph now.")
+                        :status :success
+                        :clear? true}])
+    (state/update-state! :file/unlinked-dirs (fn [dirs] (disj dirs dir))))
+  (when (= dir (config/get-repo-dir repo))
+    (fs/watch-dir! dir)))
+
 (defn run!
   []
   (let [chan (state/get-events-chan)]

+ 15 - 14
src/main/frontend/handler/metadata.cljs

@@ -41,20 +41,21 @@
 
 (defn set-pages-metadata!
   [repo]
-  (let [path (config/get-pages-metadata-path repo)
-        all-pages (->> (db/get-all-pages repo)
-                       (common-handler/fix-pages-timestamps)
-                       (map #(select-keys % [:block/name :block/created-at :block/updated-at]))
-                       (sort-by :block/name)
-                       (vec))]
-    (p/let [_ (-> (file-handler/create-pages-metadata-file repo)
-                  (p/catch (fn [] nil)))]
-      (let [new-content (with-out-str (cljs.pprint/pprint all-pages))]
-        (fs/write-file! repo
-                        (config/get-repo-dir repo)
-                        path
-                        new-content
-                        {})))))
+  (when-not (state/unlinked-dir? (config/get-repo-dir repo))
+    (let [path (config/get-pages-metadata-path repo)
+          all-pages (->> (db/get-all-pages repo)
+                         (common-handler/fix-pages-timestamps)
+                         (map #(select-keys % [:block/name :block/created-at :block/updated-at]))
+                         (sort-by :block/name)
+                         (vec))]
+      (p/let [_ (-> (file-handler/create-pages-metadata-file repo)
+                    (p/catch (fn [] nil)))]
+        (let [new-content (with-out-str (cljs.pprint/pprint all-pages))]
+          (fs/write-file! repo
+                          (config/get-repo-dir repo)
+                          path
+                          new-content
+                          {}))))))
 
 (defn set-db-encrypted-secret!
   [encrypted-secret]

+ 18 - 15
src/main/frontend/handler/repo.cljs

@@ -381,26 +381,29 @@
 
 (defn rebuild-index!
   [url]
-  (when url
-    (search/reset-indice! url)
-    (db/remove-conn! url)
-    (db/clear-query-state!)
-    (-> (p/do! (db-persist/delete-graph! url))
-        (p/catch (fn [error]
-                   (prn "Delete repo failed, error: " error))))))
+  (when-not (state/unlinked-dir? (config/get-repo-dir url))
+    (when url
+      (search/reset-indice! url)
+      (db/remove-conn! url)
+      (db/clear-query-state!)
+      (-> (p/do! (db-persist/delete-graph! url))
+          (p/catch (fn [error]
+                     (prn "Delete repo failed, error: " error)))))))
 
 (defn re-index!
   [nfs-rebuild-index! ok-handler]
-  (route-handler/redirect-to-home!)
   (when-let [repo (state/get-current-repo)]
-    (let [local? (config/local-db? repo)]
-      (if local?
-        (p/let [_ (metadata-handler/set-pages-metadata! repo)]
-          (nfs-rebuild-index! repo ok-handler))
-        (rebuild-index! repo))
-      (js/setTimeout
+    (let [dir (config/get-repo-dir repo)]
+      (when-not (state/unlinked-dir? dir)
        (route-handler/redirect-to-home!)
-       500))))
+       (let [local? (config/local-db? repo)]
+         (if local?
+           (p/let [_ (metadata-handler/set-pages-metadata! repo)]
+             (nfs-rebuild-index! repo ok-handler))
+           (rebuild-index! repo))
+         (js/setTimeout
+          (route-handler/redirect-to-home!)
+          500))))))
 
 (defn persist-db!
   ([]

+ 3 - 1
src/main/frontend/handler/web/nfs.cljs

@@ -327,9 +327,11 @@
             _ (ok-handler)]
       (state/set-nfs-refreshing! false))))
 
+;; TODO: move to frontend.handler.repo
 (defn refresh!
   [repo ok-handler]
-  (when repo
+  (when (and repo
+             (not (state/unlinked-dir? (config/get-repo-dir repo))))
     (state/set-nfs-refreshing! true)
     (p/let [_ (reload-dir! repo)
             _ (ok-handler)]

+ 4 - 0
src/main/frontend/state.cljs

@@ -1700,3 +1700,7 @@
   [repo]
   (:feature/enable-encryption?
    (get (sub-config) repo)))
+
+(defn unlinked-dir?
+  [dir]
+  (contains? (:file/unlinked-dirs @state) dir))

+ 5 - 2
yarn.lock

@@ -6806,6 +6806,11 @@ [email protected]:
     react-draggable "3.x"
     react-resizable "1.x"
 
[email protected]:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.1.0.tgz#a196e33fdf1e7aaa1fda3aefbb68bdad9e82a79d"
+  integrity sha512-9wwKJa2LB8ujtJB5MAXYYEM7JfYThZTj0YnfGxzLLWkifaLIGc7iTde2EpJ7ka5MjneRHnlxbIn5VV9k2WjUVA==
+
 react-icon-base@^2.1.2:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.1.2.tgz#a17101dad9c1192652356096860a9ab43a0766c7"
@@ -6815,8 +6820,6 @@ [email protected]:
   version "2.2.7"
   resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650"
   integrity sha512-0n4lcGqzJFcIQLoQytLdJCE0DKSA9dkwEZRYoGrIDJZFvIT6Hbajx5mv9geqhqFiNjUgtxg8kPyDfjlhymbGFg==
-  dependencies:
-    react-icon-base "2.1.0"
 
 react-is@^16.13.1, react-is@^16.3.1, react-is@^16.7.0:
   version "16.13.1"