/* * @Author: ZhaoYing * @Date: 2025-12-10 16:46:14 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-19 18:44:51 */ import { type FC, useEffect, useMemo } from 'react' import { Flex, Input, Form, Spin } from 'antd' import clsx from 'clsx' import SendIcon from '@/assets/images/conversation/send.svg' import SendDisabledIcon from '@/assets/images/conversation/sendDisabled.svg' import LoadingIcon from '@/assets/images/conversation/loading.svg' import type { ChatInputProps } from './types' /** * Chat Input Component * Provides message input and send functionality, supports keyboard shortcuts and loading state display */ const ChatInput: FC = ({ message, onSend, loading, children, fileList, fileChange, className = '', onChange }) => { const [form] = Form.useForm() const values = Form.useWatch([], form) // Monitor form value changes to control send button state // Clear form when external message is empty useEffect(() => { if (!message) { form.setFieldsValue({ message: undefined, }) } }, [form, message]) // Clear input when loading useEffect(() => { if (loading) { form.setFieldsValue({ message: undefined, }) } }, [loading]) const handleDelete = (file: any) => { fileChange?.(fileList?.filter(item => { return item.thumbUrl && file.thumbUrl ? item.thumbUrl !== file.thumbUrl : item.url && file.url ? item.url !== file.url : item.uid !== file.uid }) || []) } // Convert file object to preview URL const previewFileList = useMemo(() => { return fileList?.map(file => ({ ...file, url: file.thumbUrl || file.url || (file.originFileObj ? URL.createObjectURL(file.originFileObj) : undefined) })) || [] }, [fileList]) const handleSend = () => { if (loading || !values || !values?.message || values?.message?.trim() === '') return onSend(values.message) } console.log('previewFileList', previewFileList) return (
{previewFileList.length > 0 &&
{previewFileList.map((file) => { if (file.type.includes('image')) { return (
{file.name}
handleDelete(file)} >
) } if (file.type.includes('video')) { return (
) } if (file.type.includes('audio')) { return (
) } return (
{file.type.includes('pdf') ?
: (file.type.includes('excel') || file.type.includes('spreadsheetml.sheet') || file.type.includes('csv')) ?
: (file.type.includes('doc') || file.type.includes('docx') || file.type.includes('word') || file.type.includes('wordprocessingml.document')) ?
: null }
{file.name}
{file.type} ยท {file.size}
handleDelete(file)} >
) })}
} {/* Message input form */}
onChange?.(e.target.value)} onKeyDown={(e) => { // Enter to send, Shift+Enter for new line if (e.key === 'Enter' && !e.shiftKey && (e.target as HTMLTextAreaElement).value?.trim() !== '' && !loading) { e.preventDefault(); handleSend(); } }} />
{/* Bottom action area */} {/* Child component content (such as buttons) */}
{children}
{/* Send button - display different icons based on state */} {loading ? : !values || !values?.message || values?.message?.trim() === '' ? : }
) } export default ChatInput