diff --git a/frontend/Requirements/pluginRequirement.ts b/frontend/Requirements/pluginRequirement.ts index c8ad372..3d5f365 100644 --- a/frontend/Requirements/pluginRequirement.ts +++ b/frontend/Requirements/pluginRequirement.ts @@ -8,8 +8,8 @@ */ import { SerializeType } from "./generalRequirement"; import { ExtensionProps } from "types/extensionRequirement"; -import { useExtention } from "hooks/extensionService"; import { ExtensionService } from "service/extensionService"; +import { useExtension } from "hooks/servicesProvider"; export interface PluginConfig { name: string; // 插件名称 @@ -46,25 +46,14 @@ export interface PluginConfiguration { }; } -export interface PluginDependencies { - plugins: string[]; // 依赖的插件列表(可选) - themes: string[]; // 依赖的主题列表(可选) -} /** * 插件属性接口 * * 该接口定义了插件的属性和行为。 */ -export class usePluginProps implements ExtensionProps { - private extensionService: ExtensionService = useExtention(); - private dependencies: PluginDependencies; +export class usePluginProps extends ExtensionProps { + +} - constructor(dependencies: PluginDependencies) { - this.dependencies = dependencies; - } - action?: ((...args: any[]) => void); // 动作函数(可选) - component?: (...args: any[]) => React.FC; // 组件函数(可选) - text?: (...args: any[]) => string; // 文本生成函数(可选) -} \ No newline at end of file diff --git a/frontend/app/root.tsx b/frontend/app/root.tsx index 8913fdb..62596fe 100644 --- a/frontend/app/root.tsx +++ b/frontend/app/root.tsx @@ -1,8 +1,8 @@ import { Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react"; import type { LoaderFunction } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -import { ThemeProvider } from "hooks/themeContext"; import { createContext, useContext, ReactNode } from 'react'; +import { ServiceProvider } from "hooks/servicesProvider"; import "./tailwind.css"; export function Layout({ children }: { children: React.ReactNode }) { @@ -17,9 +17,9 @@ export function Layout({ children }: { children: React.ReactNode }) { - + {children} - + diff --git a/frontend/hooks/createServiceContext.tsx b/frontend/hooks/createServiceContext.tsx index 0948c5c..bf5934a 100644 --- a/frontend/hooks/createServiceContext.tsx +++ b/frontend/hooks/createServiceContext.tsx @@ -1,55 +1,50 @@ // File path: /hooks/createServiceContext.tsx -import { createContext, ReactNode, useContext } from "react"; +import { createContext, useContext, ReactNode, FC } from 'react'; /** - * 创建一个服务上下文,用于提供和使用服务实例。 - * - * @param name - 服务的名称,用于错误提示。 - * @param getInstance - 一个函数,用于获取服务实例。 - * @returns 返回一个包含 Provider 组件和 useService 钩子的对象。 + * 创建服务上下文的返回类型 */ -interface ServiceContextResult { - Provider: React.FC<{ children: ReactNode }>; // 提供服务实例的组件 - useService: () => T; // 获取服务实例的钩子 -} +type ServiceContextReturn = { + [K in `${N}Provider`]: FC<{ children: ReactNode }>; +} & { + [K in `use${N}`]: () => T; +}; /** - * 创建服务上下文的函数。 + * 创建服务上下文和相关钩子的工厂函数 * - * @param name - 服务的名称,用于错误提示。 - * @param getInstance - 获取服务实例的函数。 - * @returns 包含 Provider 组件和 useService 钩子的对象。 + * @param serviceName - 服务名称,用于错误信息 + * @param ServiceClass - 服务类(包含静态 getInstance 方法) */ -export function createServiceContext( - name: string, - getInstance: () => T -): ServiceContextResult { - // 创建一个上下文,初始值为 undefined。 +export function createServiceContext( + serviceName: N, + getServiceInstance: () => T +): ServiceContextReturn { const ServiceContext = createContext(undefined); - // Provider 组件,用于提供服务实例给子组件 - const Provider = ({ children }: { children: ReactNode }) => { - const service = getInstance(); + /** + * 服务提供者组件 + */ + const Provider: FC<{ children: ReactNode }> = ({ children }) => ( + + {children} + + ); - return ( - - {children} - - ); - }; - - // 获取服务实例的钩子 + /** + * 自定义钩子,用于获取服务实例 + */ const useService = (): T => { const context = useContext(ServiceContext); if (context === undefined) { - throw new Error(`use${name} must be used within a ${name}Provider`); + throw new Error(`use${serviceName} must be used within a ${serviceName}Provider`); } return context; }; return { - Provider, - useService, - }; -} + [`${serviceName}Provider`]: Provider, + [`use${serviceName}`]: useService, + } as ServiceContextReturn; +} \ No newline at end of file diff --git a/frontend/hooks/extensionService.tsx b/frontend/hooks/extensionService.tsx deleted file mode 100644 index c6a09f8..0000000 --- a/frontend/hooks/extensionService.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// File path: /d:/data/echoes/frontend/hooks/extensionService.tsx -/** - * 扩展服务上下文提供者和自定义 Hook。 - * - * 该文件包含扩展服务的上下文提供者组件和用于访问该上下文的自定义 Hook。 - */ - -import { createContext, useContext, ReactNode } from 'react'; -import { ExtensionService } from 'service/extensionService'; - -// 创建扩展服务上下文 -const ExtensionContext = createContext(undefined); - -/** - * 扩展提供者组件,用于提供扩展服务的上下文。 - * - * @param children - 要渲染的子组件。 - */ -export function ExtensionProvider({ children }: { children: ReactNode }) { - const extensionService = ExtensionService.getInstance(); // 获取扩展服务实例 - - return ( - - {children} - - ) -} - -/** - * 自定义 Hook,用于访问扩展服务上下文。 - * - * @returns {ExtensionService} - 返回扩展服务实例。 - * @throws {Error} - 如果在未被 ExtensionProvider 包裹的组件中调用,将抛出错误。 - */ -export function useExtention(): ExtensionService { - const context = useContext(ExtensionContext); // 获取扩展服务上下文 - if (context === undefined) { - throw new Error('useTheme must be used within a ThemeProvider'); // 抛出错误 - } - return context; // 返回扩展服务实例 -} \ No newline at end of file diff --git a/frontend/hooks/servicesProvider.tsx b/frontend/hooks/servicesProvider.tsx new file mode 100644 index 0000000..9c1feb8 --- /dev/null +++ b/frontend/hooks/servicesProvider.tsx @@ -0,0 +1,22 @@ +import { ExtensionService } from 'service/extensionService'; +import { ThemeService } from 'service/themeService'; +import { createServiceContext } from './createServiceContext'; +import { ReactNode } from 'react'; + +export const { + ExtensionProvider, + useExtension +} = createServiceContext('Extension', () => ExtensionService.getInstance()); + +export const { + ThemeProvider, + useTheme +} = createServiceContext("Theme", () => ThemeService.getInstance()); + +export const ServiceProvider = ({ children }: { children: ReactNode })=>( + + + {children} + + +); \ No newline at end of file diff --git a/frontend/hooks/themeContext.tsx b/frontend/hooks/themeContext.tsx deleted file mode 100644 index c045f9d..0000000 --- a/frontend/hooks/themeContext.tsx +++ /dev/null @@ -1,36 +0,0 @@ -// File path: /hooks/themeContext.tsx - -import { createContext, useContext, ReactNode } from 'react'; -import { ThemeService } from 'service/themeService'; - -const ThemeContext = createContext(undefined); - -/** - * ThemeProvider 组件用于提供主题上下文给其子组件。 - * 它使用 ThemeService 的单例实例来管理主题相关的状态和功能。 - * - * @param children - 要渲染的子组件。 - */ -export function ThemeProvider({ children }: { children: ReactNode }) { - const themeService = ThemeService.getInstance(); - - return ( - - {children} - - ); -} - -/** - * useTheme 钩子用于访问主题上下文。 - * - * @returns ThemeService - 返回主题服务的实例。 - * @throws Error - 如果在 ThemeProvider 之外使用,将抛出错误。 - */ -export function useTheme(): ThemeService { - const context = useContext(ThemeContext); - if (context === undefined) { - throw new Error('useTheme must be used within a ThemeProvider'); - } - return context; -} \ No newline at end of file diff --git a/frontend/service/extensionService.ts b/frontend/service/extensionService.ts index ff49444..fd4f3f7 100644 --- a/frontend/service/extensionService.ts +++ b/frontend/service/extensionService.ts @@ -88,7 +88,7 @@ export class ExtensionService { } //获取指定配置文件 - getConfiguration(pluginName: string): PluginConfiguration | undefined { + private getConfiguration(pluginName: string): PluginConfiguration | undefined { return this.configuration.get(pluginName); } }