feat: add grouping by status to member list

pull/105/merge
moonrailgun
parent 7db9d63349
commit 288f5a61e8

@ -147,6 +147,7 @@
"k651efa29": "Change friend nickname", "k651efa29": "Change friend nickname",
"k65b21404": "Download", "k65b21404": "Download",
"k6686ad69": "Select group members", "k6686ad69": "Select group members",
"k66ce073e": "Offline",
"k6728eaaa": "No Data", "k6728eaaa": "No Data",
"k67d68dd1": "Type", "k67d68dd1": "Type",
"k68022ee7": "All", "k68022ee7": "All",
@ -197,6 +198,7 @@
"k8157b129": "25 uses", "k8157b129": "25 uses",
"k81662255": "Create invitation code", "k81662255": "Create invitation code",
"k821ff85a": "Common", "k821ff85a": "Common",
"k823bfe63": "Online",
"k8266bcf2": "New password", "k8266bcf2": "New password",
"k83ede286": "Ack Service", "k83ede286": "Ack Service",
"k84a3bd27": "Invitation link", "k84a3bd27": "Invitation link",

@ -147,6 +147,7 @@
"k651efa29": "更改好友昵称", "k651efa29": "更改好友昵称",
"k65b21404": "下载", "k65b21404": "下载",
"k6686ad69": "选择群组成员", "k6686ad69": "选择群组成员",
"k66ce073e": "离线",
"k6728eaaa": "没有数据", "k6728eaaa": "没有数据",
"k67d68dd1": "类型", "k67d68dd1": "类型",
"k68022ee7": "全部", "k68022ee7": "全部",
@ -197,6 +198,7 @@
"k8157b129": "25次使用", "k8157b129": "25次使用",
"k81662255": "创建邀请码", "k81662255": "创建邀请码",
"k821ff85a": "通用", "k821ff85a": "通用",
"k823bfe63": "在线",
"k8266bcf2": "新密码", "k8266bcf2": "新密码",
"k83ede286": "已读服务", "k83ede286": "已读服务",
"k84a3bd27": "邀请链接", "k84a3bd27": "邀请链接",

@ -1,7 +1,6 @@
import { Icon } from 'tailchat-design'; import { Icon } from 'tailchat-design';
import { GroupUserPopover } from '@/components/popover/UserPopover/GroupUserPopover';
import { UserListItem } from '@/components/UserListItem'; import { UserListItem } from '@/components/UserListItem';
import { Divider, Dropdown, Input, MenuProps, Skeleton } from 'antd'; import { Dropdown, Input, MenuProps, Skeleton } from 'antd';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { import {
getGroupConfigWithInfo, getGroupConfigWithInfo,
@ -15,7 +14,10 @@ import {
import { Problem } from '@/components/Problem'; import { Problem } from '@/components/Problem';
import { useGroupMemberAction } from '@/hooks/useGroupMemberAction'; import { useGroupMemberAction } from '@/hooks/useGroupMemberAction';
import { UserPopover } from '@/components/popover/UserPopover'; import { UserPopover } from '@/components/popover/UserPopover';
import { Virtuoso } from 'react-virtuoso'; import { GroupedVirtuoso } from 'react-virtuoso';
import _take from 'lodash/take';
import _sum from 'lodash/sum';
import _get from 'lodash/get';
interface MembersPanelProps { interface MembersPanelProps {
groupId: string; groupId: string;
@ -57,9 +59,36 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
} }
}); });
return [...online, ...offline]; return {
[t('在线')]: online,
[t('离线')]: offline,
};
}, [userInfos, membersOnlineStatus]); }, [userInfos, membersOnlineStatus]);
const { groupCounts, groupNames, getGroupedMemberInfo } = useMemo(() => {
const groupMemberInfo = isSearching
? { '': filteredGroupMembers }
: sortedMembers;
const groupCounts = Object.values(groupMemberInfo).map(
(item) => item.length
);
const groupNames = Object.keys(groupMemberInfo);
const getGroupedMemberInfo = (
index: number,
groupIndex: number
): UserBaseInfo | null => {
const groupName = groupNames[groupIndex];
const prevIndexCount = _sum(_take(groupCounts, groupIndex));
const currentGroupIndex = index - prevIndexCount;
return _get(groupMemberInfo, [groupName, currentGroupIndex], null);
};
return { groupCounts, groupNames, getGroupedMemberInfo };
}, [isSearching, filteredGroupMembers, sortedMembers]);
if (!groupInfo) { if (!groupInfo) {
return <Problem />; return <Problem />;
} }
@ -68,7 +97,11 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
return <Skeleton />; return <Skeleton />;
} }
const renderUser = (member: UserBaseInfo) => { const renderUser = (member: UserBaseInfo | null) => {
if (!member) {
return <div />;
}
if (allowManageUser) { if (allowManageUser) {
const menu: MenuProps = generateActionMenu(member); const menu: MenuProps = generateActionMenu(member);
@ -108,10 +141,19 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
</div> </div>
<div className="flex-1"> <div className="flex-1">
<Virtuoso <GroupedVirtuoso
className="h-full" className="h-full"
data={isSearching ? filteredGroupMembers : sortedMembers} groupCounts={groupCounts}
itemContent={(i, item) => renderUser(item)} groupContent={(index) => {
return (
<div className="pt-4 px-2.5 font-bold text-sm text-opacity-80 bg-content-light dark:bg-content-dark">
{groupNames[index]} - {groupCounts[index]}
</div>
);
}}
itemContent={(i, groupIndex) =>
renderUser(getGroupedMemberInfo(i, groupIndex))
}
/> />
</div> </div>
</div> </div>

Loading…
Cancel
Save