diff --git a/web/src/components/message-item/group-button.tsx b/web/src/components/message-item/group-button.tsx
index 4a253771c..1884f9e70 100644
--- a/web/src/components/message-item/group-button.tsx
+++ b/web/src/components/message-item/group-button.tsx
@@ -1,5 +1,6 @@
import CopyToClipboard from '@/components/copy-to-clipboard';
import { useSetModalState } from '@/hooks/common-hooks';
+import { IRemoveMessageById } from '@/hooks/logic-hooks';
import {
DeleteOutlined,
DislikeOutlined,
@@ -11,7 +12,7 @@ import { Radio } from 'antd';
import { useCallback } from 'react';
import SvgIcon from '../svg-icon';
import FeedbackModal from './feedback-modal';
-import { useSendFeedback } from './hooks';
+import { useRemoveMessage, useSendFeedback } from './hooks';
import PromptModal from './prompt-modal';
interface IProps {
@@ -77,12 +78,20 @@ export const AssistantGroupButton = ({
);
};
-interface UserGroupButtonProps {
+interface UserGroupButtonProps extends IRemoveMessageById {
messageId: string;
content: string;
}
-export const UserGroupButton = ({ content }: UserGroupButtonProps) => {
+export const UserGroupButton = ({
+ content,
+ messageId,
+ removeMessageById,
+}: UserGroupButtonProps) => {
+ const { onRemoveMessage, loading } = useRemoveMessage(
+ messageId,
+ removeMessageById,
+ );
return (
@@ -91,8 +100,8 @@ export const UserGroupButton = ({ content }: UserGroupButtonProps) => {
-
-
+
+
);
diff --git a/web/src/components/message-item/hooks.ts b/web/src/components/message-item/hooks.ts
index c9023bc6c..700922570 100644
--- a/web/src/components/message-item/hooks.ts
+++ b/web/src/components/message-item/hooks.ts
@@ -1,5 +1,6 @@
-import { useFeedback } from '@/hooks/chat-hooks';
+import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
import { useSetModalState } from '@/hooks/common-hooks';
+import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
import { getMessagePureId } from '@/utils/chat';
import { useCallback } from 'react';
@@ -30,3 +31,22 @@ export const useSendFeedback = (messageId: string) => {
showModal,
};
};
+
+export const useRemoveMessage = (
+ messageId: string,
+ removeMessageById: IRemoveMessageById['removeMessageById'],
+) => {
+ const { deleteMessage, loading } = useDeleteMessage();
+
+ const onRemoveMessage = useCallback(async () => {
+ const pureId = getMessagePureId(messageId);
+ if (pureId) {
+ const retcode = await deleteMessage(pureId);
+ if (retcode === 0) {
+ removeMessageById(messageId);
+ }
+ }
+ }, [deleteMessage, messageId, removeMessageById]);
+
+ return { onRemoveMessage, loading };
+};
diff --git a/web/src/components/message-item/index.tsx b/web/src/components/message-item/index.tsx
index 99dfa31d2..873445d4c 100644
--- a/web/src/components/message-item/index.tsx
+++ b/web/src/components/message-item/index.tsx
@@ -11,6 +11,7 @@ import {
useFetchDocumentInfosByIds,
useFetchDocumentThumbnailsByIds,
} from '@/hooks/document-hooks';
+import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { IMessage } from '@/pages/chat/interface';
import MarkdownContent from '@/pages/chat/markdown-content';
import { getExtension, isImage } from '@/utils/document-util';
@@ -23,7 +24,7 @@ import styles from './index.less';
const { Text } = Typography;
-interface IProps {
+interface IProps extends IRemoveMessageById {
item: IMessage;
reference: IReference;
loading?: boolean;
@@ -40,6 +41,7 @@ const MessageItem = ({
avatar = '',
clickDocumentButton,
index,
+ removeMessageById,
}: IProps) => {
const isAssistant = item.role === MessageType.Assistant;
const isUser = item.role === MessageType.User;
@@ -125,6 +127,7 @@ const MessageItem = ({
)}
diff --git a/web/src/hooks/chat-hooks.ts b/web/src/hooks/chat-hooks.ts
index 452c80a31..0439c8763 100644
--- a/web/src/hooks/chat-hooks.ts
+++ b/web/src/hooks/chat-hooks.ts
@@ -314,6 +314,10 @@ export const useDeleteMessage = () => {
conversationId,
});
+ if (data.retcode === 0) {
+ message.success(i18n.t(`message.deleted`));
+ }
+
return data.retcode;
},
});
diff --git a/web/src/hooks/logic-hooks.ts b/web/src/hooks/logic-hooks.ts
index 7c0b66e75..d4e43f757 100644
--- a/web/src/hooks/logic-hooks.ts
+++ b/web/src/hooks/logic-hooks.ts
@@ -5,8 +5,10 @@ import { ResponseType } from '@/interfaces/database/base';
import { IAnswer } from '@/interfaces/database/chat';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
+import { IClientConversation } from '@/pages/chat/interface';
import api from '@/utils/api';
import { getAuthorization } from '@/utils/authorization-util';
+import { getMessagePureId } from '@/utils/chat';
import { PaginationProps } from 'antd';
import { FormInstance } from 'antd/lib';
import axios from 'axios';
@@ -306,6 +308,34 @@ export const useHandleMessageInputChange = () => {
};
};
+export interface IRemoveMessageById {
+ removeMessageById(messageId: string): void;
+}
+
+export const useRemoveMessageById = (
+ setCurrentConversation: (
+ callback: (state: IClientConversation) => IClientConversation,
+ ) => void,
+) => {
+ const removeMessageById = useCallback(
+ (messageId: string) => {
+ setCurrentConversation((pre) => {
+ const nextMessages =
+ pre.message?.filter(
+ (x) => getMessagePureId(x.id) !== getMessagePureId(messageId),
+ ) ?? [];
+ return {
+ ...pre,
+ message: nextMessages,
+ };
+ });
+ },
+ [setCurrentConversation],
+ );
+
+ return { removeMessageById };
+};
+
// #endregion
/**
diff --git a/web/src/pages/chat/chat-container/index.tsx b/web/src/pages/chat/chat-container/index.tsx
index a584bf06d..b87c64d61 100644
--- a/web/src/pages/chat/chat-container/index.tsx
+++ b/web/src/pages/chat/chat-container/index.tsx
@@ -27,6 +27,7 @@ const ChatContainer = () => {
addNewestAnswer,
conversationId,
loading,
+ removeMessageById,
} = useFetchConversationOnMount();
const {
handleInputChange,
@@ -69,6 +70,7 @@ const ChatContainer = () => {
reference={buildMessageItemReference(conversation, message)}
clickDocumentButton={clickDocumentButton}
index={i}
+ removeMessageById={removeMessageById}
>
);
})}
diff --git a/web/src/pages/chat/hooks.ts b/web/src/pages/chat/hooks.ts
index 13702b744..055336da0 100644
--- a/web/src/pages/chat/hooks.ts
+++ b/web/src/pages/chat/hooks.ts
@@ -17,7 +17,10 @@ import {
useShowDeleteConfirm,
useTranslate,
} from '@/hooks/common-hooks';
-import { useSendMessageWithSse } from '@/hooks/logic-hooks';
+import {
+ useRemoveMessageById,
+ useSendMessageWithSse,
+} from '@/hooks/logic-hooks';
import {
IAnswer,
IConversation,
@@ -251,6 +254,7 @@ export const useSelectCurrentConversation = () => {
const { data: conversation, loading } = useFetchNextConversation();
const { data: dialog } = useFetchNextDialog();
const { conversationId, dialogId } = useGetChatSearchParams();
+ const { removeMessageById } = useRemoveMessageById(setCurrentConversation);
// Show the entered message in the conversation immediately after sending the message
const addNewestConversation = useCallback(
@@ -348,6 +352,7 @@ export const useSelectCurrentConversation = () => {
addNewestConversation,
removeLatestMessage,
addNewestAnswer,
+ removeMessageById,
loading,
};
};
@@ -376,6 +381,7 @@ export const useFetchConversationOnMount = () => {
removeLatestMessage,
addNewestAnswer,
loading,
+ removeMessageById,
} = useSelectCurrentConversation();
const ref = useScrollToBottom(currentConversation);
@@ -387,6 +393,7 @@ export const useFetchConversationOnMount = () => {
addNewestAnswer,
conversationId,
loading,
+ removeMessageById,
};
};
@@ -408,7 +415,7 @@ export const useHandleMessageInputChange = () => {
export const useSendMessage = (
conversation: IClientConversation,
- addNewestConversation: (message: Partial, answer?: string) => void,
+ addNewestConversation: (message: Message, answer?: string) => void,
removeLatestMessage: () => void,
addNewestAnswer: (answer: IAnswer) => void,
) => {