mirror of https://github.com/logseq/logseq
feature: logseq protocol; refactor persistGraph
parent
f23c7cfd09
commit
aa29a00b88
|
@ -44,10 +44,22 @@
|
|||
[win url]
|
||||
(.info logger "open-url" (str {:url url}))
|
||||
|
||||
(let [parsed-url (js/URL. url)]
|
||||
(when (and (= (str LSP_SCHEME ":") (.-protocol parsed-url))
|
||||
(= "auth-callback" (.-host parsed-url)))
|
||||
(send-to-renderer win "loginCallback" (.get (.-searchParams parsed-url) "code")))))
|
||||
(let [parsed-url (js/URL. url)
|
||||
url-protocol (.-protocol parsed-url)
|
||||
url-host (.-host parsed-url)]
|
||||
(when (= (str LSP_SCHEME ":") url-protocol)
|
||||
(cond
|
||||
(= "auth-callback" url-host)
|
||||
(send-to-renderer win "loginCallback" (.get (.-searchParams parsed-url) "code"))
|
||||
|
||||
(= "local" url-host)
|
||||
(let [[graph page block-id] (utils/get-URL-decoded-params parsed-url ["graph" "page" "block-id"])
|
||||
graph-name (handler/get-graph-name graph)]
|
||||
(if graph-name
|
||||
(utils/send-to-renderer win "openNewWindowOfGraph" graph-name)
|
||||
(utils/send-to-renderer "notification" {:type "error"
|
||||
:payload (str "Cannot match graph name " graph
|
||||
" to any linked graph.")})))))))
|
||||
|
||||
(defn setup-interceptor! [^js app]
|
||||
(.setAsDefaultProtocolClient app LSP_SCHEME)
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
:stat (fs/statSync path)}))
|
||||
|
||||
(defn watch-dir!
|
||||
"Watch a directory if no such file watcher exists"
|
||||
[_win dir]
|
||||
(when (and (fs/existsSync dir)
|
||||
(not (get @*file-watcher dir)))
|
||||
|
|
|
@ -209,6 +209,7 @@
|
|||
dir))
|
||||
|
||||
(defn- get-graphs
|
||||
"Returns all graph names in the cache directory (strating with `logseq_local_`)"
|
||||
[]
|
||||
(let [dir (get-graphs-dir)]
|
||||
(->> (readdir dir)
|
||||
|
@ -216,6 +217,15 @@
|
|||
(map #(path/basename % ".transit"))
|
||||
(map graph-name->path))))
|
||||
|
||||
(defn get-graph-name
|
||||
"Given a graph's name, returns the graph's fullname.
|
||||
E.g., given `cat`, returns `logseq_local_<path_to_directory>/cat`
|
||||
Returns `nil` if no such graph exists."
|
||||
[graph]
|
||||
;; FIXME: path-normalize for electron?
|
||||
(->> (get-graphs)
|
||||
(some #(when (string/ends-with? % (str "/" graph)) %))))
|
||||
|
||||
(defmethod handle :getGraphs [_window [_]]
|
||||
(get-graphs))
|
||||
|
||||
|
@ -326,18 +336,22 @@
|
|||
|
||||
(defn close-watcher-when-orphaned!
|
||||
"When it's the last window for the directory, close the watcher."
|
||||
[window dir]
|
||||
(when (not (win/graph-has-other-windows? window dir))
|
||||
(watcher/close-watcher! dir)))
|
||||
[window graph-path]
|
||||
(when (not (win/graph-has-other-windows? window graph-path))
|
||||
(watcher/close-watcher! graph-path)))
|
||||
|
||||
(defmethod handle :setCurrentGraph [^js win [_ path]]
|
||||
(let [path (when path (utils/get-graph-dir path))
|
||||
old-path (state/get-window-graph-path win)]
|
||||
(when old-path (close-watcher-when-orphaned! win old-path))
|
||||
(swap! state/state assoc :graph/current path)
|
||||
(swap! state/state assoc-in [:window/graph win] path)
|
||||
(defn set-current-graph!
|
||||
[window graph-path]
|
||||
(let [old-path (state/get-window-graph-path window)]
|
||||
(when old-path (close-watcher-when-orphaned! window old-path))
|
||||
(swap! state/state assoc :graph/current graph-path)
|
||||
(swap! state/state assoc-in [:window/graph window] graph-path)
|
||||
nil))
|
||||
|
||||
(defmethod handle :setCurrentGraph [^js window [_ graph-name]]
|
||||
(when graph-name
|
||||
(set-current-graph! window (utils/get-graph-dir graph-name))))
|
||||
|
||||
(defmethod handle :runGit [_ [_ args]]
|
||||
(when (seq args)
|
||||
(git/raw! args)))
|
||||
|
@ -375,26 +389,30 @@
|
|||
(defmethod handle :graphHasMultipleWindows [^js _win [_ graph]]
|
||||
(let [dir (utils/get-graph-dir graph)
|
||||
windows (win/get-graph-all-windows dir)]
|
||||
;; windows (filter #(.isVisible %) windows) ;; for mac .hide windows. such windows should also included
|
||||
(> (count windows) 1)))
|
||||
|
||||
(defmethod handle :addDirWatcher [^js window [_ dir]]
|
||||
;; receive dir path (not repo / graph) from frontend
|
||||
;; Windows on same dir share the same watcher
|
||||
;; Only close file watcher when:
|
||||
;; 1. there is no one window on the same dir (TODO: check this on a window is closed)
|
||||
;; 1. there is no one window on the same dir
|
||||
;; 2. reset file watcher to resend `add` event on window refreshing
|
||||
(when dir
|
||||
;; adding dir watcher when the window has watcher already - must be cmd + r refreshing
|
||||
;; TODO: handle duplicated adding dir watcher when multiple windows
|
||||
;; maintain only one file watcher when multiple windows on the same dir
|
||||
(close-watcher-when-orphaned! window dir)
|
||||
(watcher/watch-dir! window dir)))
|
||||
|
||||
(defmethod handle :openNewWindow [_window [_]]
|
||||
(defn open-new-window!
|
||||
[]
|
||||
(let [win (win/create-main-window)]
|
||||
(win/on-close-actions! win close-watcher-when-orphaned!)
|
||||
(win/setup-window-listeners! win)
|
||||
nil))
|
||||
win))
|
||||
|
||||
(defmethod handle :openNewWindow [_window [_]]
|
||||
(open-new-window!)
|
||||
nil)
|
||||
|
||||
(defmethod handle :searchVersionChanged?
|
||||
[^js _win [_ graph]]
|
||||
|
@ -443,21 +461,28 @@
|
|||
(defmethod handle :default [args]
|
||||
(println "Error: no ipc handler for: " (bean/->js args)))
|
||||
|
||||
(defmethod handle :persistGraph [^js win [_ graph]]
|
||||
;; call a window holds the specific graph to persist
|
||||
(let [dir (utils/get-graph-dir graph)
|
||||
windows (win/get-graph-all-windows dir)
|
||||
;; windows (filter #(.isVisible %) windows) ;; for mac .hide windows. such windows should also included
|
||||
tar-graph-win (first windows)]
|
||||
(if tar-graph-win
|
||||
(utils/send-to-renderer tar-graph-win "persistGraph" graph)
|
||||
(utils/send-to-renderer win "persistGraphDone" graph)))) ;; if no such graph, skip directly
|
||||
(defn broadcast-persist-graph!
|
||||
"Sends persist graph event to the renderer contains the target graph.
|
||||
Returns a promise."
|
||||
[graph-name]
|
||||
(p/create (fn [resolve _reject]
|
||||
(let [graph-path (utils/get-graph-dir graph-name)
|
||||
windows (win/get-graph-all-windows graph-path)
|
||||
tar-graph-win (first windows)]
|
||||
(if tar-graph-win
|
||||
;; if no such graph, skip directly
|
||||
(do (state/set-state! :window/once-persist-done #(resolve nil))
|
||||
(utils/send-to-renderer tar-graph-win "persistGraph" graph-name))
|
||||
(resolve nil))))))
|
||||
|
||||
(defmethod handle :persistGraphDone [^js _win [_ graph]]
|
||||
;; when graph is persisted, broadcast it to all windows
|
||||
(let [windows (win/get-all-windows)]
|
||||
(doseq [window windows]
|
||||
(utils/send-to-renderer window "persistGraphDone" graph))))
|
||||
(defmethod handle :broadcastPersistGraph [^js _win [_ graph-name]]
|
||||
(broadcast-persist-graph! graph-name))
|
||||
|
||||
(defmethod handle :broadcastPersistGraphDone [^js _win [_]]
|
||||
;; main process -> renderer doesn't support promise, so we use a global var to store the callback
|
||||
(when-let [f (:window/once-persist-done @state/state)]
|
||||
(f)
|
||||
(state/set-state! :window/once-persist-done nil)))
|
||||
|
||||
(defn set-ipc-handler! [window]
|
||||
(let [main-channel "main"]
|
||||
|
|
|
@ -14,7 +14,10 @@
|
|||
:graph/current nil
|
||||
|
||||
;; window -> current graph
|
||||
:window/graph {}}))
|
||||
:window/graph {}
|
||||
|
||||
;; job to do when persistGraph is done on renderer
|
||||
:window/once-persist-done nil}))
|
||||
|
||||
(defn set-state!
|
||||
[path value]
|
||||
|
|
|
@ -123,3 +123,13 @@
|
|||
(defn get-graph-dir
|
||||
[graph-name]
|
||||
(string/replace graph-name "logseq_local_" ""))
|
||||
|
||||
(defn get-URL-decoded-params
|
||||
"Get decoded URL parameters from parsed js/URL.
|
||||
`nil` for non-existing keys."
|
||||
[^js parsed-url keys]
|
||||
(let [params (.-searchParams parsed-url)]
|
||||
(map (fn [key]
|
||||
(when-let [value (.get params key)]
|
||||
(js/decodeURI value)))
|
||||
keys)))
|
||||
|
|
|
@ -78,12 +78,13 @@
|
|||
|
||||
(js/window.apis.on "persistGraph"
|
||||
;; electron is requesting window for persisting a graph in it's db
|
||||
;; fire back "broadcastPersistGraphDone" on done
|
||||
(fn [data]
|
||||
(let [repo (bean/->clj data)
|
||||
before-f #(notification/show!
|
||||
(ui/loading (t :graph/persist))
|
||||
:warning)
|
||||
after-f #(ipc/ipc "persistGraphDone" repo)
|
||||
after-f #(ipc/ipc "broadcastPersistGraphDone")
|
||||
error-f (fn []
|
||||
(after-f)
|
||||
(notification/show!
|
||||
|
@ -96,7 +97,12 @@
|
|||
|
||||
(js/window.apis.on "loginCallback"
|
||||
(fn [code]
|
||||
(user/login-callback code))))
|
||||
(user/login-callback code)))
|
||||
|
||||
(js/window.apis.on "openNewWindowOfGraph"
|
||||
;; Handle open new window in renderer, until the destination graph doesn't rely on setting local storage
|
||||
(fn [repo]
|
||||
(ui-handler/open-new-window! nil repo))))
|
||||
|
||||
(defn listen!
|
||||
[]
|
||||
|
|
|
@ -670,17 +670,10 @@
|
|||
"Only works for electron
|
||||
Call backend to handle persisting a specific db on other window
|
||||
Skip persisting if no other windows is open (controlled by electron)
|
||||
step 1. [In HERE] a window --persistGraph-----> electron
|
||||
step 2. electron --persistGraph-----> window holds the graph
|
||||
step 3. window w/ graph --persistGraphDone-> electron
|
||||
step 4. [In HERE] electron --persistGraphDone-> all windows"
|
||||
step 1. [In HERE] a window ---broadcastPersistGraph----> electron
|
||||
step 2. electron ---------persistGraph-------> window holds the graph
|
||||
step 3. window w/ graph --broadcastPersistGraphDone-> electron
|
||||
step 4. [In HERE] a window <---broadcastPersistGraph---- electron"
|
||||
[graph]
|
||||
(p/create (fn [resolve _]
|
||||
(js/window.apis.on "persistGraphDone"
|
||||
#(let [repo (bean/->clj %)]
|
||||
(prn "received persistGraphDone" repo)
|
||||
(when (= graph repo)
|
||||
;; js/window.apis.once doesn't work
|
||||
(js/window.apis.removeAllListeners "persistGraphDone")
|
||||
(resolve repo))))
|
||||
(ipc/ipc "persistGraph" graph))))
|
||||
(p/let [_ (ipc/ipc "broadcastPersistGraph" graph)] ;; invoke for chaining promise
|
||||
nil))
|
||||
|
|
Loading…
Reference in New Issue