@@ -22,18 +22,23 @@ import {
22
22
ClockCircleOutlined ,
23
23
CodeOutlined ,
24
24
FileDoneOutlined ,
25
+ InfoCircleFilled ,
25
26
MessageOutlined ,
26
27
PlayCircleOutlined ,
27
28
SendOutlined ,
28
29
} from "@ant-design/icons" ;
29
30
import { ProgrammingLanguageOptions } from "@/utils/SelectOptions" ;
30
- import CollaborativeEditor from "@/components/CollaborativeEditor/CollaborativeEditor" ;
31
+ import CollaborativeEditor , {
32
+ CollaborativeEditorHandle ,
33
+ } from "@/components/CollaborativeEditor/CollaborativeEditor" ;
31
34
32
35
interface CollaborationProps { }
33
36
34
37
export default function CollaborationPage ( props : CollaborationProps ) {
35
38
const router = useRouter ( ) ;
36
39
40
+ const editorRef = useRef < CollaborativeEditorHandle > ( null ) ;
41
+
37
42
const [ isLoading , setIsLoading ] = useState < boolean > ( false ) ;
38
43
39
44
// Code Editor States
@@ -50,7 +55,7 @@ export default function CollaborationPage(props: CollaborationProps) {
50
55
undefined
51
56
) ;
52
57
const [ currentUser , setCurrentUser ] = useState < string | undefined > ( undefined ) ;
53
- const [ matchedUser , setMatchedUser ] = useState < string > ( "Not Connected " ) ;
58
+ const [ matchedUser , setMatchedUser ] = useState < string > ( "Loading... " ) ;
54
59
const [ sessionDuration , setSessionDuration ] = useState < number > ( ( ) => {
55
60
const storedTime = localStorage . getItem ( "session-duration" ) ;
56
61
return storedTime ? parseInt ( storedTime ) : 0 ;
@@ -67,8 +72,12 @@ export default function CollaborationPage(props: CollaborationProps) {
67
72
undefined
68
73
) ;
69
74
70
- // Modal state
75
+ // End Button Modal state
71
76
const [ isModalOpen , setIsModalOpen ] = useState < boolean > ( false ) ;
77
+ // Session End Modal State
78
+ const [ isSessionEndModalOpen , setIsSessionEndModalOpen ] =
79
+ useState < boolean > ( false ) ;
80
+ const [ countDown , setCountDown ] = useState < number > ( 5 ) ;
72
81
73
82
// Stops the session duration stopwatch
74
83
const stopStopwatch = ( ) => {
@@ -121,7 +130,7 @@ export default function CollaborationPage(props: CollaborationProps) {
121
130
122
131
// Set states from localstorage
123
132
setCollaborationId ( collabId ) ;
124
- // setMatchedUser(matchedUser); // TODO: remove after being handled in collabeditor
133
+ setMatchedUser ( matchedUser ) ;
125
134
setCurrentUser ( currentUser ) ;
126
135
127
136
// Fetch question and set question states
@@ -136,6 +145,19 @@ export default function CollaborationPage(props: CollaborationProps) {
136
145
startStopwatch ( ) ;
137
146
} , [ ] ) ;
138
147
148
+ // useEffect for timer
149
+ useEffect ( ( ) => {
150
+ if ( isSessionEndModalOpen && countDown > 0 ) {
151
+ const timer = setInterval ( ( ) => {
152
+ setCountDown ( ( prevCountDown ) => prevCountDown - 1 ) ;
153
+ } , 1000 ) ;
154
+
155
+ return ( ) => clearInterval ( timer ) ; // Clean up on component unmount or when countdown changes
156
+ } else if ( countDown === 0 ) {
157
+ router . push ( "/matching" ) ; // Redirect to matching page
158
+ }
159
+ } , [ isSessionEndModalOpen , countDown ] ) ;
160
+
139
161
// Tabs component items for testcases
140
162
const items : TabsProps [ "items" ] = [
141
163
{
@@ -166,23 +188,76 @@ export default function CollaborationPage(props: CollaborationProps) {
166
188
] ;
167
189
168
190
// Handles the cleaning of localstorage variables, stopping the timer & signalling collab user on webrtc
169
- const handleCloseCollaboration = ( ) => {
191
+ // type: "initiator" | "peer"
192
+ const handleCloseCollaboration = ( type : string ) => {
170
193
// Stop stopwatch
171
194
stopStopwatch ( ) ;
195
+ if ( editorRef . current && type === "initiator" ) {
196
+ editorRef . current . endSession ( ) ; // Call the method on the editor
197
+ }
198
+
199
+ // Trigger modal open showing session end details
200
+ setIsSessionEndModalOpen ( true ) ;
201
+
172
202
// Remove localstorage variables for collaboration
173
203
localStorage . removeItem ( "session-duration" ) ; // TODO: Remove this after collaboration backend data stored
174
204
localStorage . removeItem ( "user" ) ;
175
205
localStorage . removeItem ( "collabId" ) ;
176
206
localStorage . removeItem ( "docRefId" ) ;
177
-
178
- // Redirect back to matching page
179
- router . push ( "/matching" ) ;
207
+ localStorage . removeItem ( "matchedUser" ) ;
180
208
} ;
181
209
182
210
return (
183
211
< Layout className = "collaboration-layout" >
184
212
< Header selectedKey = { undefined } />
185
213
< Content className = "collaboration-content" >
214
+ < Modal
215
+ height = { 500 }
216
+ title = { "Session Ended" }
217
+ footer = { null }
218
+ open = { isSessionEndModalOpen }
219
+ width = { 400 }
220
+ closable = { false }
221
+ >
222
+ < p className = "session-modal-description" >
223
+ The collaboration session has ended. You will be redirected in{ " " }
224
+ { countDown }
225
+ seconds
226
+ </ p >
227
+ < p className = "session-modal-question" >
228
+ Question:{ " " }
229
+ < span className = "session-modal-title" > { questionTitle } </ span >
230
+ </ p >
231
+ < p className = "session-modal-difficulty" >
232
+ Difficulty:{ " " }
233
+ < Tag
234
+ className = "complexity-tag"
235
+ style = { {
236
+ color :
237
+ complexity === "easy"
238
+ ? "#2DB55D"
239
+ : complexity === "medium"
240
+ ? "orange"
241
+ : "red" ,
242
+ } }
243
+ >
244
+ { complexity &&
245
+ complexity . charAt ( 0 ) . toUpperCase ( ) + complexity . slice ( 1 ) }
246
+ </ Tag >
247
+ </ p >
248
+ < p className = "session-modal-duration" >
249
+ Duration:{ " " }
250
+ < span className = "session-modal-time" >
251
+ { formatTime ( sessionDuration ) }
252
+ </ span >
253
+ </ p >
254
+ < p className = "session-modal-matched-user" >
255
+ Matched User:{ " " }
256
+ < span className = "session-modal-matched-user-name" >
257
+ { matchedUser }
258
+ </ span >
259
+ </ p >
260
+ </ Modal >
186
261
< Row gutter = { 0 } className = "collab-row" >
187
262
< Col span = { 7 } className = "first-col" >
188
263
< Row className = "question-row" >
@@ -205,7 +280,7 @@ export default function CollaborationPage(props: CollaborationProps) {
205
280
</ Tag >
206
281
</ div >
207
282
< div className = "question-topic" >
208
- < text className = "topic-label" > Topics: </ text >
283
+ < span className = "topic-label" > Topics: </ span >
209
284
{ categories . map ( ( category ) => (
210
285
< Tag key = { category } > { category } </ Tag >
211
286
) ) }
@@ -254,10 +329,12 @@ export default function CollaborationPage(props: CollaborationProps) {
254
329
</ div >
255
330
{ collaborationId && currentUser && selectedLanguage && (
256
331
< CollaborativeEditor
332
+ ref = { editorRef }
257
333
user = { currentUser }
258
334
collaborationId = { collaborationId }
259
335
language = { selectedLanguage }
260
336
setMatchedUser = { setMatchedUser }
337
+ handleCloseCollaboration = { handleCloseCollaboration }
261
338
/>
262
339
) }
263
340
</ div >
@@ -276,36 +353,36 @@ export default function CollaborationPage(props: CollaborationProps) {
276
353
title = { "End Session" }
277
354
okText = { "End" }
278
355
okButtonProps = { { danger : true } }
279
- onOk = { handleCloseCollaboration }
356
+ onOk = { ( ) => handleCloseCollaboration ( "initiator" ) }
280
357
open = { isModalOpen }
281
358
onCancel = { ( ) => setIsModalOpen ( false ) }
282
359
width = { 400 }
283
360
>
284
361
< p className = "modal-description" >
285
362
Are you sure you want to quit the existing collaboration
286
- session?
363
+ session? This will end the session for both users!
287
364
</ p >
288
365
</ Modal >
289
366
< Button
290
367
danger
291
368
onClick = { ( ) => setIsModalOpen ( true ) }
292
369
className = "session-end-button"
293
370
>
294
- End
371
+ End for All
295
372
</ Button >
296
373
</ div >
297
374
298
375
< div className = "session-duration" >
299
376
Duration:
300
- < text className = "session-duration-timer" >
377
+ < span className = "session-duration-timer" >
301
378
{ formatTime ( sessionDuration ) }
302
- </ text >
379
+ </ span >
303
380
</ div >
304
381
< div className = "session-matched-user-label" >
305
382
Matched User:
306
- < text className = "session-matched-user-name" >
383
+ < span className = "session-matched-user-name" >
307
384
{ matchedUser }
308
- </ text >
385
+ </ span >
309
386
</ div >
310
387
</ div >
311
388
</ Row >
0 commit comments