feat: 增加消息撤回操作

pull/14/head
moonrailgun 3 years ago
parent 69e6453183
commit 5be90cf852

@ -23,6 +23,7 @@
"k2ec4966c": "Selected {{num}} items",
"k3172297b": "This feature is not yet open",
"k31a9d6a3": "The connect to the server is broken",
"k323b5cc7": "Recall",
"k34b5e3ab": "Send Message",
"k34e357ee": "Group Summary",
"k35abe359": "Lobby",
@ -147,6 +148,7 @@
"kd4216b7b": "Create Link",
"kd4ff36fa": "Search Friends",
"kd637a30": "Group Invite Service",
"kd983a61a": "{{nickname}} recall a message",
"kda0e155e": "Create multiplayer converse",
"kda67b115": "Unknown panel type",
"kdb57357d": "Connection failed",

@ -23,6 +23,7 @@
"k2ec4966c": "已选择 {{num}} 项",
"k3172297b": "该功能暂未开放",
"k31a9d6a3": "与服务器的链接已断开",
"k323b5cc7": "撤回",
"k34b5e3ab": "发送消息",
"k34e357ee": "群组概述",
"k35abe359": "大厅",
@ -147,6 +148,7 @@
"kd4216b7b": "创建链接",
"kd4ff36fa": "查找好友",
"kd637a30": "群组邀请服务",
"kd983a61a": "{{nickname}} 撤回了一条消息",
"kda0e155e": "创建多人会话",
"kda67b115": "未知的面板类型",
"kdb57357d": "连接失败",

@ -102,6 +102,7 @@ export {
deleteGroupPanel,
} from './model/group';
export type { GroupPanel, GroupInfo, GroupBasicInfo } from './model/group';
export { recallMessage } from './model/message';
export type { ChatMessage } from './model/message';
export type { PluginManifest } from './model/plugin';
export type { UserBaseInfo, UserLoginInfo } from './model/user';

@ -13,6 +13,8 @@ export interface ChatMessage {
reactions?: any[];
hasRecall?: boolean;
meta?: Record<string, unknown>;
createdAt?: string;
@ -61,6 +63,18 @@ export async function sendMessage(
return data;
}
/**
*
* @param messageId ID
*/
export async function recallMessage(messageId: string): Promise<ChatMessage> {
const { data } = await request.post('/api/chat/message/recallMessage', {
messageId,
});
return data;
}
/**
* idid
*/

@ -1,5 +1,6 @@
import { request } from '../api/request';
import { buildCachedRequest } from '../cache/utils';
import { SYSTEM_USERID } from '../utils/consts';
export interface UserBaseInfo {
_id: string;
@ -15,6 +16,18 @@ export interface UserLoginInfo extends UserBaseInfo {
createdAt: string;
}
// 内置用户信息
const builtinUserInfo: Record<string, UserBaseInfo> = {
[SYSTEM_USERID]: {
_id: SYSTEM_USERID,
email: 'admin@msgbyte.com',
nickname: '系统',
discriminator: '0000',
avatar: null,
temporary: false,
},
};
/**
*
*/
@ -119,6 +132,10 @@ export async function searchUserWithUniqueName(
* @param userId ID
*/
export async function fetchUserInfo(userId: string): Promise<UserBaseInfo> {
if (builtinUserInfo[userId]) {
return builtinUserInfo[userId];
}
const { data } = await request.get('/api/user/getUserInfo', {
params: {
userId,

@ -8,13 +8,17 @@ import {
t,
useCachedUserInfo,
useChatBoxContext,
MessageHelper,
recallMessage,
useAsync,
getCachedUserInfo,
useAsyncRequest,
} from 'tailchat-shared';
import { Avatar } from '@/components/Avatar';
import { useRenderPluginMessageInterpreter } from './useRenderPluginMessageInterpreter';
import { getMessageRender } from '@/plugin/common';
import { Icon } from '@iconify/react';
import { Divider, Dropdown, Menu } from 'antd';
import { MessageHelper } from 'tailchat-shared';
import { UserName } from '@/components/UserName';
import './item.less';
@ -24,6 +28,10 @@ import './item.less';
function useChatMessageItemAction(payload: ChatMessage): React.ReactElement {
const context = useChatBoxContext();
const [, handleRecallMessage] = useAsyncRequest(() => {
return recallMessage(payload._id);
}, [payload._id]);
return (
<Menu>
{context.hasContext && (
@ -31,6 +39,9 @@ function useChatMessageItemAction(payload: ChatMessage): React.ReactElement {
{t('回复')}
</Menu.Item>
)}
<Menu.Item key="recall" onClick={handleRecallMessage}>
{t('撤回')}
</Menu.Item>
</Menu>
);
}
@ -126,13 +137,50 @@ const SystemMessage: React.FC<ChatMessageItemProps> = React.memo(
);
SystemMessage.displayName = 'SystemMessage';
/**
* userId => nicknameSystemMessage
*/
const SystemMessageWithNickname: React.FC<
ChatMessageItemProps & {
userIds: string[];
overwritePayload: (nicknameList: string[]) => ChatMessage;
}
> = React.memo((props) => {
const { value: nicknameList = [] } = useAsync(() => {
return Promise.all(
props.userIds.map((userId) =>
getCachedUserInfo(userId).then((u) => u.nickname)
)
);
}, [props.userIds.join(',')]);
return (
<SystemMessage {...props} payload={props.overwritePayload(nicknameList)} />
);
});
SystemMessageWithNickname.displayName = 'SystemMessageWithNickname';
interface ChatMessageItemProps {
showAvatar: boolean;
payload: ChatMessage;
}
const ChatMessageItem: React.FC<ChatMessageItemProps> = React.memo((props) => {
if (props.payload.author === SYSTEM_USERID) {
const payload = props.payload;
if (payload.author === SYSTEM_USERID) {
return <SystemMessage {...props} />;
} else if (payload.hasRecall === true) {
return (
<SystemMessageWithNickname
{...props}
userIds={[payload.author ?? SYSTEM_USERID]}
overwritePayload={(nickname) => ({
...payload,
content: t('{{nickname}} 撤回了一条消息', {
nickname: nickname[0] ?? '',
}),
})}
/>
);
}
return <NormalMessage {...props} />;

Loading…
Cancel
Save