diff --git a/public/locales/en/chat.json b/public/locales/en/chat.json index 3622e118..09c5b12c 100644 --- a/public/locales/en/chat.json +++ b/public/locales/en/chat.json @@ -45,5 +45,6 @@ "file": "file", "image": "image", - "forward": "forward" + "forward": "forward", + "voice": "Voice" } diff --git a/public/locales/zh/chat.json b/public/locales/zh/chat.json index 21a588f5..dc173cd1 100644 --- a/public/locales/zh/chat.json +++ b/public/locales/zh/chat.json @@ -46,5 +46,6 @@ "file": "文件", "image": "图片", - "forward": "转发" + "forward": "转发", + "voice": "音频通话" } diff --git a/src/app/services/server.ts b/src/app/services/server.ts index 301f1ae4..aafbd33e 100644 --- a/src/app/services/server.ts +++ b/src/app/services/server.ts @@ -16,7 +16,8 @@ import { GithubAuthConfig, LicenseResponse, RenewLicense, - RenewLicenseResponse + RenewLicenseResponse, + AgoraTokenResponse } from "../../types/server"; import { Channel } from "../../types/channel"; import { ContentTypeKey } from "../../types/message"; @@ -109,6 +110,11 @@ export const serverApi = createApi({ body: data }) }), + getAgoraToken: builder.query({ + query: (id) => ({ + url: `group/${id}/agora_token`, + }) + }), getSMTPConfig: builder.query({ query: () => ({ url: `admin/smtp/config` }) }), @@ -320,5 +326,6 @@ export const { useLazyGetBotRelatedChannelsQuery, useSendMessageByBotMutation, useUpdateFrontendUrlMutation, - useGetFrontendUrlQuery + useGetFrontendUrlQuery, + useLazyGetAgoraTokenQuery } = serverApi; diff --git a/src/routes/chat/ChannelChat/index.tsx b/src/routes/chat/ChannelChat/index.tsx index 9e9b5854..4e8dacd8 100644 --- a/src/routes/chat/ChannelChat/index.tsx +++ b/src/routes/chat/ChannelChat/index.tsx @@ -84,7 +84,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { - + { +const Dashboard = ({ id, voicing, uid, channel }: Props) => { const dispatch = useDispatch(); - console.log("aaaaa"); + const [generateToken] = useLazyGetAgoraTokenQuery(); const { agoraConfig } = useConfig("agora"); useEffect(() => { - console.log("aaa", agoraConfig); + console.log("agora config", agoraConfig); const startConnect = async () => { // Create an instance of the Agora Engine const agoraEngine = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" }); @@ -27,17 +31,16 @@ const Dashboard = ({ voicing, uid, channel }: Props) => { await agoraEngine.subscribe(user, mediaType); console.log("subscribe success"); - // // Subscribe and play the remote audio track. - // if (mediaType == "audio") - // { - // channelParameters.remoteUid=user.uid; - // // Get the RemoteAudioTrack object from the AgoraRTCRemoteUser object. - // channelParameters.remoteAudioTrack = user.audioTrack; - // // Play the remote audio track. - // channelParameters.remoteAudioTrack.play(); - // console.log("Remote user connected: " + user.uid); + // Subscribe and play the remote audio track. + if (mediaType == "audio") { + // channelParameters.remoteUid=user.uid; + // // Get the RemoteAudioTrack object from the AgoraRTCRemoteUser object. + // channelParameters.remoteAudioTrack = user.audioTrack; + // Play the remote audio track. + user.audioTrack?.play(); + console.log("Remote user connected: " + user.uid); - // } + } // Listen for the "user-unpublished" event. agoraEngine.on("user-unpublished", user => { @@ -47,14 +50,19 @@ const Dashboard = ({ voicing, uid, channel }: Props) => { }); // Join a channel. console.log("join data ", agoraConfig); - await agoraEngine.join(agoraConfig!.app_id, agoraConfig!.rtm_key, agoraConfig!.rtm_secret, uid); - console.log("Joined channel: " + agoraConfig!.rtm_key); - // // Create a local audio track from the microphone audio. - // channelParameters.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); - // // Publish the local audio track in the channel. - // await agoraEngine.publish(channelParameters.localAudioTrack); - // console.log("Publish success!"); - dispatch(updateVoiceStatus(true)); + const { isError, data } = await generateToken(id); + if (!isError && data) { + const { channel_name, app_id, agora_token, uid } = data; + await agoraEngine.join(app_id, channel_name, agora_token, uid); + console.table(data); + // Create a local audio track from the microphone audio. + const localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); + // Publish the local audio track in the channel. + await agoraEngine.publish(localAudioTrack); + console.log("Publish success!"); + dispatch(updateVoiceStatus(true)); + } + }; if (!voicing && agoraConfig) { @@ -62,9 +70,7 @@ const Dashboard = ({ voicing, uid, channel }: Props) => { } }, [voicing, agoraConfig, uid, channel]); - return ( -
Dashboard
- ); + return voicing ? : ; }; export default Dashboard; \ No newline at end of file diff --git a/src/routes/chat/VoiceChat/JoinVoice.tsx b/src/routes/chat/VoiceChat/JoinVoice.tsx new file mode 100644 index 00000000..8083d21d --- /dev/null +++ b/src/routes/chat/VoiceChat/JoinVoice.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +type Props = {} + +const JoinVoice = (props: Props) => { + return ( +
JoinVoice
+ ); +}; + +export default JoinVoice; \ No newline at end of file diff --git a/src/routes/chat/VoiceChat/VoiceManagement.tsx b/src/routes/chat/VoiceChat/VoiceManagement.tsx new file mode 100644 index 00000000..dbe8c24c --- /dev/null +++ b/src/routes/chat/VoiceChat/VoiceManagement.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +type Props = {} + +const VoiceManagement = (props: Props) => { + return ( +
VoiceManagement
+ ); +}; + +export default VoiceManagement; \ No newline at end of file diff --git a/src/routes/chat/VoiceChat/index.tsx b/src/routes/chat/VoiceChat/index.tsx index 450fee6a..a6d626b3 100644 --- a/src/routes/chat/VoiceChat/index.tsx +++ b/src/routes/chat/VoiceChat/index.tsx @@ -7,23 +7,24 @@ import Tooltip from '../../../common/component/Tooltip'; import Dashboard from './Dashboard'; type Props = { + id: number, channel: string } -const VoiceChat = ({ channel }: Props) => { +const VoiceChat = ({ channel, id }: Props) => { const { loginUser, voice } = useAppSelector(store => { return { loginUser: store.authData.user, voice: store.authData.voice }; }); const { t } = useTranslation("chat"); const toolClass = `relative cursor-pointer`; if (!loginUser) return null; return ( - + } + content={} >
  • diff --git a/src/routes/chat/VoiceChat/useVoice.tsx b/src/routes/chat/VoiceChat/useVoice.tsx new file mode 100644 index 00000000..c69a31d0 --- /dev/null +++ b/src/routes/chat/VoiceChat/useVoice.tsx @@ -0,0 +1,23 @@ +import { useState } from "react"; +import { useAppSelector } from "../../../app/store"; + + + +const useVoice = (uid: number) => { + const [engine, setEngine] = useState(window.VoiceEngine); + const { voicing } = useAppSelector(store => { + + return { + voicing: store.users.byId[uid].voice ?? false + }; + }); + + + return { + voicing, + + }; + +}; + +export default useVoice; \ No newline at end of file diff --git a/src/types/server.ts b/src/types/server.ts index beb0d2d9..08c71372 100644 --- a/src/types/server.ts +++ b/src/types/server.ts @@ -27,6 +27,13 @@ export interface AgoraConfig { rtm_key: string; rtm_secret: string; } +export interface AgoraTokenResponse { + agora_token: string, + uid: number, + channel_name: string, + expired_in: number, + app_id: string; +} export interface SMTPConfig { enabled: boolean; host: string;