From f943edf3fe440d2d28489ad17d5c8bf2c8489e38 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 9 Jul 2023 00:38:44 +0800 Subject: [PATCH] feat: add discover server card and join action --- client/web/src/plugin/common/index.ts | 1 + client/web/src/plugin/component/index.tsx | 1 + server/locales/en-US/translation.json | 2 + server/locales/zh-CN/translation.json | 2 + .../services/discover.service.dev.ts | 32 +++- .../src/DiscoverPanel/DiscoverServerCard.tsx | 142 ++++++++++++++++++ .../src/DiscoverPanel/index.tsx | 47 +++++- .../com.msgbyte.discover/src/translate.ts | 12 ++ 8 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/DiscoverServerCard.tsx diff --git a/client/web/src/plugin/common/index.ts b/client/web/src/plugin/common/index.ts index 54b2e9bd..efebd62b 100644 --- a/client/web/src/plugin/common/index.ts +++ b/client/web/src/plugin/common/index.ts @@ -83,6 +83,7 @@ export { * @deprecated please use metaFormFieldSchema from @capital/component */ metaFormFieldSchema as fieldSchema, + getTextColorHex, } from 'tailchat-design'; /** diff --git a/client/web/src/plugin/component/index.tsx b/client/web/src/plugin/component/index.tsx index 5b51d2db..e022217c 100644 --- a/client/web/src/plugin/component/index.tsx +++ b/client/web/src/plugin/component/index.tsx @@ -14,6 +14,7 @@ export { Empty, Popover, Tag, + Skeleton, } from 'antd'; export const TextArea = Input.TextArea; export { diff --git a/server/locales/en-US/translation.json b/server/locales/en-US/translation.json index feabd88a..6bd54b41 100644 --- a/server/locales/en-US/translation.json +++ b/server/locales/en-US/translation.json @@ -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!", diff --git a/server/locales/zh-CN/translation.json b/server/locales/zh-CN/translation.json index 621d83dc..3dccdfc5 100644 --- a/server/locales/zh-CN/translation.json +++ b/server/locales/zh-CN/translation.json @@ -30,6 +30,8 @@ "k89bf46fc": "无法撤回 {{minutes}} 分钟前的消息", "k8c49f532": "设置昵称失败, 没有找到好友关系信息", "k986040de": "没有找到群组", + "k9891f980": "{{nickname}} 通过公共社区加入群组", + "k996e99cb": "该群组并非公开群组, 无法直接加入", "ka3eb52f8": "通话已结束, 时长: {{num}}分钟", "ka5b432c0": "过于频繁的请求,10 分钟内可以共用同一OTP", "ka8b712f7": "邮箱已存在!", diff --git a/server/plugins/com.msgbyte.discover/services/discover.service.dev.ts b/server/plugins/com.msgbyte.discover/services/discover.service.dev.ts index 4e7192aa..0841dfd6 100644 --- a/server/plugins/com.msgbyte.discover/services/discover.service.dev.ts +++ b/server/plugins/com.msgbyte.discover/services/discover.service.dev.ts @@ -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; diff --git a/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/DiscoverServerCard.tsx b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/DiscoverServerCard.tsx new file mode 100644 index 00000000..ce7a8e8b --- /dev/null +++ b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/DiscoverServerCard.tsx @@ -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 = 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 ( + +
+
+ +
+
+
+ +
+
+ ); + } + + return ( + +
+
+ +
+
+
+
{groupBasicInfo.name}
+
+
+
+
+ {Translate.memberCount.replace( + '{count}', + groupBasicInfo.memberCount + )} +
+ +
+
+ ); + } +); +DiscoverServerCard.displayName = 'DiscoverServerCard'; diff --git a/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/index.tsx b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/index.tsx index 1806332a..8e92d90b 100644 --- a/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/index.tsx +++ b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/DiscoverPanel/index.tsx @@ -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
DiscoverPanel: {JSON.stringify(list)}
; + if (loading) { + return ; + } + + return ( + + {Translate.discoverHeader} + + {list.map((item, i) => ( + + ))} + + + ); }); DiscoverPanel.displayName = 'DiscoverPanel'; diff --git a/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/translate.ts b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/translate.ts index c4d457ba..f9c941e0 100644 --- a/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/translate.ts +++ b/server/plugins/com.msgbyte.discover/web/plugins/com.msgbyte.discover/src/translate.ts @@ -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', + }), };