Files
official-chat-app/src/pages/chat/MsgSend.tsx
Cledwyn Lew 54f9dc947d init
2025-11-25 13:32:36 +08:00

108 lines
2.6 KiB
TypeScript

import { Button, Textarea } from '@heroui/react';
import { CircleStopIcon, SendIcon } from 'lucide-react';
interface Props {
onSend: (query: string) => void;
onStop: () => void;
running?: boolean;
value: string;
onChange: (value: string) => void;
}
export const isMobile = ((): boolean => {
const userAgent =
typeof window !== 'undefined'
? window?.navigator?.userAgent?.toLowerCase()
: '';
const mobileRegex =
/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile|tablet/i;
return mobileRegex.test(userAgent);
})();
export const MsgSend = ({
onSend,
onStop,
running = false,
value,
onChange,
}: Props) => {
const isEmptyInput = value.trim().length === 0;
const handleSend = () => {
if (value) {
onSend(value);
onChange(''); // 发送后清空输入框
}
};
return (
<>
<Textarea
className="dark"
classNames={{
label: 'text-black/50 dark:text-white/90',
input: [
'bg-transparent',
'text-black/90 dark:text-white/90',
'placeholder:text-default-700/50 dark:placeholder:text-white/60',
],
innerWrapper: 'bg-transparent items-center',
inputWrapper: ['shadow-xl', 'bg-dark/40', 'dark:bg-black/40'],
mainWrapper: 'px-2',
}}
disabled={running}
endContent={
running ? (
<Button
isIconOnly
color="primary"
radius="full"
size="sm"
onPress={() => {
onStop();
}}
>
<CircleStopIcon className="w-5 h-5" />
</Button>
) : (
<Button
isIconOnly
color="primary"
radius="full"
size="sm"
onPress={handleSend}
isDisabled={isEmptyInput}
>
<SendIcon className="w-5 h-5" />
</Button>
)
}
maxLength={1000}
maxRows={4}
minRows={1}
placeholder={running ? '正在生成...' : '按 Enter 发送'}
radius="lg"
size="lg"
value={value}
onChange={(e) => onChange(e.target.value)}
onKeyDown={(e) => {
if (
e.key === 'Enter' &&
!isMobile &&
!e.ctrlKey &&
!e.shiftKey &&
!e.altKey &&
!e.metaKey &&
!e.nativeEvent.isComposing &&
!isEmptyInput
) {
e.preventDefault();
handleSend();
}
}}
/>
</>
);
};