feat: add text panel message search right panel

pull/147/merge
moonrailgun 1 year ago
parent 0ff8f558ef
commit 176528b303

@ -1,5 +1,4 @@
import type { DependencyList } from 'react';
import { isDevelopment, t } from '..';
import { showErrorToasts } from '../manager/ui';
import type { FunctionReturningPromise } from '../types';
import { useAsyncFn } from './useAsyncFn';

@ -84,6 +84,25 @@ export async function deleteMessage(messageId: string): Promise<boolean> {
return data;
}
/**
*
* @param converseId id
* @param messageText
*/
export async function searchMessage(
text: string,
converseId: string,
groupId?: string
): Promise<ChatMessage[]> {
const { data } = await request.post('/api/chat/message/searchMessage', {
text,
converseId,
groupId,
});
return data;
}
/**
* idid
*/

@ -70,7 +70,7 @@ export function formatShortTime(date: dayjs.ConfigType): string {
}
/**
* :
* YYYY-MM-DD HH:mm:ss
*/
export function formatFullTime(date: dayjs.ConfigType): string {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');

@ -61,8 +61,9 @@ const MessageActionIcon: React.FC<{ icon: string }> = (props) => (
/**
*
*/
const NormalMessage: React.FC<ChatMessageItemProps> = React.memo((props) => {
const { showAvatar, payload } = props;
export const NormalMessage: React.FC<ChatMessageItemProps> = React.memo(
(props) => {
const { showAvatar, payload, hideAction = false } = props;
const userInfo = useCachedUserInfo(payload.author ?? '');
const [isActionBtnActive, setIsActionBtnActive] = useState(false);
@ -77,12 +78,14 @@ const NormalMessage: React.FC<ChatMessageItemProps> = React.memo((props) => {
// 禁止对消息进行操作,因为此时消息尚未发送到远程
const disableOperate =
payload.isLocal === true || payload.sendFailed === true;
hideAction === true ||
payload.isLocal === true ||
payload.sendFailed === true;
return (
<div
className={clsx(
'chat-message-item flex px-2 mobile:px-0 group relative select-text',
'chat-message-item flex px-2 mobile:px-0 group relative select-text text-sm',
{
'bg-black bg-opacity-10': isActionBtnActive,
'hover:bg-black hover:bg-opacity-5': !isActionBtnActive,
@ -210,7 +213,8 @@ const NormalMessage: React.FC<ChatMessageItemProps> = React.memo((props) => {
)}
</div>
);
});
}
);
NormalMessage.displayName = 'NormalMessage';
/**
@ -250,6 +254,7 @@ SystemMessageWithNickname.displayName = 'SystemMessageWithNickname';
interface ChatMessageItemProps {
showAvatar: boolean;
payload: LocalChatMessage;
hideAction?: boolean;
}
const ChatMessageItem: React.FC<ChatMessageItemProps> = React.memo((props) => {
const payload = props.payload;

@ -0,0 +1,62 @@
import { NormalMessage } from '@/components/ChatBox/ChatMessageList/Item';
import { Empty, Input } from 'antd';
import React from 'react';
import {
ChatMessage,
model,
showToasts,
t,
useAsyncRequest,
} from 'tailchat-shared';
export const MessageSearchPanel: React.FC<{
groupId?: string;
converseId: string;
}> = React.memo((props) => {
const { groupId, converseId } = props;
const [{ loading, value = [] }, handleSearch] = useAsyncRequest(
async (searchText: string) => {
if (searchText.length < 3) {
showToasts(t('搜索内容太短无法搜索'));
return;
}
const messages = await model.message.searchMessage(
searchText,
converseId,
groupId
);
return messages ?? [];
}
);
const searchedMessages = value as ChatMessage[];
return (
<div className="p-2">
<Input.Search
className="mb-2"
placeholder="请输入关键字"
loading={loading}
onSearch={handleSearch}
/>
{/* Result List */}
<div>
{searchedMessages.length === 0 && (
<Empty description={t('没有任何搜索结果')} />
)}
{searchedMessages.map((message) => (
<NormalMessage
key={message._id}
showAvatar={true}
payload={message}
hideAction={true}
/>
))}
</div>
</div>
);
});
MessageSearchPanel.displayName = 'MessageSearchPanel';

@ -22,6 +22,7 @@ import {
import { useFriendNicknameMap } from 'tailchat-shared/redux/hooks/useFriendNickname';
import { MembersPanel } from './MembersPanel';
import { GroupPanelContainer } from './shared/GroupPanelContainer';
import { MessageSearchPanel } from '../common/MessageSearch';
/**
*
@ -131,6 +132,21 @@ export const TextPanel: React.FC<TextPanelProps> = React.memo(
})
}
/>,
<IconBtn
key="search"
title={t('聊天记录搜索')}
shape="square"
icon="mdi:text-search"
iconClassName="text-2xl"
onClick={() =>
setRightPanel({
name: t('聊天记录'),
panel: (
<MessageSearchPanel groupId={groupId} converseId={panelId} />
),
})
}
/>,
]}
>
<ChatInputMentionsContextProvider

@ -16,6 +16,7 @@ import { OpenedPanelTip } from '@/components/OpenedPanelTip';
import { IconBtn } from '@/components/IconBtn';
import { DMPluginPanelActionProps, pluginPanelActions } from '@/plugin/common';
import { CreateDMConverse } from '@/components/modals/CreateDMConverse';
import { MessageSearchPanel } from '../common/MessageSearch';
const ConversePanelTitle: React.FC<{ converse: ChatConverseState }> =
React.memo(({ converse }) => {
@ -135,6 +136,19 @@ export const ConversePanel: React.FC<ConversePanelProps> = React.memo(
}
/>
),
<IconBtn
key="search"
title={t('聊天记录搜索')}
shape="square"
icon="mdi:text-search"
iconClassName="text-2xl"
onClick={() =>
setRightPanel({
name: t('聊天记录'),
panel: <MessageSearchPanel converseId={converseId} />,
})
}
/>,
]);
}}
>

@ -404,6 +404,11 @@ class MessageService extends TcService {
content: {
$regex: text,
},
author: {
$not: {
$eq: SYSTEM_USERID,
},
},
})
.sort({ _id: -1 })
.limit(10)

Loading…
Cancel
Save