mirror of
https://github.com/logseq/logseq.git
synced 2026-05-04 19:06:21 +00:00
116 lines
4.9 KiB
Clojure
116 lines
4.9 KiB
Clojure
(ns frontend.fs.watcher-handler
|
|
"Main ns that handles file watching events from electron's main process"
|
|
(:require [clojure.string :as string]
|
|
[frontend.config :as config]
|
|
[frontend.db :as db]
|
|
[frontend.db.model :as model]
|
|
[frontend.handler.editor :as editor]
|
|
[frontend.handler.file :as file-handler]
|
|
[frontend.handler.page :as page-handler]
|
|
[frontend.handler.ui :as ui-handler]
|
|
[logseq.graph-parser.util :as gp-util]
|
|
[logseq.graph-parser.config :as gp-config]
|
|
[logseq.graph-parser.util.block-ref :as block-ref]
|
|
[frontend.mobile.util :as mobile-util]
|
|
[lambdaisland.glogi :as log]
|
|
[promesa.core :as p]
|
|
[frontend.state :as state]
|
|
[frontend.fs :as fs]
|
|
[frontend.fs.capacitor-fs :as capacitor-fs]))
|
|
|
|
;; all IPC paths must be normalized! (via gp-util/path-normalize)
|
|
|
|
(defn- set-missing-block-ids!
|
|
[content]
|
|
(when (string? content)
|
|
(doseq [block-id (block-ref/get-all-block-ref-ids content)]
|
|
(when-let [block (try
|
|
(model/get-block-by-uuid block-id)
|
|
(catch :default _e
|
|
nil))]
|
|
(let [id-property (:id (:block/properties block))]
|
|
(when-not (= (str id-property) (str block-id))
|
|
(editor/set-block-property! block-id "id" block-id)))))))
|
|
|
|
(defn- handle-add-and-change!
|
|
[repo path content db-content mtime backup?]
|
|
(p/let [
|
|
;; save the previous content in a versioned bak file to avoid data overwritten.
|
|
_ (when backup?
|
|
(-> (when-let [repo-dir (config/get-local-dir repo)]
|
|
(file-handler/backup-file! repo-dir path db-content content))
|
|
(p/catch #(js/console.error "❌ Bak Error: " path %))))
|
|
|
|
_ (file-handler/alter-file repo path content {:re-render-root? true
|
|
:from-disk? true})]
|
|
(set-missing-block-ids! content)
|
|
(db/set-file-last-modified-at! repo path mtime)))
|
|
|
|
(defn handle-changed!
|
|
[type {:keys [dir path content stat global-dir] :as payload}]
|
|
(when dir
|
|
(let [path (gp-util/path-normalize path)
|
|
path (if (mobile-util/native-platform?)
|
|
(capacitor-fs/normalize-file-protocol-path nil path)
|
|
path)
|
|
;; Global directory events don't know their originating repo so we rely
|
|
;; on the client to correctly identify it
|
|
repo (if global-dir (state/get-current-repo) (config/get-local-repo dir))
|
|
{:keys [mtime]} stat
|
|
db-content (or (db/get-file repo path) "")]
|
|
(when (or content (contains? #{"unlink" "unlinkDir" "addDir"} type))
|
|
(cond
|
|
(and (= "unlinkDir" type) 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
|
|
|
|
(and (= "add" type)
|
|
(not= (string/trim content) (string/trim db-content)))
|
|
(let [backup? (not (string/blank? db-content))]
|
|
(handle-add-and-change! repo path content db-content mtime backup?))
|
|
|
|
(and (= "change" type)
|
|
(not (db/file-exists? repo path)))
|
|
(js/console.error "Can't get file in the db: " path)
|
|
|
|
(and (= "change" type)
|
|
(not= (string/trim content) (string/trim db-content))
|
|
(not (gp-config/local-asset? (string/replace-first path dir ""))))
|
|
(when-not (and
|
|
(string/includes? path (str "/" (config/get-journals-directory) "/"))
|
|
(or
|
|
(= (string/trim content)
|
|
(string/trim (or (state/get-default-journal-template) "")))
|
|
(= (string/trim content) "-")
|
|
(= (string/trim content) "*")))
|
|
(handle-add-and-change! repo path content db-content mtime (not global-dir))) ;; no backup for global dir
|
|
|
|
(and (= "unlink" type)
|
|
(db/file-exists? repo path))
|
|
(p/let [dir-exists? (fs/file-exists? dir "")]
|
|
(when dir-exists?
|
|
(when-let [page-name (db/get-file-page path)]
|
|
(println "Delete page: " page-name ", file path: " path ".")
|
|
(page-handler/delete! page-name #() :delete-file? false))))
|
|
|
|
(and (contains? #{"add" "change" "unlink"} type)
|
|
(string/ends-with? path "logseq/custom.css"))
|
|
(do
|
|
(println "reloading custom.css")
|
|
(ui-handler/add-style-if-exists!))
|
|
|
|
(contains? #{"add" "change" "unlink"} type)
|
|
nil
|
|
|
|
:else
|
|
(log/error :fs/watcher-no-handler {:type type
|
|
:payload payload})))
|
|
|
|
;; return nil, otherwise the entire db will be transfered by ipc
|
|
nil)))
|