| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /**
- * ActionContext - json-render 组件交互事件处理
- *
- * 提供 emit 函数供组件触发交互事件
- */
- 'use client';
- import { createContext, useContext, useCallback } from 'react';
- /**
- * Action Context 类型
- */
- interface ActionContextValue {
- emit: (eventName: string, payload?: any) => void;
- }
- /**
- * ActionContext - 用于在组件树中传递 emit 函数
- */
- export const ActionContext = createContext<ActionContextValue | null>(null);
- /**
- * ActionProvider 处理 json-render 组件的交互事件
- * 组件通过 emit() 触发事件,ActionProvider 执行相应的处理函数
- */
- interface ActionProviderActions {
- sendMessage: (message: string) => void;
- }
- interface ActionProviderProps {
- children: React.ReactNode;
- actions: ActionProviderActions;
- }
- /**
- * ActionProvider 组件 - 包装 JsonRenderer,提供事件处理能力
- */
- export function ActionProvider({ children, actions }: ActionProviderProps) {
- /**
- * emit 函数 - 组件调用此函数触发事件
- * @param eventName - 事件名称
- * @param payload - 事件负载
- */
- const emit = useCallback((eventName: string, payload?: any) => {
- console.log('[ActionProvider] Event emitted:', eventName, payload);
- switch (eventName) {
- case 'sendMessage':
- // 发送消息到聊天
- const message = typeof payload === 'string' ? payload : payload?.message || '';
- if (message) {
- actions.sendMessage(message);
- }
- break;
- case 'selectNovel':
- // 选择小说 - 简洁消息,AI 通过系统提示词知道要调用 get_novel_detail
- if (payload?.id) {
- const novelTitle = payload.title || payload.id;
- actions.sendMessage(`查看小说:${novelTitle}`);
- } else if (payload?.title) {
- actions.sendMessage(`查看小说:${payload.title}`);
- }
- break;
- case 'copy':
- // 复制文本到剪贴板
- if (payload?.text) {
- navigator.clipboard.writeText(payload.text);
- }
- break;
- default:
- console.warn('[ActionProvider] Unknown event:', eventName);
- }
- }, [actions]);
- return (
- <ActionContext.Provider value={{ emit }}>
- {children}
- </ActionContext.Provider>
- );
- }
- /**
- * Hook - 在组件中获取 emit 函数
- * 如果不在 ActionProvider 内,返回 no-op emit
- */
- export function useActionEmit() {
- const context = useContext(ActionContext);
- if (!context) {
- console.warn('[useActionEmit] ActionContext not found, returning no-op emit');
- return { emit: () => {} };
- }
- return context;
- }
|