feat: Delete message by id #2088 (#2155)

### What problem does this PR solve?

feat: Delete message by id #2088

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-08-29 14:32:04 +08:00 committed by GitHub
parent f87e7242cd
commit f8a479bf88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 84 additions and 9 deletions

View File

@ -1,5 +1,6 @@
import CopyToClipboard from '@/components/copy-to-clipboard'; import CopyToClipboard from '@/components/copy-to-clipboard';
import { useSetModalState } from '@/hooks/common-hooks'; import { useSetModalState } from '@/hooks/common-hooks';
import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { import {
DeleteOutlined, DeleteOutlined,
DislikeOutlined, DislikeOutlined,
@ -11,7 +12,7 @@ import { Radio } from 'antd';
import { useCallback } from 'react'; import { useCallback } from 'react';
import SvgIcon from '../svg-icon'; import SvgIcon from '../svg-icon';
import FeedbackModal from './feedback-modal'; import FeedbackModal from './feedback-modal';
import { useSendFeedback } from './hooks'; import { useRemoveMessage, useSendFeedback } from './hooks';
import PromptModal from './prompt-modal'; import PromptModal from './prompt-modal';
interface IProps { interface IProps {
@ -77,12 +78,20 @@ export const AssistantGroupButton = ({
); );
}; };
interface UserGroupButtonProps { interface UserGroupButtonProps extends IRemoveMessageById {
messageId: string; messageId: string;
content: string; content: string;
} }
export const UserGroupButton = ({ content }: UserGroupButtonProps) => { export const UserGroupButton = ({
content,
messageId,
removeMessageById,
}: UserGroupButtonProps) => {
const { onRemoveMessage, loading } = useRemoveMessage(
messageId,
removeMessageById,
);
return ( return (
<Radio.Group size="small"> <Radio.Group size="small">
<Radio.Button value="a"> <Radio.Button value="a">
@ -91,8 +100,8 @@ export const UserGroupButton = ({ content }: UserGroupButtonProps) => {
<Radio.Button value="b"> <Radio.Button value="b">
<SyncOutlined /> <SyncOutlined />
</Radio.Button> </Radio.Button>
<Radio.Button value="c"> <Radio.Button value="c" onClick={onRemoveMessage} disabled={loading}>
<DeleteOutlined /> <DeleteOutlined spin={loading} />
</Radio.Button> </Radio.Button>
</Radio.Group> </Radio.Group>
); );

View File

@ -1,5 +1,6 @@
import { useFeedback } from '@/hooks/chat-hooks'; import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
import { useSetModalState } from '@/hooks/common-hooks'; import { useSetModalState } from '@/hooks/common-hooks';
import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { IFeedbackRequestBody } from '@/interfaces/request/chat'; import { IFeedbackRequestBody } from '@/interfaces/request/chat';
import { getMessagePureId } from '@/utils/chat'; import { getMessagePureId } from '@/utils/chat';
import { useCallback } from 'react'; import { useCallback } from 'react';
@ -30,3 +31,22 @@ export const useSendFeedback = (messageId: string) => {
showModal, 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 };
};

View File

@ -11,6 +11,7 @@ import {
useFetchDocumentInfosByIds, useFetchDocumentInfosByIds,
useFetchDocumentThumbnailsByIds, useFetchDocumentThumbnailsByIds,
} from '@/hooks/document-hooks'; } from '@/hooks/document-hooks';
import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { IMessage } from '@/pages/chat/interface'; import { IMessage } from '@/pages/chat/interface';
import MarkdownContent from '@/pages/chat/markdown-content'; import MarkdownContent from '@/pages/chat/markdown-content';
import { getExtension, isImage } from '@/utils/document-util'; import { getExtension, isImage } from '@/utils/document-util';
@ -23,7 +24,7 @@ import styles from './index.less';
const { Text } = Typography; const { Text } = Typography;
interface IProps { interface IProps extends IRemoveMessageById {
item: IMessage; item: IMessage;
reference: IReference; reference: IReference;
loading?: boolean; loading?: boolean;
@ -40,6 +41,7 @@ const MessageItem = ({
avatar = '', avatar = '',
clickDocumentButton, clickDocumentButton,
index, index,
removeMessageById,
}: IProps) => { }: IProps) => {
const isAssistant = item.role === MessageType.Assistant; const isAssistant = item.role === MessageType.Assistant;
const isUser = item.role === MessageType.User; const isUser = item.role === MessageType.User;
@ -125,6 +127,7 @@ const MessageItem = ({
<UserGroupButton <UserGroupButton
content={item.content} content={item.content}
messageId={item.id} messageId={item.id}
removeMessageById={removeMessageById}
></UserGroupButton> ></UserGroupButton>
)} )}

View File

@ -314,6 +314,10 @@ export const useDeleteMessage = () => {
conversationId, conversationId,
}); });
if (data.retcode === 0) {
message.success(i18n.t(`message.deleted`));
}
return data.retcode; return data.retcode;
}, },
}); });

View File

@ -5,8 +5,10 @@ import { ResponseType } from '@/interfaces/database/base';
import { IAnswer } from '@/interfaces/database/chat'; import { IAnswer } from '@/interfaces/database/chat';
import { IKnowledgeFile } from '@/interfaces/database/knowledge'; import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document'; import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
import { IClientConversation } from '@/pages/chat/interface';
import api from '@/utils/api'; import api from '@/utils/api';
import { getAuthorization } from '@/utils/authorization-util'; import { getAuthorization } from '@/utils/authorization-util';
import { getMessagePureId } from '@/utils/chat';
import { PaginationProps } from 'antd'; import { PaginationProps } from 'antd';
import { FormInstance } from 'antd/lib'; import { FormInstance } from 'antd/lib';
import axios from 'axios'; 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 // #endregion
/** /**

View File

@ -27,6 +27,7 @@ const ChatContainer = () => {
addNewestAnswer, addNewestAnswer,
conversationId, conversationId,
loading, loading,
removeMessageById,
} = useFetchConversationOnMount(); } = useFetchConversationOnMount();
const { const {
handleInputChange, handleInputChange,
@ -69,6 +70,7 @@ const ChatContainer = () => {
reference={buildMessageItemReference(conversation, message)} reference={buildMessageItemReference(conversation, message)}
clickDocumentButton={clickDocumentButton} clickDocumentButton={clickDocumentButton}
index={i} index={i}
removeMessageById={removeMessageById}
></MessageItem> ></MessageItem>
); );
})} })}

View File

@ -17,7 +17,10 @@ import {
useShowDeleteConfirm, useShowDeleteConfirm,
useTranslate, useTranslate,
} from '@/hooks/common-hooks'; } from '@/hooks/common-hooks';
import { useSendMessageWithSse } from '@/hooks/logic-hooks'; import {
useRemoveMessageById,
useSendMessageWithSse,
} from '@/hooks/logic-hooks';
import { import {
IAnswer, IAnswer,
IConversation, IConversation,
@ -251,6 +254,7 @@ export const useSelectCurrentConversation = () => {
const { data: conversation, loading } = useFetchNextConversation(); const { data: conversation, loading } = useFetchNextConversation();
const { data: dialog } = useFetchNextDialog(); const { data: dialog } = useFetchNextDialog();
const { conversationId, dialogId } = useGetChatSearchParams(); const { conversationId, dialogId } = useGetChatSearchParams();
const { removeMessageById } = useRemoveMessageById(setCurrentConversation);
// Show the entered message in the conversation immediately after sending the message // Show the entered message in the conversation immediately after sending the message
const addNewestConversation = useCallback( const addNewestConversation = useCallback(
@ -348,6 +352,7 @@ export const useSelectCurrentConversation = () => {
addNewestConversation, addNewestConversation,
removeLatestMessage, removeLatestMessage,
addNewestAnswer, addNewestAnswer,
removeMessageById,
loading, loading,
}; };
}; };
@ -376,6 +381,7 @@ export const useFetchConversationOnMount = () => {
removeLatestMessage, removeLatestMessage,
addNewestAnswer, addNewestAnswer,
loading, loading,
removeMessageById,
} = useSelectCurrentConversation(); } = useSelectCurrentConversation();
const ref = useScrollToBottom(currentConversation); const ref = useScrollToBottom(currentConversation);
@ -387,6 +393,7 @@ export const useFetchConversationOnMount = () => {
addNewestAnswer, addNewestAnswer,
conversationId, conversationId,
loading, loading,
removeMessageById,
}; };
}; };
@ -408,7 +415,7 @@ export const useHandleMessageInputChange = () => {
export const useSendMessage = ( export const useSendMessage = (
conversation: IClientConversation, conversation: IClientConversation,
addNewestConversation: (message: Partial<Message>, answer?: string) => void, addNewestConversation: (message: Message, answer?: string) => void,
removeLatestMessage: () => void, removeLatestMessage: () => void,
addNewestAnswer: (answer: IAnswer) => void, addNewestAnswer: (answer: IAnswer) => void,
) => { ) => {