diff --git a/client/src/components/BuddyMatcher.jsx b/client/src/components/BuddyMatcher.jsx index 9cd73e87..439911b5 100644 --- a/client/src/components/BuddyMatcher.jsx +++ b/client/src/components/BuddyMatcher.jsx @@ -1,7 +1,7 @@ -import { Link, useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { NEW_EVENT_CHAT_RESTORE, - NEW_EVENT_CLOSED, + NEW_EVENT_CLOSED, NEW_EVENT_INACTIVE, NEW_EVENT_JOIN, NEW_EVENT_JOINED, @@ -12,7 +12,6 @@ import { connectWithId, socket } from 'src/lib/socketConnection'; import { useCallback, useEffect, useRef, useState } from 'react'; import Anonymous from 'components/Anonymous'; -import { PiPlugsLight } from 'react-icons/pi'; import { ThreeDots } from 'react-loading-icons'; import { createBrowserNotification } from 'src/lib/browserNotification'; import { isExplicitDisconnection } from 'src/lib/utils'; @@ -21,6 +20,7 @@ import { useAuth } from 'src/context/AuthContext'; import { useChat } from 'src/context/ChatContext'; import useCloseChat from 'src/hooks/useCloseChat'; import { useNotification } from 'src/lib/notification'; +import ReconnectBanner from './ReconnectBanner'; const stoppingSearchLoadingText =

Stopping the search

; const defaultLoadingText =

Looking for a random buddy

; @@ -30,19 +30,14 @@ const BuddyMatcher = () => { const navigate = useNavigate(); const { authState } = useAuth(); const { createChat, closeChat, closeAllChats } = useChat(); - const { startSearch, endSearch, app } = useApp(); - const { - setLoadingText, - startNewSearch, - loadingText - } = useCloseChat() + const { startSearch, endSearch, app } = useApp(); + const { setLoadingText, startNewSearch, loadingText } = useCloseChat(); const [disconnected, setDisconnected] = useState(false); const reconnectAttempts = useRef(0); const [isStoppingSearch, setIsStoppingSearch] = useState(false); - let timeout = null; function disconnect() { @@ -56,33 +51,29 @@ const BuddyMatcher = () => { endSearch(); } - - - const emitStopSearch = useCallback(() => { + const emitStopSearch = useCallback(() => { socket.emit(NEW_EVENT_STOP_SEARCH, { loginId: authState.loginId, email: authState.email, }); - }, []) - - ; + }, []); const handleStopSearch = () => { - emitStopSearch() + emitStopSearch(); setIsStoppingSearch(true); }; - async function handleReconnect() { + async function handleReconnect() { if (socket.connected) { return; } startSearch(); setLoadingText(defaultLoadingText); - await connectWithId(app.currentChatId) + await connectWithId(app.currentChatId); } - - const onUserJoined = useCallback(({ roomId, userIds }) => { + + const onUserJoined = useCallback(({ roomId, userIds }) => { playNotification('buddyPaired'); createBrowserNotification( "Let's Chat :)", @@ -90,32 +81,32 @@ const BuddyMatcher = () => { ); createChat(roomId, userIds); endSearch(roomId); - }, []) + }, []); const onRestoreChat = useCallback(({ chats, currentChatId }) => { Object.values(chats).forEach((chat) => { createChat(chat.id, chat.userIds, chat.messages, chat.createdAt); }); endSearch(currentChatId); - }, []) + }, []); - const onStopSearch = useCallback( () => { + const onStopSearch = useCallback(() => { setIsStoppingSearch(false); endSearch(); navigate('/'); - }, []) + }, []); const onConnect = useCallback(() => { // Here server will be informed that user is searching for - // another user + // another user socket.emit(NEW_EVENT_JOIN, { loginId: authState.loginId, email: authState.email, }); setDisconnected(false); - }, []) + }, []); - const onClose = useCallback((chatId) => { + const onClose = useCallback((chatId) => { endSearch(); closeChat(chatId); playNotification('chatClosed'); @@ -127,32 +118,30 @@ const BuddyMatcher = () => { createBrowserNotification('Chat Closed', 'Your buddy left the chat'); startNewSearch(); - }, []) + }, []); const onInactive = useCallback(() => { closeAllChats(); - }, []) + }, []); - const onDisconnect = useCallback((reason) => { + const onDisconnect = useCallback((reason) => { if (isExplicitDisconnection(reason)) { return; } disconnect(); - }, []) + }, []); const onReconnectAttempt = useCallback((attempts) => { reconnectAttempts.current = attempts; - }, []) + }, []); const onReconnectError = useCallback(() => { if (reconnectAttempts.current >= 3) { disconnect(); } - }, []) + }, []); - - useEffect(() => { setLoadingText(isStoppingSearch ? stoppingSearchLoadingText : defaultLoadingText); }, [isStoppingSearch]); @@ -187,49 +176,49 @@ const BuddyMatcher = () => { }; }, [loadingText]); - useEffect(() => { - const setupSocket = async () => { - if (!app.currentChatId) { - startSearch(); - } - - if (!socket.connected) { - try { - await connectWithId(app.currentChatId); - } catch (error) { - console.error('Failed to connect:', error); - } - } - }; - - setupSocket(); - - socket.on('connect', onConnect); - socket.on(NEW_EVENT_CLOSED, onClose); - socket.on(NEW_EVENT_JOINED, onUserJoined); - socket.on(NEW_EVENT_CHAT_RESTORE, onRestoreChat); - socket.on(NEW_EVENT_INACTIVE, onInactive); - socket.on(NEW_EVENT_STOP_SEARCH_SUCCESS, onStopSearch); - socket.on('disconnect', onDisconnect); - socket.io.on('reconnect_attempt', onReconnectAttempt); - socket.io.on('reconnect_error', onReconnectError); - - return () => { - socket - .off('connect', onConnect) - .off(NEW_EVENT_JOINED, onUserJoined) - .off(NEW_EVENT_CHAT_RESTORE, onRestoreChat) - .off(NEW_EVENT_CLOSED, onClose) - .off(NEW_EVENT_INACTIVE, onInactive) - .off('disconnect', onDisconnect); - - socket.io - .off('reconnect_attempt', onReconnectAttempt) - .off('reconnect_error', onReconnectError); - - socket.disconnect(); - }; - }, [app.currentChatId]); + useEffect(() => { + const setupSocket = async () => { + if (!app.currentChatId) { + startSearch(); + } + + if (!socket.connected) { + try { + await connectWithId(app.currentChatId); + } catch (error) { + console.error('Failed to connect:', error); + } + } + }; + + setupSocket(); + + socket.on('connect', onConnect); + socket.on(NEW_EVENT_CLOSED, onClose); + socket.on(NEW_EVENT_JOINED, onUserJoined); + socket.on(NEW_EVENT_CHAT_RESTORE, onRestoreChat); + socket.on(NEW_EVENT_INACTIVE, onInactive); + socket.on(NEW_EVENT_STOP_SEARCH_SUCCESS, onStopSearch); + socket.on('disconnect', onDisconnect); + socket.io.on('reconnect_attempt', onReconnectAttempt); + socket.io.on('reconnect_error', onReconnectError); + + return () => { + socket + .off('connect', onConnect) + .off(NEW_EVENT_JOINED, onUserJoined) + .off(NEW_EVENT_CHAT_RESTORE, onRestoreChat) + .off(NEW_EVENT_CLOSED, onClose) + .off(NEW_EVENT_INACTIVE, onInactive) + .off('disconnect', onDisconnect); + + socket.io + .off('reconnect_attempt', onReconnectAttempt) + .off('reconnect_error', onReconnectError); + + socket.disconnect(); + }; + }, [app.currentChatId]); return app.isSearching || !app.currentChatId ? (
@@ -247,25 +236,9 @@ const BuddyMatcher = () => { )}
) : disconnected ? ( -
- -

Sorry, it seems you're not connected

-
- - - Return Home - -
-
+ ) : ( - + ); }; diff --git a/client/src/components/ReconnectBanner.jsx b/client/src/components/ReconnectBanner.jsx new file mode 100644 index 00000000..a7fef169 --- /dev/null +++ b/client/src/components/ReconnectBanner.jsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { PiPlugsLight } from 'react-icons/pi'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; + +export default function ReconnectBanner({ handleReconnect }) { + return ( +
+ +

Sorry, it seems you're not connected

+
+ + + Return Home + +
+
+ ); +} + +ReconnectBanner.propTypes = { + handleReconnect: PropTypes.func, +}; +