mirror of https://github.com/msgbyte/tailchat
refactor: 好友请求处理列表与界面
parent
0f81918954
commit
cde2d81c5f
@ -0,0 +1,63 @@
|
||||
// Place your Client workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
||||
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
||||
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
||||
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
||||
// Placeholders with the same ids are connected.
|
||||
// Example:
|
||||
// "Print to console": {
|
||||
// "scope": "javascript,typescript",
|
||||
// "prefix": "log",
|
||||
// "body": [
|
||||
// "console.log('$1');",
|
||||
// "$2"
|
||||
// ],
|
||||
// "description": "Log output to console"
|
||||
// }
|
||||
{
|
||||
"React functional component": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "rfc",
|
||||
"body": [
|
||||
"import React from 'react'",
|
||||
"interface $1Props {",
|
||||
" $2",
|
||||
"}",
|
||||
"export const $1 = (props: $1Props) => {",
|
||||
" const { $3 } = props;",
|
||||
"",
|
||||
" return null;",
|
||||
"};",
|
||||
"$1.displayName = '$1';"
|
||||
]
|
||||
},
|
||||
"React memo functional component": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "rmc",
|
||||
"body": [
|
||||
"import React from 'react';",
|
||||
"",
|
||||
"interface ${1:Component}Props {",
|
||||
" $2",
|
||||
"}",
|
||||
"export const $1: React.FC<$1Props> = React.memo((props) => {",
|
||||
" const { $3 } = props;",
|
||||
"",
|
||||
" return null;",
|
||||
"});",
|
||||
"$1.displayName = '$1';"
|
||||
]
|
||||
},
|
||||
"React memo functional component pure": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "rmcp",
|
||||
"body": [
|
||||
"import React from 'react';",
|
||||
"",
|
||||
"export const ${1:Component}: React.FC = React.memo(() => {",
|
||||
" return null;",
|
||||
"});",
|
||||
"$1.displayName = '$1';"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"editor.rulers": [80]
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import { Button, ButtonProps } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
interface IconBtnProps extends ButtonProps {
|
||||
icon: string;
|
||||
}
|
||||
export const IconBtn: React.FC<IconBtnProps> = React.memo(
|
||||
({ icon, ...props }) => {
|
||||
return (
|
||||
<Button
|
||||
className="border-0 bg-black bg-opacity-30 text-white text-opacity-80 hover:text-opacity-100 hover:bg-opacity-60"
|
||||
shape="circle"
|
||||
{...props}
|
||||
icon={<Icon className="anticon" icon={icon} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
IconBtn.displayName = 'IconBtn';
|
@ -0,0 +1,53 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { Avatar } from './Avatar';
|
||||
import _isNil from 'lodash/isNil';
|
||||
import { Skeleton, Space } from 'antd';
|
||||
// import { openUserProfile } from './modals/UserProfile';
|
||||
import { useCachedUserInfo } from 'pawchat-shared';
|
||||
|
||||
// const UserAvatar = styled(Avatar)`
|
||||
// cursor: pointer !important;
|
||||
// margin-right: 10px !important;
|
||||
// `;
|
||||
|
||||
// const UserNameText = styled(Typography)`
|
||||
// flex: 1;
|
||||
// color: ${(props) => props.theme.color.headerPrimary} !important;
|
||||
// `;
|
||||
|
||||
interface UserListItemProps {
|
||||
userId: string;
|
||||
actions?: React.ReactElement[];
|
||||
}
|
||||
export const UserListItem: React.FC<UserListItemProps> = React.memo((props) => {
|
||||
const { actions = [] } = props;
|
||||
const userInfo = useCachedUserInfo(props.userId);
|
||||
const userName = userInfo.nickname;
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
console.log('clicked avatar');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex items-center h-14 px-2.5 rounded group bg-white bg-opacity-0 hover:bg-opacity-20">
|
||||
<Skeleton
|
||||
loading={_isNil(userInfo)}
|
||||
avatar={true}
|
||||
title={false}
|
||||
active={true}
|
||||
>
|
||||
<div className="mr-2" onClick={handleClick}>
|
||||
<Avatar src={userInfo.avatar} name={userName} />
|
||||
</div>
|
||||
<div className="flex-1 text-white">
|
||||
<span>{userName}</span>
|
||||
<span className="text-gray-300 opacity-0 group-hover:opacity-100">
|
||||
#{userInfo.discriminator}
|
||||
</span>
|
||||
</div>
|
||||
<Space>{...actions}</Space>
|
||||
</Skeleton>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
UserListItem.displayName = 'UserListItem';
|
@ -0,0 +1,36 @@
|
||||
import { IconBtn } from '@/components/IconBtn';
|
||||
import { UserListItem } from '@/components/UserListItem';
|
||||
import { Tooltip } from 'antd';
|
||||
import { FriendRequest, t } from 'pawchat-shared';
|
||||
import React from 'react';
|
||||
|
||||
export const RequestReceived: React.FC<{
|
||||
requests: FriendRequest[];
|
||||
}> = React.memo((props) => {
|
||||
return (
|
||||
<div className="py-2.5 px-5">
|
||||
<div>等待处理的好友请求</div>
|
||||
<div>
|
||||
{props.requests.map(({ from }) => (
|
||||
<UserListItem
|
||||
key={from}
|
||||
userId={from}
|
||||
actions={[
|
||||
<Tooltip key="accept" title={t('接受')}>
|
||||
<div>
|
||||
<IconBtn icon="mdi-check" />
|
||||
</div>
|
||||
</Tooltip>,
|
||||
<Tooltip key="deny" title={t('拒绝')}>
|
||||
<div>
|
||||
<IconBtn icon="mdi-close" />
|
||||
</div>
|
||||
</Tooltip>,
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
RequestReceived.displayName = 'RequestReceived';
|
@ -0,0 +1,31 @@
|
||||
import { IconBtn } from '@/components/IconBtn';
|
||||
import { UserListItem } from '@/components/UserListItem';
|
||||
import { Tooltip } from 'antd';
|
||||
import { FriendRequest, t } from 'pawchat-shared';
|
||||
import React from 'react';
|
||||
|
||||
export const RequestSend: React.FC<{
|
||||
requests: FriendRequest[];
|
||||
}> = React.memo((props) => {
|
||||
return (
|
||||
<div className="py-2.5 px-5">
|
||||
<div>等待对方处理的好友请求</div>
|
||||
<div>
|
||||
{props.requests.map(({ to }) => (
|
||||
<UserListItem
|
||||
key={to}
|
||||
userId={to}
|
||||
actions={[
|
||||
<Tooltip key="cancel" title={t('取消')}>
|
||||
<div>
|
||||
<IconBtn icon="mdi-close" />
|
||||
</div>
|
||||
</Tooltip>,
|
||||
]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
RequestSend.displayName = 'RequestSend';
|
Loading…
Reference in New Issue