From f03943f83467d66c8600865c4240ca36637b3ba0 Mon Sep 17 00:00:00 2001 From: ONLY-yours <1349021570@qq.com> Date: Mon, 9 Sep 2024 17:05:51 +0800 Subject: [PATCH] :sparkles: feat: add chat item actions render --- package.json | 2 +- src/ActionIconGroup/index.tsx | 4 +-- src/ChatItem/index.tsx | 4 ++- src/ChatItem/type.ts | 16 +++++++-- src/ChatList/ChatListItem.tsx | 28 ++++++++++------ src/ChatList/index.tsx | 2 ++ src/ProChat/demos/actions-chat-item.tsx | 43 +++++++++++++++++++++++++ src/ProChat/index.en-US.md | 8 +++++ src/ProChat/index.md | 8 +++++ 9 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 src/ProChat/demos/actions-chat-item.tsx diff --git a/package.json b/package.json index 7fbc4dcf..a52f32be 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "commitlint-config-gitmoji": "^2.3.1", "conventional-changelog-gitmoji-config": "^1.5.2", "cross-env": "^7.0.3", - "dumi": "2.2.16", + "dumi": "^2.2.16", "dumi-theme-antd-style": "latest", "eslint": "^8.57.0", "father": "4.3.1", diff --git a/src/ActionIconGroup/index.tsx b/src/ActionIconGroup/index.tsx index f43be8af..328f08e3 100644 --- a/src/ActionIconGroup/index.tsx +++ b/src/ActionIconGroup/index.tsx @@ -16,9 +16,9 @@ export interface ActionIconGroupItems { } export interface ActionEvent { - item: ActionIconGroupItems; + item?: ActionIconGroupItems; key: string; - keyPath: string[]; + keyPath?: string[]; } export interface ActionIconGroupProps extends Omit { diff --git a/src/ChatItem/index.tsx b/src/ChatItem/index.tsx index f52e87f3..4508c810 100644 --- a/src/ChatItem/index.tsx +++ b/src/ChatItem/index.tsx @@ -19,6 +19,7 @@ const ChatItem = memo((props) => { avatarAddon, onAvatarClick, actions, + actionsClick, className, primary, loading, @@ -121,7 +122,8 @@ const ChatItem = memo((props) => { className={`${cx(styles.actions, `${prefixClass}-list-item-actions`)}`} /> ); - return chatItemRenderConfig?.actionsRender?.(props, dom) || dom; + + return chatItemRenderConfig?.actionsRender?.(props, dom, actionsClick) || dom; }, [actions]); const titleDom = useMemo(() => { diff --git a/src/ChatItem/type.ts b/src/ChatItem/type.ts index 865c37cc..f31d84df 100644 --- a/src/ChatItem/type.ts +++ b/src/ChatItem/type.ts @@ -1,5 +1,6 @@ import { ReactNode } from 'react'; +import { ActionEvent } from '@/ActionIconGroup'; import { ActionsProps } from '@/ChatList/ActionsBar'; import { EditableMessageProps } from '@/EditableMessage'; import { ChatMessageError, DivProps, MetaData } from '@/types'; @@ -7,11 +8,20 @@ import { MarkdownProps } from '@ant-design/pro-editor'; export type WithFalse = T | false; +export type actionsClickProps = { + onStartEdit: () => void; + onFinishEdit: () => void; + onClick: (actionKey: ActionEvent) => void; +}; export interface ChatItemProps> { /** * @description Actions to be displayed in the chat item */ - actions?: ReactNode; + actions: ReactNode; + /** + * @description Actions click props,only use in render + */ + actionsClick: actionsClickProps; /** * @description Metadata for the avatar */ @@ -88,7 +98,9 @@ export interface ChatItemProps> { chatItemRenderConfig?: { titleRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>; contentRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>; - actionsRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>; + actionsRender?: WithFalse< + (props: ChatItemProps, defaultDom: ReactNode, actionsClick: actionsClickProps) => ReactNode + >; avatarRender?: WithFalse<(props: ChatItemProps, defaultDom: ReactNode) => ReactNode>; render?: WithFalse< ( diff --git a/src/ChatList/ChatListItem.tsx b/src/ChatList/ChatListItem.tsx index 00877bfd..fc6a8125 100644 --- a/src/ChatList/ChatListItem.tsx +++ b/src/ChatList/ChatListItem.tsx @@ -192,7 +192,7 @@ const ChatListItem = (props: ChatListItemProps) => { /** * 渲染操作按钮的函数。 * @param data 聊天消息的数据。 - * @returns 渲染操作按钮的组件。 + * @returns 渲染操作按钮的配置项。 */ const Actions = useRefFunction(({ data }: { data: ChatMessage }) => { if (!renderActions || !item?.role) return; @@ -216,14 +216,21 @@ const ChatListItem = (props: ChatListItemProps) => { onActionsClick?.(action, data); }; - return ( - handleActionClick?.(actionKey, data)} - text={text} - actionsProps={chatItemRenderConfig?.actionsProps?.[item.role]} - /> - ); + return { + click: { + onStartEdit: () => setEditing(true), + onFinishEdit: () => setEditing(false), + onClick: (actionKey) => handleActionClick?.(actionKey, data), + }, + components: ( + handleActionClick?.(actionKey, data)} + text={text} + actionsProps={chatItemRenderConfig?.actionsProps?.[item.role]} + /> + ), + }; }); /** @@ -243,7 +250,8 @@ const ChatListItem = (props: ChatListItemProps) => { } + actions={Actions({ data: item }).components} + actionsClick={Actions({ data: item }).click} avatar={(item as any).meta} avatarAddon={groupNav} editing={editing} diff --git a/src/ChatList/index.tsx b/src/ChatList/index.tsx index 39f61c9c..8b1a38f4 100644 --- a/src/ChatList/index.tsx +++ b/src/ChatList/index.tsx @@ -95,6 +95,8 @@ const ChatList = memo( type, }; + console.log('renderItems', renderItems); + const historyLength = data.length; const enableHistoryDivider = enableHistoryCount && diff --git a/src/ProChat/demos/actions-chat-item.tsx b/src/ProChat/demos/actions-chat-item.tsx new file mode 100644 index 00000000..e884f6a9 --- /dev/null +++ b/src/ProChat/demos/actions-chat-item.tsx @@ -0,0 +1,43 @@ +/** + * compact: true + */ +import { ProChat } from '@ant-design/pro-chat'; +import { useTheme } from 'antd-style'; + +import { Button } from 'antd'; +import { MockResponse } from '../mocks/streamResponse'; + +export default () => { + const theme = useTheme(); + + return ( +
+ { + if (props?.editing) { + return null; + } + return ( + + ); + }, + }} + request={async (messages) => { + const mockedData: string = `这是一段模拟的流式字符串数据。本次会话传入了${messages.length}条消息`; + + const mockResponse = new MockResponse(mockedData); + + return mockResponse.getResponse(); + }} + /> +
+ ); +}; diff --git a/src/ProChat/index.en-US.md b/src/ProChat/index.en-US.md index d9be303f..eb6ce03e 100644 --- a/src/ProChat/index.en-US.md +++ b/src/ProChat/index.en-US.md @@ -78,6 +78,14 @@ ProChat uses `meta` to represent the avatars, names, and other information of bo +## Customize Item Actions + +You can use the actionsRender parameter under ChatItemConfig to complete the Actions configuration for each Item + +> We do not recommend that you modify it. If you do not want it, you can directly delete this function and write it yourself using render. + + + ## Customize the [Back to Bottom] button You can customize the [Back to Bottom] button to varying degrees through the backToBottomConfiguration parameter diff --git a/src/ProChat/index.md b/src/ProChat/index.md index 3a6c6b37..de34f6d4 100644 --- a/src/ProChat/index.md +++ b/src/ProChat/index.md @@ -88,6 +88,14 @@ ProChat 使用 `meta` 来表意会话双方的头像、名称等信息。设定 +## 自定义 Item 的 Actions + +你可以使用 ChatItemConfig 下的 actionsRender 参数来完成每一个 Item 的 Actions 配置 + +> 我们并不建议你去修改,如果不想要可以直接删除这块功能自己用 render 来写 + + + ## 自定义「回到底部」按钮 你可以通过 backToBottomConfig 参数对「回到底部」按钮进行不同程度的自定义