mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-24 07:26:47 +08:00
fix: Fixed an issue where the first message would be displayed when sending the second message #2625 (#2626)
### What problem does this PR solve? fix: Fixed an issue where the first message would be displayed when sending the second message #2625 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) - [ ] New Feature (non-breaking change which adds functionality) - [ ] Documentation Update - [ ] Refactoring - [ ] Performance Improvement - [ ] Other (please describe):
This commit is contained in:
@ -19,10 +19,13 @@ import {
|
||||
} from '@/hooks/chat-hooks';
|
||||
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
||||
import { memo } from 'react';
|
||||
import { ConversationContext } from '../context';
|
||||
import styles from './index.less';
|
||||
|
||||
const ChatContainer = () => {
|
||||
interface IProps {
|
||||
controller: AbortController;
|
||||
}
|
||||
|
||||
const ChatContainer = ({ controller }: IProps) => {
|
||||
const { conversationId } = useGetChatSearchParams();
|
||||
const { data: conversation } = useFetchNextConversation();
|
||||
|
||||
@ -36,8 +39,7 @@ const ChatContainer = () => {
|
||||
handlePressEnter,
|
||||
regenerateMessage,
|
||||
removeMessageById,
|
||||
redirectToNewConversation,
|
||||
} = useSendNextMessage();
|
||||
} = useSendNextMessage(controller);
|
||||
|
||||
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
||||
useClickDrawer();
|
||||
@ -54,35 +56,33 @@ const ChatContainer = () => {
|
||||
<Flex flex={1} vertical className={styles.messageContainer}>
|
||||
<div>
|
||||
<Spin spinning={loading}>
|
||||
<ConversationContext.Provider value={redirectToNewConversation}>
|
||||
{derivedMessages?.map((message, i) => {
|
||||
return (
|
||||
<MessageItem
|
||||
loading={
|
||||
message.role === MessageType.Assistant &&
|
||||
sendLoading &&
|
||||
derivedMessages.length - 1 === i
|
||||
}
|
||||
key={message.id}
|
||||
item={message}
|
||||
nickname={userInfo.nickname}
|
||||
avatar={userInfo.avatar}
|
||||
reference={buildMessageItemReference(
|
||||
{
|
||||
message: derivedMessages,
|
||||
reference: conversation.reference,
|
||||
},
|
||||
message,
|
||||
)}
|
||||
clickDocumentButton={clickDocumentButton}
|
||||
index={i}
|
||||
removeMessageById={removeMessageById}
|
||||
regenerateMessage={regenerateMessage}
|
||||
sendLoading={sendLoading}
|
||||
></MessageItem>
|
||||
);
|
||||
})}
|
||||
</ConversationContext.Provider>
|
||||
{derivedMessages?.map((message, i) => {
|
||||
return (
|
||||
<MessageItem
|
||||
loading={
|
||||
message.role === MessageType.Assistant &&
|
||||
sendLoading &&
|
||||
derivedMessages.length - 1 === i
|
||||
}
|
||||
key={message.id}
|
||||
item={message}
|
||||
nickname={userInfo.nickname}
|
||||
avatar={userInfo.avatar}
|
||||
reference={buildMessageItemReference(
|
||||
{
|
||||
message: derivedMessages,
|
||||
reference: conversation.reference,
|
||||
},
|
||||
message,
|
||||
)}
|
||||
clickDocumentButton={clickDocumentButton}
|
||||
index={i}
|
||||
removeMessageById={removeMessageById}
|
||||
regenerateMessage={regenerateMessage}
|
||||
sendLoading={sendLoading}
|
||||
></MessageItem>
|
||||
);
|
||||
})}
|
||||
</Spin>
|
||||
</div>
|
||||
<div ref={ref} />
|
||||
|
||||
@ -1,6 +1 @@
|
||||
export enum ChatSearchParams {
|
||||
DialogId = 'dialogId',
|
||||
ConversationId = 'conversationId',
|
||||
}
|
||||
|
||||
export const EmptyConversationId = 'empty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { MessageType } from '@/constants/chat';
|
||||
import { ChatSearchParams, MessageType } from '@/constants/chat';
|
||||
import { fileIconMap } from '@/constants/common';
|
||||
import {
|
||||
useFetchManualConversation,
|
||||
@ -24,6 +24,8 @@ import {
|
||||
} from '@/hooks/logic-hooks';
|
||||
import { IConversation, IDialog, Message } from '@/interfaces/database/chat';
|
||||
import { getFileExtension } from '@/utils';
|
||||
import api from '@/utils/api';
|
||||
import { getConversationId } from '@/utils/chat';
|
||||
import { useMutationState } from '@tanstack/react-query';
|
||||
import { get } from 'lodash';
|
||||
import trim from 'lodash/trim';
|
||||
@ -32,18 +34,57 @@ import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useSearchParams } from 'umi';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { ChatSearchParams } from './constants';
|
||||
import {
|
||||
IClientConversation,
|
||||
IMessage,
|
||||
VariableTableDataType,
|
||||
} from './interface';
|
||||
|
||||
export const useSetChatRouteParams = () => {
|
||||
const [currentQueryParameters, setSearchParams] = useSearchParams();
|
||||
const newQueryParameters: URLSearchParams = useMemo(
|
||||
() => new URLSearchParams(currentQueryParameters.toString()),
|
||||
[currentQueryParameters],
|
||||
);
|
||||
|
||||
const setConversationIsNew = useCallback(
|
||||
(value: string) => {
|
||||
newQueryParameters.set(ChatSearchParams.isNew, value);
|
||||
setSearchParams(newQueryParameters);
|
||||
},
|
||||
[newQueryParameters, setSearchParams],
|
||||
);
|
||||
|
||||
const getConversationIsNew = useCallback(() => {
|
||||
return newQueryParameters.get(ChatSearchParams.isNew);
|
||||
}, [newQueryParameters]);
|
||||
|
||||
return { setConversationIsNew, getConversationIsNew };
|
||||
};
|
||||
|
||||
export const useSetNewConversationRouteParams = () => {
|
||||
const [currentQueryParameters, setSearchParams] = useSearchParams();
|
||||
const newQueryParameters: URLSearchParams = useMemo(
|
||||
() => new URLSearchParams(currentQueryParameters.toString()),
|
||||
[currentQueryParameters],
|
||||
);
|
||||
|
||||
const setNewConversationRouteParams = useCallback(
|
||||
(conversationId: string, isNew: string) => {
|
||||
newQueryParameters.set(ChatSearchParams.ConversationId, conversationId);
|
||||
newQueryParameters.set(ChatSearchParams.isNew, isNew);
|
||||
setSearchParams(newQueryParameters);
|
||||
},
|
||||
[newQueryParameters, setSearchParams],
|
||||
);
|
||||
|
||||
return { setNewConversationRouteParams };
|
||||
};
|
||||
|
||||
export const useSelectCurrentDialog = () => {
|
||||
const data = useMutationState({
|
||||
filters: { mutationKey: ['fetchDialog'] },
|
||||
@ -169,22 +210,26 @@ export const useSelectDerivedConversationList = () => {
|
||||
const { data: conversationList, loading } = useFetchNextConversationList();
|
||||
const { dialogId } = useGetChatSearchParams();
|
||||
const prologue = currentDialog?.prompt_config?.prologue ?? '';
|
||||
const { setNewConversationRouteParams } = useSetNewConversationRouteParams();
|
||||
|
||||
const addTemporaryConversation = useCallback(() => {
|
||||
const conversationId = getConversationId();
|
||||
setList((pre) => {
|
||||
if (dialogId) {
|
||||
setNewConversationRouteParams(conversationId, 'true');
|
||||
const nextList = [
|
||||
{
|
||||
id: '',
|
||||
id: conversationId,
|
||||
name: t('newConversation'),
|
||||
dialog_id: dialogId,
|
||||
is_new: true,
|
||||
message: [
|
||||
{
|
||||
content: prologue,
|
||||
role: MessageType.Assistant,
|
||||
},
|
||||
],
|
||||
} as IConversation,
|
||||
} as any,
|
||||
...conversationList,
|
||||
];
|
||||
return nextList;
|
||||
@ -192,42 +237,32 @@ export const useSelectDerivedConversationList = () => {
|
||||
|
||||
return pre;
|
||||
});
|
||||
}, [conversationList, dialogId, prologue, t]);
|
||||
}, [conversationList, dialogId, prologue, t, setNewConversationRouteParams]);
|
||||
|
||||
// When you first enter the page, select the top conversation card
|
||||
|
||||
useEffect(() => {
|
||||
addTemporaryConversation();
|
||||
}, [addTemporaryConversation]);
|
||||
setList([...conversationList]);
|
||||
}, [conversationList]);
|
||||
|
||||
return { list, addTemporaryConversation, loading };
|
||||
};
|
||||
|
||||
export const useClickConversationCard = () => {
|
||||
const [currentQueryParameters, setSearchParams] = useSearchParams();
|
||||
const newQueryParameters: URLSearchParams = useMemo(
|
||||
() => new URLSearchParams(currentQueryParameters.toString()),
|
||||
[currentQueryParameters],
|
||||
);
|
||||
|
||||
const handleClickConversation = useCallback(
|
||||
(conversationId: string) => {
|
||||
newQueryParameters.set(ChatSearchParams.ConversationId, conversationId);
|
||||
setSearchParams(newQueryParameters);
|
||||
},
|
||||
[newQueryParameters, setSearchParams],
|
||||
);
|
||||
|
||||
return { handleClickConversation };
|
||||
};
|
||||
|
||||
export const useSetConversation = () => {
|
||||
const { dialogId } = useGetChatSearchParams();
|
||||
const { updateConversation } = useUpdateNextConversation();
|
||||
|
||||
const setConversation = useCallback(
|
||||
(message: string) => {
|
||||
return updateConversation({
|
||||
async (
|
||||
message: string,
|
||||
isNew: boolean = false,
|
||||
conversationId?: string,
|
||||
) => {
|
||||
const data = await updateConversation({
|
||||
dialog_id: dialogId,
|
||||
name: message,
|
||||
is_new: isNew,
|
||||
conversation_id: conversationId,
|
||||
message: [
|
||||
{
|
||||
role: MessageType.Assistant,
|
||||
@ -235,6 +270,8 @@ export const useSetConversation = () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
[updateConversation, dialogId],
|
||||
);
|
||||
@ -242,22 +279,6 @@ export const useSetConversation = () => {
|
||||
return { setConversation };
|
||||
};
|
||||
|
||||
// export const useScrollToBottom = (currentConversation: IClientConversation) => {
|
||||
// const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
// const scrollToBottom = useCallback(() => {
|
||||
// if (currentConversation.id) {
|
||||
// ref.current?.scrollIntoView({ behavior: 'instant' });
|
||||
// }
|
||||
// }, [currentConversation]);
|
||||
|
||||
// useEffect(() => {
|
||||
// scrollToBottom();
|
||||
// }, [scrollToBottom]);
|
||||
|
||||
// return ref;
|
||||
// };
|
||||
|
||||
export const useSelectNextMessages = () => {
|
||||
const {
|
||||
ref,
|
||||
@ -271,10 +292,10 @@ export const useSelectNextMessages = () => {
|
||||
} = useSelectDerivedMessages();
|
||||
const { data: conversation, loading } = useFetchNextConversation();
|
||||
const { data: dialog } = useFetchNextDialog();
|
||||
const { conversationId, dialogId } = useGetChatSearchParams();
|
||||
const { conversationId, dialogId, isNew } = useGetChatSearchParams();
|
||||
|
||||
const addPrologue = useCallback(() => {
|
||||
if (dialogId !== '' && conversationId === '') {
|
||||
if (dialogId !== '' && isNew === 'true') {
|
||||
const prologue = dialog.prompt_config?.prologue;
|
||||
|
||||
const nextMessage = {
|
||||
@ -285,17 +306,25 @@ export const useSelectNextMessages = () => {
|
||||
|
||||
setDerivedMessages([nextMessage]);
|
||||
}
|
||||
}, [conversationId, dialog, dialogId, setDerivedMessages]);
|
||||
}, [isNew, dialog, dialogId, setDerivedMessages]);
|
||||
|
||||
useEffect(() => {
|
||||
addPrologue();
|
||||
}, [addPrologue]);
|
||||
|
||||
useEffect(() => {
|
||||
if (conversationId) {
|
||||
if (
|
||||
conversationId &&
|
||||
isNew !== 'true' &&
|
||||
conversation.message?.length > 0
|
||||
) {
|
||||
setDerivedMessages(conversation.message);
|
||||
}
|
||||
}, [conversation.message, conversationId, setDerivedMessages]);
|
||||
|
||||
if (!conversationId) {
|
||||
setDerivedMessages([]);
|
||||
}
|
||||
}, [conversation.message, conversationId, setDerivedMessages, isNew]);
|
||||
|
||||
return {
|
||||
ref,
|
||||
@ -325,12 +354,14 @@ export const useHandleMessageInputChange = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useSendNextMessage = () => {
|
||||
export const useSendNextMessage = (controller: AbortController) => {
|
||||
const { setConversation } = useSetConversation();
|
||||
const { conversationId } = useGetChatSearchParams();
|
||||
const { conversationId, isNew } = useGetChatSearchParams();
|
||||
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
const { send, answer, done, setDone, resetAnswer } = useSendMessageWithSse();
|
||||
|
||||
const { send, answer, done } = useSendMessageWithSse(
|
||||
api.completeConversation,
|
||||
);
|
||||
const {
|
||||
ref,
|
||||
derivedMessages,
|
||||
@ -341,17 +372,8 @@ export const useSendNextMessage = () => {
|
||||
removeMessageById,
|
||||
removeMessagesAfterCurrentMessage,
|
||||
} = useSelectNextMessages();
|
||||
const { data: dialog } = useFetchNextDialog();
|
||||
const currentConversationIdRef = useRef<string>('');
|
||||
|
||||
const redirectToNewConversation = useCallback(
|
||||
(isPlaying: boolean) => {
|
||||
if (!conversationId && dialog?.prompt_config?.tts && !isPlaying) {
|
||||
handleClickConversation(currentConversationIdRef.current);
|
||||
}
|
||||
},
|
||||
[dialog, handleClickConversation, conversationId],
|
||||
);
|
||||
const { setConversationIsNew, getConversationIsNew } =
|
||||
useSetChatRouteParams();
|
||||
|
||||
const sendMessage = useCallback(
|
||||
async ({
|
||||
@ -363,49 +385,46 @@ export const useSendNextMessage = () => {
|
||||
currentConversationId?: string;
|
||||
messages?: Message[];
|
||||
}) => {
|
||||
const res = await send({
|
||||
conversation_id: currentConversationId ?? conversationId,
|
||||
messages: [...(messages ?? derivedMessages ?? []), message],
|
||||
});
|
||||
const res = await send(
|
||||
{
|
||||
conversation_id: currentConversationId ?? conversationId,
|
||||
messages: [...(messages ?? derivedMessages ?? []), message],
|
||||
},
|
||||
controller,
|
||||
);
|
||||
|
||||
if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) {
|
||||
// cancel loading
|
||||
setValue(message.content);
|
||||
console.info('removeLatestMessage111');
|
||||
removeLatestMessage();
|
||||
} else {
|
||||
if (currentConversationId) {
|
||||
console.info('111');
|
||||
// new conversation
|
||||
if (!dialog?.prompt_config?.tts) {
|
||||
handleClickConversation(currentConversationId);
|
||||
}
|
||||
} else {
|
||||
console.info('222');
|
||||
// fetchConversation(conversationId);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
dialog,
|
||||
derivedMessages,
|
||||
conversationId,
|
||||
handleClickConversation,
|
||||
removeLatestMessage,
|
||||
setValue,
|
||||
send,
|
||||
controller,
|
||||
],
|
||||
);
|
||||
|
||||
const handleSendMessage = useCallback(
|
||||
async (message: Message) => {
|
||||
if (conversationId !== '') {
|
||||
const isNew = getConversationIsNew();
|
||||
if (isNew !== 'true') {
|
||||
sendMessage({ message });
|
||||
} else {
|
||||
const data = await setConversation(message.content);
|
||||
const data = await setConversation(
|
||||
message.content,
|
||||
true,
|
||||
conversationId,
|
||||
);
|
||||
if (data.retcode === 0) {
|
||||
setConversationIsNew('');
|
||||
const id = data.data.id;
|
||||
currentConversationIdRef.current = id;
|
||||
// currentConversationIdRef.current = id;
|
||||
sendMessage({
|
||||
message,
|
||||
currentConversationId: id,
|
||||
@ -414,7 +433,13 @@ export const useSendNextMessage = () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
[conversationId, setConversation, sendMessage],
|
||||
[
|
||||
setConversation,
|
||||
sendMessage,
|
||||
setConversationIsNew,
|
||||
getConversationIsNew,
|
||||
conversationId,
|
||||
],
|
||||
);
|
||||
|
||||
const { regenerateMessage } = useRegenerateMessage({
|
||||
@ -425,24 +450,10 @@ export const useSendNextMessage = () => {
|
||||
|
||||
useEffect(() => {
|
||||
// #1289
|
||||
console.log('🚀 ~ useEffect ~ answer:', answer, done);
|
||||
if (
|
||||
answer.answer &&
|
||||
(answer?.conversationId === conversationId ||
|
||||
((!done || (done && answer.audio_binary)) && conversationId === ''))
|
||||
) {
|
||||
if (answer.answer && conversationId && isNew !== 'true') {
|
||||
addNewestAnswer(answer);
|
||||
}
|
||||
}, [answer, addNewestAnswer, conversationId, done]);
|
||||
|
||||
useEffect(() => {
|
||||
// #1289 switch to another conversion window when the last conversion answer doesn't finish.
|
||||
if (conversationId) {
|
||||
setDone(true);
|
||||
} else {
|
||||
resetAnswer();
|
||||
}
|
||||
}, [setDone, conversationId, resetAnswer]);
|
||||
}, [answer, addNewestAnswer, conversationId, isNew]);
|
||||
|
||||
const handlePressEnter = useCallback(
|
||||
(documentIds: string[]) => {
|
||||
@ -479,7 +490,6 @@ export const useSendNextMessage = () => {
|
||||
ref,
|
||||
derivedMessages,
|
||||
removeMessageById,
|
||||
redirectToNewConversation,
|
||||
};
|
||||
};
|
||||
|
||||
@ -494,15 +504,12 @@ export const useGetFileIcon = () => {
|
||||
};
|
||||
|
||||
export const useDeleteConversation = () => {
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
const { removeConversation } = useRemoveNextConversation();
|
||||
|
||||
const deleteConversation = (conversationIds: Array<string>) => async () => {
|
||||
const ret = await removeConversation(conversationIds);
|
||||
if (ret === 0) {
|
||||
handleClickConversation('');
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
@ -531,6 +538,7 @@ export const useRenameConversation = () => {
|
||||
...conversation,
|
||||
conversation_id: conversation.id,
|
||||
name,
|
||||
is_new: false,
|
||||
});
|
||||
|
||||
if (ret.retcode === 0) {
|
||||
@ -564,7 +572,7 @@ export const useRenameConversation = () => {
|
||||
export const useGetSendButtonDisabled = () => {
|
||||
const { dialogId, conversationId } = useGetChatSearchParams();
|
||||
|
||||
return dialogId === '' && conversationId === '';
|
||||
return dialogId === '' || conversationId === '';
|
||||
};
|
||||
|
||||
export const useSendButtonDisabled = (value: string) => {
|
||||
@ -575,18 +583,13 @@ export const useCreateConversationBeforeUploadDocument = () => {
|
||||
const { setConversation } = useSetConversation();
|
||||
const { dialogId } = useGetChatSearchParams();
|
||||
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
|
||||
const createConversationBeforeUploadDocument = useCallback(
|
||||
async (message: string) => {
|
||||
const data = await setConversation(message);
|
||||
if (data.retcode === 0) {
|
||||
const id = data.data.id;
|
||||
handleClickConversation(id);
|
||||
}
|
||||
const data = await setConversation(message, true);
|
||||
|
||||
return data;
|
||||
},
|
||||
[setConversation, handleClickConversation],
|
||||
[setConversation],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -17,15 +17,15 @@ import {
|
||||
Space,
|
||||
Spin,
|
||||
Tag,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import ChatConfigurationModal from './chat-configuration-modal';
|
||||
import ChatContainer from './chat-container';
|
||||
import {
|
||||
useClickConversationCard,
|
||||
useDeleteConversation,
|
||||
useDeleteDialog,
|
||||
useEditDialog,
|
||||
@ -36,6 +36,7 @@ import {
|
||||
|
||||
import ChatOverviewModal from '@/components/api-service/chat-overview-modal';
|
||||
import {
|
||||
useClickConversationCard,
|
||||
useClickDialogCard,
|
||||
useFetchNextDialogList,
|
||||
useGetChatSearchParams,
|
||||
@ -89,6 +90,7 @@ const Chat = () => {
|
||||
showModal: showOverviewModal,
|
||||
} = useSetModalState();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord<IDialog>();
|
||||
const [controller, setController] = useState(new AbortController());
|
||||
|
||||
const handleAppCardEnter = (id: string) => () => {
|
||||
handleItemEnter(id);
|
||||
@ -139,31 +141,28 @@ const Chat = () => {
|
||||
showConversationRenameModal(conversationId);
|
||||
};
|
||||
|
||||
const handleDialogCardClick = (dialogId: string) => () => {
|
||||
handleClickDialog(dialogId);
|
||||
};
|
||||
const handleDialogCardClick = useCallback(
|
||||
(dialogId: string) => () => {
|
||||
handleClickDialog(dialogId);
|
||||
},
|
||||
[handleClickDialog],
|
||||
);
|
||||
|
||||
const handleConversationCardClick = (dialogId: string) => () => {
|
||||
handleClickConversation(dialogId);
|
||||
};
|
||||
const handleConversationCardClick = useCallback(
|
||||
(conversationId: string, isNew: boolean) => () => {
|
||||
handleClickConversation(conversationId, isNew ? 'true' : '');
|
||||
setController((pre) => {
|
||||
pre.abort();
|
||||
return new AbortController();
|
||||
});
|
||||
},
|
||||
[handleClickConversation],
|
||||
);
|
||||
|
||||
const handleCreateTemporaryConversation = useCallback(() => {
|
||||
addTemporaryConversation();
|
||||
}, [addTemporaryConversation]);
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleCreateTemporaryConversation,
|
||||
label: (
|
||||
<Space>
|
||||
<PlusOutlined />
|
||||
{t('newChat')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const buildAppItems = (dialog: IDialog) => {
|
||||
const dialogId = dialog.id;
|
||||
|
||||
@ -297,10 +296,9 @@ const Chat = () => {
|
||||
<b>{t('chat')}</b>
|
||||
<Tag>{conversationList.length}</Tag>
|
||||
</Space>
|
||||
<Dropdown menu={{ items }}>
|
||||
{/* <FormOutlined /> */}
|
||||
<PlusOutlined />
|
||||
</Dropdown>
|
||||
<Tooltip title={t('newChat')}>
|
||||
<PlusOutlined onClick={handleCreateTemporaryConversation} />
|
||||
</Tooltip>
|
||||
</Flex>
|
||||
<Divider></Divider>
|
||||
<Flex vertical gap={10} className={styles.chatTitleContent}>
|
||||
@ -312,7 +310,7 @@ const Chat = () => {
|
||||
<Card
|
||||
key={x.id}
|
||||
hoverable
|
||||
onClick={handleConversationCardClick(x.id)}
|
||||
onClick={handleConversationCardClick(x.id, x.is_new)}
|
||||
onMouseEnter={handleConversationCardEnter(x.id)}
|
||||
onMouseLeave={handleConversationItemLeave}
|
||||
className={classNames(styles.chatTitleCard, {
|
||||
@ -347,7 +345,7 @@ const Chat = () => {
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Divider type={'vertical'} className={styles.divider}></Divider>
|
||||
<ChatContainer></ChatContainer>
|
||||
<ChatContainer controller={controller}></ChatContainer>
|
||||
{dialogEditVisible && (
|
||||
<ChatConfigurationModal
|
||||
visible={dialogEditVisible}
|
||||
|
||||
Reference in New Issue
Block a user