1
1
/* eslint-disable react-hooks/exhaustive-deps */
2
2
import { useEffect , useRef , useState } from "react" ;
3
+ import { io } from "socket.io-client" ;
3
4
import "./App.css" ;
4
- import socket from "./socket" ;
5
-
5
+ import InfoMsg from "./components/InfoMsg" ;
6
6
import Sidebar from "./components/Sidebar" ;
7
7
import Canvas from "./components/Canvas" ;
8
8
import Menu from "./components/Menu" ;
9
9
import EraserCursor from "./components/EraserCursor" ;
10
10
import TextEditor from "./components/TextEditor" ;
11
- import { useRecoilValue , useRecoilState } from "recoil" ;
11
+ import { useRecoilValue , useRecoilState , useSetRecoilState } from "recoil" ;
12
12
import {
13
13
eraserState ,
14
14
cursorPosition ,
15
15
canvasColors ,
16
16
canvasState ,
17
17
showMenuState ,
18
18
showTextEditor ,
19
+ collaborationStarted ,
20
+ showMsg ,
21
+ roomIdAtom ,
22
+ messageTxtAtom
19
23
} from "./atoms" ;
24
+ import { useSocket } from "./Context" ;
20
25
21
- socket . connect ( ) ;
26
+ const PORT = "http://localhost:8000" ;
22
27
23
28
function App ( ) {
24
29
const [ showMenu , setShowMenu ] = useRecoilState ( showMenuState ) ;
@@ -32,7 +37,13 @@ function App() {
32
37
const canvasColor = useRecoilValue ( canvasColors ) ;
33
38
const [ currentCanvas , setCanvas ] = useRecoilState ( canvasState ) ;
34
39
const textEditor = useRecoilValue ( showTextEditor ) ;
35
-
40
+ const setTextEditor = useSetRecoilState ( showTextEditor ) ;
41
+ const hasCollaborationStarted = useRecoilValue ( collaborationStarted ) ;
42
+ const setCollaborationFlag = useSetRecoilState ( collaborationStarted ) ;
43
+ const [ showMessage , setShowMsg ] = useRecoilState ( showMsg ) ;
44
+ const [ roomId , setRoomId ] = useRecoilState ( roomIdAtom ) ;
45
+ const { socket, setSocket } = useSocket ( ) ;
46
+ const [ messageText , setMessageText ] = useRecoilState ( messageTxtAtom ) ;
36
47
37
48
function toggleMenu ( ) {
38
49
setShowMenu ( ! showMenu ) ;
@@ -76,7 +87,9 @@ function App() {
76
87
const endX = e . clientX - canvas . getBoundingClientRect ( ) . left ;
77
88
const endY = e . clientY - canvas . getBoundingClientRect ( ) . top ;
78
89
drawLine ( startX , startY , endX , endY , penColor ) ;
79
- socket . emit ( "draw" , { startX, startY, endX, endY, penColor, lineWidth } ) ;
90
+ if ( hasCollaborationStarted && socket ) {
91
+ socket . emit ( "draw" , { startX, startY, endX, endY, penColor, lineWidth, room_id : roomId } ) ;
92
+ }
80
93
setStartX ( endX ) ;
81
94
setStartY ( endY ) ;
82
95
}
@@ -104,29 +117,31 @@ function App() {
104
117
canvas . removeEventListener ( "mousedown" , handleMousedown ) ;
105
118
canvas . removeEventListener ( "mouseup" , handleMouseup ) ;
106
119
} ;
107
- } , [ penColor , eraserMode , position , ctx , isDrawing , startX , startY ] ) ;
120
+ } , [ socket , penColor , eraserMode , position , ctx , isDrawing , startX , startY ] ) ;
108
121
109
122
useEffect ( ( ) => {
110
- socket . on ( "draw" , ( data ) => {
111
- drawLine (
112
- data . startX ,
113
- data . startY ,
114
- data . endX ,
115
- data . endY ,
116
- data . penColor ,
117
- data . lineWidth
118
- ) ;
119
- } ) ;
120
-
121
- socket . on ( "clear" , ( ) => {
122
- clearRect ( ) ;
123
- } ) ;
124
-
125
- return ( ) => {
126
- socket . off ( "draw" ) ;
127
- socket . off ( "clear" ) ;
128
- } ;
129
- } , [ socket , ctx ] ) ;
123
+ if ( hasCollaborationStarted && socket ) {
124
+ socket . on ( "draw" , ( data ) => {
125
+ drawLine (
126
+ data . startX ,
127
+ data . startY ,
128
+ data . endX ,
129
+ data . endY ,
130
+ data . penColor ,
131
+ data . lineWidth
132
+ ) ;
133
+ } ) ;
134
+
135
+ socket . on ( "clear" , ( ) => {
136
+ clearRect ( ) ;
137
+ } ) ;
138
+
139
+ return ( ) => {
140
+ socket . off ( "draw" ) ;
141
+ socket . off ( "clear" ) ;
142
+ } ;
143
+ }
144
+ } , [ socket , ctx , hasCollaborationStarted ] ) ;
130
145
131
146
function clearRect ( ) {
132
147
if ( ctx ) {
@@ -136,7 +151,10 @@ function App() {
136
151
137
152
function clearOnClick ( ) {
138
153
clearRect ( ) ;
139
- socket . emit ( "clear" ) ;
154
+ if ( hasCollaborationStarted && socket ) {
155
+ const data = { room_id : roomId } ;
156
+ socket . emit ( "clear" , data ) ;
157
+ }
140
158
}
141
159
142
160
function addStroke ( e ) {
@@ -158,6 +176,71 @@ function App() {
158
176
}
159
177
}
160
178
179
+ const closeMsg = ( ) => {
180
+ setMessageText ( null ) ;
181
+ setShowMsg ( false ) ;
182
+ }
183
+
184
+ useEffect ( ( ) => {
185
+ const urlParams = new URLSearchParams ( window . location . search ) ;
186
+ const roomID = urlParams . get ( "roomID" ) ;
187
+ const RETRIES = 5 ;
188
+ const DELAY_DURATION = 2000 ;
189
+ let attempts = 0 ;
190
+
191
+ const closeConnection = ( socket ) => {
192
+ if ( attempts >= RETRIES ) {
193
+ socket . disconnect ( ) ;
194
+ setCollaborationFlag ( false ) ;
195
+ console . log ( "Max socket calls exceeded. Please try connecting again." )
196
+ }
197
+ }
198
+
199
+ if ( roomID ) {
200
+ const collaborationLink = window . location . href ;
201
+ setRoomId ( roomID ) ;
202
+ setCollaborationFlag ( true ) ;
203
+ const newSocket = io ( PORT ) ;
204
+
205
+ try {
206
+ newSocket . on ( "connect" , ( ) => {
207
+ console . log ( "connected" ) ;
208
+ try {
209
+ newSocket . emit ( "joinRoom" , { room_id : roomID } ) ;
210
+ console . log ( `joined room ${ roomID } ` ) ;
211
+ setSocket ( newSocket ) ;
212
+ setMessageText ( `Collaboration Link : ${ collaborationLink } ` ) ;
213
+ setShowMsg ( true ) ;
214
+ } catch ( error ) {
215
+ console . log ( "Can't join the room" , error ) ;
216
+ }
217
+ } ) ;
218
+
219
+ newSocket . on ( "connect_error" , ( error ) => {
220
+ attempts ++ ;
221
+ console . log ( "Failed to connect to the socket server. Retrying..." )
222
+ setTimeout ( ( ) => closeConnection ( newSocket ) , DELAY_DURATION ) ;
223
+ } )
224
+
225
+ } catch ( error ) {
226
+ console . log ( "Can't connect" , error ) ;
227
+ }
228
+ }
229
+ } , [ ] ) ;
230
+
231
+ // Hook to listen the events emitted by the server
232
+ useEffect ( ( ) => {
233
+ if ( hasCollaborationStarted && socket ) {
234
+ socket . on ( "open-text-editor" , ( ) => {
235
+ setTextEditor ( true ) ;
236
+ } ) ;
237
+
238
+ return ( ) => {
239
+ socket . off ( "open-text-editor" ) ;
240
+ } ;
241
+ }
242
+ } , [ showTextEditor , socket , hasCollaborationStarted ] ) ;
243
+
161
244
return (
162
245
< div id = "container" >
163
246
< Sidebar
@@ -172,6 +255,7 @@ function App() {
172
255
{ eraserMode && < EraserCursor > </ EraserCursor > }
173
256
{ showMenu && < Menu > </ Menu > }
174
257
{ textEditor && < TextEditor > </ TextEditor > }
258
+ { showMessage && < InfoMsg message = { messageText } clickHandler = { closeMsg } > </ InfoMsg > }
175
259
</ div >
176
260
) ;
177
261
}
0 commit comments