balibabu
commited on
Commit
·
d35be0d
1
Parent(s):
aeb6dbc
feat: Delete the file from the upload control of the message input box #1880 (#1946)
Browse files### What problem does this PR solve?
feat: Delete the file from the upload control of the message input box
#1880
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/src/assets/svg/llm/perfx-cloud.svg +10 -11
- web/src/components/indented-tree/modal.tsx +1 -1
- web/src/components/message-input/index.tsx +20 -27
- web/src/components/message-item/index.less +2 -1
- web/src/components/message-item/index.tsx +23 -6
- web/src/hooks/document-hooks.ts +27 -4
- web/src/pages/chat/chat-container/index.tsx +0 -18
- web/src/pages/chat/hooks.ts +16 -11
web/src/assets/svg/llm/perfx-cloud.svg
CHANGED
|
|
web/src/components/indented-tree/modal.tsx
CHANGED
@@ -15,7 +15,7 @@ const IndentedTreeModal = ({
|
|
15 |
|
16 |
return (
|
17 |
<Modal
|
18 |
-
title={t('chunk.
|
19 |
open={visible}
|
20 |
onCancel={hideModal}
|
21 |
width={'90vw'}
|
|
|
15 |
|
16 |
return (
|
17 |
<Modal
|
18 |
+
title={t('chunk.mind')}
|
19 |
open={visible}
|
20 |
onCancel={hideModal}
|
21 |
width={'90vw'}
|
web/src/components/message-input/index.tsx
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import { Authorization } from '@/constants/authorization';
|
2 |
import { useTranslate } from '@/hooks/common-hooks';
|
|
|
3 |
import { getAuthorization } from '@/utils/authorization-util';
|
4 |
import { PlusOutlined } from '@ant-design/icons';
|
5 |
import type { GetProp, UploadFile } from 'antd';
|
@@ -14,7 +15,7 @@ interface IProps {
|
|
14 |
value: string;
|
15 |
sendDisabled: boolean;
|
16 |
sendLoading: boolean;
|
17 |
-
onPressEnter(documentIds: string[]):
|
18 |
onInputChange: ChangeEventHandler<HTMLInputElement>;
|
19 |
conversationId: string;
|
20 |
}
|
@@ -37,50 +38,41 @@ const MessageInput = ({
|
|
37 |
conversationId,
|
38 |
}: IProps) => {
|
39 |
const { t } = useTranslate('chat');
|
|
|
40 |
|
41 |
-
const [fileList, setFileList] = useState<UploadFile[]>([
|
42 |
-
// {
|
43 |
-
// uid: '-1',
|
44 |
-
// name: 'image.png',
|
45 |
-
// status: 'done',
|
46 |
-
// url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
47 |
-
// },
|
48 |
-
// {
|
49 |
-
// uid: '-xxx',
|
50 |
-
// percent: 50,
|
51 |
-
// name: 'image.png',
|
52 |
-
// status: 'uploading',
|
53 |
-
// url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
54 |
-
// },
|
55 |
-
// {
|
56 |
-
// uid: '-5',
|
57 |
-
// name: 'image.png',
|
58 |
-
// status: 'error',
|
59 |
-
// },
|
60 |
-
]);
|
61 |
|
62 |
const handlePreview = async (file: UploadFile) => {
|
63 |
if (!file.url && !file.preview) {
|
64 |
file.preview = await getBase64(file.originFileObj as FileType);
|
65 |
}
|
66 |
-
|
67 |
-
// setPreviewImage(file.url || (file.preview as string));
|
68 |
-
// setPreviewOpen(true);
|
69 |
};
|
70 |
|
71 |
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
|
72 |
console.log('🚀 ~ newFileList:', newFileList);
|
73 |
setFileList(newFileList);
|
74 |
};
|
|
|
75 |
|
76 |
const handlePressEnter = useCallback(async () => {
|
|
|
77 |
const ids = fileList.reduce((pre, cur) => {
|
78 |
return pre.concat(get(cur, 'response.data', []));
|
79 |
}, []);
|
80 |
|
81 |
-
|
82 |
setFileList([]);
|
83 |
-
}, [fileList, onPressEnter]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
const uploadButton = (
|
86 |
<button style={{ border: 0, background: 'none' }} type="button">
|
@@ -101,7 +93,7 @@ const MessageInput = ({
|
|
101 |
type="primary"
|
102 |
onClick={handlePressEnter}
|
103 |
loading={sendLoading}
|
104 |
-
disabled={sendDisabled}
|
105 |
>
|
106 |
{t('send')}
|
107 |
</Button>
|
@@ -119,6 +111,7 @@ const MessageInput = ({
|
|
119 |
headers={{ [Authorization]: getAuthorization() }}
|
120 |
data={{ conversation_id: conversationId }}
|
121 |
method="post"
|
|
|
122 |
>
|
123 |
{fileList.length >= 8 ? null : uploadButton}
|
124 |
</Upload>
|
|
|
1 |
import { Authorization } from '@/constants/authorization';
|
2 |
import { useTranslate } from '@/hooks/common-hooks';
|
3 |
+
import { useRemoveNextDocument } from '@/hooks/document-hooks';
|
4 |
import { getAuthorization } from '@/utils/authorization-util';
|
5 |
import { PlusOutlined } from '@ant-design/icons';
|
6 |
import type { GetProp, UploadFile } from 'antd';
|
|
|
15 |
value: string;
|
16 |
sendDisabled: boolean;
|
17 |
sendLoading: boolean;
|
18 |
+
onPressEnter(documentIds: string[]): void;
|
19 |
onInputChange: ChangeEventHandler<HTMLInputElement>;
|
20 |
conversationId: string;
|
21 |
}
|
|
|
38 |
conversationId,
|
39 |
}: IProps) => {
|
40 |
const { t } = useTranslate('chat');
|
41 |
+
const { removeDocument } = useRemoveNextDocument();
|
42 |
|
43 |
+
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
const handlePreview = async (file: UploadFile) => {
|
46 |
if (!file.url && !file.preview) {
|
47 |
file.preview = await getBase64(file.originFileObj as FileType);
|
48 |
}
|
|
|
|
|
|
|
49 |
};
|
50 |
|
51 |
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
|
52 |
console.log('🚀 ~ newFileList:', newFileList);
|
53 |
setFileList(newFileList);
|
54 |
};
|
55 |
+
const isUploadingFile = fileList.some((x) => x.status === 'uploading');
|
56 |
|
57 |
const handlePressEnter = useCallback(async () => {
|
58 |
+
if (isUploadingFile) return;
|
59 |
const ids = fileList.reduce((pre, cur) => {
|
60 |
return pre.concat(get(cur, 'response.data', []));
|
61 |
}, []);
|
62 |
|
63 |
+
onPressEnter(ids);
|
64 |
setFileList([]);
|
65 |
+
}, [fileList, onPressEnter, isUploadingFile]);
|
66 |
+
|
67 |
+
const handleRemove = useCallback(
|
68 |
+
(file: UploadFile) => {
|
69 |
+
const ids = get(file, 'response.data', []);
|
70 |
+
if (ids.length) {
|
71 |
+
removeDocument(ids[0]);
|
72 |
+
}
|
73 |
+
},
|
74 |
+
[removeDocument],
|
75 |
+
);
|
76 |
|
77 |
const uploadButton = (
|
78 |
<button style={{ border: 0, background: 'none' }} type="button">
|
|
|
93 |
type="primary"
|
94 |
onClick={handlePressEnter}
|
95 |
loading={sendLoading}
|
96 |
+
disabled={sendDisabled || isUploadingFile}
|
97 |
>
|
98 |
{t('send')}
|
99 |
</Button>
|
|
|
111 |
headers={{ [Authorization]: getAuthorization() }}
|
112 |
data={{ conversation_id: conversationId }}
|
113 |
method="post"
|
114 |
+
onRemove={handleRemove}
|
115 |
>
|
116 |
{fileList.length >= 8 ? null : uploadButton}
|
117 |
</Upload>
|
web/src/components/message-item/index.less
CHANGED
@@ -7,7 +7,8 @@
|
|
7 |
width: 80%;
|
8 |
}
|
9 |
.messageItemSectionRight {
|
10 |
-
width: 80%;
|
|
|
11 |
}
|
12 |
.messageItemContent {
|
13 |
display: inline-flex;
|
|
|
7 |
width: 80%;
|
8 |
}
|
9 |
.messageItemSectionRight {
|
10 |
+
// width: 80%;
|
11 |
+
// max-width: 50vw;
|
12 |
}
|
13 |
.messageItemContent {
|
14 |
display: inline-flex;
|
web/src/components/message-item/index.tsx
CHANGED
@@ -7,15 +7,20 @@ import { IChunk } from '@/interfaces/database/knowledge';
|
|
7 |
import classNames from 'classnames';
|
8 |
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
9 |
|
10 |
-
import {
|
|
|
|
|
|
|
11 |
import MarkdownContent from '@/pages/chat/markdown-content';
|
12 |
import { getExtension, isImage } from '@/utils/document-util';
|
13 |
-
import { Avatar, Button, Flex, List } from 'antd';
|
14 |
import IndentedTreeModal from '../indented-tree/modal';
|
15 |
import NewDocumentLink from '../new-document-link';
|
16 |
import SvgIcon from '../svg-icon';
|
17 |
import styles from './index.less';
|
18 |
|
|
|
|
|
19 |
interface IProps {
|
20 |
item: Message;
|
21 |
reference: IReference;
|
@@ -38,7 +43,8 @@ const MessageItem = ({
|
|
38 |
const { t } = useTranslate('chat');
|
39 |
const fileThumbnails = useSelectFileThumbnails();
|
40 |
const { data: documentList, setDocumentIds } = useFetchDocumentInfosByIds();
|
41 |
-
|
|
|
42 |
const { visible, hideModal, showModal } = useSetModalState();
|
43 |
const [clickedDocumentId, setClickedDocumentId] = useState('');
|
44 |
|
@@ -66,8 +72,12 @@ const MessageItem = ({
|
|
66 |
const ids = item?.doc_ids ?? [];
|
67 |
if (ids.length) {
|
68 |
setDocumentIds(ids);
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
-
}, [item.doc_ids, setDocumentIds]);
|
71 |
|
72 |
return (
|
73 |
<div
|
@@ -117,6 +127,7 @@ const MessageItem = ({
|
|
117 |
dataSource={referenceDocumentList}
|
118 |
renderItem={(item) => {
|
119 |
const fileThumbnail = fileThumbnails[item.doc_id];
|
|
|
120 |
const fileExtension = getExtension(item.doc_name);
|
121 |
return (
|
122 |
<List.Item>
|
@@ -151,7 +162,8 @@ const MessageItem = ({
|
|
151 |
bordered
|
152 |
dataSource={documentList}
|
153 |
renderItem={(item) => {
|
154 |
-
const fileThumbnail =
|
|
|
155 |
const fileExtension = getExtension(item.name);
|
156 |
return (
|
157 |
<List.Item>
|
@@ -181,7 +193,12 @@ const MessageItem = ({
|
|
181 |
type={'text'}
|
182 |
onClick={handleUserDocumentClick(item.id)}
|
183 |
>
|
184 |
-
|
|
|
|
|
|
|
|
|
|
|
185 |
</Button>
|
186 |
)}
|
187 |
</Flex>
|
|
|
7 |
import classNames from 'classnames';
|
8 |
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
9 |
|
10 |
+
import {
|
11 |
+
useFetchDocumentInfosByIds,
|
12 |
+
useFetchDocumentThumbnailsByIds,
|
13 |
+
} from '@/hooks/document-hooks';
|
14 |
import MarkdownContent from '@/pages/chat/markdown-content';
|
15 |
import { getExtension, isImage } from '@/utils/document-util';
|
16 |
+
import { Avatar, Button, Flex, List, Typography } from 'antd';
|
17 |
import IndentedTreeModal from '../indented-tree/modal';
|
18 |
import NewDocumentLink from '../new-document-link';
|
19 |
import SvgIcon from '../svg-icon';
|
20 |
import styles from './index.less';
|
21 |
|
22 |
+
const { Text } = Typography;
|
23 |
+
|
24 |
interface IProps {
|
25 |
item: Message;
|
26 |
reference: IReference;
|
|
|
43 |
const { t } = useTranslate('chat');
|
44 |
const fileThumbnails = useSelectFileThumbnails();
|
45 |
const { data: documentList, setDocumentIds } = useFetchDocumentInfosByIds();
|
46 |
+
const { data: documentThumbnails, setDocumentIds: setIds } =
|
47 |
+
useFetchDocumentThumbnailsByIds();
|
48 |
const { visible, hideModal, showModal } = useSetModalState();
|
49 |
const [clickedDocumentId, setClickedDocumentId] = useState('');
|
50 |
|
|
|
72 |
const ids = item?.doc_ids ?? [];
|
73 |
if (ids.length) {
|
74 |
setDocumentIds(ids);
|
75 |
+
const documentIds = ids.filter((x) => !(x in fileThumbnails));
|
76 |
+
if (documentIds.length) {
|
77 |
+
setIds(documentIds);
|
78 |
+
}
|
79 |
}
|
80 |
+
}, [item.doc_ids, setDocumentIds, setIds, fileThumbnails]);
|
81 |
|
82 |
return (
|
83 |
<div
|
|
|
127 |
dataSource={referenceDocumentList}
|
128 |
renderItem={(item) => {
|
129 |
const fileThumbnail = fileThumbnails[item.doc_id];
|
130 |
+
|
131 |
const fileExtension = getExtension(item.doc_name);
|
132 |
return (
|
133 |
<List.Item>
|
|
|
162 |
bordered
|
163 |
dataSource={documentList}
|
164 |
renderItem={(item) => {
|
165 |
+
const fileThumbnail =
|
166 |
+
documentThumbnails[item.id] || fileThumbnails[item.id];
|
167 |
const fileExtension = getExtension(item.name);
|
168 |
return (
|
169 |
<List.Item>
|
|
|
193 |
type={'text'}
|
194 |
onClick={handleUserDocumentClick(item.id)}
|
195 |
>
|
196 |
+
<Text
|
197 |
+
style={{ maxWidth: '40vw' }}
|
198 |
+
ellipsis={{ tooltip: item.name }}
|
199 |
+
>
|
200 |
+
{item.name}
|
201 |
+
</Text>
|
202 |
</Button>
|
203 |
)}
|
204 |
</Flex>
|
web/src/hooks/document-hooks.ts
CHANGED
@@ -4,7 +4,7 @@ import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
|
4 |
import kbService from '@/services/knowledge-service';
|
5 |
import { api_host } from '@/utils/api';
|
6 |
import { buildChunkHighlights } from '@/utils/document-util';
|
7 |
-
import { useQuery } from '@tanstack/react-query';
|
8 |
import { UploadFile } from 'antd';
|
9 |
import { useCallback, useMemo, useState } from 'react';
|
10 |
import { IHighlight } from 'react-pdf-highlighter';
|
@@ -278,15 +278,38 @@ export const useFetchDocumentInfosByIds = () => {
|
|
278 |
|
279 |
export const useFetchDocumentThumbnailsByIds = () => {
|
280 |
const [ids, setDocumentIds] = useState<string[]>([]);
|
281 |
-
const { data } = useQuery({
|
282 |
queryKey: ['fetchDocumentThumbnails', ids],
|
283 |
-
|
|
|
284 |
queryFn: async () => {
|
285 |
const { data } = await kbService.document_thumbnails({ doc_ids: ids });
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
return data;
|
288 |
},
|
289 |
});
|
290 |
|
291 |
-
return { data,
|
292 |
};
|
|
|
4 |
import kbService from '@/services/knowledge-service';
|
5 |
import { api_host } from '@/utils/api';
|
6 |
import { buildChunkHighlights } from '@/utils/document-util';
|
7 |
+
import { useMutation, useQuery } from '@tanstack/react-query';
|
8 |
import { UploadFile } from 'antd';
|
9 |
import { useCallback, useMemo, useState } from 'react';
|
10 |
import { IHighlight } from 'react-pdf-highlighter';
|
|
|
278 |
|
279 |
export const useFetchDocumentThumbnailsByIds = () => {
|
280 |
const [ids, setDocumentIds] = useState<string[]>([]);
|
281 |
+
const { data } = useQuery<Record<string, string>>({
|
282 |
queryKey: ['fetchDocumentThumbnails', ids],
|
283 |
+
enabled: ids.length > 0,
|
284 |
+
initialData: {},
|
285 |
queryFn: async () => {
|
286 |
const { data } = await kbService.document_thumbnails({ doc_ids: ids });
|
287 |
+
if (data.retcode === 0) {
|
288 |
+
return data.data;
|
289 |
+
}
|
290 |
+
return {};
|
291 |
+
},
|
292 |
+
});
|
293 |
|
294 |
+
return { data, setDocumentIds };
|
295 |
+
};
|
296 |
+
|
297 |
+
export const useRemoveNextDocument = () => {
|
298 |
+
// const queryClient = useQueryClient();
|
299 |
+
const {
|
300 |
+
data,
|
301 |
+
isPending: loading,
|
302 |
+
mutateAsync,
|
303 |
+
} = useMutation({
|
304 |
+
mutationKey: ['removeDocument'],
|
305 |
+
mutationFn: async (documentId: string) => {
|
306 |
+
const data = await kbService.document_rm({ doc_id: documentId });
|
307 |
+
// if (data.retcode === 0) {
|
308 |
+
// queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
|
309 |
+
// }
|
310 |
return data;
|
311 |
},
|
312 |
});
|
313 |
|
314 |
+
return { data, loading, removeDocument: mutateAsync };
|
315 |
};
|
web/src/pages/chat/chat-container/index.tsx
CHANGED
@@ -80,24 +80,6 @@ const ChatContainer = () => {
|
|
80 |
onPressEnter={handlePressEnter}
|
81 |
conversationId={conversation.id}
|
82 |
></MessageInput>
|
83 |
-
{/* <Input
|
84 |
-
size="large"
|
85 |
-
placeholder={t('sendPlaceholder')}
|
86 |
-
value={value}
|
87 |
-
disabled={disabled}
|
88 |
-
suffix={
|
89 |
-
<Button
|
90 |
-
type="primary"
|
91 |
-
onClick={handlePressEnter}
|
92 |
-
loading={sendLoading}
|
93 |
-
disabled={sendDisabled}
|
94 |
-
>
|
95 |
-
{t('send')}
|
96 |
-
</Button>
|
97 |
-
}
|
98 |
-
onPressEnter={handlePressEnter}
|
99 |
-
onChange={handleInputChange}
|
100 |
-
/> */}
|
101 |
</Flex>
|
102 |
<Drawer
|
103 |
title="Document Previewer"
|
|
|
80 |
onPressEnter={handlePressEnter}
|
81 |
conversationId={conversation.id}
|
82 |
></MessageInput>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
</Flex>
|
84 |
<Drawer
|
85 |
title="Document Previewer"
|
web/src/pages/chat/hooks.ts
CHANGED
@@ -19,7 +19,12 @@ import {
|
|
19 |
} from '@/hooks/common-hooks';
|
20 |
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
|
21 |
import { useOneNamespaceEffectsLoading } from '@/hooks/store-hooks';
|
22 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
23 |
import { IChunk } from '@/interfaces/database/knowledge';
|
24 |
import { getFileExtension } from '@/utils';
|
25 |
import omit from 'lodash/omit';
|
@@ -379,7 +384,7 @@ export const useSelectCurrentConversation = () => {
|
|
379 |
const { conversationId, dialogId } = useGetChatSearchParams();
|
380 |
|
381 |
const addNewestConversation = useCallback(
|
382 |
-
(message:
|
383 |
setCurrentConversation((pre) => {
|
384 |
return {
|
385 |
...pre,
|
@@ -387,7 +392,8 @@ export const useSelectCurrentConversation = () => {
|
|
387 |
...pre.message,
|
388 |
{
|
389 |
role: MessageType.User,
|
390 |
-
content: message,
|
|
|
391 |
id: uuid(),
|
392 |
} as IMessage,
|
393 |
{
|
@@ -535,7 +541,7 @@ export const useHandleMessageInputChange = () => {
|
|
535 |
|
536 |
export const useSendMessage = (
|
537 |
conversation: IClientConversation,
|
538 |
-
addNewestConversation: (message:
|
539 |
removeLatestMessage: () => void,
|
540 |
addNewestAnswer: (answer: IAnswer) => void,
|
541 |
) => {
|
@@ -589,12 +595,12 @@ export const useSendMessage = (
|
|
589 |
const handleSendMessage = useCallback(
|
590 |
async (message: string, documentIds: string[]) => {
|
591 |
if (conversationId !== '') {
|
592 |
-
|
593 |
} else {
|
594 |
const data = await setConversation(message);
|
595 |
if (data.retcode === 0) {
|
596 |
const id = data.data.id;
|
597 |
-
|
598 |
}
|
599 |
}
|
600 |
},
|
@@ -616,15 +622,14 @@ export const useSendMessage = (
|
|
616 |
}, [setDone, conversationId]);
|
617 |
|
618 |
const handlePressEnter = useCallback(
|
619 |
-
|
620 |
if (trim(value) === '') return;
|
621 |
-
|
|
|
622 |
if (done) {
|
623 |
setValue('');
|
624 |
-
|
625 |
}
|
626 |
-
addNewestConversation(value);
|
627 |
-
return ret;
|
628 |
},
|
629 |
[addNewestConversation, handleSendMessage, done, setValue, value],
|
630 |
);
|
|
|
19 |
} from '@/hooks/common-hooks';
|
20 |
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
|
21 |
import { useOneNamespaceEffectsLoading } from '@/hooks/store-hooks';
|
22 |
+
import {
|
23 |
+
IAnswer,
|
24 |
+
IConversation,
|
25 |
+
IDialog,
|
26 |
+
Message,
|
27 |
+
} from '@/interfaces/database/chat';
|
28 |
import { IChunk } from '@/interfaces/database/knowledge';
|
29 |
import { getFileExtension } from '@/utils';
|
30 |
import omit from 'lodash/omit';
|
|
|
384 |
const { conversationId, dialogId } = useGetChatSearchParams();
|
385 |
|
386 |
const addNewestConversation = useCallback(
|
387 |
+
(message: Partial<Message>, answer: string = '') => {
|
388 |
setCurrentConversation((pre) => {
|
389 |
return {
|
390 |
...pre,
|
|
|
392 |
...pre.message,
|
393 |
{
|
394 |
role: MessageType.User,
|
395 |
+
content: message.content,
|
396 |
+
doc_ids: message.doc_ids,
|
397 |
id: uuid(),
|
398 |
} as IMessage,
|
399 |
{
|
|
|
541 |
|
542 |
export const useSendMessage = (
|
543 |
conversation: IClientConversation,
|
544 |
+
addNewestConversation: (message: Partial<Message>, answer?: string) => void,
|
545 |
removeLatestMessage: () => void,
|
546 |
addNewestAnswer: (answer: IAnswer) => void,
|
547 |
) => {
|
|
|
595 |
const handleSendMessage = useCallback(
|
596 |
async (message: string, documentIds: string[]) => {
|
597 |
if (conversationId !== '') {
|
598 |
+
sendMessage(message, documentIds);
|
599 |
} else {
|
600 |
const data = await setConversation(message);
|
601 |
if (data.retcode === 0) {
|
602 |
const id = data.data.id;
|
603 |
+
sendMessage(message, documentIds, id);
|
604 |
}
|
605 |
}
|
606 |
},
|
|
|
622 |
}, [setDone, conversationId]);
|
623 |
|
624 |
const handlePressEnter = useCallback(
|
625 |
+
(documentIds: string[]) => {
|
626 |
if (trim(value) === '') return;
|
627 |
+
|
628 |
+
addNewestConversation({ content: value, doc_ids: documentIds });
|
629 |
if (done) {
|
630 |
setValue('');
|
631 |
+
handleSendMessage(value.trim(), documentIds);
|
632 |
}
|
|
|
|
|
633 |
},
|
634 |
[addNewestConversation, handleSendMessage, done, setValue, value],
|
635 |
);
|