From a73b4e242f1c2cad583b71ac4a798c02e1550f81 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 22 Jan 2021 23:04:09 +0800 Subject: [PATCH] electron: add re-index support --- src/electron/electron/handler.cljs | 19 ++++++++---- src/main/frontend/fs.cljs | 9 ++++++ src/main/frontend/fs/bfs.cljs | 2 ++ src/main/frontend/fs/nfs.cljs | 4 ++- src/main/frontend/fs/node.cljs | 4 ++- src/main/frontend/fs/protocol.cljs | 3 +- src/main/frontend/handler/web/nfs.cljs | 41 +++++++++++++++----------- 7 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index 723e19dda..e5a50863a 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -41,12 +41,9 @@ (defmethod handle :stat [_window [_ path]] (fs/statSync path)) -;; TODO: Is it going to be slow if it's a huge directory -(defmethod handle :openDir [window _messages] - (let [result (.showOpenDialogSync dialog (bean/->js - {:properties ["openDirectory"]})) - path (first result) - result (->> (map +(defn- get-files + [path] + (let [result (->> (map (fn [path] (let [stat (fs/statSync path)] (when-not (.isDirectory stat) @@ -57,6 +54,16 @@ (remove nil?))] (vec (cons {:path path} result)))) +;; TODO: Is it going to be slow if it's a huge directory +(defmethod handle :openDir [window _messages] + (let [result (.showOpenDialogSync dialog (bean/->js + {:properties ["openDirectory"]})) + path (first result)] + (get-files path))) + +(defmethod handle :getFiles [window [_ path]] + (get-files path)) + (defmethod handle :default [args] (println "Error: no ipc handler for: " (bean/->js args))) diff --git a/src/main/frontend/fs.cljs b/src/main/frontend/fs.cljs index cdd76116e..801d0d29d 100644 --- a/src/main/frontend/fs.cljs +++ b/src/main/frontend/fs.cljs @@ -96,6 +96,15 @@ [(:path dir) paths]) result)))) +(defn get-files + [path-or-handle ok-handler] + (let [record (if (util/electron?) node-record nfs-record)] + (p/let [result (protocol/get-files record path-or-handle ok-handler)] + (if (util/electron?) + (let [[dir & paths] (bean/->clj result)] + [(:path dir) paths]) + result)))) + (defn mkdir-if-not-exists [dir] (when dir diff --git a/src/main/frontend/fs/bfs.cljs b/src/main/frontend/fs/bfs.cljs index b9af6ca57..c6913ad05 100644 --- a/src/main/frontend/fs/bfs.cljs +++ b/src/main/frontend/fs/bfs.cljs @@ -33,4 +33,6 @@ (stat [this dir path] (js/window.pfs.stat (str dir path))) (open-dir [this ok-handler] + nil) + (get-files [this path-or-handle ok-handler] nil)) diff --git a/src/main/frontend/fs/nfs.cljs b/src/main/frontend/fs/nfs.cljs index 98b55da52..14eb4f185 100644 --- a/src/main/frontend/fs/nfs.cljs +++ b/src/main/frontend/fs/nfs.cljs @@ -196,4 +196,6 @@ (p/rejected "File not exists"))) (open-dir [this ok-handler] (utils/openDirectory #js {:recursive true} - ok-handler))) + ok-handler)) + (get-files [this path-or-handle ok-handler] + (utils/getFiles path-or-handle true ok-handler))) diff --git a/src/main/frontend/fs/node.cljs b/src/main/frontend/fs/node.cljs index 7942e007b..f0e7f1918 100644 --- a/src/main/frontend/fs/node.cljs +++ b/src/main/frontend/fs/node.cljs @@ -42,4 +42,6 @@ (let [path (concat-path dir path)] (ipc/ipc "stat" path))) (open-dir [this ok-handler] - (ipc/ipc "openDir" {}))) + (ipc/ipc "openDir" {})) + (get-files [this path-or-handle ok-handler] + (ipc/ipc "getFiles" path-or-handle))) diff --git a/src/main/frontend/fs/protocol.cljs b/src/main/frontend/fs/protocol.cljs index 480defead..022db2ba7 100644 --- a/src/main/frontend/fs/protocol.cljs +++ b/src/main/frontend/fs/protocol.cljs @@ -9,4 +9,5 @@ (write-file! [this repo dir path content opts]) (rename! [this repo old-path new-path]) (stat [this dir path]) - (open-dir [this ok-handler])) + (open-dir [this ok-handler]) + (get-files [this path-or-handle ok-handler])) diff --git a/src/main/frontend/handler/web/nfs.cljs b/src/main/frontend/handler/web/nfs.cljs index 0d1bc2415..82a26b52c 100644 --- a/src/main/frontend/handler/web/nfs.cljs +++ b/src/main/frontend/handler/web/nfs.cljs @@ -98,6 +98,7 @@ (nfs/add-nfs-file-handle! path handle)) (set-files-aux! handles))) +;; TODO: extract code for `ls-dir-files` and `reload-dir!` (defn ls-dir-files [] (let [path-handles (atom {}) @@ -213,30 +214,34 @@ dir-name (config/get-local-dir repo) handle-path (str config/local-handle-prefix dir-name) path-handles (atom {}) - electron? (util/electron?)] + electron? (util/electron?) + nfs? (not electron?)] (state/set-graph-syncing? true) (-> (p/let [handle (idb/get-item handle-path)] - (when handle + (when (or handle electron?) ; electron doesn't store the file handle (p/let [_ (when handle (nfs/verify-permission repo handle true)) - files-result (utils/getFiles handle true - (fn [path handle] - (swap! path-handles assoc path handle))) - new-files (-> (->db-files electron? dir-name files-result) + files-result (fs/get-files (if nfs? handle + (config/get-local-dir repo)) + (fn [path handle] + (when nfs? + (swap! path-handles assoc path handle)))) + new-files (-> (->db-files electron? dir-name (second files-result)) remove-ignore-files) - _ (let [file-paths (set (map :file/path new-files))] - (swap! path-handles (fn [handles] - (->> handles - (filter (fn [[path _handle]] - (contains? file-paths - (string/replace-first path (str dir-name "/") "")))) - (into {}))))) - _ (set-files! @path-handles) + _ (when nfs? + (let [file-paths (set (map :file/path new-files))] + (swap! path-handles (fn [handles] + (->> handles + (filter (fn [[path _handle]] + (contains? file-paths + (string/replace-first path (str dir-name "/") "")))) + (into {}))))) + (set-files! @path-handles)) get-file-f (fn [path files] (some #(when (= (:file/path %) path) %) files)) {:keys [added modified deleted] :as diffs} (compute-diffs old-files new-files) ;; Use the same labels as isomorphic-git rename-f (fn [typ col] (mapv (fn [file] {:type typ :path file}) col)) - _ (when (seq deleted) + _ (when (and nfs? (seq deleted)) (let [deleted (doall (-> (map (fn [path] (if (= "/" (first path)) path @@ -247,13 +252,15 @@ (idb/remove-item! handle-path) (nfs/remove-nfs-file-handle! handle-path))) deleted)))) added-or-modified (set (concat added modified)) - _ (when (seq added-or-modified) + _ (when (and nfs? (seq added-or-modified)) (p/all (map (fn [path] (when-let [handle (get @path-handles path)] (idb/set-item! (str handle-path path) handle))) added-or-modified)))] (-> (p/all (map (fn [path] (when-let [file (get-file-f path new-files)] - (p/let [content (.text (:file/file file))] + (p/let [content (if nfs? + (.text (:file/file file)) + (:file/content file))] (assoc file :file/content content)))) added-or-modified)) (p/then (fn [result] (let [files (map #(dissoc % :file/file :file/handle) result)