From 6490901b64a8d574b55e1d1ea192bb636ce59eb6 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sat, 28 Aug 2021 20:10:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=92=E4=BB=B6=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E4=BB=8E=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=8B=89=E5=8F=96=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/cache/cache.ts | 16 ++++++++++++++ shared/index.tsx | 6 ++++- shared/model/plugin.ts | 8 +++++++ web/src/plugin/PluginStore/Item.tsx | 4 ++-- web/src/plugin/PluginStore/index.tsx | 33 ++++++++++++++++++++++++---- web/src/plugin/loader.ts | 13 +++-------- web/src/plugin/manager.ts | 15 +++++++++++-- 7 files changed, 76 insertions(+), 19 deletions(-) diff --git a/shared/cache/cache.ts b/shared/cache/cache.ts index 6913e68b..e0367514 100644 --- a/shared/cache/cache.ts +++ b/shared/cache/cache.ts @@ -1,5 +1,6 @@ import { ChatConverseInfo, fetchConverseInfo } from '../model/converse'; import { findGroupInviteByCode, GroupInvite } from '../model/group'; +import { fetchRegistryPlugins } from '../model/plugin'; import { fetchUserInfo, UserBaseInfo } from '../model/user'; import { queryClient } from './index'; @@ -46,3 +47,18 @@ export async function getCachedGroupInviteInfo( return data; } + +/** + * 获取缓存的插件列表 + */ +export async function getCachedRegistryPlugins() { + const data = await queryClient.fetchQuery( + ['pluginRegistry'], + () => fetchRegistryPlugins(), + { + staleTime: 2 * 60 * 60 * 1000, // 缓存2小时 + } + ); + + return data; +} diff --git a/shared/index.tsx b/shared/index.tsx index 10fe7594..8a21c679 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -5,7 +5,11 @@ export { createSocket } from './api/socket'; export type { AppSocket } from './api/socket'; // cache -export { getCachedUserInfo, getCachedGroupInviteInfo } from './cache/cache'; +export { + getCachedUserInfo, + getCachedGroupInviteInfo, + getCachedRegistryPlugins, +} from './cache/cache'; export { useCachedUserInfo } from './cache/useCache'; // components diff --git a/shared/model/plugin.ts b/shared/model/plugin.ts index e0599852..87118f10 100644 --- a/shared/model/plugin.ts +++ b/shared/model/plugin.ts @@ -1,3 +1,5 @@ +import { request } from '../api/request'; + export interface PluginManifest { /** * 插件用于显示的名称 @@ -46,3 +48,9 @@ export interface PluginManifest { */ requireRestart: boolean; } + +export async function fetchRegistryPlugins(): Promise { + const { data } = await request.get('/api/plugin/registry/list'); + + return data; +} diff --git a/web/src/plugin/PluginStore/Item.tsx b/web/src/plugin/PluginStore/Item.tsx index d5b25e9b..c5baee41 100644 --- a/web/src/plugin/PluginStore/Item.tsx +++ b/web/src/plugin/PluginStore/Item.tsx @@ -15,9 +15,9 @@ import { pluginManager } from '../manager'; export const PluginStoreItem: React.FC<{ manifest: PluginManifest; installed: boolean; - builtin: boolean; + builtin?: boolean; }> = React.memo((props) => { - const { manifest, builtin } = props; + const { manifest, builtin = false } = props; const [installed, setInstalled] = useState(props.installed); const [{ loading }, handleInstallPlugin] = useAsyncRequest(async () => { diff --git a/web/src/plugin/PluginStore/index.tsx b/web/src/plugin/PluginStore/index.tsx index d56ec930..554d83ce 100644 --- a/web/src/plugin/PluginStore/index.tsx +++ b/web/src/plugin/PluginStore/index.tsx @@ -11,14 +11,30 @@ import { builtinPlugins } from '../builtin'; import { pluginManager } from '../manager'; import { PluginStoreItem } from './Item'; -export const PluginStore: React.FC = React.memo(() => { - const { loading, value: installedPluginList = [] } = useAsync( +function usePluginStoreData() { + const { loading: loading1, value: installedPluginList = [] } = useAsync( async () => pluginManager.getInstalledPlugins(), [] ); + const { loading: loading2, value: allPlugins = [] } = useAsync( + async () => pluginManager.getRegistryPlugins(), + [] + ); + + const loading = loading1 || loading2; + + return { + loading, + installedPluginList, + allPlugins, + }; +} + +export const PluginStore: React.FC = React.memo(() => { + const { loading, installedPluginList, allPlugins } = usePluginStoreData(); if (loading) { - return ; + return ; } const installedPluginNameList = installedPluginList.map((p) => p.name); @@ -43,7 +59,16 @@ export const PluginStore: React.FC = React.memo(() => { {t('插件中心')} - {/* TODO: 插件中心 */} +
+ {allPlugins.map((plugin) => ( +
+ +
+ ))} +
diff --git a/web/src/plugin/loader.ts b/web/src/plugin/loader.ts index 07743a91..8706189b 100644 --- a/web/src/plugin/loader.ts +++ b/web/src/plugin/loader.ts @@ -1,5 +1,5 @@ -import { initMiniStar, regDependency, regSharedModule } from 'mini-star'; -import { builtinPlugins } from './builtin'; +import { regDependency, regSharedModule } from 'mini-star'; +import { pluginManager } from './manager'; /** * 初始化插件 @@ -8,14 +8,7 @@ export function initPlugins(): Promise { registerDependencies(); registerModules(); - const plugins = builtinPlugins.map(({ name, url }) => ({ - name, - url, - })); - - return initMiniStar({ - plugins, - }); + return pluginManager.initPlugins(); } function registerDependencies() { diff --git a/web/src/plugin/manager.ts b/web/src/plugin/manager.ts index 311325a5..0fb9b5e1 100644 --- a/web/src/plugin/manager.ts +++ b/web/src/plugin/manager.ts @@ -1,4 +1,8 @@ -import { getStorage, PluginManifest } from 'tailchat-shared'; +import { + getCachedRegistryPlugins, + getStorage, + PluginManifest, +} from 'tailchat-shared'; import { initMiniStar, loadSinglePlugin } from 'mini-star'; import _once from 'lodash/once'; import { builtinPlugins } from './builtin'; @@ -7,7 +11,7 @@ class PluginManager { /** * 存储插件列表的Key常量 */ - static STORE_KEY = '__installed_plugins'; + static STORE_KEY = '$TailchatInstalledPlugins'; /** * 初始化插件 @@ -40,6 +44,13 @@ class PluginManager { return plugins; } + /** + * 获取所有插件列表 + */ + async getRegistryPlugins(): Promise { + return await getCachedRegistryPlugins(); + } + /** * 安装插件 */