fix: join and leave

This commit is contained in:
akhdanre 2025-05-17 16:21:49 +07:00
parent 9c4b296d39
commit 3b6f827ae6
3 changed files with 59 additions and 32 deletions

View File

@ -88,7 +88,9 @@ class SocketController:
emit("error", {"message": "Failed to join session or session inactive"}) emit("error", {"message": "Failed to join session or session inactive"})
return return
join_room(session_code) session_id = session["session_id"]
join_room(session_id)
if session["is_admin"]: if session["is_admin"]:
message = "Admin has joined the room." message = "Admin has joined the room."
@ -100,7 +102,7 @@ class SocketController:
{ {
"type": "join", "type": "join",
"message": message, "message": message,
"room": session_code, "room": session_id,
"argument": "adm_update", "argument": "adm_update",
"data": { "data": {
"session_info": session["session_info"], "session_info": session["session_info"],
@ -115,13 +117,13 @@ class SocketController:
{ {
"type": "participan_join", "type": "participan_join",
"message": message, "message": message,
"room": session_code, "room": session_id,
"argument": "adm_update", "argument": "adm_update",
"data": { "data": {
"participants": session["session_info"]["participants"], "participants": session["session_info"]["participants"],
}, },
}, },
room=session_code, room=session_id,
skip_sid=request.sid, skip_sid=request.sid,
) )
@ -206,20 +208,41 @@ class SocketController:
@self.socketio.on("leave_room") @self.socketio.on("leave_room")
def handle_leave_room(data): def handle_leave_room(data):
session_code = data.get("session_id") session_id = data.get("session_id")
user_id = data.get("user_id") user_id = data.get("user_id")
username = data.get("username", "anonymous") username = data.get("username", "anonymous")
leave_room(session_code) leave_result = self.session_service.leave_session(
session_id=session_id,
user_id=user_id,
)
leave_room(session_id)
if leave_result["is_success"]:
emit(
"room_message",
{
"type": "participan_leave",
"message": f"{username} has left the room.",
"room": session_id,
"argument": "adm_update",
"data": {
"participants": leave_result["participants"],
},
},
room=session_id,
skip_sid=request.sid,
)
emit( emit(
"room_message", "room_message",
{ {
"type": "leave", "type": "leave",
"message": f"{username} has left the room.", "message": f"{username} has left the room.",
"room": session_code, "room": session_id,
"data": user_id, "argument": "adm_update",
"data": None,
}, },
room=session_code, room=session_id,
to=request.sid,
) )
@self.socketio.on("send_message") @self.socketio.on("send_message")

View File

@ -41,6 +41,7 @@ class SessionMemoryRepository:
:return: Session ID :return: Session ID
""" """
data = initial_data.model_dump() data = initial_data.model_dump()
data["id"] = data["id"]
data["created_at"] = str(data["created_at"]) data["created_at"] = str(data["created_at"])
self.set_data(f"session:{session_id}", data) self.set_data(f"session:{session_id}", data)
@ -126,6 +127,14 @@ class SessionMemoryRepository:
self.set_data(f"session:{session_id}", session) self.set_data(f"session:{session_id}", session)
return True return True
def get_user_in_session(self, session_id: str):
session = self.get_session(session_id)
if not session:
return []
existing_users = session.get("participants", [])
return existing_users
def remove_user_from_session(self, session_id: str, user_id: str) -> bool: def remove_user_from_session(self, session_id: str, user_id: str) -> bool:
""" """
Remove a user from a session Remove a user from a session
@ -133,20 +142,16 @@ class SessionMemoryRepository:
:param user_id: ID of the user to remove :param user_id: ID of the user to remove
:return: True if user was removed, False if session doesn't exist or user not in session :return: True if user was removed, False if session doesn't exist or user not in session
""" """
session = self.get_data(f"session:{session_id}") session = self.get_session(session_id)
if not session: if not session:
return False return False
original_users_count = len(session.get("participans", [])) session["participants"] = [
session["participans"] = [ user for user in session.get("participants", []) if user["id"] != user_id
user for user in session.get("participans", []) if user["id"] != user_id
] ]
if len(session["participans"]) < original_users_count: self.set_data(f"session:{session_id}", session)
self.set_data(f"session:{session_id}", session) return True
return True
return False
def set_quiz_for_session(self, session_id: str, quiz_data: QuizEntity): def set_quiz_for_session(self, session_id: str, quiz_data: QuizEntity):
""" """

View File

@ -51,10 +51,11 @@ class SessionService:
def join_session(self, session_code: str, user_id: str) -> dict: def join_session(self, session_code: str, user_id: str) -> dict:
user = self.user_repository.get_user_by_id(user_id) user = self.user_repository.get_user_by_id(user_id)
session = self.repository_redis.find_session_by_code(session_code) session = self.repository_redis.find_session_by_code(session_code)
if session is None: if session is None:
return None return None
session_id = session["id"]
is_existing_user = any( is_existing_user = any(
u["id"] == user_id for u in session.get("participants", []) u["id"] == user_id for u in session.get("participants", [])
) )
@ -63,11 +64,14 @@ class SessionService:
quiz_info = { quiz_info = {
"title": session_quiz.title, "title": session_quiz.title,
"limit_duration": session_quiz.title, "description": session_quiz.description,
"total_quiz": session_quiz.total_quiz,
"limit_duration": session_quiz.limit_duration,
} }
if session["host_id"] == user_id: if session["host_id"] == user_id:
return { return {
"session_id": session_id,
"is_admin": True, "is_admin": True,
"message": "admin joined", "message": "admin joined",
"session_info": session, "session_info": session,
@ -76,6 +80,7 @@ class SessionService:
if is_existing_user: if is_existing_user:
return { return {
"session_id": session_id,
"is_admin": False, "is_admin": False,
"user_id": str(user.id), "user_id": str(user.id),
"username": user.name, "username": user.name,
@ -95,6 +100,7 @@ class SessionService:
session = self.repository_redis.get_session(session["id"]) session = self.repository_redis.get_session(session["id"])
response = { response = {
"session_id": session_id,
"is_admin": False, "is_admin": False,
"user_id": str(user.id), "user_id": str(user.id),
"username": user.name, "username": user.name,
@ -106,20 +112,13 @@ class SessionService:
return response return response
def leave_session(self, session_id: str, user_id: str) -> dict: def leave_session(self, session_id: str, user_id: str) -> dict:
session = self.repository_mongo.get_by_id(session_id) is_success = self.repository_redis.remove_user_from_session(session_id, user_id)
if session is None: if is_success:
return {"error": "Session not found"} participant_left = self.repository_redis.get_user_in_session(session_id)
return {"is_success": True, "participants": participant_left}
if user_id == session.host_id: return {"is_success": False}
return {"message": "Host cannot leave the session"}
if user_id in session.participants:
session.participants.remove(user_id)
self.repository.update(session.id, {"participants": session.participants})
return {"message": "User has left the session"}
return {"message": "User not in session"}
def start_session(self, session_id: str) -> bool: def start_session(self, session_id: str) -> bool:
now = DatetimeUtil.now_iso() now = DatetimeUtil.now_iso()