@@ -25,6 +25,7 @@ const CollaborationSpace = () => {
25
25
const [ language , setLanguage ] = useState ( "python" ) // set default language to python
26
26
const [ output , setOutput ] = useState ( "" )
27
27
const [ messages , setMessages ] = useState ( [ ] )
28
+ const [ outputLoading , setOutputLoading ] = useState ( false )
28
29
29
30
// use https://emkc.org/api/v2/piston/runtimes to GET other languages
30
31
const LANGUAGEVERSIONS = {
@@ -33,6 +34,7 @@ const CollaborationSpace = () => {
33
34
"c++" : "10.2.0"
34
35
} ;
35
36
37
+ { /* State management for access denied toast */ }
36
38
const [ showAccessDeniedToast , setShowAccessDeniedToast ] = useState ( false ) ;
37
39
const [ toastMessage , setToastMessage ] = useState ( '' ) ;
38
40
const [ loading , setLoading ] = useState ( true ) ;
@@ -42,6 +44,18 @@ const CollaborationSpace = () => {
42
44
navigate ( "/home" ) ;
43
45
} ;
44
46
47
+ { /* State management for user join/leave toast */ }
48
+ const [ notifs , setNotifs ] = useState ( [ ] ) ;
49
+
50
+ const addNotif = ( message ) => {
51
+ const id = Date . now ( ) ; // unique id based on timestamp
52
+ setNotifs ( ( prevNotifs ) => [ ...prevNotifs , { id, message} ] ) ;
53
+
54
+ // Remove notif after 2 seconds
55
+ setTimeout ( ( ) => {
56
+ setNotifs ( ( prevNotifs ) => prevNotifs . filter ( ( notif ) => notif . id !== id ) )
57
+ } , 1500 ) ;
58
+ } ;
45
59
46
60
{ /* Set up websockets for room management on client side, and collaboration for Yjs */ }
47
61
useEffect ( ( ) => {
@@ -87,7 +101,7 @@ const CollaborationSpace = () => {
87
101
// on getting a reply from server
88
102
websocket . onmessage = ( event ) => {
89
103
const data = JSON . parse ( event . data ) ;
90
- console . log ( `[FRONTEND] data message is ${ JSON . stringify ( data ) } ` ) ;
104
+ // console.log(`[FRONTEND] data message is ${JSON.stringify(data)}`);
91
105
switch ( data . type ) {
92
106
case 'usersListUpdate' :
93
107
setUsers ( data . users ) ; // Update the user list
@@ -101,7 +115,16 @@ const CollaborationSpace = () => {
101
115
break ;
102
116
case 'newMessage' :
103
117
console . log ( "adding message" , data . message )
104
- setMessages ( ( prevMessages ) => [ ...prevMessages , data . message ] ) ;
118
+ break ;
119
+ case 'languageChange' :
120
+ addNotif ( `User ${ data . user } has changed the language to ${ data . language } ` ) ;
121
+ setLanguage ( data . language ) ;
122
+ break ;
123
+ case 'userJoin' :
124
+ addNotif ( `User ${ data . user } has joined.` )
125
+ break ;
126
+ case 'userLeft' :
127
+ addNotif ( `User ${ data . user } has left` )
105
128
break ;
106
129
default :
107
130
console . log ( "No messages received from room management server" ) ;
@@ -147,6 +170,9 @@ const CollaborationSpace = () => {
147
170
} ;
148
171
149
172
const handleCodeRun = ( ) => {
173
+
174
+ setOutputLoading ( true ) ;
175
+
150
176
const code_message = {
151
177
"language" : language ,
152
178
"files" : [
@@ -159,6 +185,7 @@ const CollaborationSpace = () => {
159
185
160
186
collabService . getCodeOutput ( code_message )
161
187
. then ( result => {
188
+ setOutputLoading ( false ) ;
162
189
console . log ( result . data . run . output )
163
190
setOutput ( result . data . run . output )
164
191
} )
@@ -176,6 +203,11 @@ const CollaborationSpace = () => {
176
203
websocketRef . current . send ( JSON . stringify ( { type : 'sendMessage' , roomId : roomId , message : message } ) ) ;
177
204
}
178
205
206
+ const handleLanguageChange = ( value ) => {
207
+ websocketRef . current . send ( JSON . stringify ( { type : 'languageChange' , roomId : roomId ,
208
+ user : userId , language : value } ) ) ;
209
+ }
210
+
179
211
if ( loading ) {
180
212
return (
181
213
< div style = { { textAlign : 'center' } } >
@@ -205,11 +237,24 @@ const CollaborationSpace = () => {
205
237
</ ToastContainer >
206
238
) : (
207
239
< >
208
- < CollabNavigationBar handleExit = { handleExit } handleCodeRun = { handleCodeRun } users = { users } setLanguage = { setLanguage } language = { language } />
240
+ { /* Toast Container for Join/Leave notifications */ }
241
+ < ToastContainer className = 'p-3' position = 'top-center' style = { { zIndex : 1050 } } >
242
+ { notifs . map ( ( notif ) => (
243
+ < Toast key = { notif . id } className = 'mb-2' style = { { backgroundColor : 'rgba(255, 255, 255, 0.8)' } } >
244
+ < Toast . Body >
245
+ < strong className = 'text-black' > { notif . message } </ strong >
246
+ </ Toast . Body >
247
+ </ Toast >
248
+ ) ) }
249
+ </ ToastContainer >
250
+
251
+ { /* Main component content */ }
252
+ < CollabNavigationBar handleExit = { handleExit } handleCodeRun = { handleCodeRun } users = { users }
253
+ setLanguage = { setLanguage } language = { language } userLangChange = { handleLanguageChange } />
209
254
< Container fluid style = { { marginTop : '20px' } } >
210
255
< Row >
211
256
< Col md = { 8 } >
212
- < CodeSpace handleEditorChange = { handleEditorChange } code = { code } language = { language } output = { output } />
257
+ < CodeSpace handleEditorChange = { handleEditorChange } loading = { outputLoading } code = { code } language = { language } output = { output } />
213
258
</ Col >
214
259
< Col md = { 4 } >
215
260
< QuestionDisplay />
0 commit comments