import IconFont from '@/components/icon-font'; import { StopOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button } from 'antd'; import React, { useMemo } from 'react'; import { Roles } from '../../config'; import { MessageItem, MessageItemAction } from '../../config/types'; import '../../style/content-item.less'; import MessageActions from './message-actions'; import MessageBody from './message-body'; import ThinkParser from './think-parser'; interface MessageItemProps { data: MessageItem; editable?: boolean; loading?: boolean; showTitle?: boolean; actions?: MessageItemAction[]; updateMessage?: (message: MessageItem) => void; onDelete?: () => void; } interface SaveActionsProps { handleSave: () => void; handleCancel: () => void; } interface ThoughtStatusProps { collapsed: boolean; setCollapsed: (collapsed: boolean) => void; isThinking: boolean; } const SaveActions: React.FC = ({ handleSave, handleCancel }) => { const intl = useIntl(); return (
); }; const ThoughtStatus: React.FC = ({ collapsed, setCollapsed, isThinking }) => { const intl = useIntl(); return (
); }; const ContentItem: React.FC = ({ updateMessage, onDelete, loading, data, editable, showTitle = true, actions = ['upload', 'delete', 'copy', 'edit'] }) => { const intl = useIntl(); const [showMarkdown, setShowMarkdown] = React.useState(true); const messageRef = React.useRef(null); const thinkerRef = React.useRef(null); const [collapsed, setCollapsed] = React.useState(false); const handleOnEdit = () => { setShowMarkdown(false); messageRef.current?.setEditContent(data.content); }; const handleSave = () => { messageRef.current?.handleSaveEdit(); setShowMarkdown(true); }; const handleCancel = () => { messageRef.current?.handleCancelEdit(); setShowMarkdown(true); }; const handleUpdateMessage = (message: MessageItem) => { updateMessage?.(message); if (data.role === Roles.Assistant) { thinkerRef.current?.reset(); } }; const reasoningContent = useMemo(() => { if (data.role === Roles.User) { return { thought: '', isThinking: false, result: '' }; } if (!thinkerRef.current && showMarkdown) { thinkerRef.current = new ThinkParser(); } if (showMarkdown) { const res = thinkerRef.current.parse(data.content); return res; } return { thought: '', isThinking: false, result: data.content }; }, [data.content, showMarkdown, data.role]); const renderTitle = useMemo(() => { if (!showTitle) { return null; } let roleTitle: React.ReactNode = intl.formatMessage({ id: `playground.${data.role}` }); let avatar = ( ); if (data.role === Roles.Assistant) { avatar = ( ); } if (data.title) { roleTitle = data.title; } return (
{avatar} {roleTitle} {data.role === Roles.Assistant && reasoningContent.thought && ( )}
); }, [ data.role, data.title, intl, showTitle, reasoningContent.thought, reasoningContent.isThinking, collapsed ]); return (
{showTitle && renderTitle}
{showMarkdown ? ( ) : ( )}
); }; export default React.memo(ContentItem);