Files
2026-03-20 07:33:46 +00:00

81 lines
2.1 KiB
TypeScript

import React from 'react'
import { cn } from '@/utils/cn'
import type { Attachment, ImageAttachment, BaseEvent, HandleImageAttachmentClick } from '../../types'
import { AttachmentItem } from './AttachmentItem'
import { ImageAttachmentItem } from './ImageAttachmentItem'
export interface UserMessageProps {
base?: BaseEvent
attachment?: Attachment[]
imageAttachment?: ImageAttachment[]
loading?: boolean
isUserInput: boolean
showTemplate?: boolean
onAttachmentClick?: (attachment: Attachment) => void
onImageAttachmentClick?: HandleImageAttachmentClick
}
/**
* 用户消息附件组件 - 展示用户上传的文件/图片,对应 next-agent UserMessage
*/
function InnerUserMessage({
attachment,
imageAttachment,
loading,
isUserInput,
onAttachmentClick,
onImageAttachmentClick,
}: UserMessageProps) {
const hasImages = !!(imageAttachment?.length)
const hasFiles = !!(attachment?.length)
if (!hasImages && !hasFiles) return null
return (
<div
className={cn(
'flex flex-col rounded-xl mt-2 mb-6 px-3',
{ 'opacity-60': loading },
isUserInput ? 'items-end' : 'items-start',
)}
>
{hasImages && (
<div
className={cn(
'flex flex-wrap gap-2 mb-2',
isUserInput ? 'justify-end' : 'justify-start',
)}
>
{imageAttachment!.map((img, i) => (
<ImageAttachmentItem
assetsType="user"
key={img.url || img.path || i}
image={img}
onClick={onImageAttachmentClick}
/>
))}
</div>
)}
{hasFiles && (
<div
className={cn(
'flex flex-wrap gap-2',
isUserInput ? 'justify-end' : 'justify-start',
)}
>
{attachment!.map((att, i) => (
<AttachmentItem
key={att.file_id || att.file_url || i}
attachment={att}
onClick={onAttachmentClick}
/>
))}
</div>
)}
</div>
)
}
export const UserMessage = React.memo(InnerUserMessage)
export default UserMessage