Skip to content

Commit

Permalink
Merge branch 'frontend_dev' of https://github.com/CS3219-AY2425S1/cs3…
Browse files Browse the repository at this point in the history
…219-ay2425s1-project-g05 into frontend_dev
  • Loading branch information
georgetayqy committed Nov 13, 2024
2 parents dddc3ef + 4cd0bef commit 515c625
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 29 deletions.
80 changes: 71 additions & 9 deletions peer-prep/src/components/Communication/Video/VideoChatWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Offer = RTCSessionDescriptionInit;

enum CALL_STATUS {
IDLE,
CALLING,
CALLING, // ready to call
CONNECTED,
INCOMING,
}
Expand All @@ -68,6 +68,9 @@ export default function VideoChatWidget({
roomId: string;
}) {
const auth = useAuth();
const [remotePeerIdFromCall, setRemotePeerIdFromCall] = useState<
string | null
>(null);

const [callStatus, setCallStatus] = useState<CALL_STATUS>(CALL_STATUS.IDLE);
const callStatusRef = useRef<CALL_STATUS>(CALL_STATUS.IDLE);
Expand All @@ -80,11 +83,12 @@ export default function VideoChatWidget({
const remoteVideoRef = useRef<HTMLVideoElement>(null);

// only when this is populated are we ready to make a call (connection wise)
const [peerId, setPeerId] = useState(null);
const [remotePeerIdValue, setRemotePeerIdValue] = useState("");
const peerInstance = useRef(null);
const peerInstance = useRef<Peer | null>(null);
const mediaConnection = useRef(null);

const [localStream, setLocalStream] = useState<MediaStream | null>(null);
const remoteStreamRef = useRef<MediaStream | null>(null);
function init() {
console.log("DEBUG: auth.user", auth.user);
if (!auth.user) {
Expand All @@ -97,11 +101,18 @@ export default function VideoChatWidget({

peer.on("open", (id) => {
console.log("DEBUG: peer open id set to", id);
setPeerId(id);
});

peer.on("call", async (call) => {
console.log("DEBUG: call received", call);
setRemotePeerIdFromCall(call.peer);

// setup a listener for when the call ends
const conn = peer.connect(call.peer);
console.log("DEBUG: conn", conn);
conn.on("data", (data) => {
console.log(`DEBUG: data received FROM PEERJS: `, data);
});

// dont answer if not ready to call
if (callStatusRef.current !== CALL_STATUS.CALLING) {
Expand All @@ -113,10 +124,14 @@ export default function VideoChatWidget({
} is calling you! Go to the chat room to answer the call.`,
title: "Incoming call",
color: "cyan",
autoClose: 10000,
autoClose: 5000,
});

setCallStatusWrapper(CALL_STATUS.INCOMING);

// set otherUser to the user who is calling
// user id is the peer id

return;
}

Expand All @@ -126,6 +141,8 @@ export default function VideoChatWidget({
audio: true,
});

setLocalStream(stream);

selfVideoRef.current.srcObject = stream;
selfVideoRef.current.play();
selfVideoRef.current.muted = true;
Expand All @@ -139,9 +156,11 @@ export default function VideoChatWidget({

call.on("close", () => {
console.log("DEBUG: call closed in receiver");

onEndCall();
});
});

peerInstance.current = peer;
}
useEffect(() => {
Expand All @@ -154,12 +173,13 @@ export default function VideoChatWidget({
const call = async () => {
if (!peerInstance.current) init();
// remote peer id is the user id
if (callStatusRef.current === CALL_STATUS.IDLE) {
setCallStatusWrapper(CALL_STATUS.CALLING);
}
// if (callStatusRef.current === CALL_STATUS.IDLE) {
setCallStatusWrapper(CALL_STATUS.CALLING);
// }

// call will fail if the other user is not ready to receive the call
const remotePeerId = `${roomId}-${otherUser?.userId}`;
const remotePeerId =
remotePeerIdFromCall || `${roomId}-${otherUser?.userId}`;

console.log("DEBUG: calling", remotePeerId);
console.log("DEBUG: READY TO CALL");
Expand All @@ -169,6 +189,10 @@ export default function VideoChatWidget({
audio: true,
});

console.log("DEBUG: stream", stream);
setLocalStream(stream);
console.log("DEBUG: local stream", localStream);

selfVideoRef.current.srcObject = stream;
selfVideoRef.current.play();
selfVideoRef.current.muted = true;
Expand All @@ -184,13 +208,50 @@ export default function VideoChatWidget({

call.on("close", () => {
console.log("DEBUG: call closed in caller");
console.log("DEBUG: ", {
localStream: call.localStream,
remoteStream: call.remoteStream,
call,
mediaConnection: mediaConnection.current,
});
call.localStream?.getTracks().forEach((track) => track.stop());
call.remoteStream?.getTracks().forEach((track) => track.stop());
onEndCall();
});

const conn = peerInstance.current.connect(remotePeerId);

// When the connection is open, send a message
conn.on("open", () => {
console.log("DEBUG: connection open");

conn.send("Hello, Peer!");
peerInstance.current.on("close", () => {
console.log("DEBUG: peer connection closed");
// when the peer connection is closed, tell the other
conn.send({ callStatus: "ended" });
});
});
};

function onEndCall() {
// console.log("DEBUG: call end function");
// console.log("DEBUG: ", {
// mediaConnection: mediaConnection.current,
// localStream,
// });

// console.log("DEBUG: localstream.getracks", localStream?.getTracks());

// stop use of webcam
localStream?.getTracks().forEach((t) => (t.enabled = false));
localStream?.getTracks().forEach((track) => track.stop());

setLocalStream(null);

// cleanup
setCallStatusWrapper(CALL_STATUS.IDLE);

if (selfVideoRef.current) selfVideoRef.current.srcObject = null;
if (remoteVideoRef.current) remoteVideoRef.current.srcObject = null;

Expand Down Expand Up @@ -270,6 +331,7 @@ export default function VideoChatWidget({
useEffect(() => {
setDomReady(true);
}, []);
if (!otherUser && !remotePeerIdFromCall) return null;
return (
<Box>
<Group gap="xs">
Expand Down
46 changes: 33 additions & 13 deletions peer-prep/src/components/TestCases/TestCasesWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
Space,
Text,
Title,
Tooltip,
useMantineColorScheme,
} from "@mantine/core";
import classes from "./TestCasesWrapper.module.css";
Expand Down Expand Up @@ -43,9 +44,7 @@ import ReactMarkdown from "react-markdown";
import { useAi } from "../../hooks/useAi";

type TestCasesWrapperProps = {
testCases: TestCase[]; // array of test cases
channelId: string | null;
questionId: string | null;

// to decide if we want to pass down a function from parent instead of passing down solutioncode
// runAllTestCases: () => void;
Expand All @@ -57,19 +56,21 @@ type TestCasesWrapperProps = {
latestResultsRef: React.MutableRefObject<TestCaseResult[]>;

roomId: string;
question: string;

question: Question;
};

const STATUS_PARTIAL = 206;
const STATUS_COMPLETE = 200;
const STATUS_CONNECTED = 201;
const STATUS_STARTED = 202;

const BLOCKED_CATEGORY_IDS = [2];

export default function TestCasesWrapper({
testCases,
channelId,
// runAllTestCases,
questionId,

currentValueRef,

userId,
Expand All @@ -78,8 +79,17 @@ export default function TestCasesWrapper({
latestResultsRef,

roomId,

question,
}: TestCasesWrapperProps) {
const questionString = question.description.descriptionText;
const questionId = question._id;
const testCases = question.testCases;

const isBlockedFromRunningTestCase = question.categoriesId.some((id) =>
BLOCKED_CATEGORY_IDS.includes(id)
);

const [latestResults, setLatestResults] = useState<TestCaseResult[]>([]);

const [currentTestCase, setCurrentTestCase] = useState<TestCase | null>(
Expand Down Expand Up @@ -125,8 +135,6 @@ export default function TestCasesWrapper({
attemptRef.current = attemptRef.current + 1;
}

console.log(attemptCodeMap, "asdnashjkdhbj");

const onMessage = (event: MessageEvent<string>) => {
console.log("LOG: event source on message");
console.log(event);
Expand Down Expand Up @@ -316,7 +324,6 @@ export default function TestCasesWrapper({
return "red";
}
}
console.log({ colorScheme });

return (
<Box className={classes.container}>
Expand All @@ -328,10 +335,23 @@ export default function TestCasesWrapper({
>
Test Cases ({testCases.length})
</Title>
<Button variant="light" onClick={runTestCases} loading={isRunning}>
{" "}
Run all testcases{" "}
</Button>
<Tooltip
label={
isBlockedFromRunningTestCase
? "Testcase running is disabled for Database questions."
: "Run your code on the server. This may take some time!"
}
>
<Button
variant="light"
onClick={runTestCases}
loading={isRunning}
disabled={isBlockedFromRunningTestCase}
>
{" "}
Run all testcases{" "}
</Button>
</Tooltip>
</Group>
<TestCasesDisplay
key={testCaseRunKey}
Expand All @@ -342,7 +362,7 @@ export default function TestCasesWrapper({
testCases={testCases}
roomId={roomId}
userId={userId}
question={question}
question={questionString}
/>
<>
{/* <>
Expand Down
9 changes: 2 additions & 7 deletions peer-prep/src/pages/Session/SessionPage/SessionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export default function SessionPage() {
roomIdReceived: string;
otherUserIdReceived: string;
} = location.state || {};
console.log({ questionReceived });
const question = questionReceived || dummyQuestion;

const roomId = useParams().roomId;
Expand Down Expand Up @@ -149,9 +148,7 @@ export default function SessionPage() {
// when true, don't show modal when # users in room < 2
// const [isWaitingForRejoin, setIsWaitingForRejoin] = useState(false);
const isWaitingForRejoinRef = useRef(false);
console.log("LOG: in session page, latestAttempt = ", {
latestResultsRef: latestResultsRef.current,
});

// don't need to rerender!
const currentValueRef = useRef("");
const peopleInRoomFromCollabServiceRef = useRef<number>(0);
Expand Down Expand Up @@ -689,15 +686,13 @@ export default function SessionPage() {
</Paper>

<TestCasesWrapper
testCases={question.testCases || []}
channelId={channelId}
questionId={question._id}
currentValueRef={currentValueRef}
userId={user._id}
otherUserId={otherUserId}
latestResultsRef={latestResultsRef}
roomId={roomId}
question={question.description.descriptionText}
question={question}
/>
</Stack>
</Flex>
Expand Down

0 comments on commit 515c625

Please sign in to comment.