import React, { ReactElement, ReactNode, useMemo } from 'react';
import cls from 'classnames';
import { Message, Metadata, RenderContentProps, MarkdownRenderProps } from '../interface';
import MarkdownRender from '../../markdownRender';
import { cssClasses, strings } from '@douyinfe/semi-foundation/chat/constants';
import { MDXProps } from 'mdx/types';
import { FileAttachment, ImageAttachment } from '../attachment';
import Code from './code';
const { PREFIX_CHAT_BOX } = cssClasses;
const { MESSAGE_STATUS, MODE, ROLE } = strings;
interface ChatBoxContentProps {
mode?: 'bubble' | 'noBubble' | 'userBubble';
customMarkDownComponents?: MDXProps['components'];
children?: string;
role?: Metadata;
message?: Message;
customRenderFunc?: (props: RenderContentProps) => ReactNode;
markdownRenderProps?: MarkdownRenderProps
}
const ChatBoxContent = (props: ChatBoxContentProps) => {
const { message = {}, customRenderFunc, role: roleInfo, customMarkDownComponents, mode, markdownRenderProps } = props;
const { content, role, status } = message;
const markdownComponents = useMemo(() => ({
'code': Code,
'SemiFile': FileAttachment,
'img': ImageAttachment,
...customMarkDownComponents
}), [customMarkDownComponents]);
const wrapCls = useMemo(() => {
const isUser = role === ROLE.USER;
const bubble = mode === MODE.BUBBLE;
const userBubble = mode === MODE.USER_BUBBLE && isUser;
return cls(`${PREFIX_CHAT_BOX}-content`, {
[`${PREFIX_CHAT_BOX}-content-${mode}`]: bubble || userBubble,
[`${PREFIX_CHAT_BOX}-content-user`]: (bubble && isUser) || userBubble,
[`${PREFIX_CHAT_BOX}-content-error`]: status === MESSAGE_STATUS.ERROR && (bubble || userBubble)
});
}, [role, status, mode]);
const node = useMemo(() => {
if (status === MESSAGE_STATUS.LOADING) {
return
;
} else {
let realContent;
if (typeof content === 'string') {
realContent =