feat: useVoice

This commit is contained in:
Tristan Yang
2023-03-24 23:07:56 +08:00
parent da00f3b797
commit 92411d0468
20 changed files with 331 additions and 132 deletions
+2 -1
View File
@@ -27,7 +27,8 @@ const whiteList = [
"createAdmin",
"getBotRelatedChannels",
"sendMessageByBot",
"replyWithChatGPT"
"replyWithChatGPT",
"getAgoraVoicingList"
];
const baseQuery = fetchBaseQuery({
+31 -2
View File
@@ -17,10 +17,12 @@ import {
LicenseResponse,
RenewLicense,
RenewLicenseResponse,
AgoraTokenResponse
AgoraTokenResponse,
AgoraVoicingListResponse
} from "../../types/server";
import { Channel } from "../../types/channel";
import { ContentTypeKey } from "../../types/message";
import { updateVoiceInfo } from "../slices/voice";
const defaultExpireDuration = 2 * 24 * 60 * 60;
@@ -115,6 +117,31 @@ export const serverApi = createApi({
url: `group/${id}/agora_token`,
})
}),
getAgoraVoicingList: builder.query<AgoraVoicingListResponse, { appid: string, key: string, secret: string }>({
query: ({ appid, key, secret }) => ({
headers: {
Authorization: `Basic ${btoa(`${key}:${secret}`)}`
},
url: `https://api.agora.io/dev/v1/channel/${appid}`,
}),
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
const { data: resp } = await queryFulfilled;
const { success } = resp;
if (success && resp.data.channels.length > 0) {
const [channel] = resp.data.channels;
const [id] = channel.channel_name.split(":").slice(-1);
// todo
dispatch(updateVoiceInfo({
id: +id,
context: "channel"
}));
}
} catch {
console.error("get voice list error");
}
}
}),
getSMTPConfig: builder.query<SMTPConfig, void>({
query: () => ({ url: `admin/smtp/config` })
}),
@@ -327,5 +354,7 @@ export const {
useSendMessageByBotMutation,
useUpdateFrontendUrlMutation,
useGetFrontendUrlQuery,
useLazyGetAgoraTokenQuery
useLazyGetAgoraTokenQuery,
useGetAgoraConfigQuery,
useGetAgoraVoicingListQuery
} = serverApi;
+1 -4
View File
@@ -85,9 +85,6 @@ const authDataSlice = createSlice({
updateRoleChanged(state, action: PayloadAction<boolean>) {
state.roleChanged = action.payload;
},
updateVoiceStatus(state, action: PayloadAction<boolean>) {
state.voice = action.payload;
},
resetAuthData() {
// remove local data
localStorage.removeItem(KEY_EXPIRE);
@@ -134,5 +131,5 @@ const authDataSlice = createSlice({
// }
});
export const { updateInitialized, updateLoginUser, setAuthData, resetAuthData, updateToken, updateRoleChanged, updateVoiceStatus } = authDataSlice.actions;
export const { updateInitialized, updateLoginUser, setAuthData, resetAuthData, updateToken, updateRoleChanged } = authDataSlice.actions;
export default authDataSlice.reducer;
+63
View File
@@ -0,0 +1,63 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export type VoiceInfo = {
context: "channel" | "dm"
id: number | null,
members: number[]
}
interface State {
joined: boolean,
voicing: VoiceInfo
}
const initialInfo = {
context: "channel" as const,
id: null,
members: []
};
const initialState: State = {
joined: false,
voicing: initialInfo
};
const voiceSlice = createSlice({
name: "voice",
initialState,
reducers: {
updateJoinStatus(state, { payload }: PayloadAction<boolean>) {
state.joined = payload;
},
updateVoiceInfo(state, { payload }: PayloadAction<VoiceInfo | null>) {
if (!payload) {
// reset
state.voicing = initialInfo;
} else {
if (state.voicing) {
state.voicing = { ...state.voicing, ...payload };
} else {
state.voicing = payload;
}
}
},
addVoiceMember(state, { payload }: PayloadAction<number>) {
if (state.voicing) {
if (!state.voicing.members.includes(payload)) {
state.voicing.members.push(payload);
}
}
},
removeVoiceMember(state, { payload }: PayloadAction<number>) {
if (state.voicing) {
const idx = state.voicing.members.findIndex((uid) => uid == payload);
if (idx > -1) {
state.voicing.members.splice(idx, 1);
}
}
}
},
});
export const { updateJoinStatus, updateVoiceInfo, addVoiceMember, removeVoiceMember } = voiceSlice.actions;
export default voiceSlice.reducer;
+2
View File
@@ -3,6 +3,7 @@ import { setupListeners } from "@reduxjs/toolkit/query";
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import listenerMiddleware from "./listener.middleware";
import authDataReducer from "./slices/auth.data";
import voiceReducer from "./slices/voice";
import footprintReducer from "./slices/footprint";
import serverReducer from "./slices/server";
import uiReducer from "./slices/ui";
@@ -23,6 +24,7 @@ import { serverApi } from "./services/server";
const reducer = combineReducers({
authData: authDataReducer,
voice: voiceReducer,
ui: uiReducer,
footprint: footprintReducer,
server: serverReducer,