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: getMessagePureId(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
- const pureId = getMessagePureId(messageId);
45
- if (pureId) {
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, getMessagePureId } from '@/utils/chat';
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.id}
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.id}
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.id}
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, MessageType } from '@/constants/chat';
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.role === MessageType.User
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
+ };