chore: remove nfs support

Assets will be stored in IndexedDB through memory fs on web.
This commit is contained in:
Tienson Qin
2025-05-13 18:40:58 +08:00
parent 5e1a968530
commit de88511bda
21 changed files with 87 additions and 564 deletions

View File

@@ -467,11 +467,9 @@
[state config title href metadata full_text]
(let [src (::src state)
repo (state/get-current-repo)
granted? (state/sub [:nfs/user-granted? repo])
href (config/get-local-asset-absolute-path href)
db-based? (config/db-based-graph? repo)]
(when (and (or db-based?
granted?
(util/electron?)
(mobile-util/native-platform?))
(nil? @src))

View File

@@ -262,17 +262,17 @@
:shortcut :go/home})
(when enable-journals?
(sidebar-item
{:class "journals-nav"
:active (and (not srs-open?)
(or (= route-name :all-journals) (= route-name :home)))
:title (t :left-side-bar/journals)
:on-click-handler (fn [e]
(if (gobj/get e "shiftKey")
(route-handler/sidebar-journals!)
(route-handler/go-to-journals!)))
:icon "calendar"
:shortcut :go/journals}))))
(sidebar-item
{:class "journals-nav"
:active (and (not srs-open?)
(or (= route-name :all-journals) (= route-name :home)))
:title (t :left-side-bar/journals)
:on-click-handler (fn [e]
(if (gobj/get e "shiftKey")
(route-handler/sidebar-journals!)
(route-handler/go-to-journals!)))
:icon "calendar"
:shortcut :go/journals}))))
(for [nav checked-navs]
(cond
@@ -955,7 +955,6 @@
(state/set-state! :editor/latest-shortcut nil)))))
[state route-match main-content']
(let [current-repo (state/sub :git/current-repo)
granted? (state/sub [:nfs/user-granted? (state/get-current-repo)])
theme (state/sub :ui/theme)
accent-color (some-> (state/sub :ui/radix-color) (name))
editor-font (some-> (state/sub :ui/editor-font) (name))
@@ -992,7 +991,7 @@
:route route-match
:current-repo current-repo
:edit? edit?
:nfs-granted? granted?
:db-restoring? db-restoring?
:sidebar-open? sidebar-open?
:settings-open? settings-open?
@@ -1067,7 +1066,6 @@
(plugins/custom-js-installer
{:t t
:current-repo current-repo
:nfs-granted? granted?
:db-restoring? db-restoring?})
(app-context-menu-observer)

View File

@@ -9,11 +9,11 @@
[frontend.components.onboarding.quick-tour :as quick-tour]
[frontend.components.page :as page]
[frontend.config :as config]
[frontend.db.model :as db-model]
[frontend.db.file-based.model :as file-model]
[frontend.db.model :as db-model]
[frontend.fs :as fs]
[frontend.fs.sync :as fs-sync]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.file-sync :refer [*beta-unavailable?] :as file-sync-handler]
[frontend.handler.notification :as notification]
[frontend.handler.page :as page-handler]

View File

@@ -586,13 +586,13 @@
(when (and develop-mode? (util/electron?) (not market?))
[:div
(ui/tooltip
(ui/button
(t :plugin/load-unpacked)
{:icon "upload"
:intent "link"
:class "load-unpacked"
:on-click plugin-handler/load-unpacked-plugin})
[:div (t :plugin/unpacked-tips)])
(ui/button
(t :plugin/load-unpacked)
{:icon "upload"
:intent "link"
:class "load-unpacked"
:on-click plugin-handler/load-unpacked-plugin})
[:div (t :plugin/unpacked-tips)])
(when (util/electron?)
(unpacked-plugin-loader selected-unpacked-pkg))])]
@@ -1524,13 +1524,13 @@
(bean/->clj (.-settingsSchema pl)) pl)))]]]]))
(rum/defc custom-js-installer
[{:keys [t current-repo db-restoring? nfs-granted?]}]
[{:keys [t current-repo db-restoring?]}]
(hooks/use-effect!
(fn []
(when (and (not db-restoring?)
(or (not util/nfs?) nfs-granted?))
(not util/nfs?))
(ui-handler/exec-js-if-exists-&-allowed! t)))
[current-repo db-restoring? nfs-granted?])
[current-repo db-restoring?])
nil)
(rum/defc perf-tip-content

View File

@@ -6,7 +6,7 @@
[frontend.db :as db]
[frontend.handler.db-based.rtc :as rtc-handler]
[frontend.handler.db-based.rtc-flows :as rtc-flows]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.file-sync :as file-sync]
[frontend.handler.graph :as graph]
[frontend.handler.notification :as notification]

View File

@@ -36,7 +36,7 @@
(defonce *once-theme-loaded? (volatile! false))
(rum/defc ^:large-vars/cleanup-todo container < rum/static
[{:keys [route theme accent-color editor-font on-click current-repo nfs-granted? db-restoring?
[{:keys [route theme accent-color editor-font on-click current-repo db-restoring?
settings-open? sidebar-open? system-theme? sidebar-blocks-len onboarding-state preferred-language]} child]
(let [mounted-fn (use-mounted)
[restored-sidebar? set-restored-sidebar?] (rum/use-state false)]
@@ -103,9 +103,9 @@
#(let [db-restored? (false? db-restoring?)]
(if db-restoring?
(util/set-title! (t :loading))
(when (or nfs-granted? db-restored?)
(when db-restored?
(route-handler/update-page-title! route))))
[nfs-granted? db-restoring? route])
[db-restoring? route])
(hooks/use-effect!
(fn []

View File

@@ -1,22 +1,22 @@
(ns frontend.extensions.excalidraw
(:require [clojure.string :as string]
;; NOTE: Always use production build of excalidraw
(:require ;; NOTE: Always use production build of excalidraw
;; See-also: https://github.com/excalidraw/excalidraw/pull/3330
["@excalidraw/excalidraw/dist/excalidraw.production.min" :refer [Excalidraw serializeAsJSON]]
[frontend.config :as config]
[frontend.db :as db]
[frontend.handler.editor :as editor-handler]
[frontend.handler.draw :as draw]
[frontend.handler.notification :as notification]
[frontend.handler.ui :as ui-handler]
[frontend.rum :as r]
[frontend.state :as state]
[frontend.ui :as ui]
[frontend.util :as util]
[goog.object :as gobj]
[goog.functions :refer [debounce]]
[rum.core :as rum]
[frontend.mobile.util :as mobile-util]))
["@excalidraw/excalidraw/dist/excalidraw.production.min" :refer [Excalidraw serializeAsJSON]]
[clojure.string :as string]
[frontend.config :as config]
[frontend.db :as db]
[frontend.handler.draw :as draw]
[frontend.handler.editor :as editor-handler]
[frontend.handler.notification :as notification]
[frontend.handler.ui :as ui-handler]
[frontend.mobile.util :as mobile-util]
[frontend.rum :as r]
[frontend.state :as state]
[frontend.ui :as ui]
[frontend.util :as util]
[goog.functions :refer [debounce]]
[goog.object :as gobj]
[rum.core :as rum]))
(def excalidraw (r/adapt-class Excalidraw))
@@ -99,8 +99,8 @@
[:div.draw-wrap
{:ref ref
:on-pointer-down (fn [e]
(util/stop e)
(state/set-block-component-editing-mode! true))
(util/stop e)
(state/set-block-component-editing-mode! true))
:on-blur #(state/set-block-component-editing-mode! false)
:style {:width @*draw-width
:height (if wide-mode? 650 500)}}
@@ -162,11 +162,8 @@
(rum/defc draw < rum/reactive
[option]
(let [repo (state/get-current-repo)
granted? (state/sub [:nfs/user-granted? repo])]
;; Web granted
(let [repo (state/get-current-repo)]
(when-not (and (config/local-file-based-graph? repo)
(not granted?)
(not (util/electron?))
(not (mobile-util/native-platform?)))
(draw-container option))))

View File

@@ -7,7 +7,6 @@
[frontend.config :as config]
[frontend.fs.capacitor-fs :as capacitor-fs]
[frontend.fs.memory-fs :as memory-fs]
[frontend.fs.nfs :as nfs]
[frontend.fs.node :as node]
[frontend.fs.protocol :as protocol]
[frontend.mobile.util :as mobile-util]
@@ -18,7 +17,6 @@
[logseq.common.util :as common-util]
[promesa.core :as p]))
(defonce nfs-backend (nfs/->Nfs))
(defonce memory-backend (memory-fs/->MemoryFs))
(defonce node-backend (node/->Node))
(defonce mobile-backend (capacitor-fs/->Capacitorfs))
@@ -31,10 +29,7 @@
node-backend
(mobile-util/native-platform?)
mobile-backend
:else
nfs-backend))
mobile-backend))
(defn get-fs
[dir & {:keys [repo rpath]}]
@@ -62,11 +57,8 @@
(and (util/electron?) (not bfs-local?))
node-backend
(mobile-util/native-platform?)
mobile-backend
:else
nfs-backend)))
mobile-backend)))
(defn mkdir!
[dir]

View File

@@ -1,366 +0,0 @@
(ns frontend.fs.nfs
"Browser File System API based fs implementation.
Rationale:
- nfs-file-handles-cache stores all file & directory handle
- idb stores top-level directory handle
- readdir/get-files is called by re-index and initial watcher to init all handles"
(:require [frontend.fs.protocol :as protocol]
[frontend.util :as util]
[clojure.string :as string]
[frontend.idb :as idb]
[promesa.core :as p]
[lambdaisland.glogi :as log]
[goog.object :as gobj]
[frontend.db :as db]
[frontend.config :as config]
[frontend.state :as state]
[frontend.handler.notification :as notification]
["/frontend/utils" :as utils]
[logseq.common.util :as common-util]
[logseq.common.path :as path]))
;; Cache the file handles in the memory so that
;; the browser will not keep asking permissions.
(defonce nfs-file-handles-cache (atom {}))
(defn- get-nfs-file-handle
[handle-path]
(get @nfs-file-handles-cache handle-path))
(defn add-nfs-file-handle!
[handle-path handle]
(prn ::DEBUG "add-nfs-file-handle!" handle-path)
(swap! nfs-file-handles-cache assoc handle-path handle))
(defn remove-nfs-file-handle!
[handle-path]
(swap! nfs-file-handles-cache dissoc handle-path))
(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)]
;; Bad code
(db/set-file-last-modified-at! repo path last-modified))))
(defn- verify-handle-permission
[handle read-write?]
(utils/verifyPermission handle read-write?))
(defn verify-permission
[repo read-write?]
(let [repo (or repo (state/get-current-repo))
repo-dir (config/get-repo-dir repo)
handle-path (str "handle/" repo-dir)
handle (get-nfs-file-handle handle-path)]
(p/then
(utils/verifyPermission handle read-write?)
(fn []
(state/set-state! [:nfs/user-granted? repo] true)
true))))
(defn check-directory-permission!
[repo]
(when (config/local-file-based-graph? repo)
(p/let [repo-dir (config/get-repo-dir repo)
handle-path (str "handle/" repo-dir)
handle (idb/get-item handle-path)]
(when handle
(add-nfs-file-handle! handle-path handle)
(verify-permission repo true)))))
(defn- contents-matched?
[disk-content db-content]
(when (and (string? disk-content) (string? db-content))
(= (string/trim disk-content) (string/trim db-content))))
(defn- await-permission-granted
"Guard against File System Access API permission, avoiding early access before granted"
[repo]
(if (state/nfs-user-granted? repo)
(p/resolved true)
(js/Promise. (fn [resolve reject]
(let [timer (atom nil)
timer' (js/setInterval (fn []
(when (state/nfs-user-granted? repo)
(js/clearInterval @timer)
(resolve true)))
1000)
_ (reset! timer timer')]
(js/setTimeout (fn []
(js/clearInterval timer)
(reject false))
100000))))))
(defn await-get-nfs-file-handle
"for accessing File handle outside, ensuring user granted."
[repo handle-path]
(p/let [_ (await-permission-granted repo)]
(get-nfs-file-handle handle-path)))
(defn- readdir-and-reload-all-handles
"Return list of filenames"
[root-dir root-handle]
(p/let [files (utils/getFiles root-handle
true
(fn [path entry]
(let [handle-path (str "handle/" path)]
;; Same for all handles here, even for directories and ignored directories(for backing up)
;; FileSystemDirectoryHandle or FileSystemFileHandle
(when-not (string/includes? path "/.")
(add-nfs-file-handle! handle-path entry)))))]
(->> files
(remove (fn [file]
(let [rpath (string/replace-first (.-webkitRelativePath file) (str root-dir "/") "")
ext (util/get-file-ext rpath)]
(or (string/blank? rpath)
(string/starts-with? rpath ".")
(string/starts-with? rpath "logseq/bak")
; (string/starts-with? rpath "logseq/version-files")
(not (contains? #{"md" "org" "excalidraw" "edn" "css"} ext))))))
(map (fn [file]
(-> (.-webkitRelativePath file)
common-util/path-normalize))))))
(defn- get-files-and-reload-all-handles
"Return list of file objects"
[root-dir root-handle]
(p/let [files (utils/getFiles root-handle
true
(fn [path entry]
(let [handle-path (str "handle/" path)]
;; Same for all handles here, even for directories and ignored directories(for backing up)
;; FileSystemDirectoryHandle or FileSystemFileHandle
(when-not (string/includes? path "/.")
(add-nfs-file-handle! handle-path entry)))))]
(p/all (->> files
(remove (fn [file]
(let [rpath (string/replace-first (.-webkitRelativePath file) (str root-dir "/") "")
ext (util/get-file-ext rpath)]
(or (string/blank? rpath)
(string/starts-with? rpath ".")
(string/starts-with? rpath "logseq/bak")
(string/starts-with? rpath "logseq/version-files")
(not (contains? #{"md" "org" "excalidraw" "edn" "css"} ext))))))
;; Read out using .text, Promise<string>
(map (fn [file]
(p/let [content (.text file)]
{:name (.-name file)
:path (-> (.-webkitRelativePath file)
common-util/path-normalize)
:mtime (.-lastModified file)
:size (.-size file)
:type (.-kind (.-handle file))
:content content
:file/file file})))))))
(defrecord ^:large-vars/cleanup-todo Nfs []
protocol/Fs
(mkdir! [_this dir]
(let [dir (path/path-normalize dir)
parent-dir (path/parent dir)
parent-handle-path (str "handle/" parent-dir)]
(-> (p/let [parent-handle (or (get-nfs-file-handle parent-handle-path)
(idb/get-item parent-handle-path))
_ (when parent-handle (verify-handle-permission parent-handle true))]
(when parent-handle
(p/let [new-dir-name (path/filename dir)
new-handle (.getDirectoryHandle ^js parent-handle new-dir-name
#js {:create true})
handle-path (str "handle/" dir)
_ (idb/set-item! handle-path new-handle)]
(add-nfs-file-handle! handle-path new-handle)
(println "dir created: " dir))))
(p/catch (fn [error]
(js/console.debug "mkdir error: " error ", dir: " dir)
(throw error))))))
(mkdir-recur! [this dir]
(protocol/mkdir! this dir))
(readdir [_this dir]
;; This method is only used for repo-dir and version-files dir
;; There's no Logseq Sync support for nfs. So assume dir is always a repo dir.
(p/let [repo-url (str "logseq_local_" dir)
_ (await-permission-granted repo-url)
handle-path (str "handle/" dir)
handle (or (get-nfs-file-handle handle-path)
(idb/get-item handle-path))
_ (when handle
(verify-handle-permission handle true))
fpaths (if (string/includes? dir "/")
(js/console.error "ERROR: unimpl")
(readdir-and-reload-all-handles dir handle))]
fpaths))
(unlink! [this repo fpath _opts]
(let [repo-dir (config/get-repo-dir repo)
filename (path/filename fpath)
handle-path (str "handle/" fpath)
recycle-dir (path/path-join repo-dir config/app-name config/recycle-dir)]
(->
(p/let [_ (protocol/mkdir! this recycle-dir)
handle (get-nfs-file-handle handle-path)
file (.getFile handle)
content (.text file)
bak-handle (get-nfs-file-handle (str "handle/" recycle-dir))
bak-filename (-> (path/relative-path repo-dir fpath)
(string/replace "/" "_")
(string/replace "\\" "_"))
file-handle (.getFileHandle ^js bak-handle bak-filename #js {:create true})
_ (utils/writeFile file-handle content)
parent-dir (path/parent fpath)
parent-handle (get-nfs-file-handle (str "handle/" parent-dir))
_ (when parent-handle
(.removeEntry ^js parent-handle filename))]
(idb/remove-item! handle-path)
(remove-nfs-file-handle! handle-path))
(p/catch (fn [error]
(log/error :unlink/path {:path fpath
:error error}))))))
(rmdir! [_this _dir]
nil)
(read-file [_this dir path _options]
(p/let [fpath (path/path-join dir path)
handle-path (str "handle/" fpath)]
(p/let [handle (or (get-nfs-file-handle handle-path)
(idb/get-item handle-path))
local-file (and handle (.getFile handle))]
(and local-file (.text local-file)))))
(write-file! [_this repo dir path content opts]
;; TODO: file backup handling
(let [fpath (path/path-join dir path)
ext (util/get-file-ext path)
file-handle-path (str "handle/" fpath)]
(p/let [file-handle (get-nfs-file-handle file-handle-path)]
(if file-handle
;; file exist
(p/let [local-file (.getFile file-handle)
disk-content (.text local-file)
db-content (db/get-file repo path)
contents-matched?' (contents-matched? disk-content db-content)]
(if (and
(not (string/blank? db-content))
(not (:skip-compare? opts))
(not contents-matched?')
(not (contains? #{"excalidraw" "edn" "css"} ext))
(not (string/includes? path "/.recycle/")))
(state/pub-event! [:file/not-matched-from-disk path disk-content content])
(p/let [_ (verify-permission repo true)
_ (utils/writeFile file-handle content)
file (.getFile file-handle)]
(when file
(db/set-file-content! repo path content)
(nfs-saved-handler repo path file)))))
;; file no-exist, write via parent dir handle
(p/let [basename (path/filename fpath)
parent-dir (path/parent fpath)
parent-dir-handle-path (str "handle/" parent-dir)
parent-dir-handle (get-nfs-file-handle parent-dir-handle-path)]
(if parent-dir-handle
;; create from directory handle
(p/let [file-handle (.getFileHandle ^js parent-dir-handle basename #js {:create true})
_ (add-nfs-file-handle! file-handle-path file-handle)
file (.getFile file-handle)
text (.text file)]
(if (string/blank? text)
(p/let [;; _ (idb/set-item! file-handle-path file-handle)
_ (utils/writeFile file-handle content)
file (.getFile file-handle)]
(when file
(nfs-saved-handler repo path file)))
(do
(notification/show! (str "The file " path " already exists, please append the content if you need it.\n Unsaved content: \n" content)
:warning
false)
(state/pub-event! [:file/alter repo path text]))))
;; TODO(andelf): Create parent directory and write
;; Normally directory are created layer by layer. So it's safe to leave this unimplemented.
(js/console.error "TODO: can not create directory hierarchy")))))))
(rename! [this repo old-path new-path]
(p/let [repo-dir (config/get-repo-dir repo)
old-rpath (path/relative-path repo-dir old-path)
new-rpath (path/relative-path repo-dir new-path)
old-content (protocol/read-file this repo-dir old-rpath nil)
_ (protocol/write-file! this repo repo-dir new-rpath old-content nil)
_ (protocol/unlink! this repo old-path nil)]))
(stat [_this fpath]
(if-let [handle (get-nfs-file-handle (str "handle/" fpath))]
(p/let [_ (verify-handle-permission handle true)
file (.getFile handle)]
(let [get-attr #(gobj/get file %)]
{:last-modified-at (get-attr "lastModified")
:size (get-attr "size")
:path fpath
:type (get-attr "type")}))
(p/rejected "File not exists")))
(open-dir [_this _dir]
(p/let [files (utils/openDirectory #js {:recursive true
:mode "readwrite"}
(fn [path entry]
(let [handle-path (str "handle/" path)]
;; Same all handles here, even for directories and ignored directories(for backing up)
;; FileSystemDirectoryHandle or FileSystemFileHandle
(when-not (string/includes? path "/.")
(add-nfs-file-handle! handle-path entry)))))
dir-handle (first files) ;; FileSystemDirectoryHandle
dir-name (.-name dir-handle)
files (->> (next files)
(remove (fn [file]
(let [rpath (.-webkitRelativePath file) ;
; (string/replace-first (.-webkitRelativePath file) (str dir-name "/") "")
ext (util/get-file-ext rpath)]
(or (string/blank? rpath)
(string/starts-with? rpath ".")
(string/starts-with? rpath "logseq/bak")
(string/starts-with? rpath "logseq/version-files")
(not (contains? #{"md" "org" "excalidraw" "edn" "css"} ext))))))
;; Read out using .text, Promise<string>
(map (fn [file]
(js/console.log "handle" file)
(p/let [content (.text file)]
;; path content size mtime
{:name (.-name file)
:path (-> (.-webkitRelativePath file)
common-util/path-normalize)
:mtime (.-lastModified file)
:size (.-size file)
:type (.-kind (.-handle file))
:content content
;; expose the following, they are used by the file system
:file/file file}))))
files (p/all files)]
(add-nfs-file-handle! (str "handle/" dir-name) dir-handle)
(idb/set-item! (str "handle/" dir-name) dir-handle)
{:path dir-name
:files files}))
(get-files [_this dir]
(when (string/includes? dir "/")
(js/console.error "BUG: get-files(nfs) only accepts repo-dir"))
(p/let [handle-path (str "handle/" dir)
handle (get-nfs-file-handle handle-path)
files (get-files-and-reload-all-handles dir handle)]
files))
(watch-dir! [_this _dir _options]
nil)
(unwatch-dir! [_this _dir]
nil))

View File

@@ -92,8 +92,6 @@
(fn []
(js/console.log "db restored, setting up repo hooks")
(state/pub-event! [:modal/nfs-ask-permission])
(page-handler/init-commands!)
(watch-for-date!)

View File

@@ -5,7 +5,6 @@
[frontend.common.thread-api :as thread-api :refer [def-thread-api]]
[frontend.config :as config]
[frontend.fs :as fs]
[frontend.fs.nfs :as nfs]
[frontend.mobile.util :as mobile-util]
[frontend.state :as state]
[frontend.util :as util]
@@ -187,21 +186,7 @@
(config/db-based-graph? (state/get-current-repo)) ; memory fs
(p/let [binary (fs/read-file repo-dir path {})
blob (js/Blob. (array binary) (clj->js {:type "image"}))]
(when blob (js/URL.createObjectURL blob)))
:else ;; nfs
(let [handle-path (str "handle/" full-path)
cached-url (get @*assets-url-cache (keyword handle-path))]
(if cached-url
(p/resolved cached-url)
;; Loading File from handle cache
;; Use await file handle, to ensure all handles are loaded.
(p/let [handle (nfs/await-get-nfs-file-handle repo handle-path)
file (and handle (.getFile handle))]
(when file
(p/let [url (js/URL.createObjectURL file)]
(swap! *assets-url-cache assoc (keyword handle-path) url)
url)))))))))
(when blob (js/URL.createObjectURL blob)))))))
(defn- decode-digest
[^js/Uint8Array digest]

View File

@@ -20,12 +20,11 @@
[frontend.extensions.fsrs :as fsrs]
[frontend.extensions.srs :as srs]
[frontend.fs.capacitor-fs :as capacitor-fs]
[frontend.fs.nfs :as nfs]
[frontend.fs.sync :as sync]
[frontend.handler.db-based.rtc :as rtc-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.events :as events]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.file-sync :as file-sync-handler]
[frontend.handler.notification :as notification]
[frontend.handler.page :as page-handler]
@@ -93,35 +92,12 @@
(shui/dialog-open!
(component-page/batch-delete-dialog selected-rows ok-handler)))
(defn ask-permission
[repo]
(when
(and (not (util/electron?))
(not (mobile-util/native-platform?)))
(fn [{:keys [close]}]
[:div
;; TODO: fn translation with args
[:p
"Grant native filesystem permission for directory: "
[:b (config/get-local-dir repo)]]
(ui/button
(t :settings-permission/start-granting)
:class "ui__modal-enter"
:on-click (fn []
(nfs/check-directory-permission! repo)
(close)))])))
(defn get-local-repo
[]
(when-let [repo (state/get-current-repo)]
(when (config/local-file-based-graph? repo)
repo)))
(defmethod events/handle :modal/nfs-ask-permission []
(when-let [repo (get-local-repo)]
(some-> (ask-permission repo)
(shui/dialog-open! {:align :top}))))
(defmethod events/handle :modal/show-cards [[_ cards-id]]
(let [db-based? (config/db-based-graph? (state/get-current-repo))]
(shui/dialog-open!

View File

@@ -17,7 +17,7 @@
[frontend.handler.editor :as editor-handler]
[frontend.handler.events :as events]
[frontend.handler.file-based.file :as file-handler]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.file-sync :as file-sync-handler]
[frontend.handler.notification :as notification]
[frontend.handler.page :as page-handler]

View File

@@ -7,7 +7,6 @@
[frontend.db.file-based.model :as file-model]
[frontend.fs :as fs]
[frontend.fs.capacitor-fs :as capacitor-fs]
[frontend.fs.nfs :as nfs]
[frontend.handler.common.config-edn :as config-edn-common-handler]
[frontend.handler.file-based.reset-file :as reset-file-handler]
[frontend.handler.global-config :as global-config-handler]
@@ -73,7 +72,7 @@
:file/content content})]
(ok-handler file-contents))))
(p/catch (fn [error]
(log/error :nfs/load-files-error repo-url)
(log/error :fs/load-files-error repo-url)
(log/error :exception error))))))
(defn backup-file!
@@ -209,11 +208,8 @@
(when path
(let [path (common-util/path-normalize path)
original-content (get file->content path)]
(-> (p/let [_ (or
(util/electron?)
(nfs/check-directory-permission! repo))]
(fs/write-plain-text-file! repo (config/get-repo-dir repo) path content
{:old-content original-content}))
(-> (fs/write-plain-text-file! repo (config/get-repo-dir repo) path content
{:old-content original-content})
(p/catch (fn [error]
(state/pub-event! [:notification/show
{:content (str "Failed to save the file " path ". Error: "

View File

@@ -1,12 +1,11 @@
(ns frontend.handler.file-based.nfs
"The File System Access API, https://web.dev/file-system-access/."
(ns frontend.handler.file-based.native-fs
"Native fs including Electron and mobile"
(:require ["/frontend/utils" :as utils]
[clojure.set :as set]
[clojure.string :as string]
[frontend.config :as config]
[frontend.db :as db]
[frontend.fs :as fs]
[frontend.fs.nfs :as nfs]
[frontend.handler.common :as common-handler]
[frontend.handler.file-based.repo :as file-repo-handler]
[frontend.handler.global-config :as global-config-handler]
@@ -142,7 +141,7 @@
(state/set-loading-files! repo false)
(when ok-handler (ok-handler {:url repo})))))))
(p/catch (fn [error]
(log/error :nfs/load-files-error repo)
(log/error :fs/load-files-error repo)
(log/error :exception error)))))))
(p/catch (fn [error]
(log/error :exception error)
@@ -253,8 +252,7 @@
(->
(p/let [handle (when-not electron? (idb/get-item handle-path))]
(when (or handle electron? mobile-native?)
(p/let [_ (when nfs? (nfs/verify-permission repo true))
local-files-result (fs/get-files repo-dir)
(p/let [local-files-result (fs/get-files repo-dir)
_ (when (config/global-config-enabled?)
;; reload global config into state
(global-config-handler/restore-global-config!))
@@ -262,7 +260,7 @@
(remove-ignore-files repo-dir nfs?))]
(handle-diffs! repo nfs? old-files new-files re-index? ok-handler))))
(p/catch (fn [error]
(log/error :nfs/load-files-error repo)
(log/error :fs/load-files-error repo)
(log/error :exception error)))
(p/finally (fn [_]
(state/set-graph-syncing? false)))))))

View File

@@ -1,25 +1,25 @@
(ns frontend.handler.file-based.repo
"Repo fns for creating, loading and parsing file graphs"
(:require [frontend.config :as config]
(:require [clojure.core.async :as async]
[clojure.core.async.interop :refer [p->c]]
[frontend.config :as config]
[frontend.db :as db]
[frontend.db.file-based.model :as file-model]
[frontend.fs :as fs]
[frontend.handler.file-based.file :as file-handler]
[frontend.handler.repo-config :as repo-config-handler]
[frontend.handler.file-based.reset-file :as reset-file-handler]
[frontend.handler.repo-config :as repo-config-handler]
[frontend.handler.route :as route-handler]
[frontend.handler.ui :as ui-handler]
[frontend.spec :as spec]
[frontend.state :as state]
[frontend.util :as util]
[promesa.core :as p]
[shadow.resource :as rc]
[logseq.graph-parser :as graph-parser]
[logseq.common.config :as common-config]
[clojure.core.async :as async]
[medley.core :as medley]
[logseq.common.path :as path]
[clojure.core.async.interop :refer [p->c]]))
[logseq.graph-parser :as graph-parser]
[medley.core :as medley]
[promesa.core :as p]
[shadow.resource :as rc]))
(defn- create-contents-file
[repo-url]
@@ -54,49 +54,13 @@
(comment
(defn- create-dummy-notes-page
[repo-url content]
(spec/validate :repos/url repo-url)
(let [repo-dir (config/get-repo-dir repo-url)
file-rpath (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")]
(p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir (config/get-pages-directory)))
_file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath content)]
(reset-file-handler/reset-file! repo-url file-rpath content)))))
(comment
(defn- create-today-journal-if-not-exists
[repo-url {:keys [content]}]
(spec/validate :repos/url repo-url)
(when (state/enable-journals? repo-url)
(let [repo-dir (config/get-repo-dir repo-url)
format (state/get-preferred-format repo-url)
title (date/today)
file-name (date/journal-title->default title)
default-content (util/default-content-with-title format)
template (state/get-default-journal-template)
template (when (and template
(not (string/blank? template)))
template)
content (cond
content
content
template
(str default-content template)
:else
default-content)
file-rpath (path/path-join (config/get-journals-directory) (str file-name "."
(config/get-file-extension format)))
page-exists? (ldb/get-page (db/get-db) title)
empty-blocks? (db/page-empty? repo-url (util/page-name-sanity-lc title))]
(when (or empty-blocks? (not page-exists?))
(p/let [_ (nfs/check-directory-permission! repo-url)
_ (fs/mkdir-if-not-exists (path/path-join repo-dir (config/get-journals-directory)))
file-exists? (fs/file-exists? repo-dir file-rpath)]
(when-not file-exists?
(p/let [_ (reset-file-handler/reset-file! repo-url file-rpath content)]
(fs/create-if-not-exists repo-url repo-dir file-rpath content)))))))))
[repo-url content]
(spec/validate :repos/url repo-url)
(let [repo-dir (config/get-repo-dir repo-url)
file-rpath (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")]
(p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir (config/get-pages-directory)))
_file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath content)]
(reset-file-handler/reset-file! repo-url file-rpath content)))))
(defn create-config-file-if-not-exists
"Creates a default logseq/config.edn if it doesn't exist"

View File

@@ -17,7 +17,7 @@
[frontend.handler.db-based.page :as db-page-handler]
[frontend.handler.db-based.property :as db-property-handler]
[frontend.handler.editor :as editor-handler]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.file-based.page :as file-page-handler]
[frontend.handler.file-based.page-property :as file-page-property]
[frontend.handler.graph :as graph-handler]

View File

@@ -3,7 +3,7 @@
[clojure.string :as string]
[frontend.components.svg :as svg]
[frontend.fs :as fs]
[frontend.handler.file-based.nfs :as nfs-handler]
[frontend.handler.file-based.native-fs :as nfs-handler]
[frontend.handler.notification :as notification]
[frontend.handler.page :as page-handler]
[frontend.mobile.util :as mobile-util]

View File

@@ -122,15 +122,8 @@
(defn <export-db!
[repo data]
(cond
(util/electron?)
(ipc/ipc :db-export repo data)
;; TODO: browser nfs-supported? auto backup
;;
:else
nil))
(when (util/electron?)
(ipc/ipc :db-export repo data)))
(defn- sqlite-error-handler
[error]

View File

@@ -71,7 +71,6 @@
:notification/show? false
:notification/content nil
:repo/loading-files? {}
:nfs/user-granted? {}
:nfs/refreshing? nil
:instrument/disabled? (storage/get "instrument-disabled")
;; TODO: how to detect the network reliably?
@@ -2280,10 +2279,6 @@ Similar to re-frame subscriptions"
[]
(:pdf/current @state))
(defn nfs-user-granted?
[repo]
(get-in @state [:nfs/user-granted? repo]))
(defn set-current-pdf!
[inflated-file]
(let [settle-file! #(set-state! :pdf/current inflated-file)]

View File

@@ -3,17 +3,16 @@
(ns frontend.util.fs
"Misc util fns built on top of frontend.fs"
(:require ["path" :as node-path]
[clojure.string :as string]
[frontend.fs :as fs]
[frontend.config :as config]
[promesa.core :as p]
[cljs.reader :as reader]
[frontend.common.file.util :as wfu]))
[clojure.string :as string]
[frontend.common.file.util :as wfu]
[frontend.config :as config]
[frontend.fs :as fs]
[promesa.core :as p]))
;; NOTE: This is not the same ignored-path? as src/electron/electron/utils.cljs.
;; The assets directory is ignored.
;;
;; When in nfs-mode, dir is "", path is relative path to graph dir.
;; When in native-mode, dir and path are absolute paths.
(defn ignored-path?
"Ignore path for ls-dir-files-with-handler! and reload-dir!"
@@ -51,8 +50,8 @@
txid-meta (and txid-str (reader/read-string txid-str))]
txid-meta)
(p/catch
(fn [^js e]
(js/console.error "[fs read txid data error]" e))))))))
(fn [^js e]
(js/console.error "[fs read txid data error]" e))))))))
(defn inflate-graphs-info
[graphs]