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.
84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import { closeModal, openModal } from '@/components/Modal';
|
|
import { ImageUploadPreviewer } from '@/components/modals/ImageUploadPreviewer';
|
|
import { fileToDataUrl } from '@/utils/file-helper';
|
|
import { isEnterHotkey } from '@/utils/hot-key';
|
|
import { Input } from 'antd';
|
|
import React, { useCallback, useRef, useState } from 'react';
|
|
import { t, uploadFile } from 'tailchat-shared';
|
|
import { ChatInputAddon } from './Addon';
|
|
import { ClipboardHelper } from './clipboard-helper';
|
|
import { ChatInputActionContext } from './context';
|
|
|
|
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();
|
|
fileToDataUrl(image).then((imageLocalUrl) => {
|
|
const key = openModal(
|
|
<ImageUploadPreviewer
|
|
imageUrl={imageLocalUrl}
|
|
onConfirm={async () => {
|
|
const fileInfo = await uploadFile(image);
|
|
const imageRemoteUrl = fileInfo.url;
|
|
|
|
// TODO: not good
|
|
props.onSendMsg(`[img]${imageRemoteUrl}[/img]`);
|
|
closeModal(key);
|
|
}}
|
|
/>
|
|
);
|
|
});
|
|
}
|
|
},
|
|
[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';
|