balibabu
Fixed an issue where refreshing the login page caused the language settings to become invalid. #249 (#250)
5769711
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg'; | |
import RenameModal from '@/components/rename-modal'; | |
import { DeleteOutlined, EditOutlined, FormOutlined } from '@ant-design/icons'; | |
import { | |
Avatar, | |
Button, | |
Card, | |
Divider, | |
Dropdown, | |
Flex, | |
MenuProps, | |
Space, | |
Spin, | |
Tag, | |
} from 'antd'; | |
import { MenuItemProps } from 'antd/lib/menu/MenuItem'; | |
import classNames from 'classnames'; | |
import { useCallback } from 'react'; | |
import ChatConfigurationModal from './chat-configuration-modal'; | |
import ChatContainer from './chat-container'; | |
import { | |
useClickConversationCard, | |
useClickDialogCard, | |
useEditDialog, | |
useFetchConversationList, | |
useFetchDialogOnMount, | |
useGetChatSearchParams, | |
useHandleItemHover, | |
useRemoveConversation, | |
useRemoveDialog, | |
useRenameConversation, | |
useSelectConversationList, | |
useSelectConversationListLoading, | |
useSelectDialogListLoading, | |
useSelectFirstDialogOnMount, | |
} from './hooks'; | |
import { useTranslate } from '@/hooks/commonHooks'; | |
import styles from './index.less'; | |
const Chat = () => { | |
const dialogList = useSelectFirstDialogOnMount(); | |
const { onRemoveDialog } = useRemoveDialog(); | |
const { onRemoveConversation } = useRemoveConversation(); | |
const { handleClickDialog } = useClickDialogCard(); | |
const { handleClickConversation } = useClickConversationCard(); | |
const { dialogId, conversationId } = useGetChatSearchParams(); | |
const { list: conversationList, addTemporaryConversation } = | |
useSelectConversationList(); | |
const { activated, handleItemEnter, handleItemLeave } = useHandleItemHover(); | |
const { | |
activated: conversationActivated, | |
handleItemEnter: handleConversationItemEnter, | |
handleItemLeave: handleConversationItemLeave, | |
} = useHandleItemHover(); | |
const { | |
conversationRenameLoading, | |
initialConversationName, | |
onConversationRenameOk, | |
conversationRenameVisible, | |
hideConversationRenameModal, | |
showConversationRenameModal, | |
} = useRenameConversation(); | |
const { | |
dialogSettingLoading, | |
initialDialog, | |
onDialogEditOk, | |
dialogEditVisible, | |
clearDialog, | |
hideDialogEditModal, | |
showDialogEditModal, | |
} = useEditDialog(); | |
const dialogLoading = useSelectDialogListLoading(); | |
const conversationLoading = useSelectConversationListLoading(); | |
const { t } = useTranslate('chat'); | |
useFetchDialogOnMount(dialogId, true); | |
const handleAppCardEnter = (id: string) => () => { | |
handleItemEnter(id); | |
}; | |
const handleConversationCardEnter = (id: string) => () => { | |
handleConversationItemEnter(id); | |
}; | |
const handleShowChatConfigurationModal = | |
(dialogId?: string): any => | |
(info: any) => { | |
info?.domEvent?.preventDefault(); | |
info?.domEvent?.stopPropagation(); | |
showDialogEditModal(dialogId); | |
}; | |
const handleRemoveDialog = | |
(dialogId: string): MenuItemProps['onClick'] => | |
({ domEvent }) => { | |
domEvent.preventDefault(); | |
domEvent.stopPropagation(); | |
onRemoveDialog([dialogId]); | |
}; | |
const handleRemoveConversation = | |
(conversationId: string): MenuItemProps['onClick'] => | |
({ domEvent }) => { | |
domEvent.preventDefault(); | |
domEvent.stopPropagation(); | |
onRemoveConversation([conversationId]); | |
}; | |
const handleShowConversationRenameModal = | |
(conversationId: string): MenuItemProps['onClick'] => | |
({ domEvent }) => { | |
domEvent.preventDefault(); | |
domEvent.stopPropagation(); | |
showConversationRenameModal(conversationId); | |
}; | |
const handleDialogCardClick = (dialogId: string) => () => { | |
handleClickDialog(dialogId); | |
}; | |
const handleConversationCardClick = (dialogId: string) => () => { | |
handleClickConversation(dialogId); | |
}; | |
const handleCreateTemporaryConversation = useCallback(() => { | |
addTemporaryConversation(); | |
}, [addTemporaryConversation]); | |
const items: MenuProps['items'] = [ | |
{ | |
key: '1', | |
onClick: handleCreateTemporaryConversation, | |
label: ( | |
<Space> | |
<EditOutlined /> | |
{t('newChat')} | |
</Space> | |
), | |
}, | |
]; | |
const buildAppItems = (dialogId: string) => { | |
const appItems: MenuProps['items'] = [ | |
{ | |
key: '1', | |
onClick: handleShowChatConfigurationModal(dialogId), | |
label: ( | |
<Space> | |
<EditOutlined /> | |
{t('edit', { keyPrefix: 'common' })} | |
</Space> | |
), | |
}, | |
{ type: 'divider' }, | |
{ | |
key: '2', | |
onClick: handleRemoveDialog(dialogId), | |
label: ( | |
<Space> | |
<DeleteOutlined /> | |
{t('delete', { keyPrefix: 'common' })} | |
</Space> | |
), | |
}, | |
]; | |
return appItems; | |
}; | |
const buildConversationItems = (conversationId: string) => { | |
const appItems: MenuProps['items'] = [ | |
{ | |
key: '1', | |
onClick: handleShowConversationRenameModal(conversationId), | |
label: ( | |
<Space> | |
<EditOutlined /> | |
Edit | |
</Space> | |
), | |
}, | |
{ type: 'divider' }, | |
{ | |
key: '2', | |
onClick: handleRemoveConversation(conversationId), | |
label: ( | |
<Space> | |
<DeleteOutlined /> | |
Delete chat | |
</Space> | |
), | |
}, | |
]; | |
return appItems; | |
}; | |
useFetchConversationList(); | |
return ( | |
<Flex className={styles.chatWrapper}> | |
<Flex className={styles.chatAppWrapper}> | |
<Flex flex={1} vertical> | |
<Button type="primary" onClick={handleShowChatConfigurationModal()}> | |
{t('createAssistant')} | |
</Button> | |
<Divider></Divider> | |
<Flex className={styles.chatAppContent} vertical gap={10}> | |
<Spin spinning={dialogLoading} wrapperClassName={styles.chatSpin}> | |
{dialogList.map((x) => ( | |
<Card | |
key={x.id} | |
hoverable | |
className={classNames(styles.chatAppCard, { | |
[styles.chatAppCardSelected]: dialogId === x.id, | |
})} | |
onMouseEnter={handleAppCardEnter(x.id)} | |
onMouseLeave={handleItemLeave} | |
onClick={handleDialogCardClick(x.id)} | |
> | |
<Flex justify="space-between" align="center"> | |
<Space size={15}> | |
<Avatar src={x.icon} shape={'square'} /> | |
<section> | |
<b>{x.name}</b> | |
<div>{x.description}</div> | |
</section> | |
</Space> | |
{activated === x.id && ( | |
<section> | |
<Dropdown menu={{ items: buildAppItems(x.id) }}> | |
<ChatAppCube | |
className={styles.cubeIcon} | |
></ChatAppCube> | |
</Dropdown> | |
</section> | |
)} | |
</Flex> | |
</Card> | |
))} | |
</Spin> | |
</Flex> | |
</Flex> | |
</Flex> | |
<Divider type={'vertical'} className={styles.divider}></Divider> | |
<Flex className={styles.chatTitleWrapper}> | |
<Flex flex={1} vertical> | |
<Flex | |
justify={'space-between'} | |
align="center" | |
className={styles.chatTitle} | |
> | |
<Space> | |
<b>{t('chat')}</b> | |
<Tag>{conversationList.length}</Tag> | |
</Space> | |
<Dropdown menu={{ items }}> | |
<FormOutlined /> | |
</Dropdown> | |
</Flex> | |
<Divider></Divider> | |
<Flex vertical gap={10} className={styles.chatTitleContent}> | |
<Spin | |
spinning={conversationLoading} | |
wrapperClassName={styles.chatSpin} | |
> | |
{conversationList.map((x) => ( | |
<Card | |
key={x.id} | |
hoverable | |
onClick={handleConversationCardClick(x.id)} | |
onMouseEnter={handleConversationCardEnter(x.id)} | |
onMouseLeave={handleConversationItemLeave} | |
className={classNames(styles.chatTitleCard, { | |
[styles.chatTitleCardSelected]: x.id === conversationId, | |
})} | |
> | |
<Flex justify="space-between" align="center"> | |
<div>{x.name}</div> | |
{conversationActivated === x.id && x.id !== '' && ( | |
<section> | |
<Dropdown | |
menu={{ items: buildConversationItems(x.id) }} | |
> | |
<ChatAppCube | |
className={styles.cubeIcon} | |
></ChatAppCube> | |
</Dropdown> | |
</section> | |
)} | |
</Flex> | |
</Card> | |
))} | |
</Spin> | |
</Flex> | |
</Flex> | |
</Flex> | |
<Divider type={'vertical'} className={styles.divider}></Divider> | |
<ChatContainer></ChatContainer> | |
<ChatConfigurationModal | |
visible={dialogEditVisible} | |
initialDialog={initialDialog} | |
showModal={showDialogEditModal} | |
hideModal={hideDialogEditModal} | |
loading={dialogSettingLoading} | |
onOk={onDialogEditOk} | |
clearDialog={clearDialog} | |
></ChatConfigurationModal> | |
<RenameModal | |
visible={conversationRenameVisible} | |
hideModal={hideConversationRenameModal} | |
onOk={onConversationRenameOk} | |
initialName={initialConversationName} | |
loading={conversationRenameLoading} | |
></RenameModal> | |
</Flex> | |
); | |
}; | |
export default Chat; | |