diff --git a/web/src/components/Panel/group/Wrapper.tsx b/web/src/components/Panel/group/Wrapper.tsx index f307488e..28536e1e 100644 --- a/web/src/components/Panel/group/Wrapper.tsx +++ b/web/src/components/Panel/group/Wrapper.tsx @@ -6,6 +6,11 @@ import { CommonPanelWrapper } from '../common/Wrapper'; import { usePanelWindow } from '@/hooks/usePanelWindow'; import { OpenedPanelTip } from '@/components/OpenedPanelTip'; import { IconBtn } from '@/components/IconBtn'; +import { + DMPluginPanelActionProps, + GroupPluginPanelActionProps, + pluginPanelActions, +} from '@/plugin/common'; /** * 群组面板通用包装器 @@ -41,6 +46,26 @@ export const GroupPanelWrapper: React.FC<GroupPanelWrapperProps> = React.memo( <CommonPanelWrapper header={panelInfo.name} actions={(setRightPanel) => [ + ...pluginPanelActions + .filter( + (action): action is GroupPluginPanelActionProps => + action.position === 'group' + ) + .map((action) => ( + <IconBtn + key={action.name} + title={action.label} + shape="square" + icon={action.icon} + iconClassName="text-2xl" + onClick={() => + action.onClick({ + groupId: props.groupId, + panelId: props.panelId, + }) + } + /> + )), <IconBtn key="open" title={t('在新窗口打开')} diff --git a/web/src/components/Panel/personal/ConversePanel.tsx b/web/src/components/Panel/personal/ConversePanel.tsx index 113a72b0..73fd1556 100644 --- a/web/src/components/Panel/personal/ConversePanel.tsx +++ b/web/src/components/Panel/personal/ConversePanel.tsx @@ -14,6 +14,7 @@ import { AppendDMConverseMembers } from '@/components/modals/AppendDMConverseMem import { usePanelWindow } from '@/hooks/usePanelWindow'; import { OpenedPanelTip } from '@/components/OpenedPanelTip'; import { IconBtn } from '@/components/IconBtn'; +import { DMPluginPanelActionProps, pluginPanelActions } from '@/plugin/common'; const ConversePanelTitle: React.FC<{ converse: ChatConverseState }> = React.memo(({ converse }) => { @@ -60,6 +61,21 @@ export const ConversePanel: React.FC<ConversePanelProps> = React.memo( } return _compact([ + ...pluginPanelActions + .filter( + (action): action is DMPluginPanelActionProps => + action.position === 'dm' + ) + .map((action) => ( + <IconBtn + key={action.name} + title={action.label} + shape="square" + icon={action.icon} + iconClassName="text-2xl" + onClick={() => action.onClick({ converseId })} + /> + )), <IconBtn key="open" title={t('在新窗口打开')} diff --git a/web/src/plugin/common/reg.ts b/web/src/plugin/common/reg.ts index 6078b84e..db8fe252 100644 --- a/web/src/plugin/common/reg.ts +++ b/web/src/plugin/common/reg.ts @@ -161,3 +161,36 @@ export const [pluginRootRoute, regPluginRootRoute] = buildRegList<{ 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 +>();