diff --git a/backend/collaboration-service/package.json b/backend/collaboration-service/package.json
index 236a9e15cc..0db507e47c 100644
--- a/backend/collaboration-service/package.json
+++ b/backend/collaboration-service/package.json
@@ -9,7 +9,8 @@
"test": "jest",
"lint": "eslint . --fix --no-error-on-unmatched-pattern && prettier --write --ignore-unknown .",
"start": "npm run build && node dist/server.js",
- "dev": "nodemon src/server.ts"
+ "dev": "nodemon src/server.ts",
+ "format": "prettier --write ."
},
"license": "MIT",
"dependencies": {
diff --git a/backend/collaboration-service/src/services/socketio.service.ts b/backend/collaboration-service/src/services/socketio.service.ts
index 860b453eda..c58749d098 100644
--- a/backend/collaboration-service/src/services/socketio.service.ts
+++ b/backend/collaboration-service/src/services/socketio.service.ts
@@ -61,6 +61,19 @@ export class WebSocketConnection {
}
})
+ socket.on('end-session', async () => {
+ const socketsInRoom = this.io.sockets.adapter.rooms.get(roomId)
+ if (socketsInRoom) {
+ socketsInRoom.forEach((socketId) => {
+ const socket = this.io.sockets.sockets.get(socketId)
+ if (socket) {
+ socket.leave(roomId)
+ socket.disconnect(true)
+ }
+ })
+ }
+ })
+
socket.on('disconnect', async () => {
const room = this.io.sockets.adapter.rooms.get(roomId)
socket.leave(roomId)
diff --git a/frontend/pages/code/[id]/index.tsx b/frontend/pages/code/[id]/index.tsx
index d1895ec0ab..eb9450eb01 100644
--- a/frontend/pages/code/[id]/index.tsx
+++ b/frontend/pages/code/[id]/index.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { EndIcon, PlayIcon } from '@/assets/icons'
import { ChatModel, ICollabDto, LanguageMode, getCodeMirrorLanguage } from '@repo/collaboration-types'
import { useEffect, useRef, useState } from 'react'
@@ -25,6 +27,7 @@ import { ISubmission } from '@repo/submission-types'
import { mapLanguageToJudge0 } from '@/util/language-mapper'
import TestResult from '../test-result'
import { Cross1Icon } from '@radix-ui/react-icons'
+import ConfirmDialog from '@/components/customs/confirm-dialog'
import { getChatHistory, getCollabHistory } from '@/services/collaboration-service-api'
import ReadOnlyCodeMirrorEditor from '../read-only-editor'
import { ResultModel } from '@repo/collaboration-types'
@@ -49,11 +52,12 @@ export default function Code() {
const [isOtherUserOnline, setIsOtherUserOnline] = useState(true)
const [isCodeRunning, setIsCodeRunning] = useState(false)
const [activeTest, setActiveTest] = useState(0)
+ const [isViewOnly, setIsViewOnly] = useState(true)
+ const [isDialogOpen, setIsDialogOpen] = useState(false)
const [retry, setRetry] = useState(0)
const [testResult, setTestResult] = useState<{ data: ResultModel | undefined; expectedOutput: string } | undefined>(
undefined
)
- const [isViewOnly, setIsViewOnly] = useState(true)
const retrieveMatchDetails = async (matchId: string) => {
const response = await getMatchDetails(matchId).catch((err) => {
@@ -94,7 +98,6 @@ export default function Code() {
})
socketRef.current.on('connect', async () => {
- console.log('hi')
if (socketRef.current) {
socketRef.current.emit('joinRoom', { roomId: id })
setChatData((await getChatHistory(id as string)) ?? [])
@@ -130,6 +133,12 @@ export default function Code() {
}
})
+ socketRef.current.on('disconnect', () => {
+ if (!isViewOnly) {
+ router.push('/')
+ }
+ })
+
socketRef.current.on('receive_message', (data: ChatModel) => {
setChatData((prev) => [...prev, data])
})
@@ -184,10 +193,18 @@ export default function Code() {
router.push('/sessions')
return
}
+
+ if (socketRef.current) {
+ setIsDialogOpen(true)
+ }
+ }
+
+ function handleEndSessionConfirmation() {
if (socketRef.current) {
- socketRef.current.disconnect()
+ socketRef.current?.emit('end-session')
+ router.push('/')
}
- router.push('/')
+ setIsDialogOpen(false)
}
const renderCloseButton = () => {
@@ -292,6 +309,17 @@ export default function Code() {
+ setIsDialogOpen(false)}
+ confirmHandler={handleEndSessionConfirmation}
+ />