File size: 3,500 Bytes
2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 d35be0d 2eeb8b1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
import { Authorization } from '@/constants/authorization';
import { useTranslate } from '@/hooks/common-hooks';
import { useRemoveNextDocument } from '@/hooks/document-hooks';
import { getAuthorization } from '@/utils/authorization-util';
import { PlusOutlined } from '@ant-design/icons';
import type { GetProp, UploadFile } from 'antd';
import { Button, Flex, Input, Upload, UploadProps } from 'antd';
import get from 'lodash/get';
import { ChangeEventHandler, useCallback, useState } from 'react';
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
interface IProps {
disabled: boolean;
value: string;
sendDisabled: boolean;
sendLoading: boolean;
onPressEnter(documentIds: string[]): void;
onInputChange: ChangeEventHandler<HTMLInputElement>;
conversationId: string;
}
const getBase64 = (file: FileType): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file as any);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
const MessageInput = ({
disabled,
value,
onPressEnter,
sendDisabled,
sendLoading,
onInputChange,
conversationId,
}: IProps) => {
const { t } = useTranslate('chat');
const { removeDocument } = useRemoveNextDocument();
const [fileList, setFileList] = useState<UploadFile[]>([]);
const handlePreview = async (file: UploadFile) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj as FileType);
}
};
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
console.log('🚀 ~ newFileList:', newFileList);
setFileList(newFileList);
};
const isUploadingFile = fileList.some((x) => x.status === 'uploading');
const handlePressEnter = useCallback(async () => {
if (isUploadingFile) return;
const ids = fileList.reduce((pre, cur) => {
return pre.concat(get(cur, 'response.data', []));
}, []);
onPressEnter(ids);
setFileList([]);
}, [fileList, onPressEnter, isUploadingFile]);
const handleRemove = useCallback(
(file: UploadFile) => {
const ids = get(file, 'response.data', []);
if (ids.length) {
removeDocument(ids[0]);
}
},
[removeDocument],
);
const uploadButton = (
<button style={{ border: 0, background: 'none' }} type="button">
<PlusOutlined />
<div style={{ marginTop: 8 }}>Upload</div>
</button>
);
return (
<Flex gap={10} vertical>
<Input
size="large"
placeholder={t('sendPlaceholder')}
value={value}
disabled={disabled}
suffix={
<Button
type="primary"
onClick={handlePressEnter}
loading={sendLoading}
disabled={sendDisabled || isUploadingFile}
>
{t('send')}
</Button>
}
onPressEnter={handlePressEnter}
onChange={onInputChange}
/>
<Upload
action="/v1/document/upload_and_parse"
listType="picture-card"
fileList={fileList}
onPreview={handlePreview}
onChange={handleChange}
multiple
headers={{ [Authorization]: getAuthorization() }}
data={{ conversation_id: conversationId }}
method="post"
onRemove={handleRemove}
>
{fileList.length >= 8 ? null : uploadButton}
</Upload>
</Flex>
);
};
export default MessageInput;
|