mirror of https://github.com/msgbyte/tailchat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
6.9 KiB
TypeScript
317 lines
6.9 KiB
TypeScript
import type { ChatInputActionContextProps } from '@/components/ChatBox/ChatInputBox/context';
|
|
import {
|
|
buildRegFn,
|
|
buildRegList,
|
|
ChatMessage,
|
|
GroupPanel,
|
|
regSocketEventListener,
|
|
PermissionItemType,
|
|
GroupPanelFeature,
|
|
InboxItem,
|
|
buildRegMap,
|
|
BasicInboxItem,
|
|
} from 'tailchat-shared';
|
|
import type { MetaFormFieldMeta } from 'tailchat-design';
|
|
import type { FullModalFactoryConfig } from '@/components/FullModal/Factory';
|
|
import type { ReactElement } from 'react';
|
|
|
|
/**
|
|
* 注册自定义面板
|
|
*/
|
|
export interface PluginCustomPanel {
|
|
/**
|
|
* 面板位置:
|
|
*
|
|
* - personal: 个人面板中的一项
|
|
* - setting: 设置面板
|
|
* - groupdetail: 群组详情
|
|
* - navbar*: 导航栏
|
|
*/
|
|
position:
|
|
| 'personal'
|
|
| 'setting'
|
|
| 'groupdetail'
|
|
| 'navbar-more'
|
|
| 'navbar-group'
|
|
| 'navbar-personal';
|
|
|
|
/**
|
|
* Iconify 名
|
|
*/
|
|
icon: string;
|
|
|
|
/**
|
|
* 自定义面板唯一标识名
|
|
*/
|
|
name: string;
|
|
|
|
/**
|
|
* 自定义面板显示名
|
|
*/
|
|
label: string;
|
|
|
|
/**
|
|
* 渲染组件
|
|
*/
|
|
render: React.ComponentType;
|
|
}
|
|
export const [pluginCustomPanel, regCustomPanel] =
|
|
buildRegList<PluginCustomPanel>();
|
|
|
|
export interface PluginPanelMenu {
|
|
name: string;
|
|
label: string;
|
|
icon?: string;
|
|
onClick: (panelInfo: GroupPanel) => void;
|
|
}
|
|
|
|
/**
|
|
* 注册群组面板
|
|
*/
|
|
export interface PluginGroupPanel {
|
|
/**
|
|
* 面板唯一标识
|
|
* @example com.msgbyte.webview/grouppanel
|
|
*/
|
|
name: string;
|
|
|
|
/**
|
|
* 面板显示名
|
|
*/
|
|
label: string;
|
|
|
|
/**
|
|
* 插件提供者, 用于引导没有安装插件的用户安装插件
|
|
*/
|
|
provider: string;
|
|
|
|
/**
|
|
* 额外的表单数据, 用于创建面板时使用
|
|
*/
|
|
extraFormMeta: MetaFormFieldMeta[];
|
|
|
|
/**
|
|
* 该面板如何渲染
|
|
*/
|
|
render: React.ComponentType<{ panelInfo: GroupPanel }>;
|
|
|
|
/**
|
|
* 面板项右键菜单
|
|
*/
|
|
menus?: PluginPanelMenu[];
|
|
|
|
/**
|
|
* 面板功能特性
|
|
*/
|
|
feature?: GroupPanelFeature[];
|
|
}
|
|
export const [pluginGroupPanel, regGroupPanel] =
|
|
buildRegList<PluginGroupPanel>();
|
|
|
|
export interface PluginMessageInterpreter {
|
|
name?: string;
|
|
explainMessage: (message: string) => React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* 消息解释器
|
|
* 即用于解释消息内容, 并把结果渲染到消息下面
|
|
*/
|
|
export const [messageInterpreter, regMessageInterpreter] =
|
|
buildRegList<PluginMessageInterpreter>();
|
|
|
|
/**
|
|
* 消息渲染器
|
|
* 输入消息,返回渲染节点
|
|
*/
|
|
export const [getMessageRender, regMessageRender] = buildRegFn<
|
|
(message: string) => React.ReactNode
|
|
>('message-render', (message) => message);
|
|
|
|
/**
|
|
* 消息渲染器
|
|
* 输入消息,返回渲染节点
|
|
*/
|
|
const defaultMessageTextDecorators = {
|
|
url: (url: string, label?: string) => url,
|
|
image: (plain: string, attrs: Record<string, unknown>) => plain,
|
|
card: (plain: string, payload: Record<string, unknown>) => plain,
|
|
mention: (userId: string, userName: string) => `@${userName}`,
|
|
emoji: (emojiCode: string) => emojiCode,
|
|
serialize: (plain: string) => plain,
|
|
};
|
|
const [_getMessageTextDecorators, regMessageTextDecorators] = buildRegFn<
|
|
() => Partial<typeof defaultMessageTextDecorators>
|
|
>('message-text-decorators', () => defaultMessageTextDecorators);
|
|
function getMessageTextDecorators() {
|
|
return {
|
|
...defaultMessageTextDecorators,
|
|
..._getMessageTextDecorators(),
|
|
};
|
|
}
|
|
export { getMessageTextDecorators, regMessageTextDecorators };
|
|
|
|
interface ChatInputAction {
|
|
label: string;
|
|
onClick: (actions: ChatInputActionContextProps) => void;
|
|
}
|
|
export type { ChatInputActionContextProps };
|
|
export const [pluginChatInputActions, regChatInputAction] =
|
|
buildRegList<ChatInputAction>();
|
|
|
|
interface ChatInputButton {
|
|
render: () => React.ReactElement;
|
|
}
|
|
export const [pluginChatInputButtons, regChatInputButton] =
|
|
buildRegList<ChatInputButton>();
|
|
|
|
export { regSocketEventListener };
|
|
|
|
/**
|
|
* 注册配色方案
|
|
*/
|
|
export const [pluginColorScheme, regPluginColorScheme] = buildRegList<{
|
|
label: string;
|
|
name: string;
|
|
}>();
|
|
|
|
/**
|
|
* 注册检查服务方案
|
|
*/
|
|
export const [pluginInspectServices, regInspectService] = buildRegList<{
|
|
label: string;
|
|
name: string;
|
|
}>();
|
|
|
|
/**
|
|
* 注册对消息的额外解释函数
|
|
*/
|
|
export const [pluginMessageExtraParsers, regMessageExtraParser] = buildRegList<{
|
|
name: string;
|
|
render: (payload: ChatMessage) => React.ReactNode;
|
|
}>();
|
|
|
|
/**
|
|
* 注册根路由
|
|
*/
|
|
export const [pluginRootRoute, regPluginRootRoute] = buildRegList<{
|
|
name: string;
|
|
path: string;
|
|
component: React.ComponentType;
|
|
}>();
|
|
|
|
export interface BasePluginPanelActionProps {
|
|
/**
|
|
* 唯一标识
|
|
*/
|
|
name: string;
|
|
/**
|
|
* 显示名
|
|
*/
|
|
label: string;
|
|
/**
|
|
* 来自iconify的图标标识
|
|
*/
|
|
icon: string;
|
|
}
|
|
|
|
export interface GroupPluginPanelActionProps
|
|
extends BasePluginPanelActionProps {
|
|
position: 'group';
|
|
onClick: (ctx: { groupId: string; panelId: string }) => void;
|
|
}
|
|
|
|
export interface DMPluginPanelActionProps extends BasePluginPanelActionProps {
|
|
position: 'dm';
|
|
onClick: (ctx: { converseId: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* 注册 面板操作 到面板右上角
|
|
*/
|
|
export const [pluginPanelActions, regPluginPanelAction] = buildRegList<
|
|
GroupPluginPanelActionProps | DMPluginPanelActionProps
|
|
>();
|
|
|
|
/**
|
|
* 注册插件权限
|
|
*/
|
|
export const [pluginPermission, regPluginPermission] =
|
|
buildRegList<PermissionItemType>();
|
|
|
|
/**
|
|
* 注册自定义群组面板badge
|
|
*/
|
|
export const [pluginGroupPanelBadges, regGroupPanelBadge] = buildRegList<{
|
|
name: string;
|
|
render: (groupId: string, panelId: string) => React.ReactNode;
|
|
}>();
|
|
|
|
/**
|
|
* 注册自定义群组文本面板项额外操作菜单
|
|
*/
|
|
export const [
|
|
pluginGroupTextPanelExtraMenus,
|
|
regPluginGroupTextPanelExtraMenu,
|
|
] = buildRegList<PluginPanelMenu>();
|
|
|
|
interface PluginUserExtraInfo {
|
|
name: string;
|
|
label: string;
|
|
/**
|
|
* 自定义渲染函数
|
|
* 可选
|
|
*/
|
|
component?: {
|
|
render?: React.ComponentType<{
|
|
value: unknown;
|
|
}>;
|
|
editor?: React.ComponentType<{
|
|
value: unknown;
|
|
onSave: (val: unknown) => void;
|
|
}>;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 注册用户自定义信息(比如社交账号,地理位置,手机号这些非必须的信息)
|
|
*/
|
|
export const [pluginUserExtraInfo, regUserExtraInfo] =
|
|
buildRegList<PluginUserExtraInfo>();
|
|
|
|
type PluginSettings = FullModalFactoryConfig & {
|
|
position: 'system'; // 后面可能还会有个人设置/群组设置
|
|
};
|
|
|
|
/**
|
|
* 注册插件设置项
|
|
*/
|
|
export const [pluginSettings, regPluginSettings] =
|
|
buildRegList<PluginSettings>();
|
|
|
|
interface PluginInboxItem {
|
|
/**
|
|
* 来源
|
|
*/
|
|
source: string;
|
|
getPreview: (inboxItem: BasicInboxItem) => { title: string; desc: string };
|
|
render: React.ComponentType<{ inboxItem: BasicInboxItem }>;
|
|
}
|
|
|
|
/**
|
|
* 注册收件箱内容
|
|
*/
|
|
export const [pluginInboxItemMap, regPluginInboxItemMap] =
|
|
buildRegMap<PluginInboxItem>();
|
|
|
|
export const [pluginGroupConfigItems, regPluginGroupConfigItem] = buildRegList<{
|
|
name: string;
|
|
title: string;
|
|
tip?: string;
|
|
component: (props: {
|
|
value: any;
|
|
onChange: (val: unknown) => void;
|
|
loading: boolean;
|
|
}) => ReactElement;
|
|
}>();
|