소스 검색

fix(native-fs): today journal not created automaticaly

Idb file handles should be cleared when unlinking a local directory.
Tienson Qin 5 년 전
부모
커밋
690a090c87

+ 6 - 4
src/main/frontend/components/repo.cljs

@@ -42,8 +42,8 @@
            (when (nfs-handler/supported?)
              [:div.flex.flex-col
               [:div (ui/button
-                      (t :open-a-directory)
-                      :on-click nfs-handler/ls-dir-files)]
+                     (t :open-a-directory)
+                     :on-click nfs-handler/ls-dir-files)]
               [:span.warning.mt-2.text-sm "Warning: this is an experimental feature,"
                [:br]
                "please only use it for testing purpose."]])]
@@ -62,7 +62,8 @@
                                       "Clone again and re-index the db")
                              :on-click (fn []
                                          (if local?
-                                           (nfs-handler/refresh! url)
+                                           (nfs-handler/refresh! url
+                                                                 repo-handler/create-today-journal!)
                                            (repo-handler/rebuild-index! url))
                                          (js/setTimeout
                                           (fn []
@@ -92,7 +93,8 @@
           (let [syncing? (state/sub :graph/syncing?)]
             [:div.ml-2.mr-1.opacity-70.hover:opacity-100 {:class (if syncing? "loader" "initial")}
              [:a
-              {:on-click #(nfs-handler/refresh! repo)
+              {:on-click #(nfs-handler/refresh! repo
+                                                repo-handler/create-today-journal!)
                :title (str "Sync files with the local directory: " (config/get-local-dir repo))}
               svg/refresh]])
           (let [changed-files (state/sub [:repo/changed-files repo])

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

@@ -281,7 +281,8 @@
 
 (defonce idb-db-prefix "logseq-db/")
 (defonce local-db-prefix "logseq_local_")
-(defonce local-handle-prefix (str "handle/" local-db-prefix))
+(defonce local-handle "handle")
+(defonce local-handle-prefix (str local-handle "/" local-db-prefix))
 
 (defn local-db?
   [s]

+ 85 - 61
src/main/frontend/fs.cljs

@@ -132,69 +132,93 @@
      :else
      (js/window.pfs.readFile (str dir "/" path) option))))
 
+(defn nfs-saved-handler
+  [repo path file]
+  (when-let [last-modified (gobj/get file "lastModified")]
+    ;; TODO: extract
+    (let [path (if (= \/ (first path))
+                 (subs path 1)
+                 path)]
+      (db/set-file-last-modified-at! repo path last-modified))))
+
 (defn write-file
-  ([dir path content]
-   (write-file dir path content nil))
-  ([dir path content {:keys [old-content nfs-saved-handler last-modified-at]}]
-   (cond
-     (local-db? dir)
-     (let [parts (string/split path "/")
-           basename (last parts)
-           sub-dir (->> (butlast parts)
-                        (remove string/blank?)
-                        (string/join "/"))
-           sub-dir-handle-path (str "handle/"
-                                    (subs dir 1)
-                                    (if sub-dir
-                                      (str "/" sub-dir)))
-           handle-path (if (= "/" (last sub-dir-handle-path))
-                         (subs sub-dir-handle-path 0 (dec (count sub-dir-handle-path)))
-                         sub-dir-handle-path)
-           basename-handle-path (str handle-path "/" basename)]
-       (p/let [file-handle (idb/get-item basename-handle-path)
-               _ (add-nfs-file-handle! basename-handle-path file-handle)]
-         (if file-handle
-           (p/let [local-file (.getFile file-handle)
-                   local-content (.text local-file)
-                   local-last-modified-at (gobj/get local-file "lastModified")
-                   current-time (util/time-ms)
-                   new? (> current-time local-last-modified-at)
-                   not-changed? (= last-modified-at local-last-modified-at)
-                   format (-> (util/get-file-ext path)
-                              (config/get-file-format))]
-             (if (and local-content old-content new? not-changed?)
-               (do
-                 (utils/verifyPermission file-handle true)
-                 (p/let [_ (utils/writeFile file-handle content)
-                         file (.getFile file-handle)]
-                   (nfs-saved-handler file)))
-               (do
-                 (js/alert (str "The file has been modified in your local disk! File path: " path
-                                ", save your changes and click the refresh button to reload it.")))))
-           ;; create file handle
-           (->
-            (p/let [handle (idb/get-item handle-path)]
-              (if handle
+  ([repo dir path content]
+   (write-file repo dir path content nil))
+  ([repo dir path content {:keys [old-content last-modified-at]}]
+   (->
+    (cond
+      (local-db? dir)
+      (let [parts (string/split path "/")
+            basename (last parts)
+            sub-dir (->> (butlast parts)
+                         (remove string/blank?)
+                         (string/join "/"))
+            sub-dir-handle-path (str "handle/"
+                                     (subs dir 1)
+                                     (if sub-dir
+                                       (str "/" sub-dir)))
+            handle-path (if (= "/" (last sub-dir-handle-path))
+                          (subs sub-dir-handle-path 0 (dec (count sub-dir-handle-path)))
+                          sub-dir-handle-path)
+            basename-handle-path (str handle-path "/" basename)]
+        (p/let [file-handle (idb/get-item basename-handle-path)]
+          (when file-handle
+            (add-nfs-file-handle! basename-handle-path file-handle))
+          (if file-handle
+            (p/let [local-file (.getFile file-handle)
+                    local-content (.text local-file)
+                    local-last-modified-at (gobj/get local-file "lastModified")
+                    current-time (util/time-ms)
+                    new? (> current-time local-last-modified-at)
+                    new-created? (nil? last-modified-at)
+                    not-changed? (= last-modified-at local-last-modified-at)
+                    format (-> (util/get-file-ext path)
+                               (config/get-file-format))]
+              ;; (println {:last-modified-at last-modified-at
+              ;;           :local-last-modified-at local-last-modified-at
+              ;;           :not-changed? not-changed?
+              ;;           :new-created? new-created?})
+              (if (and local-content old-content new?
+                       (or not-changed? new-created?))
                 (do
-                  (utils/verifyPermission handle true)
-                  (p/let [file-handle (.getFileHandle ^js handle basename #js {:create true})
-                          _ (idb/set-item! basename-handle-path file-handle)
-                          _ (utils/writeFile file-handle content)
+                  (utils/verifyPermission file-handle true)
+                  (p/let [_ (utils/writeFile file-handle content)
                           file (.getFile file-handle)]
-                    (nfs-saved-handler file)))
-                (println "Error: directory handle not exists: " handle-path)))
-            (p/catch (fn [error]
-                       (println "Write local file failed: " {:path path})
-                       (js/console.error error)))))))
+                    (when file
+                      (nfs-saved-handler repo path file))))
+                (do
+                  (js/alert (str "The file has been modified in your local disk! File path: " path
+                                 ", save your changes and click the refresh button to reload it.")))))
+            ;; create file handle
+            (->
+             (p/let [handle (idb/get-item handle-path)]
+               (if handle
+                 (do
+                   (utils/verifyPermission handle true)
+                   (p/let [file-handle (.getFileHandle ^js handle basename #js {:create true})
+                           _ (idb/set-item! basename-handle-path file-handle)
+                           _ (utils/writeFile file-handle content)
+                           file (.getFile file-handle)]
+                     (when file
+                       (nfs-saved-handler repo path file))))
+                 (println "Error: directory handle not exists: " handle-path)))
+             (p/catch (fn [error]
+                        (println "Write local file failed: " {:path path})
+                        (js/console.error error)))))))
 
-     js/window.pfs
-     (js/window.pfs.writeFile (str dir "/" path) content)
+      js/window.pfs
+      (js/window.pfs.writeFile (str dir "/" path) content)
 
-     :else
-     nil)))
+      :else
+      nil)
+    (p/catch (fn [error]
+               (log/error :file/write-failed? {:dir dir
+                                               :path path
+                                               :error error})
+               (js/alert "Current file can't be saved! Please copy its content to your local file system and click the refresh button."))))))
 
 (defn rename
-  [old-path new-path]
+  [repo old-path new-path]
   (cond
     (local-db? old-path)
     ;; create new file
@@ -204,7 +228,7 @@
             handle (idb/get-item (str "handle" old-path))
             file (.getFile handle)
             content (.text file)
-            _ (write-file dir new-basename content)]
+            _ (write-file repo dir new-basename content)]
       (unlink old-path nil))
 
     :else
@@ -246,9 +270,9 @@
            (mkdir dir)))))))
 
 (defn create-if-not-exists
-  ([dir path]
-   (create-if-not-exists dir path ""))
-  ([dir path initial-content]
+  ([repo dir path]
+   (create-if-not-exists repo dir path ""))
+  ([repo dir path initial-content]
    (let [path (if (util/starts-with? path "/")
                 path
                 (str "/" path))]
@@ -256,7 +280,7 @@
       (stat dir path)
       (fn [_stat] true)
       (fn [error]
-        (write-file dir path initial-content)
+        (write-file repo dir path initial-content)
         false)))))
 
 (defn file-exists?

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

@@ -26,14 +26,8 @@
 (defn- watch-for-date!
   []
   (js/setInterval (fn []
-                    (state/set-today! (date/today))
-                    (when-let [repo (state/get-current-repo)]
-                      (when (or (db/cloned? repo)
-                                (config/local-db? repo))
-                        (let [today-page (string/lower-case (date/today))]
-                          (when (empty? (db/get-page-blocks-no-cache repo today-page))
-                            (repo-handler/create-today-journal-if-not-exists repo))))))
-                  1000))
+                    (when-not (state/nfs-refreshing?)
+                      (repo-handler/create-today-journal!))) 1000))
 
 (defn store-schema!
   []

+ 12 - 12
src/main/frontend/handler/draw.cljs

@@ -61,18 +61,18 @@
       (let [repo-dir (util/get-repo-dir repo)]
         (->
          (p/do!
-           (create-draws-directory! repo)
-           (fs/write-file repo-dir path data)
-           (git-handler/git-add repo path)
-           (ok-handler file)
-           (let [modified-at (tc/to-long (t/now))]
-             (db/transact! repo
-                           [{:file/path path
-                             :file/last-modified-at modified-at}
-                            {:page/name file
-                             :page/file path
-                             :page/last-modified-at (tc/to-long (t/now))
-                             :page/journal? false}])))
+          (create-draws-directory! repo)
+          (fs/write-file repo repo-dir path data)
+          (git-handler/git-add repo path)
+          (ok-handler file)
+          (let [modified-at (tc/to-long (t/now))]
+            (db/transact! repo
+                          [{:file/path path
+                            :file/last-modified-at modified-at}
+                           {:page/name file
+                            :page/file path
+                            :page/last-modified-at (tc/to-long (t/now))
+                            :page/journal? false}])))
          (p/catch (fn [error]
                     (prn "Write file failed, path: " path ", data: " data)
                     (js/console.dir error))))))))

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

@@ -458,7 +458,7 @@
                                       (or (:page/original-name page)
                                           (:page/name page)))
                                     (text/remove-level-spaces value (keyword format)))]
-                   (p/let [_ (fs/create-if-not-exists dir file-path content)
+                   (p/let [_ (fs/create-if-not-exists repo dir file-path content)
                            _ (git-handler/git-add repo path)]
                      (db/reset-file! repo path content)
                      (ui-handler/re-render-root!)
@@ -696,7 +696,7 @@
             (let [content (util/default-content-with-title format (or
                                                                    (:page/original-name page)
                                                                    (:page/name page)))]
-              (p/let [_ (fs/create-if-not-exists dir file-path content)
+              (p/let [_ (fs/create-if-not-exists repo dir file-path content)
                       _ (git-handler/git-add repo path)]
                 (db/reset-file! repo path
                                 (str content

+ 4 - 13
src/main/frontend/handler/file.cljs

@@ -118,11 +118,6 @@
         (p/catch (fn [error]
                    (log/error :load-files-error error))))))
 
-(defn nfs-saved-handler
-  [repo path file]
-  (when-let [last-modified (gobj/get file "lastModified")]
-    (db/set-file-last-modified-at! repo path last-modified)))
-
 (defn alter-file
   [repo path content {:keys [reset? re-render-root? add-history? update-status?]
                       :or {reset? true
@@ -139,10 +134,8 @@
         (db/reset-file! repo path content))
       (db/set-file-content! repo path content))
     (util/p-handle
-     (fs/write-file (util/get-repo-dir repo) path content {:old-content original-content
-                                                           :last-modified-at (db/get-file-last-modified-at repo path)
-                                                           :nfs-saved-handler (fn [file]
-                                                                                (nfs-saved-handler repo path file))})
+     (fs/write-file repo (util/get-repo-dir repo) path content {:old-content original-content
+                                                                :last-modified-at (db/get-file-last-modified-at repo path)})
      (fn [_]
        (git-handler/git-add repo path update-status?)
        (when (= path (str config/app-name "/" config/config-file))
@@ -194,11 +187,9 @@
     (let [write-file-f (fn [[path content]]
                          (let [original-content (get file->content path)]
                            (-> (p/let [_ (fs/check-directory-permission! repo)]
-                                 (fs/write-file (util/get-repo-dir repo) path content
+                                 (fs/write-file repo (util/get-repo-dir repo) path content
                                                 {:old-content original-content
-                                                 :last-modified-at (db/get-file-last-modified-at repo path)
-                                                 :nfs-saved-handler (fn [file]
-                                                                      (nfs-saved-handler repo path file))}))
+                                                 :last-modified-at (db/get-file-last-modified-at repo path)}))
                                (p/catch (fn [error]
                                           (log/error :write-file/failed {:path path
                                                                          :content content

+ 24 - 23
src/main/frontend/handler/page.cljs

@@ -63,7 +63,7 @@
                 :error)
                ;; create the file
                (let [content (util/default-content-with-title format title)]
-                 (p/let [_ (fs/create-if-not-exists dir file-path content)
+                 (p/let [_ (fs/create-if-not-exists repo dir file-path content)
                          _ (git-handler/git-add repo path)]
                    (db/reset-file! repo path content)
                    (when redirect?
@@ -293,7 +293,8 @@
         old-path (:file/path file)
         new-path (compute-new-file-path old-path new-name)]
     (->
-     (p/let [_ (fs/rename (str (util/get-repo-dir repo) "/" old-path)
+     (p/let [_ (fs/rename repo
+                          (str (util/get-repo-dir repo) "/" old-path)
                           (str (util/get-repo-dir repo) "/" new-path))]
        ;; update db
        (db/transact! repo [{:db/id (:db/id file)
@@ -428,32 +429,32 @@
   [project permalink]
   (let [url (util/format "%s%s/%s" config/api project permalink)]
     (js/Promise.
-      (fn [resolve reject]
-        (util/delete url
-          (fn [result]
-            (resolve result))
-          (fn [error]
-            (log/error :page/http-delete-failed error)
-            (reject error)))))))
+     (fn [resolve reject]
+       (util/delete url
+                    (fn [result]
+                      (resolve result))
+                    (fn [error]
+                      (log/error :page/http-delete-failed error)
+                      (reject error)))))))
 
 (defn get-page-list-by-project-name
   [project]
   (js/Promise.
-    (fn [resolve _]
-      (if-not (string? project)
-        (resolve :project-name-is-invalid)
-        (let [url (util/format "%sprojects/%s/pages" config/api project)]
+   (fn [resolve _]
+     (if-not (string? project)
+       (resolve :project-name-is-invalid)
+       (let [url (util/format "%sprojects/%s/pages" config/api project)]
          (util/fetch url
-           (fn [result]
-             (log/debug :page/get-page-list result)
-             (let [data (:result result)]
-               (if (sequential? data)
-                 (do (state/set-published-pages data)
-                     (resolve data))
-                 (log/error :page/http-get-list-result-malformed result))))
-           (fn [error]
-             (log/error :page/http-get-list-failed error)
-             (resolve error))))))))
+                     (fn [result]
+                       (log/debug :page/get-page-list result)
+                       (let [data (:result result)]
+                         (if (sequential? data)
+                           (do (state/set-published-pages data)
+                               (resolve data))
+                           (log/error :page/http-get-list-result-malformed result))))
+                     (fn [error]
+                       (log/error :page/http-get-list-failed error)
+                       (resolve error))))))))
 
 (defn update-state-and-notify
   [page-name]

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

@@ -6,6 +6,7 @@
             [lambdaisland.glogi :as log]
             [frontend.state :as state]
             [frontend.db :as db]
+            [frontend.idb :as idb]
             [frontend.git :as git]
             [cljs-bean.core :as bean]
             [frontend.date :as date]
@@ -52,7 +53,7 @@
         dir (str repo-dir "/" app-dir)]
     (p/let [_ (fs/mkdir-if-not-exists dir)]
       (let [default-content config/config-default-content]
-        (p/let [file-exists? (fs/create-if-not-exists repo-dir (str app-dir "/" config/config-file) default-content)]
+        (p/let [file-exists? (fs/create-if-not-exists repo-url repo-dir (str app-dir "/" config/config-file) default-content)]
           (let [path (str app-dir "/" config/config-file)
                 old-content (when file-exists?
                               (db/get-file repo-url path))
@@ -73,7 +74,7 @@
         file-path (str "/" path)
         default-content (util/default-content-with-title format "contents")]
     (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" (state/get-pages-directory)))
-            file-exists? (fs/create-if-not-exists repo-dir file-path default-content)]
+            file-exists? (fs/create-if-not-exists repo-url repo-dir file-path default-content)]
       (when-not file-exists?
         (db/reset-file! repo-url path default-content)
         (git-handler/git-add repo-url path)))))
@@ -86,7 +87,7 @@
         file-path (str "/" path)
         default-content ""]
     (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" config/app-name))
-            file-exists? (fs/create-if-not-exists repo-dir file-path default-content)]
+            file-exists? (fs/create-if-not-exists repo-url repo-dir file-path default-content)]
       (when-not file-exists?
         (db/reset-file! repo-url path default-content)
         (git-handler/git-add repo-url path)))))
@@ -98,7 +99,7 @@
         path (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")
         file-path (str "/" path)]
     (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" (config/get-pages-directory)))
-            _file-exists? (fs/create-if-not-exists repo-dir file-path content)]
+            _file-exists? (fs/create-if-not-exists repo-url repo-dir file-path content)]
       (db/reset-file! repo-url path content))))
 
 (defn create-today-journal-if-not-exists
@@ -134,12 +135,22 @@
      (when (or empty-blocks?
                (not page-exists?))
        (p/let [_ (fs/mkdir-if-not-exists (str repo-dir "/" config/default-journals-directory))
-               file-exists? (fs/create-if-not-exists repo-dir file-path content)]
+               file-exists? (fs/create-if-not-exists repo-url repo-dir file-path content)]
          (when-not file-exists?
            (db/reset-file! repo-url path content)
            (ui-handler/re-render-root!)
            (git-handler/git-add repo-url path)))))))
 
+(defn create-today-journal!
+  []
+  (state/set-today! (date/today))
+  (when-let [repo (state/get-current-repo)]
+    (when (or (db/cloned? repo)
+              (config/local-db? repo))
+      (let [today-page (string/lower-case (date/today))]
+        (when (empty? (db/get-page-blocks-no-cache repo today-page))
+          (create-today-journal-if-not-exists repo))))))
+
 (defn create-default-files!
   [repo-url]
   (spec/validate :repos/url repo-url)
@@ -452,10 +463,8 @@
                       (fs/rmdir (util/get-repo-dir url))
                       (state/delete-repo! repo))]
     (if (config/local-db? url)
-      (do
-        (delete-db-f)
-        ;; clear handles
-)
+      (p/let [_ (idb/clear-local-db! url)] ; clear file handles
+        (delete-db-f))
       (util/delete (str config/api "repos/" id)
                    delete-db-f
                    (fn [error]

+ 15 - 7
src/main/frontend/handler/web/nfs.cljs

@@ -188,10 +188,15 @@
                   ;; Use the same labels as isomorphic-git
                   rename-f (fn [typ col] (mapv (fn [file] {:type typ :path file}) col))
                   _ (when (seq deleted)
-                      (p/all (map (fn [path]
-                                    (let [handle-path (str handle-path path)]
-                                      (idb/remove-item! handle-path)
-                                      (fs/remove-nfs-file-handle! handle-path))) deleted)))
+                      (let [deleted (doall
+                                     (-> (map (fn [path] (if (= "/" (first path))
+                                                           path
+                                                           (str "/" path))) deleted)
+                                         (distinct)))]
+                        (p/all (map (fn [path]
+                                      (let [handle-path (str handle-path path)]
+                                        (idb/remove-item! handle-path)
+                                        (fs/remove-nfs-file-handle! handle-path))) deleted))))
                   added-or-modified (set (concat added modified))
                   _ (when (seq added-or-modified)
                       (p/all (map (fn [path]
@@ -226,10 +231,13 @@
                 (p/finally (fn [_]
                              (state/set-graph-syncing? false))))))))))
 
-(defn- refresh!
-  [repo]
+(defn refresh!
+  [repo ok-handler]
   (when repo
-    (reload-dir! repo)))
+    (state/set-nfs-refreshing! true)
+    (p/let [_ (reload-dir! repo)
+            _ (ok-handler)]
+      (state/set-nfs-refreshing! false))))
 
 (defn supported?
   []

+ 10 - 0
src/main/frontend/idb.cljs

@@ -5,6 +5,7 @@
             [promesa.core :as p]
             [clojure.string :as string]
             [frontend.config :as config]
+            [frontend.util :as util]
             [frontend.storage :as storage]))
 
 ;; offline db
@@ -53,3 +54,12 @@
   (p/let [ks (get-keys)]
     (->> (filter (fn [k] (string/starts-with? k (str config/idb-db-prefix config/local-db-prefix))) ks)
          (map #(string/replace-first % config/idb-db-prefix "")))))
+
+(defn clear-local-db!
+  [repo]
+  (when repo
+    (p/let [ks (get-keys)
+            ks (filter (fn [k] (string/starts-with? k (str config/local-handle "/" repo))) ks)]
+      (when (seq ks)
+        (p/all (map (fn [key]
+                      (remove-item! key)) ks))))))

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

@@ -27,6 +27,7 @@
     :repo/sync-status {}
     :repo/changed-files nil
     :nfs/loading-files? nil
+    :nfs/refreshing? nil
     ;; TODO: how to detect the network reliably?
     :network/online? true
     :indexeddb/support? true
@@ -1002,6 +1003,14 @@
   [repo file?]
   (get-in (:db/latest-txs @state) [repo file?]))
 
+(defn set-nfs-refreshing!
+  [value]
+  (set-state! :nfs/refreshing? value))
+
+(defn nfs-refreshing?
+  []
+  (:nfs/refreshing? @state))
+
 ;; TODO: Move those to the uni `state`
 
 (defonce editor-op (atom nil))