mirror of
https://github.com/logseq/logseq.git
synced 2026-04-26 07:05:10 +00:00
feat(plugin): merge implementation
This commit is contained in:
181
src/main/frontend/handler/plugin.cljs
Normal file
181
src/main/frontend/handler/plugin.cljs
Normal file
@@ -0,0 +1,181 @@
|
||||
(ns frontend.handler.plugin
|
||||
(:require [promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[frontend.util :as util]
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.notification :as notifications]
|
||||
[camel-snake-kebab.core :as csk]
|
||||
[frontend.state :as state]
|
||||
[medley.core :as md]
|
||||
[electron.ipc :as ipc]
|
||||
[cljs-bean.core :as bean]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defonce lsp-enabled? (util/electron?))
|
||||
|
||||
;; state handlers
|
||||
(defn register-plugin
|
||||
[pl]
|
||||
(swap! state/state update-in [:plugin/installed-plugins] assoc (keyword (:id pl)) pl))
|
||||
|
||||
(defn unregister-plugin
|
||||
[id]
|
||||
(js/LSPluginCore.unregister id))
|
||||
|
||||
(defn host-mounted!
|
||||
[]
|
||||
(and lsp-enabled? (js/LSPluginCore.hostMounted)))
|
||||
|
||||
(defn register-plugin-slash-command
|
||||
[pid [cmd actions]]
|
||||
(prn (if-let [pid (keyword pid)]
|
||||
(when (contains? (:plugin/installed-plugins @state/state) pid)
|
||||
(do (swap! state/state update-in [:plugin/installed-commands pid]
|
||||
(fnil merge {}) (hash-map cmd (mapv #(conj % {:pid pid}) actions)))
|
||||
true)))))
|
||||
|
||||
(defn unregister-plugin-slash-command
|
||||
[pid]
|
||||
(swap! state/state md/dissoc-in [:plugin/installed-commands (keyword pid)]))
|
||||
|
||||
(defn register-plugin-simple-command
|
||||
;; action => [:action-key :event-key]
|
||||
[pid {:keys [key label type] :as cmd} action]
|
||||
(if-let [pid (keyword pid)]
|
||||
(when (contains? (:plugin/installed-plugins @state/state) pid)
|
||||
(do (swap! state/state update-in [:plugin/simple-commands pid]
|
||||
(fnil conj []) [type cmd action pid])
|
||||
true))))
|
||||
|
||||
(defn unregister-plugin-simple-command
|
||||
[pid]
|
||||
(swap! state/state md/dissoc-in [:plugin/simple-commands (keyword pid)]))
|
||||
|
||||
(defn update-plugin-settings
|
||||
[id settings]
|
||||
(swap! state/state update-in [:plugin/installed-plugins id] assoc :settings settings))
|
||||
|
||||
(defn open-readme!
|
||||
[url display]
|
||||
(when url
|
||||
(-> (p/let [content (js/api.load_plugin_readme url)]
|
||||
(state/set-state! :plugin/active-readme content)
|
||||
(state/set-modal! display))
|
||||
(p/catch #(notifications/show! "No README file." :warn)))))
|
||||
|
||||
(defn load-unpacked-plugin
|
||||
[]
|
||||
(if util/electron?
|
||||
(p/let [path (ipc/ipc "openDialogSync")]
|
||||
(when-not (:plugin/selected-unpacked-pkg @state/state)
|
||||
(state/set-state! :plugin/selected-unpacked-pkg path)))))
|
||||
|
||||
(defn reset-unpacked-state
|
||||
[]
|
||||
(state/set-state! :plugin/selected-unpacked-pkg nil))
|
||||
|
||||
(defn hook-plugin
|
||||
[tag type payload plugin-id]
|
||||
(when lsp-enabled?
|
||||
(js-invoke js/LSPluginCore
|
||||
(str "hook" (string/capitalize (name tag)))
|
||||
(name type)
|
||||
(if (map? payload)
|
||||
(bean/->js (into {} (for [[k v] payload] [(csk/->camelCase k) (if (uuid? v) (str v) v)]))))
|
||||
(if (keyword? plugin-id) (name plugin-id) plugin-id))))
|
||||
|
||||
(defn hook-plugin-app
|
||||
([type payload] (hook-plugin-app type payload nil))
|
||||
([type payload plugin-id] (hook-plugin :app type payload plugin-id)))
|
||||
|
||||
(defn hook-plugin-editor
|
||||
([type payload] (hook-plugin-editor type payload nil))
|
||||
([type payload plugin-id] (hook-plugin :editor type payload plugin-id)))
|
||||
|
||||
(defn get-ls-dotdir-root
|
||||
[]
|
||||
(ipc/ipc "getLogseqDotDirRoot"))
|
||||
|
||||
(defn- get-user-default-plugins
|
||||
[]
|
||||
(p/catch
|
||||
(p/let [files ^js (ipc/ipc "getUserDefaultPlugins")
|
||||
files (js->clj files)]
|
||||
(map #(hash-map :url %) files))
|
||||
(fn [e]
|
||||
(js/console.error e))))
|
||||
|
||||
;; components
|
||||
(rum/defc lsp-indicator < rum/reactive
|
||||
[]
|
||||
(let [text (state/sub :plugin/indicator-text)]
|
||||
(if (= text "END")
|
||||
[:span]
|
||||
[:div
|
||||
{:style
|
||||
{:width "100%"
|
||||
:height "100vh"
|
||||
:display "flex"
|
||||
:align-items "center"
|
||||
:justify-content "center"}}
|
||||
[:span
|
||||
{:style
|
||||
{:color "#aaa"
|
||||
:font-size "38px"}} (or text "Loading ...")]])))
|
||||
|
||||
(defn init-plugins
|
||||
[callback]
|
||||
|
||||
(let [el (js/document.createElement "div")]
|
||||
(.appendChild js/document.body el)
|
||||
(rum/mount
|
||||
(lsp-indicator) el))
|
||||
|
||||
(state/set-state! :plugin/indicator-text "Loading...")
|
||||
|
||||
(p/then
|
||||
(p/let [root (get-ls-dotdir-root)
|
||||
_ (.setupPluginCore js/LSPlugin (bean/->js {:localUserConfigRoot root}))
|
||||
_ (doto js/LSPluginCore
|
||||
(.on "registered"
|
||||
(fn [^js pl]
|
||||
(register-plugin
|
||||
(bean/->clj (.parse js/JSON (.stringify js/JSON pl))))))
|
||||
|
||||
(.on "unregistered" (fn [pid]
|
||||
(let [pid (keyword pid)]
|
||||
;; plugins
|
||||
(swap! state/state md/dissoc-in [:plugin/installed-plugins (keyword pid)])
|
||||
;; commands
|
||||
(unregister-plugin-slash-command pid))))
|
||||
|
||||
(.on "theme-changed" (fn [^js themes]
|
||||
(swap! state/state assoc :plugin/installed-themes
|
||||
(vec (mapcat (fn [[_ vs]] (bean/->clj vs)) (bean/->clj themes))))))
|
||||
|
||||
(.on "theme-selected" (fn [^js opts]
|
||||
(let [opts (bean/->clj opts)
|
||||
url (:url opts)
|
||||
mode (:mode opts)]
|
||||
(when mode (state/set-theme! mode))
|
||||
(state/set-state! :plugin/selected-theme url))))
|
||||
|
||||
(.on "settings-changed" (fn [id ^js settings]
|
||||
(let [id (keyword id)]
|
||||
(when (and settings
|
||||
(contains? (:plugin/installed-plugins @state/state) id))
|
||||
(update-plugin-settings id (bean/->clj settings)))))))
|
||||
|
||||
default-plugins (get-user-default-plugins)
|
||||
|
||||
_ (.register js/LSPluginCore (bean/->js (if (seq default-plugins) default-plugins [])) true)])
|
||||
#(do
|
||||
(state/set-state! :plugin/indicator-text "END")
|
||||
(callback))))
|
||||
|
||||
(defn setup!
|
||||
"setup plugin core handler"
|
||||
[callback]
|
||||
(if (not lsp-enabled?)
|
||||
(callback)
|
||||
(init-plugins callback)))
|
||||
Reference in New Issue
Block a user