balibabu
commited on
Commit
·
2052ec7
1
Parent(s):
768eae1
Fix: In order to distinguish the keys of a pair of messages, add a prefix to the id when rendering the message. #4409 (#4451)
Browse files### What problem does this PR solve?
Fix: In order to distinguish the keys of a pair of messages, add a
prefix to the id when rendering the message. #4409
### Type of change
- [x] Bug Fix (non-breaking change which fixes an issue)
web/src/components/message-item/hooks.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
|
|
| 2 |
import { useSetModalState } from '@/hooks/common-hooks';
|
| 3 |
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
|
| 4 |
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
|
| 5 |
-
import { getMessagePureId } from '@/utils/chat';
|
| 6 |
import { hexStringToUint8Array } from '@/utils/common-util';
|
| 7 |
import { SpeechPlayer } from 'openai-speech-stream-player';
|
| 8 |
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
@@ -15,7 +14,7 @@ export const useSendFeedback = (messageId: string) => {
|
|
| 15 |
async (params: IFeedbackRequestBody) => {
|
| 16 |
const ret = await feedback({
|
| 17 |
...params,
|
| 18 |
-
messageId:
|
| 19 |
});
|
| 20 |
|
| 21 |
if (ret === 0) {
|
|
@@ -41,9 +40,8 @@ export const useRemoveMessage = (
|
|
| 41 |
const { deleteMessage, loading } = useDeleteMessage();
|
| 42 |
|
| 43 |
const onRemoveMessage = useCallback(async () => {
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
const code = await deleteMessage(pureId);
|
| 47 |
if (code === 0) {
|
| 48 |
removeMessageById?.(messageId);
|
| 49 |
}
|
|
|
|
| 2 |
import { useSetModalState } from '@/hooks/common-hooks';
|
| 3 |
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
|
| 4 |
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
|
|
|
|
| 5 |
import { hexStringToUint8Array } from '@/utils/common-util';
|
| 6 |
import { SpeechPlayer } from 'openai-speech-stream-player';
|
| 7 |
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
|
| 14 |
async (params: IFeedbackRequestBody) => {
|
| 15 |
const ret = await feedback({
|
| 16 |
...params,
|
| 17 |
+
messageId: messageId,
|
| 18 |
});
|
| 19 |
|
| 20 |
if (ret === 0) {
|
|
|
|
| 40 |
const { deleteMessage, loading } = useDeleteMessage();
|
| 41 |
|
| 42 |
const onRemoveMessage = useCallback(async () => {
|
| 43 |
+
if (messageId) {
|
| 44 |
+
const code = await deleteMessage(messageId);
|
|
|
|
| 45 |
if (code === 0) {
|
| 46 |
removeMessageById?.(messageId);
|
| 47 |
}
|
web/src/hooks/logic-hooks.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
|
| 7 |
import { IClientConversation, IMessage } from '@/pages/chat/interface';
|
| 8 |
import api from '@/utils/api';
|
| 9 |
import { getAuthorization } from '@/utils/authorization-util';
|
| 10 |
-
import { buildMessageUuid
|
| 11 |
import { PaginationProps, message } from 'antd';
|
| 12 |
import { FormInstance } from 'antd/lib';
|
| 13 |
import axios from 'axios';
|
|
@@ -309,7 +309,9 @@ export const useSelectDerivedMessages = () => {
|
|
| 309 |
...pre,
|
| 310 |
{
|
| 311 |
...message,
|
| 312 |
-
id: buildMessageUuid(message),
|
|
|
|
|
|
|
| 313 |
},
|
| 314 |
{
|
| 315 |
role: MessageType.Assistant,
|
|
@@ -353,10 +355,7 @@ export const useSelectDerivedMessages = () => {
|
|
| 353 |
const removeMessageById = useCallback(
|
| 354 |
(messageId: string) => {
|
| 355 |
setDerivedMessages((pre) => {
|
| 356 |
-
const nextMessages =
|
| 357 |
-
pre?.filter(
|
| 358 |
-
(x) => getMessagePureId(x.id) !== getMessagePureId(messageId),
|
| 359 |
-
) ?? [];
|
| 360 |
return nextMessages;
|
| 361 |
});
|
| 362 |
},
|
|
|
|
| 7 |
import { IClientConversation, IMessage } from '@/pages/chat/interface';
|
| 8 |
import api from '@/utils/api';
|
| 9 |
import { getAuthorization } from '@/utils/authorization-util';
|
| 10 |
+
import { buildMessageUuid } from '@/utils/chat';
|
| 11 |
import { PaginationProps, message } from 'antd';
|
| 12 |
import { FormInstance } from 'antd/lib';
|
| 13 |
import axios from 'axios';
|
|
|
|
| 309 |
...pre,
|
| 310 |
{
|
| 311 |
...message,
|
| 312 |
+
id: buildMessageUuid(message), // The message id is generated on the front end,
|
| 313 |
+
// and the message id returned by the back end is the same as the question id,
|
| 314 |
+
// so that the pair of messages can be deleted together when deleting the message
|
| 315 |
},
|
| 316 |
{
|
| 317 |
role: MessageType.Assistant,
|
|
|
|
| 355 |
const removeMessageById = useCallback(
|
| 356 |
(messageId: string) => {
|
| 357 |
setDerivedMessages((pre) => {
|
| 358 |
+
const nextMessages = pre?.filter((x) => x.id !== messageId) ?? [];
|
|
|
|
|
|
|
|
|
|
| 359 |
return nextMessages;
|
| 360 |
});
|
| 361 |
},
|
web/src/pages/chat/chat-container/index.tsx
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
| 18 |
useGetChatSearchParams,
|
| 19 |
} from '@/hooks/chat-hooks';
|
| 20 |
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
|
|
|
| 21 |
import { memo } from 'react';
|
| 22 |
import styles from './index.less';
|
| 23 |
|
|
@@ -64,7 +65,7 @@ const ChatContainer = ({ controller }: IProps) => {
|
|
| 64 |
sendLoading &&
|
| 65 |
derivedMessages.length - 1 === i
|
| 66 |
}
|
| 67 |
-
key={message
|
| 68 |
item={message}
|
| 69 |
nickname={userInfo.nickname}
|
| 70 |
avatar={userInfo.avatar}
|
|
|
|
| 18 |
useGetChatSearchParams,
|
| 19 |
} from '@/hooks/chat-hooks';
|
| 20 |
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
| 21 |
+
import { buildMessageUuidWithRole } from '@/utils/chat';
|
| 22 |
import { memo } from 'react';
|
| 23 |
import styles from './index.less';
|
| 24 |
|
|
|
|
| 65 |
sendLoading &&
|
| 66 |
derivedMessages.length - 1 === i
|
| 67 |
}
|
| 68 |
+
key={buildMessageUuidWithRole(message)}
|
| 69 |
item={message}
|
| 70 |
nickname={userInfo.nickname}
|
| 71 |
avatar={userInfo.avatar}
|
web/src/pages/chat/share/large.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import { buildMessageItemReference } from '../utils';
|
|
| 14 |
import PdfDrawer from '@/components/pdf-drawer';
|
| 15 |
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
|
| 16 |
import { useFetchFlowSSE } from '@/hooks/flow-hooks';
|
|
|
|
| 17 |
import styles from './index.less';
|
| 18 |
|
| 19 |
const ChatContainer = () => {
|
|
@@ -54,7 +55,7 @@ const ChatContainer = () => {
|
|
| 54 |
{derivedMessages?.map((message, i) => {
|
| 55 |
return (
|
| 56 |
<MessageItem
|
| 57 |
-
key={message
|
| 58 |
avatardialog={avatarData?.avatar}
|
| 59 |
item={message}
|
| 60 |
nickname="You"
|
|
|
|
| 14 |
import PdfDrawer from '@/components/pdf-drawer';
|
| 15 |
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
|
| 16 |
import { useFetchFlowSSE } from '@/hooks/flow-hooks';
|
| 17 |
+
import { buildMessageUuidWithRole } from '@/utils/chat';
|
| 18 |
import styles from './index.less';
|
| 19 |
|
| 20 |
const ChatContainer = () => {
|
|
|
|
| 55 |
{derivedMessages?.map((message, i) => {
|
| 56 |
return (
|
| 57 |
<MessageItem
|
| 58 |
+
key={buildMessageUuidWithRole(message)}
|
| 59 |
avatardialog={avatarData?.avatar}
|
| 60 |
item={message}
|
| 61 |
nickname="You"
|
web/src/pages/flow/chat/box.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import PdfDrawer from '@/components/pdf-drawer';
|
|
| 11 |
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
| 12 |
import { useFetchFlow } from '@/hooks/flow-hooks';
|
| 13 |
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
|
|
|
| 14 |
import styles from './index.less';
|
| 15 |
|
| 16 |
const FlowChatBox = () => {
|
|
@@ -46,7 +47,7 @@ const FlowChatBox = () => {
|
|
| 46 |
sendLoading &&
|
| 47 |
derivedMessages.length - 1 === i
|
| 48 |
}
|
| 49 |
-
key={message
|
| 50 |
nickname={userInfo.nickname}
|
| 51 |
avatar={userInfo.avatar}
|
| 52 |
avatardialog={cavasInfo.avatar}
|
|
|
|
| 11 |
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
| 12 |
import { useFetchFlow } from '@/hooks/flow-hooks';
|
| 13 |
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
| 14 |
+
import { buildMessageUuidWithRole } from '@/utils/chat';
|
| 15 |
import styles from './index.less';
|
| 16 |
|
| 17 |
const FlowChatBox = () => {
|
|
|
|
| 47 |
sendLoading &&
|
| 48 |
derivedMessages.length - 1 === i
|
| 49 |
}
|
| 50 |
+
key={buildMessageUuidWithRole(message)}
|
| 51 |
nickname={userInfo.nickname}
|
| 52 |
avatar={userInfo.avatar}
|
| 53 |
avatardialog={cavasInfo.avatar}
|
web/src/utils/chat.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { EmptyConversationId
|
| 2 |
import { Message } from '@/interfaces/database/chat';
|
| 3 |
import { IMessage } from '@/pages/chat/interface';
|
| 4 |
import { omit } from 'lodash';
|
|
@@ -10,21 +10,11 @@ export const isConversationIdExist = (conversationId: string) => {
|
|
| 10 |
|
| 11 |
export const buildMessageUuid = (message: Partial<Message | IMessage>) => {
|
| 12 |
if ('id' in message && message.id) {
|
| 13 |
-
return message.
|
| 14 |
-
? `${MessageType.User}_${message.id}`
|
| 15 |
-
: `${MessageType.Assistant}_${message.id}`;
|
| 16 |
}
|
| 17 |
return uuid();
|
| 18 |
};
|
| 19 |
|
| 20 |
-
export const getMessagePureId = (id?: string) => {
|
| 21 |
-
const strings = id?.split('_') ?? [];
|
| 22 |
-
if (strings.length > 0) {
|
| 23 |
-
return strings.at(-1);
|
| 24 |
-
}
|
| 25 |
-
return id;
|
| 26 |
-
};
|
| 27 |
-
|
| 28 |
export const buildMessageListWithUuid = (messages?: Message[]) => {
|
| 29 |
return (
|
| 30 |
messages?.map((x: Message | IMessage) => ({
|
|
@@ -37,3 +27,10 @@ export const buildMessageListWithUuid = (messages?: Message[]) => {
|
|
| 37 |
export const getConversationId = () => {
|
| 38 |
return uuid().replace(/-/g, '');
|
| 39 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { EmptyConversationId } from '@/constants/chat';
|
| 2 |
import { Message } from '@/interfaces/database/chat';
|
| 3 |
import { IMessage } from '@/pages/chat/interface';
|
| 4 |
import { omit } from 'lodash';
|
|
|
|
| 10 |
|
| 11 |
export const buildMessageUuid = (message: Partial<Message | IMessage>) => {
|
| 12 |
if ('id' in message && message.id) {
|
| 13 |
+
return message.id;
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
return uuid();
|
| 16 |
};
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
export const buildMessageListWithUuid = (messages?: Message[]) => {
|
| 19 |
return (
|
| 20 |
messages?.map((x: Message | IMessage) => ({
|
|
|
|
| 27 |
export const getConversationId = () => {
|
| 28 |
return uuid().replace(/-/g, '');
|
| 29 |
};
|
| 30 |
+
|
| 31 |
+
// When rendering each message, add a prefix to the id to ensure uniqueness.
|
| 32 |
+
export const buildMessageUuidWithRole = (
|
| 33 |
+
message: Partial<Message | IMessage>,
|
| 34 |
+
) => {
|
| 35 |
+
return `${message.role}_${message.id}`;
|
| 36 |
+
};
|