feat: rename conversation

This commit is contained in:
billchen 2024-02-28 16:25:06 +08:00
parent 627f2ed0c7
commit c5df762558
6 changed files with 198 additions and 19 deletions

View file

@ -0,0 +1,78 @@
import { Form, Input, Modal } from 'antd';
import { useEffect } from 'react';
import { IModalManagerChildrenProps } from '../modal-manager';
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
loading: boolean;
initialName: string;
onOk: (name: string) => void;
showModal?(): void;
}
const RenameModal = ({
visible,
hideModal,
loading,
initialName,
onOk,
}: IProps) => {
const [form] = Form.useForm();
type FieldType = {
name?: string;
};
const handleOk = async () => {
const ret = await form.validateFields();
return onOk(ret.name);
};
const handleCancel = () => {
hideModal();
};
const onFinish = (values: any) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
useEffect(() => {
form.setFieldValue('name', initialName);
}, [initialName, form]);
return (
<Modal
title="Rename"
open={visible}
onOk={handleOk}
onCancel={handleCancel}
okButtonProps={{ loading }}
confirmLoading={loading}
>
<Form
name="basic"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ maxWidth: 600 }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
form={form}
>
<Form.Item<FieldType>
label="Name"
name="name"
rules={[{ required: true, message: 'Please input name!' }]}
>
<Input />
</Form.Item>
</Form>
</Modal>
);
};
export default RenameModal;

View file

@ -8,7 +8,7 @@ import classNames from 'classnames';
import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
import reactStringReplace from 'react-string-replace';
import {
useFetchConversation,
useFetchConversationOnMount,
useGetFileIcon,
useScrollToBottom,
useSendMessage,
@ -187,7 +187,7 @@ const MessageItem = ({
const ChatContainer = () => {
const [value, setValue] = useState('');
const conversation: IClientConversation = useFetchConversation();
const conversation: IClientConversation = useFetchConversationOnMount();
const { sendMessage } = useSendMessage();
const loading = useOneNamespaceEffectsLoading('chatModel', [
'completeConversation',

View file

@ -1,6 +1,8 @@
import showDeleteConfirm from '@/components/deleting-confirm';
import { MessageType } from '@/constants/chat';
import { fileIconMap } from '@/constants/common';
import { useSetModalState } from '@/hooks/commonHooks';
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
import { IConversation, IDialog } from '@/interfaces/database/chat';
import { getFileExtension } from '@/utils';
import omit from 'lodash/omit';
@ -14,7 +16,7 @@ import {
VariableTableDataType,
} from './interface';
import { ChatModelState } from './model';
import { isConversationIdNotExist } from './utils';
import { isConversationIdExist } from './utils';
export const useFetchDialogList = () => {
const dispatch = useDispatch();
@ -392,30 +394,50 @@ export const useSetConversation = () => {
return { setConversation };
};
export const useFetchConversation = () => {
const dispatch = useDispatch();
const { conversationId } = useGetChatSearchParams();
const conversation = useSelector(
export const useSelectCurrentConversation = () => {
const conversation: IClientConversation = useSelector(
(state: any) => state.chatModel.currentConversation,
);
const setCurrentConversation = useSetCurrentConversation();
const fetchConversation = useCallback(() => {
if (isConversationIdNotExist(conversationId)) {
dispatch({
return conversation;
};
export const useFetchConversation = () => {
const dispatch = useDispatch();
const fetchConversation = useCallback(
(conversationId: string, needToBeSaved = true) => {
return dispatch<any>({
type: 'chatModel/getConversation',
payload: {
needToBeSaved,
conversation_id: conversationId,
},
});
},
[dispatch],
);
return fetchConversation;
};
export const useFetchConversationOnMount = () => {
const { conversationId } = useGetChatSearchParams();
const conversation = useSelectCurrentConversation();
const setCurrentConversation = useSetCurrentConversation();
const fetchConversation = useFetchConversation();
const fetchConversationOnMount = useCallback(() => {
if (isConversationIdExist(conversationId)) {
fetchConversation(conversationId);
} else {
setCurrentConversation({} as IClientConversation);
}
}, [dispatch, conversationId, setCurrentConversation]);
}, [fetchConversation, setCurrentConversation, conversationId]);
useEffect(() => {
fetchConversation();
}, [fetchConversation]);
fetchConversationOnMount();
}, [fetchConversationOnMount]);
return conversation;
};
@ -522,4 +544,56 @@ export const useRemoveConversation = () => {
return { onRemoveConversation };
};
export const useRenameConversation = () => {
const dispatch = useDispatch();
const [conversation, setConversation] = useState<IClientConversation>(
{} as IClientConversation,
);
const fetchConversation = useFetchConversation();
const {
visible: conversationRenameVisible,
hideModal: hideConversationRenameModal,
showModal: showConversationRenameModal,
} = useSetModalState();
const onConversationRenameOk = useCallback(
async (name: string) => {
const ret = await dispatch<any>({
type: 'chatModel/setConversation',
payload: { ...conversation, conversation_id: conversation.id, name },
});
if (ret.retcode === 0) {
hideConversationRenameModal();
}
},
[dispatch, conversation, hideConversationRenameModal],
);
const loading = useOneNamespaceEffectsLoading('chatModel', [
'setConversation',
]);
const handleShowConversationRenameModal = useCallback(
async (conversationId: string) => {
const ret = await fetchConversation(conversationId, false);
if (ret.retcode === 0) {
setConversation(ret.data);
}
showConversationRenameModal();
},
[showConversationRenameModal, fetchConversation],
);
return {
conversationRenameLoading: loading,
initialConversationName: conversation.name,
onConversationRenameOk,
conversationRenameVisible,
hideConversationRenameModal,
showConversationRenameModal: handleShowConversationRenameModal,
};
};
//#endregion

View file

@ -25,11 +25,13 @@ import {
useHandleItemHover,
useRemoveConversation,
useRemoveDialog,
useRenameConversation,
useSelectConversationList,
useSelectFirstDialogOnMount,
useSetCurrentDialog,
} from './hooks';
import RenameModal from '@/components/rename-modal';
import styles from './index.less';
const Chat = () => {
@ -49,6 +51,14 @@ const Chat = () => {
handleItemEnter: handleConversationItemEnter,
handleItemLeave: handleConversationItemLeave,
} = useHandleItemHover();
const {
conversationRenameLoading,
initialConversationName,
onConversationRenameOk,
conversationRenameVisible,
hideConversationRenameModal,
showConversationRenameModal,
} = useRenameConversation();
useFetchDialog(dialogId, true);
@ -87,6 +97,14 @@ const Chat = () => {
onRemoveConversation([conversationId]);
};
const handleShowConversationRenameModal =
(conversationId: string): MenuItemProps['onClick'] =>
({ domEvent }) => {
domEvent.preventDefault();
domEvent.stopPropagation();
showConversationRenameModal(conversationId);
};
const handleDialogCardClick = (dialogId: string) => () => {
handleClickDialog(dialogId);
};
@ -143,7 +161,7 @@ const Chat = () => {
const appItems: MenuProps['items'] = [
{
key: '1',
onClick: handleShowChatConfigurationModal(conversationId),
onClick: handleShowConversationRenameModal(conversationId),
label: (
<Space>
<EditOutlined />
@ -262,6 +280,13 @@ const Chat = () => {
hideModal={hideModal}
id={currentDialog.id}
></ChatConfigurationModal>
<RenameModal
visible={conversationRenameVisible}
hideModal={hideConversationRenameModal}
onOk={onConversationRenameOk}
initialName={initialConversationName}
loading={conversationRenameLoading}
></RenameModal>
</Flex>
);
};

View file

@ -110,8 +110,10 @@ const model: DvaModel<ChatModelState> = {
return data.retcode;
},
*getConversation({ payload }, { call, put }) {
const { data } = yield call(chatService.getConversation, payload);
if (data.retcode === 0) {
const { data } = yield call(chatService.getConversation, {
conversation_id: payload.conversation_id,
});
if (data.retcode === 0 && payload.needToBeSaved) {
yield put({
type: 'kFModel/fetch_document_thumbnails',
payload: {
@ -120,7 +122,7 @@ const model: DvaModel<ChatModelState> = {
});
yield put({ type: 'setCurrentConversation', payload: data.data });
}
return data.retcode;
return data;
},
*setConversation({ payload }, { call, put }) {
const { data } = yield call(chatService.setConversation, payload);

View file

@ -12,7 +12,7 @@ export const excludeUnEnabledVariables = (values: any) => {
);
};
export const isConversationIdNotExist = (conversationId: string) => {
export const isConversationIdExist = (conversationId: string) => {
return conversationId !== EmptyConversationId && conversationId !== '';
};