-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
watcher_handler.cljs
122 lines (106 loc) · 5.17 KB
/
watcher_handler.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
(ns frontend.fs.watcher-handler
(: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.repo :as repo-handler]
[frontend.handler.ui :as ui-handler]
[logseq.graph-parser.util :as gp-util]
[frontend.util.text :as text-util]
[lambdaisland.glogi :as log]
[electron.ipc :as ipc]
[promesa.core :as p]
[frontend.state :as state]
[frontend.encrypt :as encrypt]
[frontend.fs :as fs]))
;; all IPC paths must be normalized! (via gp-util/path-normalize)
(defn- set-missing-block-ids!
[content]
(when (string? content)
(doseq [block-id (text-util/extract-all-block-refs content)]
(when-let [block (try
(model/get-block-by-uuid block-id)
(catch js/Error _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? (ipc/ipc "backupDbFile" (config/get-local-dir repo) path db-content content))
_ (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] :as payload}]
(when dir
(let [path (gp-util/path-normalize path)
repo (config/get-local-repo dir)
pages-metadata-path (config/get-pages-metadata-path)
{:keys [mtime]} stat
db-content (or (db/get-file repo path) "")]
(when (and (or content (contains? #{"unlink" "unlinkDir" "addDir"} type))
(not (encrypt/content-encrypted? content))
(not (:encryption/graph-parsing? @state/state)))
(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))
(not= path pages-metadata-path))
(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= path pages-metadata-path))
(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 true))
(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 #() :unlink-file? true))))
(and (contains? #{"add" "change" "unlink"} type)
(string/ends-with? path "logseq/custom.css"))
(do
(println "reloading custom.css")
(ui-handler/add-style-if-exists!))
;; When metadata is added to watcher, update timestamps in db accordingly
;; This event is not triggered on re-index
;; Persistent metadata is gold standard when db is offline, so it's forced
(and (contains? #{"add"} type)
(= path pages-metadata-path))
(p/do! (repo-handler/update-pages-metadata! repo content true))
;; Change is triggered by external changes, so update to the db
;; Don't forced update when db is online, but resolving conflicts
(and (contains? #{"change"} type)
(= path pages-metadata-path))
(p/do! (repo-handler/update-pages-metadata! repo content false))
(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)))