maybe working full?

This commit is contained in:
Arjun Patel
2022-01-22 21:22:03 -08:00
parent 1baa07faa4
commit 7220867bec
6 changed files with 201 additions and 95 deletions
+85 -1
View File
@@ -1,3 +1,9 @@
import {
ClientConfig,
IAgoraRTC,
IAgoraRTCClient,
IMicrophoneAudioTrack,
} from "agora-rtc-sdk-ng";
import { Tooltip } from "antd";
import {
collection,
@@ -7,9 +13,11 @@ import {
where,
} from "firebase/firestore";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useAuth } from "../../contexts/authContext";
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
import OfficeRoom from "../../models/officeRoom";
import { appId } from "../../services/agoraService";
import { Collections } from "../../services/collections";
import OfficeRoomService from "../../services/officeRoomService";
import OfficeCard from "../OfficeCard";
@@ -18,9 +26,18 @@ const db = getFirestore();
const officeRoomService = new OfficeRoomService();
const config: ClientConfig = {
mode: "rtc",
codec: "vp8",
};
export default function Office() {
const { currUser } = useAuth();
const { team } = useTeamDashboardContext();
const [agoraRtc, setAgoraRtc] = useState<IAgoraRTC>(null);
const [agoraRtcClient, setAgoraRtcClient] = useState<IAgoraRTCClient>(null);
const [localAudioTrack, setLocalAudioTrack] =
useState<IMicrophoneAudioTrack>(null);
const [officeRoomsMap, setOfficeRoomsMap] = useState<Map<string, OfficeRoom>>(
new Map<string, OfficeRoom>()
@@ -66,6 +83,68 @@ export default function Office() {
});
}, []);
// set up agora stuff
useEffect(() => {
(async function () {
// dynamic import as the server side import doesn't work
const AgoraRTC = (await import("agora-rtc-sdk-ng")).default;
const agoraClient = AgoraRTC.createClient(config);
setAgoraRtcClient(agoraClient);
setAgoraRtc(AgoraRTC);
})();
}, []);
async function handleJoinChannel(channelName: string, agoraToken: string) {
const localTrack: IMicrophoneAudioTrack =
await agoraRtc.createMicrophoneAudioTrack();
setLocalAudioTrack(localTrack);
let init = async (chanName: string) => {
agoraRtcClient.on("user-published", async (user, mediaType) => {
await agoraRtcClient.subscribe(user, mediaType);
console.log("subscribe success");
if (mediaType === "audio") {
user.audioTrack?.play();
}
});
agoraRtcClient.on("user-unpublished", async (user, type) => {
console.log("unpublished", user, type);
if (type === "audio") {
user.audioTrack?.stop();
}
await agoraRtcClient.unsubscribe(user);
});
agoraRtcClient.on("user-left", (user) => {
console.log("user left", user);
});
await agoraRtcClient.join(appId, chanName, agoraToken, null);
if (localTrack) await agoraRtcClient.publish(localTrack);
};
if (localTrack) {
console.log("init ready");
init(channelName);
} else {
toast.error("Not ready for joining call");
return;
}
}
async function handleLeaveChannel() {
// destroy local track
localAudioTrack?.close();
// leave all channels
await agoraRtcClient.leave();
}
const allOfficeRooms = Array.from(officeRoomsMap.values());
allOfficeRooms.sort((a, b) => {
@@ -98,7 +177,12 @@ export default function Office() {
{/* all office rooms */}
<span className="flex flex-col overflow-auto pr-2 space-y-2">
{allOfficeRooms.map((officeRoom) => (
<OfficeCard key={officeRoom.id} officeRoom={officeRoom} />
<OfficeCard
key={officeRoom.id}
officeRoom={officeRoom}
handleJoinChannel={handleJoinChannel}
handleLeaveChannel={handleLeaveChannel}
/>
))}
{/* <OfficeCard /> */}
</span>
+24 -16
View File
@@ -7,17 +7,16 @@ import OfficeRoom, { OfficeRoomState } from "../models/officeRoom";
import { User } from "../models/user";
import OfficeRoomService from "../services/officeRoomService";
import { VscDebugDisconnect } from "react-icons/vsc";
import {
AgoraVideoPlayer,
createClient,
createMicrophoneAudioTrack,
} from "agora-rtc-react";
import AgoraService from "../services/agoraService";
interface IOfficeCard {
officeRoom: OfficeRoom;
handleJoinChannel: Function;
handleLeaveChannel: Function;
}
const officeRoomService = new OfficeRoomService();
const agoraService = new AgoraService();
export default function OfficeCard(props: IOfficeCard) {
const { currUser } = useAuth();
@@ -48,36 +47,43 @@ export default function OfficeCard(props: IOfficeCard) {
}
try {
// todo: pass in the right channel name based on the office room id
const agoraToken = await officeRoomService.getAgoraToken();
// agora token from CF
const agoraToken = await agoraService.getAgoraToken(props.officeRoom.id);
console.log(agoraToken);
// // function to do it all
// await officeRoomService.joinOfficeRoom(props.officeRoom, currUser.uid);
// join right channel on agora
// handle joining agora channel
await props.handleJoinChannel(props.officeRoom.id, agoraToken);
// const newMembers = [...props.officeRoom.members, currUser.uid];
// await officeRoomService.updateMembersInOfficeRoom(
// props.officeRoom.id,
// newMembers
// );
// update firestore to add ourselves in the office room
const newMembers = [...props.officeRoom.members, currUser.uid];
await officeRoomService.updateMembersInOfficeRoom(
props.officeRoom.id,
newMembers
);
} catch (error) {
console.error(error);
toast.error("problem joining office room");
}
toast.dismiss();
toast.success("joined office room");
}
async function handleLeaveOfficeRoom() {
// leave the channel for agora
toast.loading("leaving");
// leave from firestore database
if (!props.officeRoom.members.includes(currUser.uid)) {
toast.error("You are not in this office room!");
return;
}
try {
// leave agora channel
await props.handleLeaveChannel();
// leave from firestore database
const newMembersInRoom = props.officeRoom.members.filter(
(memberId) => memberId != currUser.uid
);
@@ -90,6 +96,8 @@ export default function OfficeCard(props: IOfficeCard) {
console.error(error);
toast.error("problem leaving office room");
}
toast.dismiss();
toast.success("left office room");
}
// check if user is in the office room
-23
View File
@@ -6,7 +6,6 @@
"": {
"name": "nirvana",
"dependencies": {
"agora-rtc-react": "^1.1.0",
"agora-rtc-sdk-ng": "^4.8.1",
"antd": "^4.18.3",
"firebase": "^9.6.2",
@@ -2584,20 +2583,6 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"optional": true
},
"node_modules/agora-rtc-react": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/agora-rtc-react/-/agora-rtc-react-1.1.0.tgz",
"integrity": "sha512-+cvK3gXcUC2FzXkrN9L/nE5B6FqgP2w7fWid5wpsdtzmBMf/gehzN1cDhMSDz2oI3Jq/9zo9R4iVswPx+QtAGA==",
"dependencies": {
"agora-rtc-sdk-ng": "^4.3.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^16.8.0 || ^17"
}
},
"node_modules/agora-rtc-sdk-ng": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.8.1.tgz",
@@ -11296,14 +11281,6 @@
}
}
},
"agora-rtc-react": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/agora-rtc-react/-/agora-rtc-react-1.1.0.tgz",
"integrity": "sha512-+cvK3gXcUC2FzXkrN9L/nE5B6FqgP2w7fWid5wpsdtzmBMf/gehzN1cDhMSDz2oI3Jq/9zo9R4iVswPx+QtAGA==",
"requires": {
"agora-rtc-sdk-ng": "^4.3.0"
}
},
"agora-rtc-sdk-ng": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.8.1.tgz",
-1
View File
@@ -8,7 +8,6 @@
"lint": "next lint"
},
"dependencies": {
"agora-rtc-react": "^1.1.0",
"agora-rtc-sdk-ng": "^4.8.1",
"antd": "^4.18.3",
"firebase": "^9.6.2",
+81 -9
View File
@@ -1,22 +1,94 @@
import {
import AgoraRTC, {
ClientConfig,
IAgoraRTCRemoteUser,
ICameraVideoTrack,
IMicrophoneAudioTrack,
} from "agora-rtc-sdk-ng";
import {
AgoraVideoPlayer,
createClient,
createMicrophoneAndCameraTracks,
createMicrophoneAudioTrack,
} from "agora-rtc-react";
// import {
// AgoraVideoPlayer,
// createClient,
// createMicrophoneAndCameraTracks,
// createMicrophoneAudioTrack,
// } from "agora-rtc-react";
import { getFunctions, httpsCallable } from "firebase/functions";
import toast from "react-hot-toast";
const config: ClientConfig = {
mode: "rtc",
codec: "vp8",
};
const useClient = createClient(config);
const useMicrophoneTracks = createMicrophoneAudioTrack();
// const useClient = createClient(config);
// const useMicrophoneTracks = createMicrophoneAudioTrack();
// TODO: move this to env file
const appId: string = "c8dfd65deb5c4741bd564085627139d0"; //ENTER APP ID HERE
export default class AgoraService {
private functions = getFunctions();
// private rtcClient = useClient();
async getAgoraToken(channelName: string): Promise<string> {
const cfResult = httpsCallable(this.functions, "agoraToken");
return await cfResult({ channelName })
.then((result: { data: { token: string } }) => {
const data = result.data;
if (!data.token) {
throw new Error("No token retrieved from agora");
}
return data.token;
})
.catch((error) => {
// Getting the Error details.
const code = error.code;
const message = error.message;
const details = error.details;
throw error;
});
}
// async handleJoinChannel(channelName: string, agoraToken: string) {
// const localTrack: IMicrophoneAudioTrack =
// await AgoraRTC.createMicrophoneAudioTrack();
// let init = async (name: string) => {
// this.rtcClient.on("user-published", async (user, mediaType) => {
// await this.rtcClient.subscribe(user, mediaType);
// console.log("subscribe success");
// if (mediaType === "audio") {
// user.audioTrack?.play();
// }
// });
// this.rtcClient.on("user-unpublished", async (user, type) => {
// console.log("unpublished", user, type);
// if (type === "audio") {
// user.audioTrack?.stop();
// }
// await this.rtcClient.unsubscribe(user);
// });
// this.rtcClient.on("user-left", (user) => {
// console.log("user left", user);
// });
// await this.rtcClient.join(appId, name, agoraToken, null);
// if (localTrack) await this.rtcClient.publish(localTrack);
// };
// if (localTrack) {
// console.log("init ready");
// init(channelName);
// } else {
// toast.error("Not ready for joining call");
// return;
// }
// }
}
export { appId };
+11 -45
View File
@@ -10,17 +10,14 @@ import {
writeBatch,
} from "firebase/firestore";
import OfficeRoom, { OfficeRoomState } from "../models/officeRoom";
// import AgoraService from "./agoraService";
import { Collections } from "./collections";
import { getFunctions, httpsCallable } from "firebase/functions";
interface IAgoraTokenResult {
data: { token: string };
}
export default class OfficeRoomService {
private db: Firestore = getFirestore();
private batch = writeBatch(this.db);
private functions = getFunctions();
// private agoraService = new AgoraService();
async createInitialOfficeRooms(createdByUserId: string, teamId: string) {
const entrance = new OfficeRoom("Entrance", teamId, createdByUserId);
@@ -51,47 +48,16 @@ export default class OfficeRoomService {
await this.batch.commit();
}
// async createOrUpdateRoom(room: Room) {
// if (room.id) {
// //update
// await this.updateRoom(room);
// } else {
// //create
// const roomDocRef = await addDoc(collection(this.db, Collections.rooms), {
// ...room,
// createdDate: serverTimestamp(),
// });
// }
// }
async joinOfficeRoom(officeRoom: OfficeRoom, userId: string) {
// get agoraToken
// const agoraToken = await this.agoraService.getAgoraToken();
async getAgoraToken(): Promise<string> {
// const agoraToken = await fetch("/api/agora/token", {
// method: "post",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({ channelName: "testChannel" }),
// });
// join channel
// await this.agoraService.handleJoinChannel(officeRoom.id, agoraToken);
const cfResult = httpsCallable(this.functions, "agoraToken");
return await cfResult({ channelName: "testChannel" })
.then((result: IAgoraTokenResult) => {
const data = result.data;
if (!data.token) {
throw new Error("No token retrieved from agora");
}
return data.token;
})
.catch((error) => {
// Getting the Error details.
const code = error.code;
const message = error.message;
const details = error.details;
throw error;
});
// update members list in firestore
const newMembers = [...officeRoom.members, userId];
await this.updateMembersInOfficeRoom(officeRoom.id, newMembers);
}
async updateMembersInOfficeRoom(