Skip to content

Commit 6ab7b07

Browse files
authored
Merge pull request #182 from CS3219-AY2425S1/set-up-collab-service-frontend
Set up common room logic in preparation for collaboration service
2 parents 8767ac9 + 6547c1b commit 6ab7b07

File tree

3 files changed

+99
-21
lines changed

3 files changed

+99
-21
lines changed

frontend/components/matching/find-match.tsx

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import { useAuth } from "@/app/auth/auth-context";
88
import { joinMatchQueue } from "@/lib/join-match-queue";
99
import { leaveMatchQueue } from "@/lib/leave-match-queue";
1010
import { subscribeMatch } from "@/lib/subscribe-match";
11+
import { useRouter } from "next/navigation";
1112

1213
export default function FindMatch() {
14+
const router = useRouter();
1315
const [selectedDifficulty, setSelectedDifficulty] = useState<string>("");
1416
const [selectedTopic, setSelectedTopic] = useState<string>("");
1517
const [isSearching, setIsSearching] = useState<boolean>(false);
@@ -62,6 +64,8 @@ export default function FindMatch() {
6264
return;
6365
}
6466

67+
let isMatched = false;
68+
6569
const response = await joinMatchQueue(
6670
auth.token,
6771
auth?.user?.id,
@@ -70,12 +74,41 @@ export default function FindMatch() {
7074
);
7175
switch (response.status) {
7276
case 201:
73-
toast({
74-
title: "Matched",
75-
description: "Successfully matched",
76-
variant: "success",
77-
});
78-
return;
77+
const initialResponseData = await response.json();
78+
let responseData;
79+
if (typeof initialResponseData === "string") {
80+
try {
81+
responseData = JSON.parse(initialResponseData);
82+
} catch (error) {
83+
toast({
84+
title: "Error",
85+
description: "Unexpected error occured, please try again",
86+
variant: "destructive",
87+
});
88+
return;
89+
}
90+
} else {
91+
responseData = initialResponseData;
92+
}
93+
94+
if (responseData.room_id) {
95+
isMatched = true;
96+
const roomId = responseData.room_id;
97+
toast({
98+
title: "Matched",
99+
description: "Successfully matched",
100+
variant: "success",
101+
});
102+
router.push(`/collaboration/${roomId}`);
103+
} else {
104+
toast({
105+
title: "Error",
106+
description: "Room ID not found",
107+
variant: "destructive",
108+
});
109+
}
110+
break;
111+
79112
case 202:
80113
case 304:
81114
setIsSearching(true);
@@ -87,24 +120,55 @@ export default function FindMatch() {
87120
const queueTimeout = setTimeout(() => {
88121
handleCancel(true);
89122
}, waitTimeout);
90-
ws.onmessage = () => {
91-
setIsSearching(false);
92-
clearTimeout(queueTimeout);
93-
toast({
94-
title: "Matched",
95-
description: "Successfully matched",
96-
variant: "success",
97-
});
98-
ws.onclose = () => null;
123+
124+
ws.onmessage = (event) => {
125+
let responseData;
126+
127+
try {
128+
responseData = JSON.parse(event.data);
129+
if (typeof responseData === "string") {
130+
responseData = JSON.parse(responseData);
131+
}
132+
} catch (error) {
133+
toast({
134+
title: "Error",
135+
description: "Unexpected error occured, please try again",
136+
variant: "destructive",
137+
});
138+
return;
139+
}
140+
141+
const roomId = responseData.room_id;
142+
if (roomId) {
143+
isMatched = true;
144+
setIsSearching(false);
145+
clearTimeout(queueTimeout);
146+
toast({
147+
title: "Matched",
148+
description: "Successfully matched",
149+
variant: "success",
150+
});
151+
router.push(`/collaboration/${roomId}`);
152+
} else {
153+
toast({
154+
title: "Error",
155+
description: "Room ID not found",
156+
variant: "destructive",
157+
});
158+
}
99159
};
160+
100161
ws.onclose = () => {
101162
setIsSearching(false);
102163
clearTimeout(queueTimeout);
103-
toast({
104-
title: "Matching Stopped",
105-
description: "Matching has been stopped",
106-
variant: "destructive",
107-
});
164+
if (!isMatched) {
165+
// Only show this toast if no match was made
166+
toast({
167+
title: "Matching Stopped",
168+
description: "Matching has been stopped",
169+
variant: "destructive",
170+
});
171+
}
108172
};
109173
return;
110174
default:

matching-service/app/logic/matching.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from typing import Union
33

44
from logger import logger
5-
from models.match import MatchModel, MessageModel
5+
from models.match import MatchModel
66
from utils.redis import acquire_lock, redis_client, release_lock
77
from utils.socketmanager import manager
8+
import hashlib
89

910
async def find_match_else_enqueue(
1011
user_id: str,
@@ -40,11 +41,15 @@ async def find_match_else_enqueue(
4041
queue = await redis_client.lrange(queue_key, 0, -1)
4142
logger.debug(_get_queue_state_message(topic, difficulty, queue, False))
4243
await release_lock(redis_client, queue_key)
44+
45+
room_id = generate_room_id(matched_user, user_id)
46+
4347
response = MatchModel(
4448
user1=matched_user,
4549
user2=user_id,
4650
topic=topic,
4751
difficulty=difficulty,
52+
room_id=room_id,
4853
)
4954
await manager.broadcast(matched_user, topic, difficulty, response.json())
5055
await manager.disconnect_all(matched_user, topic, difficulty)
@@ -87,3 +92,11 @@ def _get_queue_state_message(topic, difficulty, queue, before: bool):
8792
if before:
8893
return "Before - " + postfix
8994
return "After - " + postfix
95+
96+
# Generate room ID for matched users
97+
def generate_room_id(user1_id: str, user2_id: str) -> str:
98+
# Ensure consistency of room ID by ordering user IDs alphabetically
99+
sorted_users = sorted([user1_id, user2_id])
100+
concatenated_ids = f"{sorted_users[0]}-{sorted_users[1]}"
101+
return hashlib.sha256(concatenated_ids.encode()).hexdigest()[:10]
102+

matching-service/app/models/match.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class MatchModel(BaseModel):
55
user2: str
66
topic: str
77
difficulty: str
8+
room_id: str
89

910
class MessageModel(BaseModel):
1011
message: str

0 commit comments

Comments
 (0)