|
|
|
@ -1,7 +1,6 @@
|
|
|
|
|
import { Icon } from 'tailchat-design';
|
|
|
|
|
import { GroupUserPopover } from '@/components/popover/UserPopover/GroupUserPopover';
|
|
|
|
|
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 {
|
|
|
|
|
getGroupConfigWithInfo,
|
|
|
|
@ -15,7 +14,10 @@ import {
|
|
|
|
|
import { Problem } from '@/components/Problem';
|
|
|
|
|
import { useGroupMemberAction } from '@/hooks/useGroupMemberAction';
|
|
|
|
|
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 {
|
|
|
|
|
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]);
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
return <Problem />;
|
|
|
|
|
}
|
|
|
|
@ -68,7 +97,11 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
|
|
|
|
|
return <Skeleton />;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const renderUser = (member: UserBaseInfo) => {
|
|
|
|
|
const renderUser = (member: UserBaseInfo | null) => {
|
|
|
|
|
if (!member) {
|
|
|
|
|
return <div />;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (allowManageUser) {
|
|
|
|
|
const menu: MenuProps = generateActionMenu(member);
|
|
|
|
|
|
|
|
|
@ -108,10 +141,19 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<Virtuoso
|
|
|
|
|
<GroupedVirtuoso
|
|
|
|
|
className="h-full"
|
|
|
|
|
data={isSearching ? filteredGroupMembers : sortedMembers}
|
|
|
|
|
itemContent={(i, item) => renderUser(item)}
|
|
|
|
|
groupCounts={groupCounts}
|
|
|
|
|
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>
|
|
|
|
|