feat: add discover server card and join action

pull/105/head
moonrailgun 2 years ago
parent 2709beb2d8
commit f943edf3fe

@ -83,6 +83,7 @@ export {
* @deprecated please use metaFormFieldSchema from @capital/component
*/
metaFormFieldSchema as fieldSchema,
getTextColorHex,
} from 'tailchat-design';
/**

@ -14,6 +14,7 @@ export {
Empty,
Popover,
Tag,
Skeleton,
} from 'antd';
export const TextArea = Input.TextArea;
export {

@ -30,6 +30,8 @@
"k89bf46fc": "Unable to recall messages from {{minutes}} minutes ago",
"k8c49f532": "Failed to set nickname, no friendship information found",
"k986040de": "No group found",
"k9891f980": "{{nickname}} joined the group through the public community",
"k996e99cb": "This group is not a public group and cannot be joined directly",
"ka3eb52f8": "Call ended, duration: {{num}} minutes",
"ka5b432c0": "Too frequent requests can share the same OTP within 10 minutes",
"ka8b712f7": "Email already exists!",

@ -30,6 +30,8 @@
"k89bf46fc": "无法撤回 {{minutes}} 分钟前的消息",
"k8c49f532": "设置昵称失败, 没有找到好友关系信息",
"k986040de": "没有找到群组",
"k9891f980": "{{nickname}} 通过公共社区加入群组",
"k996e99cb": "该群组并非公开群组, 无法直接加入",
"ka3eb52f8": "通话已结束, 时长: {{num}}分钟",
"ka5b432c0": "过于频繁的请求10 分钟内可以共用同一OTP",
"ka8b712f7": "邮箱已存在!",

@ -1,4 +1,4 @@
import type { TcContext } from 'tailchat-server-sdk';
import { call, TcContext } from 'tailchat-server-sdk';
import { TcService, TcDbService } from 'tailchat-server-sdk';
import type { DiscoverDocument, DiscoverModel } from '../models/discover';
@ -24,6 +24,11 @@ class DiscoverService extends TcService {
size: { type: 'number', default: 20 },
},
});
this.registerAction('join', this.join, {
params: {
groupId: 'string',
},
});
}
async all(ctx: TcContext<{ page: number; size: number }>) {
@ -42,6 +47,31 @@ class DiscoverService extends TcService {
return { list };
}
async join(ctx: TcContext<{ groupId: string }>) {
const { groupId } = ctx.params;
const t = ctx.meta.t;
const isExists = await this.adapter.model.exists({
groupId,
active: true,
});
if (!isExists) {
throw new Error(t('该群组并非公开群组, 无法直接加入'));
}
await ctx.call('group.joinGroup', {
groupId: String(groupId),
});
await call(ctx).addGroupSystemMessage(
String(groupId),
t('{{nickname}} 通过公共社区加入群组', {
nickname: ctx.meta.user.nickname,
})
);
}
}
export default DiscoverService;

@ -0,0 +1,142 @@
import React from 'react';
import styled from 'styled-components';
import {
postRequest,
useAsync,
useAsyncRequest,
getTextColorHex,
} from '@capital/common';
import { Avatar, Skeleton, Button } from '@capital/component';
import { Translate } from '../translate';
import { request } from '../request';
const Root = styled.div`
width: 100%;
height: 320px;
display: flex;
flex-direction: column;
overflow: hidden;
border-radius: 8px;
position: relative;
background-color: #2c3441;
.header {
height: 143px;
position: relative;
display: block;
overflow: visible;
margin-bottom: 32px;
.icon {
position: absolute;
bottom: -21px;
left: 12px;
border: 6px solid #2c3441;
border-radius: 6px;
}
}
.body {
display: flex;
padding: 0 16px 16px;
overflow: hidden;
flex: 1;
.name {
font-weight: 600;
}
.desc {
opacity: 0.8;
}
}
.footer {
padding: 0 16px 16px;
font-size: 0.7rem;
opacity: 0.8;
display: flex;
justify-content: space-between;
align-items: center;
* + * {
margin-left: 4px;
}
}
`;
interface DiscoverServerCardProps {
groupId: string;
}
export const DiscoverServerCard: React.FC<DiscoverServerCardProps> = React.memo(
(props) => {
const { value: groupBasicInfo } = useAsync(async () => {
const { data } = await postRequest('/group/getGroupBasicInfo', {
groupId: props.groupId,
});
return data;
}, [props.groupId]);
const [{ loading: joinLoading }, handleJoin] = useAsyncRequest(async () => {
await request.post('join', {
groupId: props.groupId,
});
}, [props.groupId]);
if (!groupBasicInfo) {
return (
<Root>
<div className="header">
<div className="icon">
<Skeleton.Avatar active={true} size={40} shape={'square'} />
</div>
</div>
<div className="body">
<Skeleton active={true} />
</div>
</Root>
);
}
return (
<Root>
<div
className="header"
style={{ background: getTextColorHex(groupBasicInfo.name) }}
>
<div className="icon">
<Avatar
shape="square"
size={40}
src={groupBasicInfo.icon}
name={groupBasicInfo.name}
/>
</div>
</div>
<div className="body">
<div className="name">{groupBasicInfo.name}</div>
<div className="desc"></div>
</div>
<div className="footer">
<div>
{Translate.memberCount.replace(
'{count}',
groupBasicInfo.memberCount
)}
</div>
<Button
size="small"
type="primary"
loading={joinLoading}
onClick={handleJoin}
>
{Translate.join}
</Button>
</div>
</Root>
);
}
);
DiscoverServerCard.displayName = 'DiscoverServerCard';

@ -1,14 +1,57 @@
import React from 'react';
import { useAsync } from '@capital/common';
import { LoadingSpinner } from '@capital/component';
import { request } from '../request';
import styled from 'styled-components';
import { DiscoverServerCard } from './DiscoverServerCard';
import { Translate } from '../translate';
interface DiscoverServerItem {
groupId: string;
order: number;
active: boolean;
}
const Root = styled.div`
width: 100%;
`;
const DiscoverServerHeader = styled.div`
font-size: 1.5rem;
padding: 32px 0;
text-align: center;
`;
const DiscoverServerList = styled.div`
margin-top: 16px;
display: grid;
grid-gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
padding: 10px;
`;
export const DiscoverPanel: React.FC = React.memo(() => {
const { value: list } = useAsync(async () => {
const { loading, value: list = [] } = useAsync(async (): Promise<
DiscoverServerItem[]
> => {
const { data } = await request.get('all');
return data.list ?? [];
}, []);
return <div>DiscoverPanel: {JSON.stringify(list)}</div>;
if (loading) {
return <LoadingSpinner />;
}
return (
<Root>
<DiscoverServerHeader>{Translate.discoverHeader}</DiscoverServerHeader>
<DiscoverServerList>
{list.map((item, i) => (
<DiscoverServerCard key={i} groupId={item.groupId} />
))}
</DiscoverServerList>
</Root>
);
});
DiscoverPanel.displayName = 'DiscoverPanel';

@ -5,4 +5,16 @@ export const Translate = {
'zh-CN': '探索',
'en-US': 'Discover',
}),
memberCount: localTrans({
'zh-CN': '{count} 位成员',
'en-US': '{count} members',
}),
discoverHeader: localTrans({
'zh-CN': '在这里探索你感兴趣的群组',
'en-US': 'Explore the groups you are interested in here',
}),
join: localTrans({
'zh-CN': '加入',
'en-US': 'Join',
}),
};

Loading…
Cancel
Save