diff --git a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/MeetingView.tsx b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/MeetingView.tsx index b0dff7e9..c3c2d247 100644 --- a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/MeetingView.tsx +++ b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/MeetingView.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; import { getJWTUserInfo, isValidStr, showErrorToasts } from '@capital/common'; -import type { IAgoraRTCRemoteUser } from 'agora-rtc-react'; import { useClient } from './client'; import { Videos } from './Videos'; import { Controls } from './Controls'; @@ -9,6 +8,7 @@ import { useMemoizedFn } from 'ahooks'; import { request } from '../request'; import styled from 'styled-components'; import { useMeetingStore } from './store'; +import { NetworkStats } from './NetworkStats'; const Root = styled.div` .body { @@ -74,7 +74,7 @@ export const MeetingView: React.FC = React.memo((props) => { const { appId, token } = data ?? {}; await client.join(appId, channelName, token, _id); - console.log('client.remoteUsers', client.remoteUsers); + await client.enableDualStream(); setStart(true); } catch (err) { showErrorToasts(err); @@ -94,6 +94,8 @@ export const MeetingView: React.FC = React.memo((props) => { return ( + +
{start ? : }
diff --git a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/NetworkStats.tsx b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/NetworkStats.tsx new file mode 100644 index 00000000..f0f54fe2 --- /dev/null +++ b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/NetworkStats.tsx @@ -0,0 +1,78 @@ +import { localTrans } from '@capital/common'; +import type { NetworkQuality } from 'agora-rtc-react'; +import React, { useEffect, useState } from 'react'; +import styled from 'styled-components'; +import { Translate } from '../translate'; +import { useClient } from './client'; + +const Root = styled.div` + display: flex; + position: absolute; + padding: 4px 8px; + z-index: 20; + + div + div { + margin-left: 8px; + } +`; + +export const NetworkStats: React.FC = React.memo(() => { + const client = useClient(); + const [stats, setStats] = useState(undefined); + + useEffect(() => { + const cb = (stats: NetworkQuality) => { + setStats(stats); + }; + + client.on('network-quality', cb); + + return () => { + client.off('network-quality', cb); + }; + }, []); + + if (!stats) { + return null; + } + + return ( + +
+ {Translate.uplink}: {parseQualityText(stats.uplinkNetworkQuality)} +
+
+ {Translate.downlink}: {parseQualityText(stats.downlinkNetworkQuality)} +
+
+ ); +}); +NetworkStats.displayName = 'NetworkStats'; + +function parseQualityText(quality: 0 | 1 | 2 | 3 | 4 | 5 | 6) { + if (quality === 1 || quality === 2) { + return localTrans({ + 'zh-CN': '优秀', + 'en-US': 'Good', + }); + } + + if (quality === 3 || quality === 4) { + return localTrans({ + 'zh-CN': '一般', + 'en-US': 'Normal', + }); + } + + if (quality === 5 || quality === 6) { + return localTrans({ + 'zh-CN': '差', + 'en-US': 'Bad', + }); + } + + return localTrans({ + 'zh-CN': '未知', + 'en-US': 'Unknown', + }); +} diff --git a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/VideoView.tsx b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/VideoView.tsx index 6543e1d7..77c948a8 100644 --- a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/VideoView.tsx +++ b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/FloatWindow/VideoView.tsx @@ -1,4 +1,4 @@ -import { UserName } from '@capital/component'; +import { UserAvatar, UserName } from '@capital/component'; import { AgoraVideoPlayer, IAgoraRTCRemoteUser } from 'agora-rtc-react'; import React from 'react'; import styled from 'styled-components'; @@ -15,6 +15,9 @@ const Root = styled.div` justify-self: center; align-self: center; overflow: hidden; + display: flex; + justify-content: center; + align-items: center; .player { width: 100%; @@ -36,8 +39,10 @@ export const VideoView: React.FC<{ return ( - {user.hasVideo && ( + {user.hasVideo ? ( + ) : ( + )} @@ -53,8 +58,10 @@ export const OwnVideoView: React.FC<{}> = React.memo(() => { return ( - {ready && mediaPerm.video && ( + {ready && mediaPerm.video ? ( + ) : ( + )} diff --git a/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/translate.ts b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/translate.ts new file mode 100644 index 00000000..bf67b5ea --- /dev/null +++ b/server/plugins/com.msgbyte.agora/web/plugins/com.msgbyte.agora/src/translate.ts @@ -0,0 +1,12 @@ +import { localTrans } from '@capital/common'; + +export const Translate = { + uplink: localTrans({ + 'zh-CN': '上行网络', + 'en-US': 'Uplink', + }), + downlink: localTrans({ + 'zh-CN': '下行网络', + 'en-US': 'Downlink', + }), +};