mirror of https://github.com/msgbyte/tailchat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
import { getMessageTextDecorators } from '@/plugin/common';
|
|
import { isEnterHotkey } from '@/utils/hot-key';
|
|
import { Input } from 'antd';
|
|
import React, { useCallback, useRef, useState } from 'react';
|
|
import { t } from 'tailchat-shared';
|
|
import { ChatInputAddon } from './Addon';
|
|
import { ClipboardHelper } from './clipboard-helper';
|
|
import { ChatInputActionContext } from './context';
|
|
import { uploadMessageImage } from './utils';
|
|
|
|
interface ChatInputBoxProps {
|
|
onSendMsg: (msg: string) => void;
|
|
}
|
|
export const ChatInputBox: React.FC<ChatInputBoxProps> = React.memo((props) => {
|
|
const inputRef = useRef<Input>(null);
|
|
const [message, setMessage] = useState('');
|
|
const handleSendMsg = useCallback(() => {
|
|
props.onSendMsg(message);
|
|
setMessage('');
|
|
inputRef.current?.focus();
|
|
}, [message]);
|
|
|
|
const handleKeyDown = useCallback(
|
|
(e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
if (isEnterHotkey(e.nativeEvent)) {
|
|
e.preventDefault();
|
|
handleSendMsg();
|
|
}
|
|
},
|
|
[handleSendMsg]
|
|
);
|
|
|
|
const handlePaste = useCallback(
|
|
(e: React.ClipboardEvent<HTMLDivElement>) => {
|
|
const helper = new ClipboardHelper(e);
|
|
const image = helper.hasImage();
|
|
if (image) {
|
|
// 上传图片
|
|
e.preventDefault();
|
|
uploadMessageImage(image).then(({ url, width, height }) => {
|
|
props.onSendMsg(
|
|
getMessageTextDecorators().image(url, { width, height })
|
|
);
|
|
});
|
|
}
|
|
},
|
|
[props.onSendMsg]
|
|
);
|
|
|
|
return (
|
|
<ChatInputActionContext.Provider value={{ sendMsg: props.onSendMsg }}>
|
|
<div className="px-4 py-2">
|
|
<div className="bg-white dark:bg-gray-600 flex rounded-md items-center">
|
|
<Input
|
|
ref={inputRef}
|
|
className="outline-none shadow-none border-0 py-2.5 px-4 flex-1"
|
|
placeholder={t('输入一些什么')}
|
|
value={message}
|
|
onChange={(e) => setMessage(e.target.value)}
|
|
onKeyDown={handleKeyDown}
|
|
onPaste={handlePaste}
|
|
/>
|
|
|
|
<div className="px-2">
|
|
<ChatInputAddon />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</ChatInputActionContext.Provider>
|
|
);
|
|
});
|
|
ChatInputBox.displayName = 'ChatInputBox';
|