Skip to content

Commit

Permalink
fix: chatItemRenderConfig.render support defaultDom
Browse files Browse the repository at this point in the history
  • Loading branch information
chenshuai2144 committed Feb 2, 2024
1 parent 7ff9344 commit f891f3a
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 18 deletions.
8 changes: 5 additions & 3 deletions src/ChatItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,16 @@ const ChatItem = memo<ChatItemProps>((props) => {
{mobile && type === 'block' && <BorderSpacing borderSpacing={MOBILE_AVATAR_SIZE} />}
</Flexbox>
);
return (
chatItemRenderConfig?.render?.(props, {
return chatItemRenderConfig?.render?.(
props,
{
avatar: avatarDom,
messageContent: messageContentDom,
actions: actionsDom,
title: titleDom,
itemDom,
}) || itemDom
},
itemDom,
);
});

Expand Down
3 changes: 2 additions & 1 deletion src/ChatItem/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,14 @@ export interface ChatItemProps<T = Record<string, any>> {
render?: WithFalse<
(
props: ChatItemProps,
defaultDom: {
domsMap: {
avatar: ReactNode;
title: ReactNode;
messageContent: ReactNode;
actions: ReactNode;
itemDom: ReactNode;
},
defaultDom: ReactNode,
) => ReactNode
>;
};
Expand Down
25 changes: 25 additions & 0 deletions src/ChatList/ActionsBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,41 @@ import { memo } from 'react';
import ActionIconGroup, { type ActionIconGroupProps } from '@/ActionIconGroup';
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar';

/**
* ActionsBar组件的属性类型定义
*/
export interface ActionsBarProps extends ActionIconGroupProps {
/**
* 文本内容
*/
text?: {
/**
* 复制文本
*/
copy?: string;
/**
* 删除文本
*/
delete?: string;
/**
* 编辑文本
*/
edit?: string;
/**
* 重新生成文本
*/
regenerate?: string;
};
/**
* 内容
*/
content?: React.ReactNode | undefined;
}

/**
* ActionsBar 组件
* 用于渲染操作按钮组。
*/
const ActionsBar = memo<ActionsBarProps>(({ text, ...rest }) => {
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
return (
Expand Down
80 changes: 67 additions & 13 deletions src/ChatList/ChatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,64 @@ export type RenderMessageExtra = FC<ChatMessage>;
export type RenderErrorMessage = FC<ChatMessage>;
export type RenderAction = FC<ActionsBarProps & ChatMessage>;

/**
* 聊天列表项的属性。
* @template T 聊天列表项的额外数据类型。
*/
export interface ListItemProps<T = Record<string, any>> {
/**
* 聊天项的导航组件。
*/
groupNav?: ChatItemProps['avatarAddon'];
/**
* 是否正在加载。
*/
loading?: boolean;
/**
* @description 点击操作按钮的回调函数
* 点击操作按钮的回调函数
*/
onActionsClick?: OnActionClick;
/**
* @description 消息变化的回调函数
* 消息变化的回调函数
*/
onMessageChange?: OnMessageChange;
/**
* 渲染操作按钮的函数。
*/
renderActions?: {
[actionKey: string]: RenderAction;
};
/**
* @description 渲染错误消息的函数
* 渲染错误消息的函数
*/
renderErrorMessages?: {
[errorType: 'default' | string]: RenderErrorMessage;
};
/**
* 渲染列表项的函数。
*/
renderItems?: {
[role: RenderRole]: RenderItem;
};
/**
* @description 渲染消息的函数
* 渲染消息的函数
*/
renderMessages?: {
[role: RenderRole]: RenderMessage;
};
/**
* @description 渲染消息额外内容的函数
* 渲染消息额外内容的函数
*/
renderMessagesExtra?: {
[role: RenderRole]: RenderMessageExtra;
};
/**
* @description 是否显示聊天项的名称
* 是否显示聊天项的名称
* @default false
*/
showTitle?: boolean;
/**
* @description 文本内容
* 文本内容
*/
text?: ChatItemProps['text'] &
ActionsBarProps['text'] & {
Expand All @@ -70,27 +86,36 @@ export interface ListItemProps<T = Record<string, any>> {
[key: string]: string;
};
/**
* @description 聊天列表的类型
* 聊天列表的类型
* @default 'chat'
*/
type?: 'docs' | 'chat';

/**
* @description 聊天项的类名
* 聊天项的类名
* @default ''
*/
chatItemClassName?: string;

/**
* @description 聊天项的渲染函数
* 聊天项的渲染函数
*/
chatItemRenderConfig?: ChatItemProps['chatItemRenderConfig'];

/**
* 原始数据。
*/
originData?: ChatItemProps<T>['originData'];
}

/**
* 聊天列表项的属性。
* @template T 聊天列表项的额外数据类型。
*/
export type ChatListItemProps<T = Record<string, any>> = ChatMessage & ListItemProps<T>;

/**
* 聊天列表项组件。
* @param props 组件属性。
* @returns 聊天列表项组件。
*/
const ChatListItem = (props: ChatListItemProps) => {
const {
renderMessagesExtra,
Expand All @@ -115,6 +140,10 @@ const ChatListItem = (props: ChatListItemProps) => {

const { message } = App.useApp();

/**
* 渲染列表项的函数。
* @returns 渲染列表项的函数。
*/
const RenderItem = useMemo(() => {
if (!renderItems || !item?.role) return;
let renderFunction;
Expand All @@ -124,6 +153,12 @@ const ChatListItem = (props: ChatListItemProps) => {
return renderFunction;
}, [renderItems?.[item.role]]);

/**
* 渲染消息的函数。
* @param editableContent 可编辑的内容。
* @param data 聊天消息的数据。
* @returns 渲染消息的组件。
*/
const RenderMessage = useRefFunction(
({ editableContent, data }: { data: ChatMessage; editableContent: ReactNode }) => {
if (!renderMessages || !item?.role) return;
Expand All @@ -136,6 +171,11 @@ const ChatListItem = (props: ChatListItemProps) => {
},
);

/**
* 渲染消息额外内容的函数。
* @param data 聊天消息的数据。
* @returns 渲染消息额外内容的组件。
*/
const MessageExtra = useRefFunction(({ data }: { data: ChatMessage }) => {
if (!renderMessagesExtra || !item?.role) return;
let RenderFunction;
Expand All @@ -146,6 +186,11 @@ const ChatListItem = (props: ChatListItemProps) => {
return <RenderFunction {...data} />;
});

/**
* 渲染错误消息的函数。
* @param data 聊天消息的数据。
* @returns 渲染错误消息的组件。
*/
const ErrorMessage = useRefFunction(({ data }: { data: ChatMessage }) => {
if (!renderErrorMessages || !item?.error?.type) return;
let RenderFunction;
Expand All @@ -157,6 +202,11 @@ const ChatListItem = (props: ChatListItemProps) => {
return <RenderFunction {...data} />;
});

/**
* 渲染操作按钮的函数。
* @param data 聊天消息的数据。
* @returns 渲染操作按钮的组件。
*/
const Actions = useRefFunction(({ data }: { data: ChatMessage }) => {
if (!renderActions || !item?.role) return;
let RenderFunction;
Expand Down Expand Up @@ -188,6 +238,10 @@ const ChatListItem = (props: ChatListItemProps) => {
);
});

/**
* 错误信息。
* @returns 错误信息对象。
*/
const error = useMemo(() => {
if (!item.error) return;
return {
Expand Down
12 changes: 12 additions & 0 deletions src/ChatList/HistoryDivider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@ import { memo } from 'react';
import Icon from '@/Icon';
import Tag from '@/components/Tag';

/**
* 历史记录分割线组件的属性。
*/
interface HistoryDividerProps {
/**
* 是否启用分割线。
*/
enable?: boolean;
/**
* 分割线文本。
*/
text?: string;
}

/**
* 历史记录分割线组件。
*/
const HistoryDivider = memo<HistoryDividerProps>(({ enable, text }) => {
if (!enable) return null;

Expand Down
10 changes: 9 additions & 1 deletion src/ChatList/ShouldUpdateItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import isEqual from 'fast-deep-equal';
import { Component } from 'react';

/**
* 组件用于判断是否需要更新的辅助类。
*/
class ShouldUpdateItem extends Component<
{
shouldUpdate?: (prevProps: any, nextProps: any) => boolean;
Expand All @@ -9,6 +11,11 @@ class ShouldUpdateItem extends Component<
},
any
> {
/**
* 判断组件是否需要更新。
* @param nextProps - 下一个属性对象。
* @returns 如果需要更新则返回 true,否则返回 false。
*/
shouldComponentUpdate(nextProps: any) {
if (nextProps.shouldUpdate) {
return nextProps.shouldUpdate(this.props, nextProps);
Expand All @@ -19,6 +26,7 @@ class ShouldUpdateItem extends Component<
return true;
}
}

render() {
return this.props.children;
}
Expand Down
25 changes: 25 additions & 0 deletions src/ChatList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ export type {
RenderMessageExtra,
} from './ChatListItem';

/**
* ChatList组件用于显示聊天列表。
*
* @component
* @param {Object} props - 组件属性
* @param {Function} props.onActionsClick - 点击操作按钮时的回调函数
* @param {Function} props.renderMessagesExtra - 渲染额外的消息内容的回调函数
* @param {string} props.className - 自定义类名
* @param {Array} props.data - 聊天数据数组
* @param {string} [props.type='chat'] - 聊天类型,默认为'chat'
* @param {string} props.text - 文本内容
* @param {boolean} props.showTitle - 是否显示标题
* @param {Function} props.itemShouldUpdate - 判断聊天项是否需要更新的回调函数
* @param {Function} props.onMessageChange - 消息内容变化时的回调函数
* @param {Function} props.renderMessages - 渲染消息内容的回调函数
* @param {Function} props.renderErrorMessages - 渲染错误消息的回调函数
* @param {string} props.loadingId - 正在加载的聊天项的ID
* @param {Function} props.renderItems - 渲染聊天项的回调函数
* @param {boolean} props.enableHistoryCount - 是否启用历史记录计数
* @param {Function} props.renderActions - 渲染操作按钮的回调函数
* @param {number} [props.historyCount=0] - 历史记录计数
* @param {Object} props.chatItemRenderConfig - 聊天项渲染配置
* @returns {JSX.Element} 聊天列表组件
*/
const ChatList = memo<ChatListProps>(
({
onActionsClick,
Expand All @@ -52,6 +76,7 @@ const ChatList = memo<ChatListProps>(
const { cx, styles } = useStyles();
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixClass = getPrefixCls('pro-chat');

return (
<div className={cx(styles.container, `${prefixClass}-list`, className)} {...props}>
{data.map((item, index) => {
Expand Down
Loading

0 comments on commit f891f3a

Please sign in to comment.