Skip to content

Commit 71fae00

Browse files
authored
Merge pull request #131 from CS3219-AY2425S1/jmsandiegoo/bugfix
Collaboration Bug Fixes
2 parents 2dad575 + 98b5bc7 commit 71fae00

File tree

3 files changed

+97
-92
lines changed

3 files changed

+97
-92
lines changed

backend/gateway-service/src/modules/collaboration/collaborationws.controller.ts

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,16 @@ export class CollaborationGateway implements OnGatewayDisconnect {
105105
this.server.to(sessionId).emit(SESSION_JOINED, {
106106
userId, // the user who recently joined
107107
sessionId,
108-
messages, // chat messages
108+
sessionMessages: messages, // chat messages
109109
language: existingLanguage || 'python3', // default language
110110
sessionUserProfiles, // returns the all session member profiles
111111
});
112-
113-
return {
114-
success: true,
115-
data: {
116-
messages, // chat messages
117-
},
118-
};
119112
} catch (e) {
120113
console.log(e);
121-
return {
122-
success: false,
114+
client.emit(SESSION_ERROR, {
115+
event: SESSION_JOIN,
123116
error: `Failed to join session: ${e.message}`,
124-
};
117+
});
125118
}
126119
}
127120

@@ -158,10 +151,11 @@ export class CollaborationGateway implements OnGatewayDisconnect {
158151
sessionUserProfiles,
159152
});
160153
} catch (e) {
161-
return {
162-
success: false,
154+
console.log(e);
155+
client.emit(SESSION_ERROR, {
156+
event: SESSION_JOIN,
163157
error: `Failed to leave session: ${e.message}`,
164-
};
158+
});
165159
}
166160
}
167161

@@ -191,18 +185,13 @@ export class CollaborationGateway implements OnGatewayDisconnect {
191185
message,
192186
timestamp,
193187
});
194-
195-
return {
196-
success: true,
197-
data: { id },
198-
};
199188
} catch (e) {
200189
console.log(e);
201-
return {
202-
success: false,
203-
data: { id },
190+
client.emit(SESSION_ERROR, {
191+
event: CHAT_SEND_MESSAGE,
192+
data: { id, timestamp },
204193
error: `Failed to send message: ${e.message}`,
205-
};
194+
});
206195
}
207196
}
208197

@@ -222,7 +211,10 @@ export class CollaborationGateway implements OnGatewayDisconnect {
222211
const { userId, sessionId, questionId, code, language } = payload;
223212

224213
if (!userId || !sessionId || !code) {
225-
client.emit(SESSION_ERROR, 'Invalid submit request payload.');
214+
client.emit(SESSION_ERROR, {
215+
event: SUBMIT,
216+
error: 'Invalid submit request payload.',
217+
});
226218
return;
227219
}
228220

@@ -316,7 +308,10 @@ export class CollaborationGateway implements OnGatewayDisconnect {
316308
const { userId, sessionId, language } = payload;
317309

318310
if (!userId || !sessionId || !language) {
319-
client.emit(SESSION_ERROR, 'Invalid change language request payload.');
311+
client.emit(SESSION_ERROR, {
312+
event: CHANGE_LANGUAGE,
313+
error: 'Invalid change language request payload.',
314+
});
320315
return;
321316
}
322317

@@ -345,7 +340,10 @@ export class CollaborationGateway implements OnGatewayDisconnect {
345340
const { userId, sessionId } = payload;
346341

347342
if (!userId || !sessionId) {
348-
client.emit(SESSION_ERROR, 'Invalid change language request payload.');
343+
client.emit(SESSION_ERROR, {
344+
event: SESSION_END,
345+
error: 'Invalid session end request payload.',
346+
});
349347
return;
350348
}
351349

frontend/src/app/collaboration/_components/Editor/CollaborativeEditor/CollaborativeEditorTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useSessionContext } from "@/contexts/SessionContext";
55
export default function CollaborativeEditorTab() {
66
const {sessionId, userProfile} = useSessionContext();
77

8-
const socketUrl = process.env.NEXT_PUBLIC_Y_WEBSOCKET_URL || "ws://localhost:4001";
8+
const socketUrl = process.env.PUBLIC_Y_WEBSOCKET_URL || "ws://localhost:4001";
99

1010
if (!userProfile) {
1111
return <div>Loading user profile...</div>;

frontend/src/contexts/SessionContext.tsx

Lines changed: 72 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -162,104 +162,76 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
162162

163163
setMessages((prev) => [...prev, newMessage]);
164164

165-
socket.emit(
166-
"chatSendMessage",
167-
newMessage,
168-
(ack: {
169-
success: boolean;
170-
data: { id: string; timestamp: string };
171-
error: string | undefined;
172-
}) => {
173-
setMessages((prev) =>
174-
prev.map((message) => {
175-
if (message.id !== ack.data.id) return message;
176-
if (ack.success) {
177-
return {
178-
...message,
179-
status: ChatMessageStatusEnum.enum.sent,
180-
};
181-
} else {
182-
return {
183-
...message,
184-
status: ChatMessageStatusEnum.enum.failed,
185-
};
186-
}
187-
})
188-
);
189-
190-
if (ack.success) {
191-
newMessage.status = ChatMessageStatusEnum.enum.sent;
192-
newMessage.timestamp = ack.data.timestamp;
193-
} else {
194-
newMessage.status = ChatMessageStatusEnum.enum.failed;
195-
}
196-
}
197-
);
165+
socket.emit("chatSendMessage", newMessage);
198166
},
199167
[sessionId, socket, userProfile.id]
200168
);
201169

202170
const handleJoinSession = useCallback(
203171
(payload: SessionJoinRequest) => {
204172
if (!socket.connected) return;
205-
206-
socket.emit(
207-
"sessionJoin",
208-
payload,
209-
(ack: {
210-
success: boolean;
211-
data: { messages: ChatMessages };
212-
error: string | undefined;
213-
}) => {
214-
try {
215-
if (!ack.success) throw new Error(ack.error);
216-
setConnectionStatus("connected");
217-
const currentMessages = ChatMessagesSchema.parse(
218-
ack.data.messages.map((message: ChatMessage) => ({
219-
...message,
220-
status: ChatMessageStatusEnum.enum.sent,
221-
}))
222-
);
223-
setMessages([...currentMessages]);
224-
} catch (e) {
225-
setConnectionStatus("failed");
226-
}
227-
}
228-
);
173+
socket.emit("sessionJoin", payload);
229174
},
230175
[socket]
231176
);
232177

233178
const onSessionJoined = useCallback(
234179
({
180+
userId,
235181
language,
182+
sessionMessages,
236183
sessionUserProfiles,
237184
}: {
185+
userId: string;
238186
language: string;
187+
sessionMessages: ChatMessages;
239188
sessionUserProfiles: SessionUserProfiles;
240189
}) => {
241190
console.log("sessionJoined occured");
242191
try {
243-
_setLanguage(language);
192+
if (userProfile.id === userId) {
193+
setConnectionStatus("connected");
194+
const currentMessages = ChatMessagesSchema.parse(
195+
sessionMessages.map((message: ChatMessage) => ({
196+
...message,
197+
status: ChatMessageStatusEnum.enum.sent,
198+
}))
199+
);
200+
201+
setMessages([...currentMessages]);
202+
}
244203

204+
_setLanguage(language);
245205
const currentSessionUserProfiles =
246206
SessionUserProfilesSchema.parse(sessionUserProfiles);
247207
setSessionUserProfiles([...currentSessionUserProfiles]);
248208
} catch (e) {
249-
// TODO toast here
250209
console.log(e);
251210
}
252211
},
253-
[]
212+
[userProfile.id]
254213
);
255214

256215
const onChatReceiveMessage = useCallback(
257216
(newMessage: ChatMessage) => {
217+
console.log("chatReceiveMessage occured");
258218
try {
259219
newMessage["status"] = ChatMessageStatusEnum.enum.sent;
260220
const messageParsed = ChatMessageSchema.parse(newMessage);
261221

262-
if (messageParsed.userId === userProfile.id) return;
222+
if (messageParsed.userId === userProfile.id) {
223+
// set the loclly sent message
224+
setMessages((prev) =>
225+
prev.map((message) => {
226+
if (message.id !== messageParsed.id) return message;
227+
return {
228+
...message,
229+
status: ChatMessageStatusEnum.enum.sent,
230+
};
231+
})
232+
);
233+
return;
234+
}
263235

264236
setMessages((prev) => [...prev, messageParsed]);
265237
} catch (e) {
@@ -370,7 +342,7 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
370342
userId: userProfile.id,
371343
sessionId,
372344
});
373-
}, [socket]);
345+
}, [sessionId, socket, userProfile.id]);
374346

375347
const onSessionEnded = useCallback(
376348
({ endedBy }: { endedBy: string; message: string }) => {
@@ -386,7 +358,39 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
386358
router.push("/dashboard");
387359
}, 4000);
388360
},
389-
[toast, router]
361+
[toast, userProfile.id, router]
362+
);
363+
364+
const onSessionError = useCallback(
365+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
366+
({
367+
event,
368+
data,
369+
error,
370+
}: {
371+
event: string;
372+
data: undefined | { id: string; timestamp: string };
373+
error: string;
374+
}) => {
375+
console.log(`Session Error received ${error}`);
376+
377+
if (event === "sessionJoin") {
378+
setConnectionStatus("failed");
379+
}
380+
381+
if (event === "chatSendMessage") {
382+
setMessages((prev) =>
383+
prev.map((message) => {
384+
if (message.id !== data?.id) return message;
385+
return {
386+
...message,
387+
status: ChatMessageStatusEnum.enum.failed,
388+
};
389+
})
390+
);
391+
}
392+
},
393+
[]
390394
);
391395

392396
// connect to the session socket on mount
@@ -412,6 +416,7 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
412416
socket.on("submitted", onSubmitted);
413417

414418
socket.on("sessionEnded", onSessionEnded);
419+
socket.on("sessionError", onSessionError);
415420

416421
return () => {
417422
socket.emit("sessionLeave", {
@@ -432,6 +437,8 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
432437
onSessionJoined,
433438
onSessionLeft,
434439
onLanguageChanged,
440+
onSessionEnded,
441+
onSessionError,
435442
]);
436443

437444
const contextValue: SessionContextType = useMemo(
@@ -463,7 +470,6 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
463470
}),
464471
[
465472
connectionStatus,
466-
codeReview,
467473
sessionId,
468474
sessionUserProfiles,
469475
getUserProfileDetailByUserId,
@@ -476,7 +482,8 @@ export const SessionProvider: React.FC<SessionProviderProps> = ({
476482
submitting,
477483
submissionResult,
478484
testResultPanel,
479-
setTestResultPanel,
485+
endSession,
486+
codeReview,
480487
setCurrentClientCode,
481488
generateCodeReview,
482489
]

0 commit comments

Comments
 (0)