mirror of https://github.com/logseq/logseq
Enhance/plugins (#8202)
* improve(plugins): install hooks with user options * improve(plugin): remove todos * improve(plugin): hook for a specific plugin * e2e tests * improve(ui): global search bar for the results from the custom search servicepull/8197/head
parent
1eb94092f0
commit
675811ccde
|
@ -0,0 +1,72 @@
|
|||
import { expect } from '@playwright/test'
|
||||
import { test } from './fixtures'
|
||||
|
||||
test('enabled plugin system default', async ({ page }) => {
|
||||
const callAPI = callPageAPI.bind(null, page)
|
||||
|
||||
const pluginEnabled = await callAPI('get_state_from_store', 'plugin/enabled')
|
||||
await expect(pluginEnabled).toBe(true)
|
||||
|
||||
expect(await page.evaluate(`typeof logseq.api.get_current_graph`))
|
||||
.toBe('function')
|
||||
|
||||
const currentGraph = await callAPI('get_current_graph')
|
||||
expect(Object.keys(currentGraph)).toEqual(['url', 'name', 'path'])
|
||||
})
|
||||
|
||||
test('play a plugin<logseq-journals-calendar> from the Marketplace', async ({ page }) => {
|
||||
await page.keyboard.press('t+p')
|
||||
const searchInput = page.locator('.search-ctls .form-input')
|
||||
await searchInput.type('journals')
|
||||
|
||||
const pluginCards = page.locator('.cp__plugins-item-card')
|
||||
|
||||
if (await pluginCards.count()) {
|
||||
await pluginCards.locator('.ctl .ls-icon-settings').hover()
|
||||
await page.locator('text=Uninstall').click()
|
||||
|
||||
const confirmYes = page.locator('button').locator('text=Yes')
|
||||
await confirmYes.click()
|
||||
}
|
||||
|
||||
// install a plugin from Marketplace
|
||||
await page.locator('button').locator('text=Marketplace').click()
|
||||
await page.locator('text=Journals calendar')
|
||||
|
||||
await page.locator('.cp__plugins-item-card').first().locator('text=Install').click()
|
||||
// wait for the plugin installed
|
||||
await page.locator('.cp__plugins-item-card').first().locator('text=Installed')
|
||||
await page.locator('a.ui__modal-close').click()
|
||||
|
||||
// toolbar plugins manager
|
||||
const pluginFlag = page.locator('.toolbar-plugins-manager-trigger')
|
||||
|
||||
await expect(pluginFlag).toBeVisible()
|
||||
|
||||
await pluginFlag.click()
|
||||
|
||||
await expect(pluginFlag.locator('text=Plugins')).toBeVisible()
|
||||
await expect(pluginFlag.locator('text=Settings')).toBeVisible()
|
||||
|
||||
await page.locator('text=goto-today').click()
|
||||
await page.locator('body').click()
|
||||
|
||||
const goToToday = page.locator('#logseq-journals-calendar--goto-today').locator('a.button')
|
||||
await expect(goToToday).toBeVisible()
|
||||
await goToToday.click()
|
||||
|
||||
// TODO: debug
|
||||
await expect(page.locator('body[data-page="page"]')).toBeVisible()
|
||||
})
|
||||
|
||||
/**
|
||||
* @param page
|
||||
* @param method
|
||||
* @param args
|
||||
*/
|
||||
async function callPageAPI(page, method, ...args) {
|
||||
return await page.evaluate(([method, args]) => {
|
||||
// @ts-ignore
|
||||
return window.logseq.api[method]?.(...args)
|
||||
}, [method, args])
|
||||
}
|
|
@ -308,7 +308,6 @@ class LSPluginCaller extends EventEmitter {
|
|||
|
||||
this._callUserModel = async (type, ...payloads: any[]) => {
|
||||
if (type.startsWith(FLAG_AWAIT)) {
|
||||
// TODO: attach arguments with method call
|
||||
return await refChild.get(
|
||||
type.replace(FLAG_AWAIT, ''),
|
||||
...payloads
|
||||
|
|
|
@ -1398,8 +1398,15 @@ class LSPluginCore
|
|||
})
|
||||
}
|
||||
|
||||
const p = pid && this._registeredPlugins.get(pid)
|
||||
|
||||
if (p && !p.disabled && p.options.entry) {
|
||||
act(p)
|
||||
return
|
||||
}
|
||||
|
||||
for (const [_, p] of this._registeredPlugins) {
|
||||
if (p.options.theme || p.disabled) {
|
||||
if (!p.options.entry || p.disabled) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ export interface IAppProxy {
|
|||
onSidebarVisibleChanged: IUserHook<{ visible: boolean }>
|
||||
|
||||
// internal
|
||||
_installPluginHook: (pid: string, hook: string) => void
|
||||
_installPluginHook: (pid: string, hook: string, opts?: any) => void
|
||||
_uninstallPluginHook: (pid: string, hookOrAll: string | boolean) => void
|
||||
}
|
||||
|
||||
|
|
|
@ -737,6 +737,7 @@ export class LSPluginUser
|
|||
|
||||
const type = `hook:${tag}:${safeSnakeCase(e)}`
|
||||
const handler = args[0]
|
||||
const opts = args[1]
|
||||
caller[f](type, handler)
|
||||
|
||||
const unlisten = () => {
|
||||
|
@ -747,7 +748,7 @@ export class LSPluginUser
|
|||
}
|
||||
|
||||
if (!isOff) {
|
||||
that.App._installPluginHook(pid, type)
|
||||
that.App._installPluginHook(pid, type, opts)
|
||||
} else {
|
||||
unlisten()
|
||||
return
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -636,7 +636,8 @@
|
|||
(reload-fn false)
|
||||
(assoc s ::reload (partial reload-fn true))))}
|
||||
[state]
|
||||
(let [pkgs (state/sub :plugin/marketplace-pkgs)
|
||||
(let [*list-node-ref (rum/create-ref)
|
||||
pkgs (state/sub :plugin/marketplace-pkgs)
|
||||
stats (state/sub :plugin/marketplace-stats)
|
||||
installed-plugins (state/sub :plugin/installed-plugins)
|
||||
installing (state/sub :plugin/installing)
|
||||
|
@ -688,7 +689,7 @@
|
|||
fn-query-flag (fn [] (string/join "_" (map #(str @%) [*filter-by *sort-by *search-key *category])))
|
||||
str-query-flag (fn-query-flag)
|
||||
_ (when (not= str-query-flag @*cached-query-flag)
|
||||
(when-let [^js list-cnt (rum/ref-node state "list-ref")]
|
||||
(when-let [^js list-cnt (rum/deref *list-node-ref)]
|
||||
(set! (.-scrollTop list-cnt) 0))
|
||||
(reset! *current-page 1))
|
||||
_ (reset! *cached-query-flag str-query-flag)
|
||||
|
@ -723,7 +724,7 @@
|
|||
[:div.cp__plugins-marketplace-cnt
|
||||
{:class (util/classnames [{:has-installing (boolean installing)}])}
|
||||
[:div.cp__plugins-item-lists
|
||||
{:ref "list-ref"}
|
||||
{:ref *list-node-ref}
|
||||
[:div.cp__plugins-item-lists-inner
|
||||
;; items list
|
||||
(for [item sorted-plugins]
|
||||
|
@ -750,7 +751,8 @@
|
|||
(rum/local nil ::cached-query-flag)
|
||||
(rum/local 1 ::current-page)
|
||||
[state]
|
||||
(let [installed-plugins (state/sub [:plugin/installed-plugins])
|
||||
(let [*list-node-ref (rum/create-ref)
|
||||
installed-plugins (state/sub [:plugin/installed-plugins])
|
||||
installed-plugins (vals installed-plugins)
|
||||
updating (state/sub :plugin/installing)
|
||||
develop-mode? (state/sub :ui/developer-mode?)
|
||||
|
@ -799,7 +801,7 @@
|
|||
fn-query-flag (fn [] (string/join "_" (map #(str @%) [*filter-by *sort-by *search-key *category])))
|
||||
str-query-flag (fn-query-flag)
|
||||
_ (when (not= str-query-flag @*cached-query-flag)
|
||||
(when-let [^js list-cnt (rum/ref-node state "list-ref")]
|
||||
(when-let [^js list-cnt (rum/deref *list-node-ref)]
|
||||
(set! (.-scrollTop list-cnt) 0))
|
||||
(reset! *current-page 1))
|
||||
_ (reset! *cached-query-flag str-query-flag)
|
||||
|
@ -822,7 +824,7 @@
|
|||
agent-opts)
|
||||
|
||||
[:div.cp__plugins-item-lists.pb-6
|
||||
{:ref "list-ref"}
|
||||
{:ref *list-node-ref}
|
||||
[:div.cp__plugins-item-lists-inner
|
||||
(for [item sorted-plugins]
|
||||
(rum/with-key
|
||||
|
@ -928,7 +930,6 @@
|
|||
;; all done
|
||||
[:div.py-4 [:strong.text-xl (str "\uD83C\uDF89 " (t :plugin.install-from-file/success))]])])
|
||||
|
||||
|
||||
(defn open-select-theme!
|
||||
[]
|
||||
(state/set-sub-modal! installed-themes))
|
||||
|
|
|
@ -370,7 +370,7 @@
|
|||
[{:type :graph-add-filter}]
|
||||
result)
|
||||
repo (state/get-current-repo)]
|
||||
[:div
|
||||
[:div.results-inner
|
||||
(ui/auto-complete
|
||||
result
|
||||
{:class "search-results"
|
||||
|
@ -554,7 +554,7 @@
|
|||
[:span.pr-2 (ui/icon "puzzle")]
|
||||
(:name v)
|
||||
(when-let [result (and v (:result v))]
|
||||
(str " (" (count (:blocks result)) ")"))]
|
||||
(str " (" (apply + (map count ((juxt :blocks :pages :files) result))) ")"))]
|
||||
:on-click #(reset! *active-engine-tab k))])])
|
||||
|
||||
(if-not (nil? @*active-engine-tab)
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
@apply flex flex-col overflow-auto;
|
||||
|
||||
> .search-results-wrap {
|
||||
@apply flex-1 overflow-auto h-full;
|
||||
@apply flex flex-col flex-1 overflow-hidden h-full;
|
||||
|
||||
> .results-inner {
|
||||
@apply h-full overflow-y-auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +34,7 @@
|
|||
|
||||
.search-results-engines {
|
||||
&-tabs {
|
||||
@apply flex list-none -mx-2 mb-2;
|
||||
@apply flex list-none -mx-2 mb-2 px-2;
|
||||
|
||||
background: var(--ls-primary-background-color);
|
||||
|
||||
|
@ -43,6 +47,7 @@
|
|||
background: transparent;
|
||||
border-radius: 0;
|
||||
line-height: 1;
|
||||
color: var(--ls-primary-text-color);
|
||||
}
|
||||
|
||||
&.is-active .ui__button {
|
||||
|
|
|
@ -1542,21 +1542,22 @@ Similar to re-frame subscriptions"
|
|||
(update-vals engines #(assoc % :result nil)))))
|
||||
|
||||
(defn install-plugin-hook
|
||||
[pid hook]
|
||||
([pid hook] (install-plugin-hook pid hook true))
|
||||
([pid hook opts]
|
||||
(when-let [pid (keyword pid)]
|
||||
(set-state!
|
||||
[:plugin/installed-hooks hook]
|
||||
(conj
|
||||
((fnil identity #{}) (get-in @state [:plugin/installed-hooks hook]))
|
||||
pid)) true))
|
||||
(assoc
|
||||
((fnil identity {}) (get-in @state [:plugin/installed-hooks hook]))
|
||||
pid opts)) true)))
|
||||
|
||||
(defn uninstall-plugin-hook
|
||||
[pid hook-or-all]
|
||||
(when-let [pid (keyword pid)]
|
||||
(if (nil? hook-or-all)
|
||||
(swap! state update :plugin/installed-hooks #(update-vals % (fn [ids] (disj ids pid))))
|
||||
(swap! state update :plugin/installed-hooks #(update-vals % (fn [ids] (dissoc ids pid))))
|
||||
(when-let [coll (get-in @state [:plugin/installed-hooks hook-or-all])]
|
||||
(set-state! [:plugin/installed-hooks hook-or-all] (disj coll pid))))
|
||||
(set-state! [:plugin/installed-hooks hook-or-all] (dissoc coll pid))))
|
||||
true))
|
||||
|
||||
(defn slot-hook-exist?
|
||||
|
|
|
@ -80,8 +80,8 @@
|
|||
(js/console.error "[parse hiccup error]" e) input))))
|
||||
|
||||
(defn ^:export install-plugin-hook
|
||||
[pid hook]
|
||||
(state/install-plugin-hook pid hook))
|
||||
[pid hook ^js opts]
|
||||
(state/install-plugin-hook pid hook (bean/->clj opts)))
|
||||
|
||||
(defn ^:export uninstall-plugin-hook
|
||||
[pid hook-or-all]
|
||||
|
|
Loading…
Reference in New Issue