| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | (ns frontend.components.plugins  (:require [rum.core :as rum]            [frontend.state :as state]            [cljs-bean.core :as bean]            [frontend.ui :as ui]            [frontend.util :as util]            [electron.ipc :as ipc]            [promesa.core :as p]            [frontend.components.svg :as svg]            [frontend.handler.notification :as notification]            [frontend.handler.plugin :as plugin-handler]            [clojure.string :as string]))(rum/defc installed-themes  < rum/reactive  []  (let [themes (state/sub :plugin/installed-themes)        selected (state/sub :plugin/selected-theme)        themes (cons {:name "Default Theme" :url nil :description "Logseq default light/dark theme."} themes)]    [:div.cp__themes-installed     [:h2.mb-4.text-xl "Installed Themes"]     (for [opt themes]       (let [current-selected (= selected (:url opt))]         [:div.it.flex.px-3.py-2.mb-2.rounded-sm.justify-between          {:key   (:url opt)           :class [(if current-selected "is-selected")]           :on-click #(do (js/LSPluginCore.selectTheme (if current-selected nil (clj->js opt)))                          (state/set-modal! nil))}          [:section           [:strong.block (:name opt)]           [:small.opacity-30 (:description opt)]]          [:small.flex-shrink-0.flex.items-center.opacity-10           (if current-selected "current")]]))]))(rum/defc unpacked-plugin-loader  [unpacked-pkg-path]  (rum/use-effect!   (fn []     (let [err-handle           (fn [^js e]             (case (keyword (aget e "name"))               :IllegalPluginPackageError               (notification/show! "Illegal Logseq plugin package." :error)               :ExistedImportedPluginPackageError               (notification/show! "Existed Imported plugin package." :error)               :default)             (plugin-handler/reset-unpacked-state))           reg-handle #(plugin-handler/reset-unpacked-state)]       (when unpacked-pkg-path         (doto js/LSPluginCore           (.once "error" err-handle)           (.once "registered" reg-handle)           (.register (bean/->js {:url unpacked-pkg-path}))))       #(doto js/LSPluginCore          (.off "error" err-handle)          (.off "registered" reg-handle))))   [unpacked-pkg-path])  (when unpacked-pkg-path    [:strong.inline-flex.px-3 "Loading ..."]))(rum/defc simple-markdown-display  < rum/reactive  []  (let [[content item] (state/sub :plugin/active-readme)]    [:div.cp__plugins-details     {:on-click (fn [^js/MouseEvent e]                  (when-let [target (.-target e)]                    (when (and (= (string/lower-case (.-nodeName target)) "a")                               (not (string/blank? (. target getAttribute "href"))))                      (js/apis.openExternal (. target getAttribute "href"))                      (.preventDefault e))))}     (when-let [repo (:repository item)]       (when-let [repo (if (string? repo) repo (:url repo))]         [:div.p-4.rounded-md.bg-base-3          [:strong [:a.flex.items-center {:target "_blank" :href repo} [:span.mr-1 (svg/github {:width 25 :height 25})] repo]]]))     [:div.p-1.bg-transparent.border-none.ls-block      {:style                   {:min-height "60vw"}       :dangerouslySetInnerHTML {:__html content}}]]))(rum/defc plugin-item-card  [{:keys [id name settings version url description author icon usf] :as item}]  (let [disabled (:disabled settings)]    [:div.cp__plugins-item-card     [:div.l.link-block      {:on-click #(plugin-handler/open-readme! url item simple-markdown-display)}      (if icon        [:img.icon {:src icon}]        svg/folder)]     [:div.r      [:h3.head.text-xl.font-bold.pt-1.5       {:on-click #(plugin-handler/open-readme! url item simple-markdown-display)}       [:span name]       [:sup.inline-block.px-1.text-xs.opacity-30 version]]      [:div.desc.text-xs.opacity-60       [:p description]       ;;[:small (js/JSON.stringify (bean/->js settings))]]      [:div.flag       [:p.text-xs.text-gray-300.pr-2.flex.justify-between.dark:opacity-40        [:small author]        [:small (str "ID: " id)]]]      [:div.ctl       [:div.l        [:div.de         [:strong svg/settings-sm]         [:ul.menu-list          [:li {:on-click #(if usf (js/apis.openPath usf))} "Open settings"]          [:li {:on-click #(js/apis.openPath url)} "Open plugin package"]          [:li {:on-click                #(let [confirm-fn                       (ui/make-confirm-modal                        {:title      (str "Are you sure uninstall plugin [" name "] ?")                         :on-confirm (fn [_ {:keys [close-fn]}]                                       (close-fn)                                       (plugin-handler/unregister-plugin id))})]                   (state/set-modal! confirm-fn))}           "Uninstall plugin"]]]]       [:div.flex.items-center        [:small.de (if disabled "Disabled" "Enabled")]        (ui/toggle (not disabled)                   (fn []                     (js-invoke js/LSPluginCore (if disabled "enable" "disable") id))                   true)]]]]))(rum/defc installed-page  < rum/reactive  []  (let [installed-plugins (state/sub :plugin/installed-plugins)        selected-unpacked-pkg (state/sub :plugin/selected-unpacked-pkg)]    [:div.cp__plugins-page-installed     [:h1 "Installed Plugins"]     [:div.mb-6.flex.items-center.justify-between      (ui/button       "Load unpacked plugin"       :intent "logseq"       :on-click plugin-handler/load-unpacked-plugin)      (unpacked-plugin-loader selected-unpacked-pkg)      (when (util/electron?)        (ui/button         [:span.flex.items-center           ;;svg/settings-sm          "Open plugin preferences file"]         :intent "logseq"         :on-click (fn []                     (p/let [root (plugin-handler/get-ls-dotdir-root)]                       (js/apis.openPath (str root "/preferences.json"))))))]     [:div.cp__plugins-item-lists.grid-cols-1.md:grid-cols-2.lg:grid-cols-3      (for [[_ item] installed-plugins]        (rum/with-key (plugin-item-card item) (:id item)))]]))(defn open-select-theme!  []  (state/set-modal! installed-themes))(rum/defc hook-ui-slot  ([type payload] (hook-ui-slot type payload nil))  ([type payload opts]   (let [id (str "slot__" (util/rand-str 8))]     (rum/use-effect!      (fn []        (plugin-handler/hook-plugin-app type {:slot id :payload payload} nil)        #())      [])     [:div.lsp-hook-ui-slot      (merge opts {:id id})])))
 |