refactor: 将群组用户操作相关的逻辑单独抽象成一个hooks方便复用

pull/70/head
moonrailgun 2 years ago
parent b44ccfd762
commit 7645300bda

@ -1,93 +1,26 @@
import { Icon } from 'tailchat-design';
import { openReconfirmModalP } from '@/components/Modal';
import { GroupUserPopover } from '@/components/popover/GroupUserPopover';
import { UserListItem } from '@/components/UserListItem';
import { Divider, Dropdown, Input, MenuProps, Skeleton } from 'antd';
import React, { useMemo } from 'react';
import {
formatFullTime,
getGroupConfigWithInfo,
GroupMember,
humanizeMsDuration,
model,
PERMISSION,
showToasts,
t,
useAsyncRequest,
useCachedOnlineStatus,
useGroupInfo,
useHasGroupPermission,
UserBaseInfo,
useSearch,
useUserInfoList,
} from 'tailchat-shared';
import _compact from 'lodash/compact';
import { Problem } from '@/components/Problem';
import { useGroupMemberAction } from '@/hooks/useGroupMemberAction';
interface MembersPanelProps {
groupId: string;
}
function getMembersHasMute(members: GroupMember[], userId: string): boolean {
const member = members.find((m) => m.userId === userId);
if (!member || !member.muteUntil) {
return false;
}
const muteUntil = member.muteUntil;
return new Date(muteUntil).valueOf() > new Date().valueOf();
}
/**
*
*/
function useMemberMuteAction(
groupId: string,
userInfoList: model.user.UserBaseInfo[]
) {
/**
*
*/
const [, handleMuteMember] = useAsyncRequest(
async (memberId: string, ms: number) => {
const memberInfo = userInfoList.find((m) => m._id === memberId);
if (!memberInfo) {
throw new Error(t('没有找到用户'));
}
if (
await openReconfirmModalP({
title: t('确定要禁言 {{name}} 么', { name: memberInfo.nickname }),
content: t('禁言 {{length}}, 预计到 {{until}} 为止', {
length: humanizeMsDuration(ms),
until: formatFullTime(new Date().valueOf() + ms),
}),
})
) {
await model.group.muteGroupMember(groupId, memberId, ms);
showToasts(t('操作成功'), 'success');
}
},
[groupId, userInfoList]
);
/**
*
*/
const [, handleUnmuteMember] = useAsyncRequest(
async (memberId: string) => {
await model.group.muteGroupMember(groupId, memberId, -1);
showToasts(t('操作成功'), 'success');
},
[groupId]
);
return { handleMuteMember, handleUnmuteMember };
}
/**
*
*/
@ -109,10 +42,11 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
setSearchText,
isSearching,
searchResult: filteredGroupMembers,
} = useSearch({
dataSource: userInfoList,
filterFn: (item, searchText) => item.nickname.includes(searchText),
});
getMemberHasMute,
handleMuteMember,
handleUnmuteMember,
handleRemoveGroupMember,
} = useGroupMemberAction(groupId);
const groupedMembers = useMemo(() => {
const online: UserBaseInfo[] = [];
@ -132,27 +66,6 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
};
}, [userInfoList, membersOnlineStatus]);
const { handleMuteMember, handleUnmuteMember } = useMemberMuteAction(
groupId,
userInfoList
);
/**
*
*/
const [, handleRemoveGroupMember] = useAsyncRequest(
async (memberId: string) => {
const confirm = await openReconfirmModalP({
title: t('确认要将该用户移出群组么'),
});
if (confirm) {
await model.group.deleteGroupMember(groupId, memberId);
showToasts(t('操作成功'), 'success');
}
},
[groupId]
);
if (!groupInfo) {
return <Problem />;
}
@ -162,7 +75,7 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
}
const renderUser = (member: UserBaseInfo) => {
const hasMute = getMembersHasMute(members, member._id);
const hasMute = getMemberHasMute(member._id);
if (allowManageUser) {
const muteItems: MenuProps['items'] = hasMute

@ -14,6 +14,7 @@ import { GroupRole } from './Role';
import { GroupSummary } from './Summary';
import _compact from 'lodash/compact';
import { GroupConfig } from './Config';
import { GroupMember } from './Member';
interface SettingsViewProps {
groupId: string;
@ -31,11 +32,13 @@ export const GroupDetail: React.FC<SettingsViewProps> = React.memo((props) => {
);
const [
allowManageConfig,
allowManageUser,
allowManagePanel,
allowManageInvite,
allowManageRoles,
] = useHasGroupPermission(groupId, [
PERMISSION.core.groupConfig,
PERMISSION.core.manageUser,
PERMISSION.core.managePanel,
PERMISSION.core.manageInvite,
PERMISSION.core.manageRoles,
@ -58,6 +61,11 @@ export const GroupDetail: React.FC<SettingsViewProps> = React.memo((props) => {
title: t('配置'),
content: <GroupConfig groupId={groupId} />,
},
allowManageUser && {
type: 'item',
title: t('成员'),
content: <GroupMember groupId={groupId} />,
},
allowManagePanel && {
type: 'item',
title: t('面板'),

@ -0,0 +1,127 @@
import { openReconfirmModalP } from '@/components/Modal';
import { useCallback } from 'react';
import {
formatFullTime,
humanizeMsDuration,
model,
showSuccessToasts,
t,
useAsyncRequest,
useGroupInfo,
useGroupMemberInfos,
useMemoizedFn,
useSearch,
} from 'tailchat-shared';
/**
*
*/
export function useGroupMemberAction(groupId: string) {
const groupInfo = useGroupInfo(groupId);
const members = groupInfo?.members ?? [];
const userInfos = useGroupMemberInfos(groupId);
const { handleMuteMember, handleUnmuteMember } = useMemberMuteAction(
groupId,
userInfos
);
const { searchText, setSearchText, isSearching, searchResult } = useSearch({
dataSource: userInfos,
filterFn: (item, searchText) => item.nickname.includes(searchText),
});
/**
*
*/
const [, handleRemoveGroupMember] = useAsyncRequest(
async (memberId: string) => {
const confirm = await openReconfirmModalP({
title: t('确认要将该用户移出群组么'),
});
if (confirm) {
await model.group.deleteGroupMember(groupId, memberId);
showSuccessToasts();
}
},
[groupId]
);
const getMemberHasMute = useCallback(
(userId: string): boolean => {
const member = members.find((m) => m.userId === userId);
if (!member || !member.muteUntil) {
return false;
}
const muteUntil = member.muteUntil;
return new Date(muteUntil).valueOf() > new Date().valueOf();
},
[members]
);
return {
// 搜索相关
searchText,
setSearchText,
isSearching,
searchResult,
getMemberHasMute,
// 用户操作
handleMuteMember,
handleUnmuteMember,
handleRemoveGroupMember,
};
}
/**
*
*/
function useMemberMuteAction(
groupId: string,
userInfoList: model.user.UserBaseInfo[]
) {
/**
*
*/
const [, handleMuteMember] = useAsyncRequest(
async (memberId: string, ms: number) => {
const memberInfo = userInfoList.find((m) => m._id === memberId);
if (!memberInfo) {
throw new Error(t('没有找到用户'));
}
if (
await openReconfirmModalP({
title: t('确定要禁言 {{name}} 么', { name: memberInfo.nickname }),
content: t('禁言 {{length}}, 预计到 {{until}} 为止', {
length: humanizeMsDuration(ms),
until: formatFullTime(new Date().valueOf() + ms),
}),
})
) {
await model.group.muteGroupMember(groupId, memberId, ms);
showSuccessToasts();
}
},
[groupId, userInfoList]
);
/**
*
*/
const [, handleUnmuteMember] = useAsyncRequest(
async (memberId: string) => {
await model.group.muteGroupMember(groupId, memberId, -1);
showSuccessToasts();
},
[groupId]
);
return { handleMuteMember, handleUnmuteMember };
}
Loading…
Cancel
Save