Skip to content

Commit

Permalink
feat: add fast change role group with group member right click menu m…
Browse files Browse the repository at this point in the history
…anage #171
  • Loading branch information
moonrailgun committed Nov 10, 2023
1 parent ba37f36 commit ed3e9ca
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 42 deletions.
5 changes: 4 additions & 1 deletion client/shared/i18n/langs/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"k5d2a6631": "Allow to manage channels",
"k5f91e72c": "Built Plugins",
"k5fc9ccb6": "Operation too frequently",
"k5fde4f8e": "Assign roles",
"k609d9f28": "Please enter the server address (example: http://127.0.0.1:11000)",
"k61a1db2": "Already applied",
"k62051fcc": "Upload failed",
Expand Down Expand Up @@ -165,7 +166,7 @@
"k6cc401b0": "No role groups are currently selected",
"k6cd79ab": "Click for details",
"k6e4e3d7a": "All messages in this group are marked as read",
"k6eac768d": "Add Members",
"k6eac768d": "Add Roles",
"k6ee71a71": "Global Configuration",
"k6efe275c": "Mark as read",
"k6fb230da": "Pending friend request",
Expand Down Expand Up @@ -225,6 +226,7 @@
"k8f6ab535": "Unable to install",
"k8f6dfd40": "Current members",
"k9179206d": "Reconnecting",
"k924278f0": "Remove user [{{name}}] role [{{roleName}}] success",
"k9277af78": "Retry",
"k92a84117": "Claim account",
"k95222176": "Unread",
Expand Down Expand Up @@ -328,6 +330,7 @@
"kc74e5f62": "Search for members",
"kc77e00c7": "Allow members to view the panel",
"kc7cc96c8": "From",
"kc8c4ccbb": "Grant user [{{name}}] role [{{roleName}}] success",
"kc9283683": "Are you sure you want to delete the panel [{{name}}]",
"kc9bd3ad6": "Reset to default permissions",
"kc9cc6154": "Friends",
Expand Down
5 changes: 4 additions & 1 deletion client/shared/i18n/langs/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"k5d2a6631": "允许管理频道",
"k5f91e72c": "内置插件",
"k5fc9ccb6": "操作过于频繁",
"k5fde4f8e": "分配身份组",
"k609d9f28": "请输入服务器地址(示例: http://127.0.0.1:11000)",
"k61a1db2": "已申请",
"k62051fcc": "上传失败",
Expand Down Expand Up @@ -165,7 +166,7 @@
"k6cc401b0": "当前没有选择任何角色组",
"k6cd79ab": "点击查看详情",
"k6e4e3d7a": "已标记该群组所有消息已读",
"k6eac768d": "添加角色",
"k6eac768d": "添加身份组",
"k6ee71a71": "全局配置",
"k6efe275c": "标记为已读",
"k6fb230da": "等待处理的好友请求",
Expand Down Expand Up @@ -225,6 +226,7 @@
"k8f6ab535": "无法安装",
"k8f6dfd40": "当前成员数",
"k9179206d": "正在重新链接",
"k924278f0": "移除用户 [{{name}}] 身份组 [{{roleName}}] 成功",
"k9277af78": "重试",
"k92a84117": "认领账号",
"k95222176": "未读",
Expand Down Expand Up @@ -328,6 +330,7 @@
"kc74e5f62": "搜索成员",
"kc77e00c7": "允许成员查看面板",
"kc7cc96c8": "来自",
"kc8c4ccbb": "授予用户 [{{name}}] 身份组 [{{roleName}}] 成功",
"kc9283683": "确定要删除面板 【{{name}}】 么",
"kc9bd3ad6": "重置为默认权限",
"kc9cc6154": "好友",
Expand Down
8 changes: 2 additions & 6 deletions client/web/src/components/Panel/group/MembersPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
const membersOnlineStatus = useCachedOnlineStatus(
members.map((m) => m.userId)
);
const [allowManageUser] = useHasGroupPermission(groupId, [
PERMISSION.core.manageUser,
]);
const { hideGroupMemberDiscriminator } = getGroupConfigWithInfo(groupInfo);

const {
Expand Down Expand Up @@ -102,9 +99,8 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
return <div />;
}

if (allowManageUser) {
const menu: MenuProps = generateActionMenu(member);

const menu = generateActionMenu(member);
if ((menu.items ?? []).length > 0) {
return (
<Dropdown key={member._id} trigger={['contextMenu']} menu={menu}>
<div>
Expand Down
127 changes: 93 additions & 34 deletions client/web/src/hooks/useGroupMemberAction.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { openReconfirmModalP } from '@/components/Modal';
import type { MenuProps } from 'antd';
import { useCallback } from 'react';
import {
formatFullTime,
humanizeMsDuration,
model,
PERMISSION,
showSuccessToasts,
t,
useAsyncRequest,
useEvent,
useGroupInfo,
useGroupMemberInfos,
useMemoizedFn,
useHasGroupPermission,
UserBaseInfo,
useSearch,
} from 'tailchat-shared';
Expand All @@ -23,8 +24,13 @@ import { useFriendNicknameMap } from 'tailchat-shared/redux/hooks/useFriendNickn
export function useGroupMemberAction(groupId: string) {
const groupInfo = useGroupInfo(groupId);
const members = groupInfo?.members ?? [];
const roles = groupInfo?.roles ?? [];
const userInfos = useGroupMemberInfos(groupId);
const friendNicknameMap = useFriendNicknameMap();
const [allowManageUser, allowManageRoles] = useHasGroupPermission(groupId, [
PERMISSION.core.manageUser,
PERMISSION.core.manageRoles,
]);

const { handleMuteMember, handleUnmuteMember } = useMemberMuteAction(
groupId,
Expand Down Expand Up @@ -64,26 +70,31 @@ export function useGroupMemberAction(groupId: string) {
[groupId]
);

const getMemberHasMute = useCallback(
(userId: string): boolean => {
const member = members.find((m) => m.userId === userId);
const getMemberHasMute = useEvent((userId: string): boolean => {
const member = members.find((m) => m.userId === userId);

if (!member || !member.muteUntil) {
return false;
}
if (!member || !member.muteUntil) {
return false;
}

const muteUntil = member.muteUntil;
const muteUntil = member.muteUntil;

return new Date(muteUntil).valueOf() > new Date().valueOf();
},
[members]
);
return new Date(muteUntil).valueOf() > new Date().valueOf();
});

const generateActionMenu = useMemoizedFn(
(member: UserBaseInfo): MenuProps => {
const hasMute = getMemberHasMute(member._id);
const getMemberRoles = useEvent((userId: string): string[] => {
return members.find((m) => m.userId === userId)?.roles ?? [];
});

const muteItems: MenuProps['items'] = hasMute
/**
* 生成群组成员操作菜单
*/
const generateActionMenu = useEvent((member: UserBaseInfo): MenuProps => {
const hasMute = getMemberHasMute(member._id);
const memberRoles = getMemberRoles(member._id);

const muteItems: MenuProps['items'] = allowManageUser
? hasMute
? [
{
key: 'unmute',
Expand Down Expand Up @@ -136,23 +147,71 @@ export function useGroupMemberAction(groupId: string) {
},
],
},
];

const menu: MenuProps = {
items: _compact([
...muteItems,
{
key: 'delete',
label: t('移出群组'),
danger: true,
onClick: () => handleRemoveGroupMember(member._id),
},
] as MenuProps['items']),
};

return menu;
}
);
]
: [];

const roleItems: MenuProps['items'] =
allowManageRoles && roles.length > 0
? [
{
key: 'manageRole',
label: t('分配身份组'),
children: roles.map((role) => ({
key: role._id,
label: role.name,
className: memberRoles.includes(role._id)
? 'underline'
: undefined,
onClick: async () => {
// switch member role
if (memberRoles.includes(role._id)) {
// 已拥有该身份
await model.group.removeGroupMemberRoles(
groupId,
[member._id],
[role._id]
);
showSuccessToasts(
t('移除用户 [{{name}}] 身份组 [{{roleName}}] 成功', {
name: member.nickname,
roleName: role.name,
})
);
} else {
// 没有该身份
await model.group.appendGroupMemberRoles(
groupId,
[member._id],
[role._id]
);
showSuccessToasts(
t('授予用户 [{{name}}] 身份组 [{{roleName}}] 成功', {
name: member.nickname,
roleName: role.name,
})
);
}
},
})),
},
]
: [];

const menu: MenuProps = {
items: _compact([
...muteItems,
...roleItems,
allowManageUser && {
key: 'delete',
label: t('移出群组'),
danger: true,
onClick: () => handleRemoveGroupMember(member._id),
},
] as MenuProps['items']),
};

return menu;
});

return {
userInfos,
Expand Down

0 comments on commit ed3e9ca

Please sign in to comment.