Re-enable StrictMode by handling WebSocket reconnection

GitLab: #150
GitLab: #170
Change-Id: Ibf20b8b20773c106f5fdc2bbed04d06e6bc97bcf
diff --git a/client/src/contexts/WebSocketProvider.tsx b/client/src/contexts/WebSocketProvider.tsx
index 8c530c6..0d153dc 100644
--- a/client/src/contexts/WebSocketProvider.tsx
+++ b/client/src/contexts/WebSocketProvider.tsx
@@ -54,6 +54,7 @@
   const [isConnected, setIsConnected] = useState(false);
   const webSocketRef = useRef<WebSocket>();
   const callbacksRef = useRef<WebSocketCallbacks>(buildWebSocketCallbacks());
+  const reconnectionTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
 
   const { token: accessToken } = useAuthContext();
 
@@ -83,20 +84,24 @@
 
     const webSocket = new WebSocket(url);
 
-    webSocket.onopen = () => {
-      console.debug('WebSocket connected');
-      setIsConnected(true);
-    };
-
-    webSocket.onclose = () => {
+    const close = (reconnect = false) => {
       console.debug('WebSocket disconnected');
       setIsConnected(false);
       for (const callbacks of Object.values(callbacksRef.current)) {
         callbacks.clear();
       }
-      setTimeout(connect, 1000);
+      if (reconnect) {
+        reconnectionTimeoutRef.current = setTimeout(connect, 2000);
+      }
     };
 
+    webSocket.onopen = () => {
+      console.debug('WebSocket connected');
+      setIsConnected(true);
+    };
+
+    webSocket.onclose = () => close(true);
+
     webSocket.onmessage = <T extends WebSocketMessageType>(event: MessageEvent<string>) => {
       const messageString = event.data;
       console.debug('WebSocket received message', messageString);
@@ -119,13 +124,21 @@
     };
 
     webSocket.onerror = (event: Event) => {
-      console.error('Closing WebSocket due to an error:', event);
-      webSocketRef.current?.close();
+      console.error('WebSocket errored', event);
     };
 
     webSocketRef.current = webSocket;
 
     return () => {
+      // Cancel any previous reconnection attempt
+      if (reconnectionTimeoutRef.current !== undefined) {
+        clearTimeout(reconnectionTimeoutRef.current);
+        reconnectionTimeoutRef.current = undefined;
+      }
+
+      // Setup a closure without reconnection
+      webSocket.onclose = () => close();
+
       switch (webSocket.readyState) {
         case webSocket.CONNECTING:
           webSocket.onopen = () => webSocket.close();
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 4924a97..0fa4b14 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -20,6 +20,7 @@
 import './i18n';
 
 import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { StrictMode } from 'react';
 import { createRoot } from 'react-dom/client';
 import { Provider } from 'react-redux';
 import { RouterProvider } from 'react-router-dom';
@@ -43,13 +44,12 @@
 const root = createRoot(container);
 root.render(
   <Provider store={store}>
-    {/* TODO: Put back StrictMode (https://git.jami.net/savoirfairelinux/jami-web/-/issues/170) */}
-    {/*<StrictMode>*/}
-    <QueryClientProvider client={queryClient}>
-      <CustomThemeProvider>
-        <RouterProvider router={router} />
-      </CustomThemeProvider>
-    </QueryClientProvider>
-    {/*</StrictMode>*/}
+    <StrictMode>
+      <QueryClientProvider client={queryClient}>
+        <CustomThemeProvider>
+          <RouterProvider router={router} />
+        </CustomThemeProvider>
+      </QueryClientProvider>
+    </StrictMode>
   </Provider>
 );