feat: 增加群组成员popover

release/desktop
moonrailgun 3 years ago
parent 240bd72cb6
commit ae3829628a

@ -30,7 +30,6 @@ export const Avatar: React.FC<AvatarProps> = React.memo((_props) => {
const style: React.CSSProperties = useMemo(
() => ({
cursor: 'inherit',
userSelect: 'none',
...props.style,
backgroundColor: color,

@ -0,0 +1,40 @@
import React, { useState } from 'react';
import { Avatar, AvatarProps } from '../Avatar';
import { Image } from '../Image';
export const AvatarWithPreview: React.FC<AvatarProps> = React.memo((props) => {
const [visible, setVisible] = useState(false);
const hasImage = typeof props.src === 'string';
return (
<>
<div
style={{
cursor: hasImage ? 'pointer' : 'auto',
}}
onClick={() => setVisible(!visible)}
>
<Avatar {...props} />
</div>
{hasImage && (
<div
style={{
display: 'none',
}}
>
<Image
preview={{
visible,
src: String(props.src),
onVisibleChange: (value) => {
setVisible(value);
},
}}
/>
</div>
)}
</>
);
});
AvatarWithPreview.displayName = 'AvatarWithPreview';

@ -1,5 +1,6 @@
export { AutoFolder } from './AutoFolder';
export { Avatar } from './Avatar';
export { AvatarWithPreview } from './AvatarWithPreview';
export { CombinedAvatar } from './Avatar/combined';
export { DelayTip } from './DelayTip';
export { Highlight } from './Highlight';

@ -32,6 +32,7 @@
"k2c7df74f": "Modify Group Panel",
"k2d6cfb27": "Chat Channel",
"k2ec4966c": "Selected {{num}} items",
"k2edb3d74": "Guest",
"k3081870c": "More",
"k313bda4b": "OTP",
"k3172297b": "This feature is not yet open",

@ -32,6 +32,7 @@
"k2c7df74f": "编辑群组面板",
"k2d6cfb27": "聊天频道",
"k2ec4966c": "已选择 {{num}} 项",
"k2edb3d74": "游客",
"k3081870c": "更多",
"k313bda4b": "OTP",
"k3172297b": "该功能暂未开放",

@ -117,6 +117,7 @@ export type {
GroupInfo,
GroupBasicInfo,
GroupInvite,
GroupMember,
} from './model/group';
export {
sendMessage,

@ -1,4 +1,5 @@
import { Icon } from '@/components/Icon';
import { GroupUserPopover } from '@/components/popover/GroupUserPopover';
import { UserListItem } from '@/components/UserListItem';
import { Divider, Input, Skeleton } from 'antd';
import React, { useMemo, useState } from 'react';
@ -55,7 +56,11 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
const isSearching = searchStr !== '';
const renderUser = (member: UserBaseInfo) => (
<UserListItem key={member._id} userId={member._id} />
<UserListItem
key={member._id}
userId={member._id}
popover={<GroupUserPopover userInfo={member} />}
/>
);
return (

@ -1,11 +1,13 @@
import React, { useCallback } from 'react';
import React from 'react';
import { Avatar } from './Avatar';
import _isEmpty from 'lodash/isEmpty';
import { Skeleton, Space } from 'antd';
import { Popover, PopoverProps, Skeleton, Space } from 'antd';
import { useCachedUserInfo, useCachedOnlineStatus } from 'tailchat-shared';
import clsx from 'clsx';
interface UserListItemProps {
userId: string;
popover?: PopoverProps['content'];
actions?: React.ReactElement[];
}
export const UserListItem: React.FC<UserListItemProps> = React.memo((props) => {
@ -14,11 +16,6 @@ export const UserListItem: React.FC<UserListItemProps> = React.memo((props) => {
const [isOnline] = useCachedOnlineStatus([props.userId]);
const userName = userInfo.nickname;
const handleClick = useCallback(() => {
// TODO 点击展开用户信息卡片
console.log('clicked avatar');
}, []);
return (
<div className="flex items-center h-14 px-2.5 rounded group bg-black bg-opacity-0 hover:bg-opacity-20 dark:bg-white dark:bg-opacity-0 dark:hover:bg-opacity-20">
<Skeleton
@ -27,8 +24,17 @@ export const UserListItem: React.FC<UserListItemProps> = React.memo((props) => {
title={false}
active={true}
>
<div className="mr-2" onClick={handleClick}>
<Avatar src={userInfo.avatar} name={userName} isOnline={isOnline} />
<div className="mr-2">
<Popover content={props.popover} placement="left" trigger="click">
<Avatar
className={clsx({
'cursor-pointer': !!props.popover,
})}
src={userInfo.avatar}
name={userName}
isOnline={isOnline}
/>
</Popover>
</div>
<div className="flex-1 text-gray-900 dark:text-white">
<span>{userName}</span>

@ -0,0 +1,29 @@
import { Tag } from 'antd';
import React from 'react';
import { AvatarWithPreview } from 'tailchat-design';
import { t, UserBaseInfo } from 'tailchat-shared';
export const GroupUserPopover: React.FC<{
userInfo: UserBaseInfo;
}> = React.memo((props) => {
const { userInfo } = props;
return (
<div className="w-80">
<AvatarWithPreview
size={80}
src={userInfo.avatar}
name={userInfo.nickname}
/>
<div className="text-xl mt-2">
<span className="font-semibold">{userInfo.nickname}</span>
<span className="opacity-60 ml-1">#{userInfo.discriminator}</span>
</div>
<div>
{userInfo.temporary && <Tag color="processing">{t('游客')}</Tag>}
</div>
</div>
);
});
GroupUserPopover.displayName = 'GroupUserPopover';

@ -350,4 +350,26 @@
border-color: #177ddc;
}
}
// Popover
.ant-popover {
.ant-popover-arrow > .ant-popover-arrow-content,
.ant-popover-arrow > .ant-popover-arrow-content::before,
.ant-popover-inner {
background-color: #1f1f1f;
}
.ant-popover-inner-content {
color: rgba(255, 255, 255, 0.85);
}
}
// Tag
.ant-tag {
&.ant-tag-processing {
color: #177ddc;
background: #111b26;
border-color: #153450;
}
}
}

Loading…
Cancel
Save