feat: allow remove converse from dmlist

if user offline, will call user.dmlist.addConverse which ensure converse in dmlist
pull/150/head
moonrailgun 2 years ago
parent 5e38294fee
commit 018d311da6

@ -335,6 +335,22 @@ export async function appendUserDMConverse(
return data; return data;
} }
/**
*
*/
export async function removeUserDMConverse(
converseId: string
): Promise<UserDMList> {
const { data } = await request.post<UserDMList>(
'/api/user/dmlist/removeConverse',
{
converseId,
}
);
return data;
}
/** /**
* *
* @param fieldName * @param fieldName

@ -210,6 +210,16 @@ const chatSlice = createSlice({
state.converses[converseId].hasFetchedHistory = true; state.converses[converseId].hasFetchedHistory = true;
}, },
removeConverse(state, action: PayloadAction<{ converseId: string }>) {
const { converseId } = action.payload;
if (!state.converses[converseId]) {
return;
}
delete state.converses[converseId];
},
/** /**
* *
*/ */

@ -1,14 +1,18 @@
import { import {
chatActions,
ChatConverseState, ChatConverseState,
getCachedUserInfo, getCachedUserInfo,
model,
useAppDispatch,
useAsync, useAsync,
useAsyncRequest,
useDMConverseName, useDMConverseName,
useUnread, useUnread,
useUserId, useUserId,
} from 'tailchat-shared'; } from 'tailchat-shared';
import React from 'react'; import React from 'react';
import { SidebarItem } from '../SidebarItem'; import { SidebarItem } from '../SidebarItem';
import { CombinedAvatar } from 'tailchat-design'; import { CombinedAvatar, Icon } from 'tailchat-design';
import _without from 'lodash/without'; import _without from 'lodash/without';
interface SidebarDMItemProps { interface SidebarDMItemProps {
@ -17,9 +21,11 @@ interface SidebarDMItemProps {
export const SidebarDMItem: React.FC<SidebarDMItemProps> = React.memo( export const SidebarDMItem: React.FC<SidebarDMItemProps> = React.memo(
(props) => { (props) => {
const converse = props.converse; const converse = props.converse;
const converseId = converse._id;
const name = useDMConverseName(converse); const name = useDMConverseName(converse);
const userId = useUserId(); const userId = useUserId();
const [hasUnread] = useUnread([converse._id]); const [hasUnread] = useUnread([converseId]);
const dispatch = useAppDispatch();
const { value: icon } = useAsync(async () => { const { value: icon } = useAsync(async () => {
if (!userId) { if (!userId) {
@ -42,13 +48,27 @@ export const SidebarDMItem: React.FC<SidebarDMItemProps> = React.memo(
); );
}, [converse.members, userId]); }, [converse.members, userId]);
const [, handleRemove] = useAsyncRequest(async () => {
dispatch(chatActions.removeConverse({ converseId }));
await model.user.removeUserDMConverse(converseId);
}, [converseId]);
return ( return (
<SidebarItem <SidebarItem
key={converse._id} key={converseId}
name={name} name={name}
// action={<Icon icon="mdi:close" />} // TODO action={
<Icon
icon="mdi:close"
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
handleRemove();
}}
/>
}
icon={icon} icon={icon}
to={`/main/personal/converse/${converse._id}`} to={`/main/personal/converse/${converseId}`}
badge={hasUnread} badge={hasUnread}
/> />
); );

@ -27,6 +27,13 @@ export function call(ctx: TcPureContext) {
userId, userId,
}); });
}, },
/**
* 线
*/
async isUserOnline(userIds: string[]): Promise<boolean[]> {
return await ctx.call('gateway.checkUserOnline', { userIds });
},
/** /**
* *
* groupId * groupId

@ -18,6 +18,7 @@ import {
} from 'tailchat-server-sdk'; } from 'tailchat-server-sdk';
import type { Group } from '../../../models/group/group'; import type { Group } from '../../../models/group/group';
import { isValidStr } from '../../../lib/utils'; import { isValidStr } from '../../../lib/utils';
import _ from 'lodash';
interface MessageService interface MessageService
extends TcService, extends TcService,
@ -180,12 +181,13 @@ class MessageService extends TcService {
const { converseId, groupId, content, plain, meta } = ctx.params; const { converseId, groupId, content, plain, meta } = ctx.params;
const userId = ctx.meta.userId; const userId = ctx.meta.userId;
const t = ctx.meta.t; const t = ctx.meta.t;
const isGroupMessage = isValidStr(groupId);
/** /**
* *
*/ */
await this.checkConversePermission(ctx, converseId, groupId); // 鉴权是否能获取到会话内容 await this.checkConversePermission(ctx, converseId, groupId); // 鉴权是否能获取到会话内容
if (isValidStr(groupId)) { if (isGroupMessage) {
// 是群组消息, 鉴权是否禁言 // 是群组消息, 鉴权是否禁言
const groupInfo = await call(ctx).getGroupInfo(groupId); const groupInfo = await call(ctx).getGroupInfo(groupId);
const member = groupInfo.members.find((m) => String(m.userId) === userId); const member = groupInfo.members.find((m) => String(m.userId) === userId);
@ -208,7 +210,40 @@ class MessageService extends TcService {
const json = await this.transformDocuments(ctx, {}, message); const json = await this.transformDocuments(ctx, {}, message);
this.roomcastNotify(ctx, converseId, 'add', json); if (isGroupMessage) {
this.roomcastNotify(ctx, converseId, 'add', json);
} else {
// 如果是私信的话需要基于用户去推送
// 因为用户可能不订阅消息(删除了dmlist)
const converseInfo = await call(ctx).getConverseInfo(converseId);
if (converseInfo) {
const converseMemberIds = converseInfo.members.map((m) => String(m));
call(ctx)
.isUserOnline(converseMemberIds)
.then((onlineList) => {
_.zip(converseMemberIds, onlineList).forEach(
([memberId, isOnline]) => {
if (isOnline) {
// 用户在线,则直接推送,通过客户端来创建会话
this.unicastNotify(ctx, memberId, 'add', json);
} else {
// 用户离线,确保追加到会话中
ctx.call(
'user.dmlist.addConverse',
{ converseId },
{
meta: {
userId: memberId,
},
}
);
}
}
);
});
}
}
ctx.emit('chat.message.updateMessage', { ctx.emit('chat.message.updateMessage', {
type: 'add', type: 'add',

@ -61,13 +61,13 @@ class UserDMListService extends TcService {
}, },
{ {
$pull: { $pull: {
converseIds: new db.Types.ObjectId(converseId), converseIds: converseId,
}, },
} }
) )
.exec(); .exec();
return modifiedCount; return { modifiedCount };
} }
/** /**

Loading…
Cancel
Save