/* * @Author: ZhaoYing * @Date: 2025-12-10 16:46:14 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-23 17:46:25 */ import { type FC, useEffect, useMemo, useState } from 'react' import { Flex, Input, Spin } from 'antd' import clsx from 'clsx' 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 [inputValue, setInputValue] = useState('') const [isFocus, setIsFocus] = useState(false) // Clear input when external message is cleared useEffect(() => { if (!message) setInputValue('') }, [message]) // Clear input when loading useEffect(() => { if (loading) setInputValue('') }, [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 }) || []) } 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 || !inputValue || inputValue.trim() === '') return onSend(inputValue) } const canSend = !loading && inputValue.trim() !== '' 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.name}
{file.type?.split('/')[file.type?.split('/').length - 1]} ยท {file.size}
handleDelete(file)} >
) })}
} {/* Message input area */} { setInputValue(e.target.value) 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(); } }} onFocus={() => setIsFocus(true)} onBlur={() => setIsFocus(false)} /> {/* Bottom action area */}
{children}
) } export default ChatInput