From e187008ee90ee37b8d276e3ee32c753b663cbebd Mon Sep 17 00:00:00 2001 From: MJinH <97130553+MJinH@users.noreply.github.com> Date: Mon, 15 Jan 2024 06:53:23 -0800 Subject: [PATCH 1/7] fix: Chat isn't visible (#590) Co-authored-by: moon19960501@gmail.com Co-authored-by: Dunsin <78784850+Dun-sin@users.noreply.github.com> --- src/lib/decryptMessage.ts | 2 +- src/pages/anonymous.tsx | 1 - src/server/handlers.ts | 6 +++--- src/server/lib/lib.ts | 2 +- src/server/models/MessageModel.ts | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/lib/decryptMessage.ts b/src/lib/decryptMessage.ts index 59a69b15..f9327a12 100644 --- a/src/lib/decryptMessage.ts +++ b/src/lib/decryptMessage.ts @@ -1,6 +1,6 @@ import CryptoJS from 'crypto-js'; -const secretKey = process.env.SECRET_KEY; +const secretKey = process.env.NEXT_PUBLIC_SECRET_KEY; export default (message: string) => { if (!secretKey) { diff --git a/src/pages/anonymous.tsx b/src/pages/anonymous.tsx index 1759fb65..286101ec 100644 --- a/src/pages/anonymous.tsx +++ b/src/pages/anonymous.tsx @@ -305,7 +305,6 @@ const Anonymous = () => { socket?.io.off('reconnect_attempt', onReconnectAttempt); socket?.io.off('reconnect_error', onReconnectError); - socket?.disconnect(); newMessageEvents.forEach(event => { socket?.off(event, onNewMessage); diff --git a/src/server/handlers.ts b/src/server/handlers.ts index c18c0000..4f14a6b2 100644 --- a/src/server/handlers.ts +++ b/src/server/handlers.ts @@ -230,11 +230,11 @@ const messageCounts: { [id: string]: number; } = {}; -export const SendMessageHandler = (socket: Socket) => { +export const SendMessageHandler = (io: Server, socket: Socket) => { socket.on( constants.NEW_EVENT_SEND_MESSAGE, async ( - { senderId, message, time, chatId, containsBadword, replyTo }, + { senderId, message, time, room: chatId, containsBadword, replyTo }, returnMessageToSender ) => { // Below line is just a failed message simulator for testing purposes. @@ -282,7 +282,7 @@ export const SendMessageHandler = (socket: Socket) => { const messageDetails = { ...sentMessage, - room: chatId, + chatId, status: 'sent', }; diff --git a/src/server/lib/lib.ts b/src/server/lib/lib.ts index fd77e425..436b43ae 100644 --- a/src/server/lib/lib.ts +++ b/src/server/lib/lib.ts @@ -14,7 +14,7 @@ import { MessageType, } from '@/types/types'; -const secretKey = process.env.SECRET_KEY; +const secretKey = process.env.NEXT_PUBLIC_SECRET_KEY; const waitingUsers: activeUserIdType = {}; diff --git a/src/server/models/MessageModel.ts b/src/server/models/MessageModel.ts index e14c0396..92ca3e03 100644 --- a/src/server/models/MessageModel.ts +++ b/src/server/models/MessageModel.ts @@ -59,7 +59,7 @@ const messageSchema = new Schema( default: false, }, replyTo: { - type: Schema.Types.ObjectId, + type: String, ref: 'Message', }, }, From 230aaeb7db57967685b985ded7d09664623995fc Mon Sep 17 00:00:00 2001 From: Mathias Ayivor <74247733+mathiasayivor@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:25:07 +0000 Subject: [PATCH 2/7] fix: properly restore chats (#596) --- src/components/PageWrapper.tsx | 23 +++++++++++++++++++++-- src/pages/anonymous.tsx | 10 +--------- src/pages/searching.tsx | 8 ++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/components/PageWrapper.tsx b/src/components/PageWrapper.tsx index 2b3ac851..c1c8b89f 100644 --- a/src/components/PageWrapper.tsx +++ b/src/components/PageWrapper.tsx @@ -4,17 +4,20 @@ import { useRouter } from 'next/navigation'; // Store import { useAuth } from '@/context/AuthContext'; import { useApp } from '@/context/AppContext'; -import { ChatProvider } from '@/context/ChatContext'; +import { ChatProvider, useChat } from '@/context/ChatContext'; +import events from '@/shared/constants/constants'; // Components import NavBar from './NavBar'; import useIsTabActive from '@/hooks/useIsTabActive'; import { ProviderType } from '@/types/propstypes'; +import { useSocket } from '@/context/SocketContext'; const PageWrapper = ({ children }: ProviderType) => { const { isLoggedIn } = useAuth(); - const { updateOnlineStatus, app } = useApp(); + const { updateOnlineStatus, endSearch, app } = useApp(); + const { createChat } = useChat() const router = useRouter(); const { settings } = app; @@ -22,6 +25,8 @@ const PageWrapper = ({ children }: ProviderType) => { const isTabActive = useIsTabActive(); + const { socket } = useSocket(); + useEffect(() => { if (!isLoggedIn) { return; @@ -42,6 +47,20 @@ const PageWrapper = ({ children }: ProviderType) => { !isLoggedIn && router.push('/login'); }, [isLoggedIn, router]); + useEffect(() => { + const onRestoreChat = ({ chats, currentChatId }: any) => { + Object.values(chats).forEach((chat: any) => { + createChat(chat.id, chat.userIds, chat.messages, chat.createdAt); + }); + endSearch(currentChatId); + }; + + socket?.on(events.NEW_EVENT_CHAT_RESTORE, onRestoreChat); + return () => { + socket?.off(events.NEW_EVENT_CHAT_RESTORE, onRestoreChat); + }; + }, [socket]); + return (
{ navigate.push('/searching'); }); - socket?.on(events.NEW_EVENT_CHAT_RESTORE, ({ chats, currentChatId }) => { - Object.values(chats).forEach((chat: any) => { - chat = chat as ChatIdType; - createChat(chat.id, chat.userIds, chat.messages, chat.createdAt); - }); - endSearch(currentChatId); - }); - const connectionEvents = { connect: () => { updateConnection(false); @@ -297,7 +289,6 @@ const Anonymous = () => { return () => { socket?.off(events.NEW_EVENT_ONLINE_STATUS, onlineStatushandler); socket?.off('connect'); - socket?.off(events.NEW_EVENT_CHAT_RESTORE); socket?.off(events.NEW_EVENT_CLOSE); socket?.off(events.NEW_EVENT_INACTIVE); socket?.off('disconnect', onDisconnect); @@ -305,6 +296,7 @@ const Anonymous = () => { socket?.io.off('reconnect_attempt', onReconnectAttempt); socket?.io.off('reconnect_error', onReconnectError); + socket?.disconnect(); newMessageEvents.forEach(event => { socket?.off(event, onNewMessage); diff --git a/src/pages/searching.tsx b/src/pages/searching.tsx index d95f24c3..a3c8e123 100644 --- a/src/pages/searching.tsx +++ b/src/pages/searching.tsx @@ -98,6 +98,14 @@ const Searching = () => { }; }, [app.currentChatId, authState.email, authState.loginId, router, socket]); + useEffect(() => { + if (!app.currentChatId) { + return; + } + + router.push('/anonymous') + }, [app.currentChatId]) + useEffect(() => { if (loadingText === defaultLoadingText) { timeout = setTimeout(() => { From e9055f35442a48a3d19d8cd95b31671ed8dbbfbf Mon Sep 17 00:00:00 2001 From: Danilo Ferrari <40414119+DevDaniloFerrari@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:38:28 -0300 Subject: [PATCH 3/7] feat: Dynamic import BadWordsNext (#598) --- src/components/Chat.tsx | 30 ++++++--------------- src/components/Chat/BadwordHideShow.tsx | 35 +++++++++++++++++++++++++ src/types/propstypes.ts | 8 ++++++ 3 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 src/components/Chat/BadwordHideShow.tsx diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx index 81aec43a..0fc040da 100644 --- a/src/components/Chat.tsx +++ b/src/components/Chat.tsx @@ -15,8 +15,6 @@ import { Icon } from '@iconify/react'; import { v4 as uuid } from 'uuid'; import { throttle } from 'lodash'; import MarkdownIt from 'markdown-it'; -import BadWordsNext from 'bad-words-next'; -import en from 'bad-words-next/data/en.json'; import { useChat } from '@/context/ChatContext'; import { useAuth } from '@/context/AuthContext'; @@ -37,6 +35,7 @@ import PreviousMessages from './Chat/PreviousMessages'; import decryptMessage from '@/lib/decryptMessage'; import useInactiveChat from '@/hooks/useInactiveChat'; import { MessageType, InputRefType } from '@/types/types'; +import BadwordHideShow from './Chat/BadwordHideShow'; let senderId: string | undefined; @@ -83,7 +82,11 @@ const Chat = () => { typographer: true, }); - const badwords = new BadWordsNext({ data: en }); + const getBadwords = async () => { + const BadWordsNext = (await import('bad-words-next')).default; + const en = (await import('bad-words-next/data/en.json')).default; + return new BadWordsNext({ data: en }); + } function logOut() { dispatchAuth({ @@ -174,6 +177,7 @@ const Chat = () => { // Here whenever user will submit message it will be send to the server const handleSubmit = async (e: FormEvent) => { + const badwords = await getBadwords(); e.preventDefault(); socket?.emit(events.NEW_EVENT_TYPING, { @@ -488,25 +492,7 @@ const Chat = () => { : 'rounded-r-md' }`} > - {typeof message === 'string' ? ( - - ) : badwordChoices[id] === 'hide' ? ( - badwords.filter(message) - ) : badwordChoices[id] === 'show' ? ( - message - ) : ( - message - )} + { + const badwords = new BadWordsNext({ data: en }); + + return (<>{typeof message === 'string' ? ( + + ) : badwordChoices[id] === 'hide' ? ( + badwords.filter(message) + ) : badwordChoices[id] === 'show' ? ( + message + ) : ( + message + )}) +}; + +export default BadwordHideShow; diff --git a/src/types/propstypes.ts b/src/types/propstypes.ts index 0ce6fb48..fa7f92bf 100644 --- a/src/types/propstypes.ts +++ b/src/types/propstypes.ts @@ -2,6 +2,14 @@ import { Dispatch, SetStateAction, ReactNode } from 'react'; import { DebouncedFunc } from 'lodash'; import { InputRefType } from './types'; +import MarkdownIt from 'markdown-it'; + +export type BadwordHideShowProps = { + id: string; + message: string; + md: MarkdownIt; + badwordChoices: { [id: string]: string }; +}; export type DropDownProps = { id: string; From a92b07cc7d9ac46fe39268c3f922b80f69b7e40a Mon Sep 17 00:00:00 2001 From: Dunsin Date: Wed, 24 Jan 2024 07:16:15 +0100 Subject: [PATCH 4/7] refactor: change chatId to room --- package-lock.json | 24 +++++- package.json | 3 +- src/components/Chat.tsx | 34 ++++---- src/components/Chat/DropDownOption.tsx | 2 +- src/components/Chat/MessageSeen.tsx | 14 ++-- src/components/NavBar.tsx | 2 +- src/components/PageWrapper.tsx | 4 +- src/context/AppContext.tsx | 4 +- src/context/ChatContext.tsx | 20 ++--- src/lib/chatHelper.ts | 8 +- src/lib/chatSocket.ts | 16 ++-- src/pages/anonymous.tsx | 30 +++---- src/pages/index.tsx | 2 +- src/pages/searching.tsx | 10 +-- src/reducer/appReducer.ts | 8 +- src/reducer/chatReducer.ts | 20 ++--- src/server/handlers.ts | 77 +++++++++--------- src/server/lib/lib.ts | 106 ++++++++++++++----------- src/server/models/ActiveUserModel.ts | 13 +-- src/types/contextTypes.ts | 14 ++-- src/types/types.ts | 8 +- 21 files changed, 227 insertions(+), 192 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a940b0a..714bb134 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "whischat", - "version": "0.0.0-development", + "version": "v3.0.0-development", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "whischat", - "version": "0.0.0-development", + "version": "v3.0.0-development", "dependencies": { "@types/crypto-js": "^4.1.3", "@types/express": "^4.17.21", @@ -46,6 +46,7 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/socket.io-client": "^3.0.0", "autoprefixer": "^10.0.1", "cz-conventional-changelog": "^3.3.0", "eslint": "^8.53.0", @@ -1772,6 +1773,16 @@ "socket.io": "*" } }, + "node_modules/@types/socket.io-client": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-3.0.0.tgz", + "integrity": "sha512-s+IPvFoEIjKA3RdJz/Z2dGR4gLgysKi8owcnrVwNjgvc01Lk68LJDDsG2GRqegFITcxmvCMYM7bhMpwEMlHmDg==", + "deprecated": "This is a stub types definition. socket.io-client provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "socket.io-client": "*" + } + }, "node_modules/@types/uuid": { "version": "9.0.6", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz", @@ -14636,6 +14647,15 @@ "socket.io": "*" } }, + "@types/socket.io-client": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-3.0.0.tgz", + "integrity": "sha512-s+IPvFoEIjKA3RdJz/Z2dGR4gLgysKi8owcnrVwNjgvc01Lk68LJDDsG2GRqegFITcxmvCMYM7bhMpwEMlHmDg==", + "dev": true, + "requires": { + "socket.io-client": "*" + } + }, "@types/uuid": { "version": "9.0.6", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz", diff --git a/package.json b/package.json index b59c2fbe..054c1775 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/socket.io-client": "^3.0.0", "autoprefixer": "^10.0.1", "cz-conventional-changelog": "^3.3.0", "eslint": "^8.53.0", @@ -81,4 +82,4 @@ "*.{js,jsx,ts,tsx}": "eslint --fix", "*.--write": "prettier --write ." } -} \ No newline at end of file +} diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx index 0fc040da..e0796daf 100644 --- a/src/components/Chat.tsx +++ b/src/components/Chat.tsx @@ -101,23 +101,23 @@ const Chat = () => { inputRef.current.value = ''; setEditing({ isediting: false, messageID: '' }); socket?.timeout(10000).emit(events.NEW_EVENT_TYPING, { - chatId: app.currentChatId, + room: app.currentroom, isTyping: false, }); }; const sortedMessages = useMemo(() => { - if (!app.currentChatId) { + if (!app.currentroom) { return; } - return Object.values(state[app.currentChatId]?.messages ?? {})?.sort( + return Object.values(state[app.currentroom]?.messages ?? {})?.sort( (a, b) => { const da = new Date(a.time), db = new Date(b.time); return da.getTime() - db.getTime(); } ); - }, [state, app.currentChatId]); + }, [state, app.currentroom]); const doSend = async ({ senderId, @@ -181,7 +181,7 @@ const Chat = () => { e.preventDefault(); socket?.emit(events.NEW_EVENT_TYPING, { - chatId: app.currentChatId, + room: app.currentroom, isTyping: false, }); const d = new Date(); @@ -197,14 +197,14 @@ const Chat = () => { const oldMessage = messageObject?.message; const editedMessage = await editMessage({ id: editing.messageID, - chatId: app.currentChatId, + room: app.currentroom, newMessage: message as string, oldMessage, }); updateMessage({ ...editedMessage, - room: app.currentChatId, + room: app.currentroom, isEdited: true, }); } catch (e) { @@ -215,7 +215,7 @@ const Chat = () => { } else { doSend({ senderId, - room: app.currentChatId, + room: app.currentroom, message: message as string, time: d.getTime(), containsBadword: badwords.check(message as string), @@ -234,7 +234,7 @@ const Chat = () => { const handleTypingStatus = throttle(e => { if (e.target.value.length > 0) { socket?.timeout(5000).emit(events.NEW_EVENT_TYPING, { - chatId: app.currentChatId, + room: app.currentroom, isTyping: true, }); } @@ -292,18 +292,18 @@ const Chat = () => { const deleteMessageHandler = ({ id, - chatId, + room, }: { id: string; - chatId: string; + room: string; }) => { - removeMessage(id, chatId); + removeMessage(id, room); }; const editMessageHandler = (messageEdited: MessageType) => { updateMessage({ ...messageEdited, - room: app.currentChatId, + room: app.currentroom, isEdited: true, }); }; @@ -314,12 +314,12 @@ const Chat = () => { const readMessageHandler = ({ messageId, - chatId, + room, }: { messageId: string; - chatId: string; + room: string; }) => { - receiveMessage(messageId, chatId); + receiveMessage(messageId, room); }; // This is used to recive message form other user. @@ -336,7 +336,7 @@ const Chat = () => { socket?.off(events.NEW_EVENT_READ_MESSAGE, readMessageHandler); socket?.off(events.NEW_EVENT_SEND_FAILED, limitMessageHandler); }; - }, [app.currentChatId, socket]); + }, [app.currentroom, socket]); // this is used to send the notification for inactive chat to the respective user // get the last message sent diff --git a/src/components/Chat/DropDownOption.tsx b/src/components/Chat/DropDownOption.tsx index a74c84ec..f86d9c16 100644 --- a/src/components/Chat/DropDownOption.tsx +++ b/src/components/Chat/DropDownOption.tsx @@ -77,7 +77,7 @@ const DropDownOptions = ({ try { const messageDeleted = await deleteMessage({ id, - chatId: gottenMessage.room as string, + room: gottenMessage.room as string, }); console.log(messageDeleted); diff --git a/src/components/Chat/MessageSeen.tsx b/src/components/Chat/MessageSeen.tsx index b6a6b888..fa735a30 100644 --- a/src/components/Chat/MessageSeen.tsx +++ b/src/components/Chat/MessageSeen.tsx @@ -18,10 +18,10 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { const { seenMessage } = useChatUtils(socket); const sortedMessages = useMemo(() => { - if (!app.currentChatId) { + if (!app.currentroom) { return; } - return Object.values(state[app.currentChatId]?.messages ?? {})?.sort( + return Object.values(state[app.currentroom]?.messages ?? {})?.sort( (a, b) => { const da = new Date(a.time), db = new Date(b.time); @@ -29,7 +29,7 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { return da.getTime() - db.getTime(); } ); - }, [state, app.currentChatId]); + }, [state, app.currentroom]); useEffect(() => { // Initialize Intersection Observer @@ -42,19 +42,19 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { ?.getAttribute('id') ?.split('-')[1] as string; - if (!app.currentChatId) { + if (!app.currentroom) { return; } try { seenMessage({ messageId, - chatId: app.currentChatId, + room: app.currentroom, }); } catch (e) { return; } - receiveMessage(messageId, app.currentChatId); + receiveMessage(messageId, app.currentroom); } }); }, @@ -81,7 +81,7 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { // Clean up the observer observer.disconnect(); }; - }, [sortedMessages, isTabVisible, app.currentChatId, isSender]); + }, [sortedMessages, isTabVisible, app.currentroom, isSender]); return isSender &&

{isRead ? 'Seen' : 'Not Seen'}

; }; diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 8631dc46..cf634791 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -69,7 +69,7 @@ const NavBar = () => { const fullscreenPages = ['/founduser']; const hideNavbar = useMemo( - () => fullscreenPages.includes(location) && app.currentChatId, + () => fullscreenPages.includes(location) && app.currentroom, [location, app] ); diff --git a/src/components/PageWrapper.tsx b/src/components/PageWrapper.tsx index c1c8b89f..763c0407 100644 --- a/src/components/PageWrapper.tsx +++ b/src/components/PageWrapper.tsx @@ -48,11 +48,11 @@ const PageWrapper = ({ children }: ProviderType) => { }, [isLoggedIn, router]); useEffect(() => { - const onRestoreChat = ({ chats, currentChatId }: any) => { + const onRestoreChat = ({ chats, currentroom }: any) => { Object.values(chats).forEach((chat: any) => { createChat(chat.id, chat.userIds, chat.messages, chat.createdAt); }); - endSearch(currentChatId); + endSearch(currentroom); }; socket?.on(events.NEW_EVENT_CHAT_RESTORE, onRestoreChat); diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx index 1436923f..b9ee4ac2 100644 --- a/src/context/AppContext.tsx +++ b/src/context/AppContext.tsx @@ -102,10 +102,10 @@ export const AppProvider = ({ children }: ProviderType) => { }); } - function endSearch(currentChatId: string | null = null): undefined { + function endSearch(currentroom: string | null = null): undefined { dispatch({ type: 'STOP_SEARCHING', - payload: { currentChatId }, + payload: { currentroom }, }); } diff --git a/src/context/ChatContext.tsx b/src/context/ChatContext.tsx index 959dc53d..63f61e59 100644 --- a/src/context/ChatContext.tsx +++ b/src/context/ChatContext.tsx @@ -83,7 +83,7 @@ export const ChatProvider = ({ children }: ProviderType) => { }); }, createChat: ( - chatId: string, + room: string, userIds: [string, string], messages: MessageIdType = {}, createdAt?: Date @@ -91,31 +91,31 @@ export const ChatProvider = ({ children }: ProviderType) => { try { dispatch({ type: 'CREATE_CHAT', - payload: { chatId, userIds, messages, createdAt }, + payload: { room, userIds, messages, createdAt }, }); - console.log('context', { chatId, userIds, messages, createdAt }); - return { chatId, userIds }; + console.log('context', { room, userIds, messages, createdAt }); + return { room, userIds }; } catch (error) { console.error('Error creating chat:', error); return { error }; } }, - removeMessage: (id: string, chatId: string) => { + removeMessage: (id: string, room: string) => { dispatch({ type: 'REMOVE_MESSAGE', - payload: { id, room: chatId }, + payload: { id, room }, }); }, - receiveMessage: (id: string, chatId: string) => { + receiveMessage: (id: string, room: string) => { dispatch({ type: 'RECEIVE_MESSAGE', - payload: { id, room: chatId }, + payload: { id, room }, }); }, - closeChat: (chatId: string) => { + closeChat: (room: string) => { dispatch({ type: 'CLOSE_CHAT', - payload: { chatId }, + payload: { room }, }); }, closeAllChats: () => { diff --git a/src/lib/chatHelper.ts b/src/lib/chatHelper.ts index 89690578..70af2bd8 100644 --- a/src/lib/chatHelper.ts +++ b/src/lib/chatHelper.ts @@ -1,13 +1,13 @@ -import { AppType, ChatIdType, MessageType } from '@/types/types'; +import { AppType, RoomType, MessageType } from '@/types/types'; import { RefObject } from 'react'; -export default (state: ChatIdType, app: AppType) => { +export default (state: RoomType, app: AppType) => { const getMessage = (id: string): MessageType | null => { - if (app.currentChatId === null) { + if (app.currentroom === null) { return null; } - const chatContent = state[app.currentChatId]; + const chatContent = state[app.currentroom]; if (!chatContent) { return null; diff --git a/src/lib/chatSocket.ts b/src/lib/chatSocket.ts index 8ecc9d68..e46de6e3 100644 --- a/src/lib/chatSocket.ts +++ b/src/lib/chatSocket.ts @@ -30,7 +30,7 @@ export default function useChatUtils(socket: Socket | undefined) { }); } - function deleteMessage({ id, chatId }: { id: string; chatId: string }) { + function deleteMessage({ id, room }: { id: string; room: string }) { return new Promise((resolve, reject) => { if (!socket?.connected) { reject(null); @@ -41,7 +41,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_DELETE_MESSAGE, - { id, chatId }, + { id, room }, (err: any, messageDeleted: any) => { if (err) { reject(err); @@ -56,13 +56,13 @@ export default function useChatUtils(socket: Socket | undefined) { function editMessage({ id, - chatId, + room, newMessage, oldMessage, isEdited, }: { id: string; - chatId: string | null; + room: string | null; newMessage: string; oldMessage: string | undefined; isEdited?: boolean; @@ -77,7 +77,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_EDIT_MESSAGE, - { id, chatId, newMessage, oldMessage, isEdited }, + { id, room, newMessage, oldMessage, isEdited }, (err: any, messageEdited: MessageType) => { if (err) { reject(err); @@ -92,10 +92,10 @@ export default function useChatUtils(socket: Socket | undefined) { function seenMessage({ messageId, - chatId, + room, }: { messageId: string; - chatId: string; + room: string; }) { return new Promise((resolve, reject) => { if (!socket?.connected) { @@ -107,7 +107,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_READ_MESSAGE, - { messageId, chatId }, + { messageId, room }, (err: any, messagedRead: any) => { if (err) { reject(err); diff --git a/src/pages/anonymous.tsx b/src/pages/anonymous.tsx index 7f812eaa..d2956980 100644 --- a/src/pages/anonymous.tsx +++ b/src/pages/anonymous.tsx @@ -29,19 +29,19 @@ import { createBrowserNotification } from '@/lib/browserNotification'; import useKeyPress, { ShortcutFlags } from '@/hooks/useKeyPress'; import useCheckTimePassed from '@/hooks/useCheckTimePassed'; -import { ChatIdType, OnlineStatus } from '@/types/types'; +import { RoomType, OnlineStatus } from '@/types/types'; import PageWrapper from '@/components/PageWrapper'; const centerItems = `flex items-center justify-center`; const Anonymous = () => { const { app, endSearch, updateConnection } = useApp(); - const { currentChatId, onlineStatus, disconnected } = app; + const { currentroom, onlineStatus, disconnected } = app; const { clearTimer } = useCheckTimePassed(0, 0); const notification = useNotification({ settings: app.settings }); const { createChat, closeAllChats } = useChat(); - const currentChatIdRef = useRef(currentChatId); + const currentroomRef = useRef(currentroom); const reconnectAttempts = useRef(0); const [isTyping, setIsTyping] = useState(false); @@ -63,9 +63,9 @@ const Anonymous = () => { socket?.on( events.NEW_EVENT_DISPLAY, - ({ isTyping, chatId }: { isTyping: boolean; chatId: string }) => { + ({ isTyping, room }: { isTyping: boolean; room: string }) => { // eslint-disable-next-line curly - if (chatId !== currentChatId) return; + if (room !== currentroom) return; if (!isTyping) { setIsTyping(false); return; @@ -84,9 +84,9 @@ const Anonymous = () => { ); const closeChatHandler = (autoSearch = false) => { - const currentChatId = currentChatIdRef.current; + const currentroom = currentroomRef.current; - if (!currentChatId) { + if (!currentroom) { navigate.push('/'); return; } @@ -97,7 +97,7 @@ const Anonymous = () => { ?.timeout(30000) .emit( events.NEW_EVENT_CLOSE, - currentChatId, + currentroom, (err: any, chatClosed: boolean) => { if (err) { alert('An error occured whiles closing chat.'); @@ -106,7 +106,7 @@ const Anonymous = () => { } if (chatClosed) { - closeChat(currentChatId); + closeChat(currentroom); } endSearch(null); @@ -161,9 +161,9 @@ const Anonymous = () => { events.NEW_EVENT_EDIT_MESSAGE, ]; - socket?.on(events.NEW_EVENT_CLOSE, async chatId => { + socket?.on(events.NEW_EVENT_CLOSE, async room => { endSearch(null); - closeChat(chatId); + closeChat(room); await notification?.playNotification('chatClosed'); if ( @@ -255,7 +255,7 @@ const Anonymous = () => { function disconnect() { reconnectAttempts.current = 0; - if (app.currentChatId) { + if (app.currentroom) { return; } @@ -310,7 +310,7 @@ const Anonymous = () => { socket?.off(event, value); } }; - }, [app.currentChatId, navigate, socket]); + }, [app.currentroom, navigate, socket]); useEffect(() => { if (!onlineStatus) { @@ -319,9 +319,9 @@ const Anonymous = () => { socket?.timeout(5000).emit(events.NEW_EVENT_ONLINE_STATUS, { onlineStatus, - chatId: currentChatId, + room: currentroom, }); - }, [onlineStatus, currentChatId, socket]); + }, [onlineStatus, currentroom, socket]); return ( diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 027f7946..87b7b227 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -39,7 +39,7 @@ export default function Home() { href='/searching' className={`${centerElement} hover:no-underline hover:text-black font-medium text-black text-[1.5em] w-[8em] h-[2.3em] mt-[-5px] rounded-[30px] transition duration-300 ease-in-out bg-[#FF9F1C] hover:bg-[#FBBF24]`} > - {app.currentChatId ? 'Open Chat' : 'Start'} + {app.currentroom ? 'Open Chat' : 'Start'} diff --git a/src/pages/searching.tsx b/src/pages/searching.tsx index a3c8e123..606b0b23 100644 --- a/src/pages/searching.tsx +++ b/src/pages/searching.tsx @@ -57,7 +57,7 @@ const Searching = () => { }, [isStoppingSearch]); useEffect(() => { - if (!app.currentChatId) { + if (!app.currentroom) { startSearch(); } @@ -96,15 +96,15 @@ const Searching = () => { return () => { socket?.off(events.NEW_EVENT_STOP_SEARCH_SUCCESS); }; - }, [app.currentChatId, authState.email, authState.loginId, router, socket]); + }, [app.currentroom, authState.email, authState.loginId, router, socket]); useEffect(() => { - if (!app.currentChatId) { + if (!app.currentroom) { return; } - router.push('/anonymous') - }, [app.currentChatId]) + router.push('/anonymous'); + }, [app.currentroom]); useEffect(() => { if (loadingText === defaultLoadingText) { diff --git a/src/reducer/appReducer.ts b/src/reducer/appReducer.ts index 9131cb97..ce481a16 100644 --- a/src/reducer/appReducer.ts +++ b/src/reducer/appReducer.ts @@ -8,7 +8,7 @@ export const initialState: AppType = { theme: true, }, tmpSettings: {}, - currentChatId: null, + currentroom: null, isSearching: false, onlineStatus: null, disconnected: false, @@ -35,15 +35,15 @@ export default function appReducer(state: AppType, action: any) { case 'START_SEARCHING': { clonedState.isSearching = true; - clonedState.currentChatId = null; + clonedState.currentroom = null; break; } case 'STOP_SEARCHING': { - const { currentChatId } = action.payload; + const { currentroom } = action.payload; clonedState.isSearching = false; - clonedState.currentChatId = currentChatId; + clonedState.currentroom = currentroom; break; } diff --git a/src/reducer/chatReducer.ts b/src/reducer/chatReducer.ts index 83af847f..95ed2be4 100644 --- a/src/reducer/chatReducer.ts +++ b/src/reducer/chatReducer.ts @@ -1,5 +1,5 @@ import { cloneState } from '@/lib/utils'; -import { ChatIdType } from '@/types/types'; +import { RoomType } from '@/types/types'; const messageInitial = { message: '', @@ -14,21 +14,21 @@ const messageInitial = { oldMessages: [], isRead: false, }; -export const initialState: ChatIdType = {}; +export const initialState: RoomType = {}; -export default function chatReducer(state: ChatIdType, action: any) { +export default function chatReducer(state: RoomType, action: any) { const clonedState = cloneState(state); switch (action.type) { case 'CREATE_CHAT': { const { - chatId, + room, userIds, messages = messageInitial, createdAt = new Date(), } = action.payload; - console.log('context', { chatId, userIds }); - clonedState[chatId] = { + console.log('context', { room, userIds }); + clonedState[room] = { userIds, messages, createdAt, @@ -38,15 +38,15 @@ export default function chatReducer(state: ChatIdType, action: any) { } case 'CLOSE_CHAT': { - const { chatId } = action.payload; + const { room } = action.payload; - delete clonedState[chatId]; + delete clonedState[room]; break; } case 'CLOSE_ALL_CHATS': { - for (const chatId in clonedState) { - delete clonedState[chatId]; + for (const room in clonedState) { + delete clonedState[room]; } break; } diff --git a/src/server/handlers.ts b/src/server/handlers.ts index 4f14a6b2..f2536386 100644 --- a/src/server/handlers.ts +++ b/src/server/handlers.ts @@ -1,7 +1,7 @@ import { Server, Socket } from 'socket.io'; import constants from '@/shared/constants/constants'; -import { ChatIdType, OnlineStatus } from '@/types/types'; +import { RoomType, OnlineStatus } from '@/types/types'; import { chatExists, closeChat, @@ -22,23 +22,20 @@ import { export const CloseChatHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_CLOSE, - async ( - chatId: string | string[], - setChatClosed: (arg0: boolean) => void - ) => { + async (room: string | string[], setChatClosed: (arg0: boolean) => void) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !chatExists(chatId as string)) { + if (!user || !chatExists(room as string)) { setChatClosed(false); return; } - const inactiveList = await closeChat(chatId as string); + const inactiveList = await closeChat(room as string); setChatClosed(true); - socket.broadcast.to(chatId).emit(constants.NEW_EVENT_CLOSE, chatId); + socket.broadcast.to(room).emit(constants.NEW_EVENT_CLOSE, room); inactiveList?.forEach((loginId: string) => { socket.broadcast.to(loginId).emit(constants.NEW_EVENT_INACTIVE); }); @@ -49,21 +46,21 @@ export const CloseChatHandler = (socket: Socket) => { export const DeleteManagerHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_DELETE_MESSAGE, - async ({ id: messageId, chatId }, messageWasDeletedSuccessfully) => { + async ({ id: messageId, room }, messageWasDeletedSuccessfully) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !messageId || !chatId) { + if (!user || !messageId || !room) { messageWasDeletedSuccessfully(false); return; } - const messageDeleted = await removeMessage(chatId, messageId); + const messageDeleted = await removeMessage(room, messageId); socket.broadcast - .to(chatId) - .emit(constants.NEW_EVENT_DELETE_MESSAGE, { id: messageId, chatId }); + .to(room) + .emit(constants.NEW_EVENT_DELETE_MESSAGE, { id: messageId, room }); messageWasDeletedSuccessfully(messageDeleted); } ); @@ -73,25 +70,25 @@ export const EditMessageHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_EDIT_MESSAGE, async ( - { id: messageId, chatId, newMessage, oldMessage }, + { id: messageId, room, newMessage, oldMessage }, messageWasEditedSuccessfully ) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !messageId || !chatId) { + if (!user || !messageId || !room) { messageWasEditedSuccessfully(false); return; } - const messageEdited = await editMessage(chatId, { + const messageEdited = await editMessage(room, { id: messageId, message: newMessage, oldMessage, }); socket.broadcast - .to(chatId) + .to(room) .emit(constants.NEW_EVENT_EDIT_MESSAGE, messageEdited); messageWasEditedSuccessfully(messageEdited); } @@ -133,21 +130,21 @@ export const JoinHandler = (io: Server, socket: Socket) => { // First join the user to the last chat if (!user?.socketIds.includes(socket.id)) { - socket.join(user?.currentChatId as string); + socket.join(user?.currentroom as string); user?.socketConnections.push(socket); user?.socketIds.push(socket.id); } - const chats: ChatIdType = {}; + const chats: RoomType = {}; - user?.chatIds.forEach(chatId => { - chats[chatId] = getChat(chatId); + user?.rooms.forEach(room => { + chats[room] = getChat(room); }); // Then return all chat messages socket.emit(constants.NEW_EVENT_CHAT_RESTORE, { chats, - currentChatId: user?.currentChatId, + currentroom: user?.currentroom, }); return; } @@ -173,9 +170,9 @@ export const LogOutHandler = (io: Server, socket: Socket) => { // User is an anonymous user, so close all active chats if (!user.email) { - for (const chatId of user.chatIds) { - const inactiveList = await closeChat(chatId); - io.to(chatId).emit(constants.NEW_EVENT_CLOSE, chatId); + for (const room of user.rooms) { + const inactiveList = await closeChat(room); + io.to(room).emit(constants.NEW_EVENT_CLOSE, room); inactiveList?.forEach(emailOrLoginId => { socket.broadcast .to(emailOrLoginId) @@ -191,13 +188,13 @@ export const OnlineStatusHandler = (socket: Socket) => { constants.NEW_EVENT_ONLINE_STATUS, ({ onlineStatus, - chatId, + room, }: { onlineStatus: OnlineStatus; - chatId: string; + room: string; }): void => { socket.broadcast - .to(chatId) + .to(room) .emit(constants.NEW_EVENT_ONLINE_STATUS, onlineStatus); } ); @@ -206,19 +203,19 @@ export const OnlineStatusHandler = (socket: Socket) => { export const SeenMessageHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_READ_MESSAGE, - async ({ messageId, chatId }, messageSuccessfullySeen) => { + async ({ messageId, room }, messageSuccessfullySeen) => { const user = getActiveUser({ socketId: socket.id }); - if (!user || !messageId || !chatId) { + if (!user || !messageId || !room) { messageSuccessfullySeen(false); return; } - const messageSeen = await seenMessage(chatId, messageId); + const messageSeen = await seenMessage(room, messageId); - socket.broadcast.to(chatId).emit(constants.NEW_EVENT_READ_MESSAGE, { + socket.broadcast.to(room).emit(constants.NEW_EVENT_READ_MESSAGE, { messageId, - chatId, + room, }); messageSuccessfullySeen(messageSeen); @@ -234,7 +231,7 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { socket.on( constants.NEW_EVENT_SEND_MESSAGE, async ( - { senderId, message, time, room: chatId, containsBadword, replyTo }, + { senderId, message, time, room: room, containsBadword, replyTo }, returnMessageToSender ) => { // Below line is just a failed message simulator for testing purposes. @@ -271,7 +268,7 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { /** * Cache the sent message in memory a nd persist to db */ - const sentMessage = await addMessage(chatId, { + const sentMessage = await addMessage(room, { message, time, senderId, @@ -282,14 +279,14 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { const messageDetails = { ...sentMessage, - chatId, + room, status: 'sent', }; returnMessageToSender(messageDetails); socket.broadcast - .to(chatId) + .to(room) .emit(constants.NEW_EVENT_RECEIVE_MESSAGE, messageDetails); // Update the message count for the user @@ -315,10 +312,10 @@ export const StopSearchHandler = (socket: Socket) => { }; export const TypingHandler = (socket: Socket) => { - socket.on(constants.NEW_EVENT_TYPING, ({ chatId, isTyping }) => { + socket.on(constants.NEW_EVENT_TYPING, ({ room, isTyping }) => { socket - .to(chatId) + .to(room) .timeout(5000) - .emit(constants.NEW_EVENT_DISPLAY, { isTyping, chatId }); + .emit(constants.NEW_EVENT_DISPLAY, { isTyping, room }); }); }; diff --git a/src/server/lib/lib.ts b/src/server/lib/lib.ts index 436b43ae..7f9a3762 100644 --- a/src/server/lib/lib.ts +++ b/src/server/lib/lib.ts @@ -6,7 +6,7 @@ import ActiveUser from '@/server/models/ActiveUserModel'; import Chat from '@/server/models/ChatModel'; import Message from '@/server/models/MessageModel'; import { - ChatIdType, + RoomType, activeUserIdType, ActiveUserType, ChatType, @@ -20,14 +20,14 @@ const waitingUsers: activeUserIdType = {}; const activeUsers: activeUserIdType = {}; -const chats: ChatIdType = {}; +const chats: RoomType = {}; function addActiveUser(user: ActiveUserType) { activeUsers[user.loginId] = user; } -function getChat(chatId: string): ChatType { - return chats[chatId] ?? null; +function getChat(room: string): ChatType { + return chats[room] ?? null; } function getActiveUser( @@ -64,7 +64,7 @@ function getActiveUser( } function getChatsCount(id: string) { - return getActiveUser(id)?.chatIds.length; + return getActiveUser(id)?.rooms.length; } async function delActiveUser(user: ActiveUserType) { @@ -105,6 +105,17 @@ async function init() { }; } + type objType = { + id: string; + email: string | null; + loginId: string; + socketConnections: Socket[]; + socketIds: string[]; + currentChat?: string | null; + currentroom: string | null; + rooms: string[]; + }; + for await (const activeUser of ActiveUser.find()) { const chats = await Chat.find({ users: { @@ -112,10 +123,15 @@ async function init() { }, }); - activeUsers[activeUser.loginId] = { + const obj: objType = { ...activeUser.optimizedVersion, - chatIds: chats.map(chat => chat._id.toString()), + currentroom: activeUser.optimizedVersion.currentChat, + rooms: chats.map(chat => chat._id.toString()) as string[], }; + + delete obj.currentChat; + + activeUsers[activeUser.loginId] = obj; } } @@ -130,7 +146,7 @@ async function createChat(users: ActiveUserType[]) { messages: [], }; - const chatId = _chat._id.toString(); + const room = _chat._id.toString(); // TODO: this shouldn't happen as now new users are added to active users collection instead of users collection. // find a way to take users from users and fill it in active users. @@ -145,10 +161,10 @@ async function createChat(users: ActiveUserType[]) { _chat.users.push(user.id); users[i].id = user._id.toString(); - users[i].currentChatId = chatId; - users[i].chatIds.push(chatId); + users[i].currentroom = room; + users[i].rooms.push(room); users[i].socketConnections.map(socket => { - socket.join(chatId); + socket.join(room); }); addActiveUser(users[i]); @@ -161,17 +177,17 @@ async function createChat(users: ActiveUserType[]) { userIds: users.map(user => user.loginId) as [string, string], }; - chats[chatId] = optimizedChat; + chats[room] = optimizedChat; - return { id: chatId, ...optimizedChat }; + return { id: room, ...optimizedChat }; } -async function closeChat(chatId: string) { +async function closeChat(room: string) { await Chat.deleteOne({ - _id: chatId, + _id: room, }); - const chat = getChat(chatId); + const chat = getChat(room); if (!chat) { return null; @@ -192,18 +208,18 @@ async function closeChat(chatId: string) { continue; } - user.chatIds.forEach((id, i) => { - if (id === chatId) { - user.chatIds.splice(i, 1); + user.rooms.forEach((id, i) => { + if (id === room) { + user.rooms.splice(i, 1); } }); await Chat.deleteOne({ - _id: chatId, + _id: room, }); if (getChatsCount(userId) === 0) { - user.currentChatId = null; + user.currentroom = null; await delActiveUser(user); if (!inactiveList.includes(user.loginId)) { @@ -212,17 +228,17 @@ async function closeChat(chatId: string) { } } - delete chats[chatId]; + delete chats[room]; return inactiveList; } -function chatExists(chatId: string) { - return Boolean(getChat(chatId)); +function chatExists(room: string) { + return Boolean(getChat(room)); } async function addMessage( - chatId: string, + room: string, { message, time, @@ -240,7 +256,7 @@ async function addMessage( return null; } - if (!chats[chatId]) { + if (!chats[room]) { return null; } @@ -260,7 +276,7 @@ async function addMessage( await Chat.updateOne( { - _id: chatId, + _id: room, }, { $push: { @@ -269,13 +285,13 @@ async function addMessage( } ); - chats[chatId].messages[optimizedMessage.id] = optimizedMessage; + chats[room].messages[optimizedMessage.id] = optimizedMessage; return optimizedMessage; } -async function removeMessage(chatId: string, messageId: string) { - if (!chats[chatId]) { +async function removeMessage(room: string, messageId: string) { + if (!chats[room]) { return false; } @@ -287,24 +303,24 @@ async function removeMessage(chatId: string, messageId: string) { return false; } - delete chats[chatId].messages[messageId]; + delete chats[room].messages[messageId]; return true; } async function editMessage( - chatId: string, + room: string, { id, message, oldMessage, }: { id: string; message: string; oldMessage: string } ) { - if (!chats[chatId]) { + if (!chats[room]) { return false; } - if (!chats[chatId].messages[id]) { + if (!chats[room].messages[id]) { return false; } @@ -320,20 +336,20 @@ async function editMessage( { new: true } ); - chats[chatId].messages[id].message = message; - chats[chatId].messages[id].isEdited = true; - if (!Array.isArray(chats[chatId].messages[id].oldMessages)) { - chats[chatId].messages[id].oldMessages = []; + chats[room].messages[id].message = message; + chats[room].messages[id].isEdited = true; + if (!Array.isArray(chats[room].messages[id].oldMessages)) { + chats[room].messages[id].oldMessages = []; } - chats[chatId].messages[id]?.oldMessages?.push(oldMessage); - return chats[chatId].messages[id]; + chats[room].messages[id]?.oldMessages?.push(oldMessage); + return chats[room].messages[id]; } catch { return false; } } -async function seenMessage(chatId: string, messageId: string) { - if (!chats[chatId]) { +async function seenMessage(room: string, messageId: string) { + if (!chats[room]) { return false; } @@ -352,7 +368,7 @@ async function seenMessage(chatId: string, messageId: string) { { new: true } ); - chats[chatId].messages[messageId].isRead = isRead; + chats[room].messages[messageId].isRead = isRead; } catch { return false; } @@ -399,8 +415,8 @@ function addToWaitingList({ email, socketConnections: [socket], socketIds: [socket.id], - chatIds: [], - currentChatId: null, + rooms: [], + currentroom: null, }, { get(target, prop, receiver) { diff --git a/src/server/models/ActiveUserModel.ts b/src/server/models/ActiveUserModel.ts index 12a11337..932c01fe 100644 --- a/src/server/models/ActiveUserModel.ts +++ b/src/server/models/ActiveUserModel.ts @@ -1,4 +1,5 @@ import { Schema, Document, Model, model, Types, models } from 'mongoose'; +import { Socket } from 'socket.io'; export interface ActiveUserSchemaDocument extends Document { email: string | null; @@ -11,10 +12,10 @@ export interface ActiveUserSchemaDocument extends Document { id: string; email: string | null; loginId: string; - socketConnections: any[]; - socketIds: any[]; - currentChatId: string | null; - chatIds: any[]; + socketConnections: Socket[]; + socketIds: string[]; + currentChat: string | null; + rooms: string[]; }; } @@ -47,8 +48,8 @@ activeUserSchema.virtual('optimizedVersion').get(function ( loginId: this.loginId, socketConnections: [], socketIds: [], - currentChatId: this.currentChat?.toString() || null, - chatIds: [], + currentChat: this.currentChat?.toString() || null, + rooms: [], }; }); diff --git a/src/types/contextTypes.ts b/src/types/contextTypes.ts index 55aaba31..c97ddf3a 100644 --- a/src/types/contextTypes.ts +++ b/src/types/contextTypes.ts @@ -2,7 +2,7 @@ import { Dispatch } from 'react'; import { AppType, AuthType, - ChatIdType, + RoomType, MessageIdType, MessageType, SettingsType, @@ -18,20 +18,20 @@ export type DialogType = { export type ChatContextType = { createChat: ( - chatId: string, + room: string, userIds: [string, string], messages?: MessageIdType, createdAt?: Date ) => any; - messages: ChatIdType; - removeMessage: (id: string, chatid: string) => void; + messages: RoomType; + removeMessage: (id: string, room: string) => void; addMessage: (message: MessageType) => void; updateMessage: (message: any) => void; - closeChat: (chatId: string) => void; + closeChat: (room: string) => void; currentReplyMessage: MessageType | null; currentReplyMessageId: string; closeAllChats: () => void; - receiveMessage: (id: string, chatId: string) => void; + receiveMessage: (id: string, room: string) => void; startReply: (messageId: string) => void; cancelReply: () => void; }; @@ -43,7 +43,7 @@ export type AppContextType = { updateTmpSettings: (newSettings: SettingsType) => void; cancelSettingsUpdate: () => void; startSearch: () => undefined; - endSearch: (currentChatId: null | string) => undefined; + endSearch: (currentroom: null | string) => undefined; loadUserSettings: (settings: SettingsType) => void; updateOnlineStatus: (onlineStatus: Date | string | null) => void; updateConnection: (isDisconnected: boolean) => void; diff --git a/src/types/types.ts b/src/types/types.ts index 830f7568..56a4fa08 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -20,7 +20,7 @@ export type SettingsType = { export type AppType = { settings: SettingsType; tmpSettings: {}; - currentChatId: string | null; + currentroom: string | null; isSearching: boolean; onlineStatus: OnlineStatus; disconnected: boolean; @@ -58,7 +58,7 @@ export type ChatType = { userIds: [string, string]; }; -export type ChatIdType = { +export type RoomType = { [id: string]: ChatType; }; @@ -68,8 +68,8 @@ export type ActiveUserType = { loginId: string; socketConnections: Socket[]; socketIds: string[]; - currentChatId: null | string; - chatIds: string[]; + currentroom: null | string; + rooms: string[]; }; export type activeUserIdType = { From 44c59e714e3999dbe3a3ecd21d34b3bb6a15712f Mon Sep 17 00:00:00 2001 From: Dunsin <78784850+Dun-sin@users.noreply.github.com> Date: Wed, 24 Jan 2024 07:39:25 +0100 Subject: [PATCH 5/7] Update src/pages/searching.tsx --- src/pages/searching.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/searching.tsx b/src/pages/searching.tsx index 459f07b2..99fdeeb8 100644 --- a/src/pages/searching.tsx +++ b/src/pages/searching.tsx @@ -107,7 +107,7 @@ const Searching = () => { }, [app.currentroom]); useEffect(() => { - if (!app.currentChatId) { + if (!app.currentroom) { return; } From 053019e4264302735c68e17c346c7eb000c0dc58 Mon Sep 17 00:00:00 2001 From: Dunsin Date: Wed, 24 Jan 2024 07:47:58 +0100 Subject: [PATCH 6/7] refactor: change naming to currentroom --- src/pages/searching.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/searching.tsx b/src/pages/searching.tsx index 99fdeeb8..d34cde2f 100644 --- a/src/pages/searching.tsx +++ b/src/pages/searching.tsx @@ -111,8 +111,8 @@ const Searching = () => { return; } - router.push('/anonymous') - }, [app.currentChatId]) + router.push('/anonymous'); + }, [app.currentroom]); useEffect(() => { if (loadingText === defaultLoadingText) { From 34d3e0abaa0a869a7fa95ae98f4a4e68cd11c5b8 Mon Sep 17 00:00:00 2001 From: Dunsin Date: Wed, 24 Jan 2024 18:24:40 +0100 Subject: [PATCH 7/7] refactor: change naming from room to roomId --- src/components/Chat.tsx | 42 +++++++------- src/components/Chat/DropDownOption.tsx | 4 +- src/components/Chat/MessageSeen.tsx | 14 ++--- src/components/NavBar.tsx | 2 +- src/components/PageWrapper.tsx | 4 +- src/context/AppContext.tsx | 4 +- src/context/ChatContext.tsx | 20 +++---- src/lib/chatHelper.ts | 8 +-- src/lib/chatSocket.ts | 16 +++--- src/pages/anonymous.tsx | 28 ++++----- src/pages/index.tsx | 2 +- src/pages/searching.tsx | 16 ++---- src/reducer/appReducer.ts | 8 +-- src/reducer/chatReducer.ts | 64 ++++++++++----------- src/server/handlers.ts | 73 ++++++++++++----------- src/server/lib/lib.ts | 80 ++++++++++++-------------- src/server/models/ActiveUserModel.ts | 4 +- src/types/contextTypes.ts | 10 ++-- src/types/types.ts | 6 +- 19 files changed, 198 insertions(+), 207 deletions(-) diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx index e0796daf..0f106c8f 100644 --- a/src/components/Chat.tsx +++ b/src/components/Chat.tsx @@ -101,34 +101,34 @@ const Chat = () => { inputRef.current.value = ''; setEditing({ isediting: false, messageID: '' }); socket?.timeout(10000).emit(events.NEW_EVENT_TYPING, { - room: app.currentroom, + roomId: app.currentRoomId, isTyping: false, }); }; const sortedMessages = useMemo(() => { - if (!app.currentroom) { + if (!app.currentRoomId) { return; } - return Object.values(state[app.currentroom]?.messages ?? {})?.sort( + return Object.values(state[app.currentRoomId]?.messages ?? {})?.sort( (a, b) => { const da = new Date(a.time), db = new Date(b.time); return da.getTime() - db.getTime(); } ); - }, [state, app.currentroom]); + }, [state, app.currentRoomId]); const doSend = async ({ senderId, - room, + roomId, message, time, containsBadword, replyTo = null, }: { senderId: string; - room: string | null; + roomId: string | null; message: string; time: number; containsBadword: boolean; @@ -139,7 +139,7 @@ const Chat = () => { senderId, message, time, - room, + roomId, containsBadword, replyTo, }); @@ -157,7 +157,7 @@ const Chat = () => { try { updateMessage({ senderId, - room, + roomId, id: uuid(), message, time, @@ -181,7 +181,7 @@ const Chat = () => { e.preventDefault(); socket?.emit(events.NEW_EVENT_TYPING, { - room: app.currentroom, + roomId: app.currentRoomId, isTyping: false, }); const d = new Date(); @@ -197,14 +197,14 @@ const Chat = () => { const oldMessage = messageObject?.message; const editedMessage = await editMessage({ id: editing.messageID, - room: app.currentroom, + roomId: app.currentRoomId, newMessage: message as string, oldMessage, }); updateMessage({ ...editedMessage, - room: app.currentroom, + roomId: app.currentRoomId, isEdited: true, }); } catch (e) { @@ -215,7 +215,7 @@ const Chat = () => { } else { doSend({ senderId, - room: app.currentroom, + roomId: app.currentRoomId, message: message as string, time: d.getTime(), containsBadword: badwords.check(message as string), @@ -234,7 +234,7 @@ const Chat = () => { const handleTypingStatus = throttle(e => { if (e.target.value.length > 0) { socket?.timeout(5000).emit(events.NEW_EVENT_TYPING, { - room: app.currentroom, + roomId: app.currentRoomId, isTyping: true, }); } @@ -292,18 +292,18 @@ const Chat = () => { const deleteMessageHandler = ({ id, - room, + roomId, }: { id: string; - room: string; + roomId: string; }) => { - removeMessage(id, room); + removeMessage(id, roomId); }; const editMessageHandler = (messageEdited: MessageType) => { updateMessage({ ...messageEdited, - room: app.currentroom, + roomId: app.currentRoomId, isEdited: true, }); }; @@ -314,12 +314,12 @@ const Chat = () => { const readMessageHandler = ({ messageId, - room, + roomId, }: { messageId: string; - room: string; + roomId: string; }) => { - receiveMessage(messageId, room); + receiveMessage(messageId, roomId); }; // This is used to recive message form other user. @@ -336,7 +336,7 @@ const Chat = () => { socket?.off(events.NEW_EVENT_READ_MESSAGE, readMessageHandler); socket?.off(events.NEW_EVENT_SEND_FAILED, limitMessageHandler); }; - }, [app.currentroom, socket]); + }, [app.currentRoomId, socket]); // this is used to send the notification for inactive chat to the respective user // get the last message sent diff --git a/src/components/Chat/DropDownOption.tsx b/src/components/Chat/DropDownOption.tsx index f86d9c16..3774a651 100644 --- a/src/components/Chat/DropDownOption.tsx +++ b/src/components/Chat/DropDownOption.tsx @@ -77,7 +77,7 @@ const DropDownOptions = ({ try { const messageDeleted = await deleteMessage({ id, - room: gottenMessage.room as string, + roomId: gottenMessage.roomId as string, }); console.log(messageDeleted); @@ -86,7 +86,7 @@ const DropDownOptions = ({ return; } - removeMessage(id, gottenMessage.room as string); + removeMessage(id, gottenMessage.roomId as string); } catch (e) { console.log(e); updateMessage(gottenMessage); diff --git a/src/components/Chat/MessageSeen.tsx b/src/components/Chat/MessageSeen.tsx index fa735a30..95a9dcb7 100644 --- a/src/components/Chat/MessageSeen.tsx +++ b/src/components/Chat/MessageSeen.tsx @@ -18,10 +18,10 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { const { seenMessage } = useChatUtils(socket); const sortedMessages = useMemo(() => { - if (!app.currentroom) { + if (!app.currentRoomId) { return; } - return Object.values(state[app.currentroom]?.messages ?? {})?.sort( + return Object.values(state[app.currentRoomId]?.messages ?? {})?.sort( (a, b) => { const da = new Date(a.time), db = new Date(b.time); @@ -29,7 +29,7 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { return da.getTime() - db.getTime(); } ); - }, [state, app.currentroom]); + }, [state, app.currentRoomId]); useEffect(() => { // Initialize Intersection Observer @@ -42,19 +42,19 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { ?.getAttribute('id') ?.split('-')[1] as string; - if (!app.currentroom) { + if (!app.currentRoomId) { return; } try { seenMessage({ messageId, - room: app.currentroom, + roomId: app.currentRoomId, }); } catch (e) { return; } - receiveMessage(messageId, app.currentroom); + receiveMessage(messageId, app.currentRoomId); } }); }, @@ -81,7 +81,7 @@ const MessageSeen = ({ isRead, isSender }: MessageSeenProps) => { // Clean up the observer observer.disconnect(); }; - }, [sortedMessages, isTabVisible, app.currentroom, isSender]); + }, [sortedMessages, isTabVisible, app.currentRoomId, isSender]); return isSender &&

{isRead ? 'Seen' : 'Not Seen'}

; }; diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index cf634791..fe1193ae 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -69,7 +69,7 @@ const NavBar = () => { const fullscreenPages = ['/founduser']; const hideNavbar = useMemo( - () => fullscreenPages.includes(location) && app.currentroom, + () => fullscreenPages.includes(location) && app.currentRoomId, [location, app] ); diff --git a/src/components/PageWrapper.tsx b/src/components/PageWrapper.tsx index 763c0407..50934882 100644 --- a/src/components/PageWrapper.tsx +++ b/src/components/PageWrapper.tsx @@ -48,11 +48,11 @@ const PageWrapper = ({ children }: ProviderType) => { }, [isLoggedIn, router]); useEffect(() => { - const onRestoreChat = ({ chats, currentroom }: any) => { + const onRestoreChat = ({ chats, currentRoomId }: any) => { Object.values(chats).forEach((chat: any) => { createChat(chat.id, chat.userIds, chat.messages, chat.createdAt); }); - endSearch(currentroom); + endSearch(currentRoomId); }; socket?.on(events.NEW_EVENT_CHAT_RESTORE, onRestoreChat); diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx index b9ee4ac2..4a70a2f4 100644 --- a/src/context/AppContext.tsx +++ b/src/context/AppContext.tsx @@ -102,10 +102,10 @@ export const AppProvider = ({ children }: ProviderType) => { }); } - function endSearch(currentroom: string | null = null): undefined { + function endSearch(currentRoomId: string | null = null): undefined { dispatch({ type: 'STOP_SEARCHING', - payload: { currentroom }, + payload: { currentRoomId }, }); } diff --git a/src/context/ChatContext.tsx b/src/context/ChatContext.tsx index 63f61e59..c216250e 100644 --- a/src/context/ChatContext.tsx +++ b/src/context/ChatContext.tsx @@ -83,7 +83,7 @@ export const ChatProvider = ({ children }: ProviderType) => { }); }, createChat: ( - room: string, + roomId: string, userIds: [string, string], messages: MessageIdType = {}, createdAt?: Date @@ -91,31 +91,31 @@ export const ChatProvider = ({ children }: ProviderType) => { try { dispatch({ type: 'CREATE_CHAT', - payload: { room, userIds, messages, createdAt }, + payload: { roomId, userIds, messages, createdAt }, }); - console.log('context', { room, userIds, messages, createdAt }); - return { room, userIds }; + console.log('context', { roomId, userIds, messages, createdAt }); + return { roomId, userIds }; } catch (error) { console.error('Error creating chat:', error); return { error }; } }, - removeMessage: (id: string, room: string) => { + removeMessage: (id: string, roomId: string) => { dispatch({ type: 'REMOVE_MESSAGE', - payload: { id, room }, + payload: { id, roomId }, }); }, - receiveMessage: (id: string, room: string) => { + receiveMessage: (id: string, roomId: string) => { dispatch({ type: 'RECEIVE_MESSAGE', - payload: { id, room }, + payload: { id, roomId }, }); }, - closeChat: (room: string) => { + closeChat: (roomId: string) => { dispatch({ type: 'CLOSE_CHAT', - payload: { room }, + payload: { roomId }, }); }, closeAllChats: () => { diff --git a/src/lib/chatHelper.ts b/src/lib/chatHelper.ts index 70af2bd8..5fa19827 100644 --- a/src/lib/chatHelper.ts +++ b/src/lib/chatHelper.ts @@ -3,11 +3,11 @@ import { RefObject } from 'react'; export default (state: RoomType, app: AppType) => { const getMessage = (id: string): MessageType | null => { - if (app.currentroom === null) { + if (app.currentRoomId === null) { return null; } - const chatContent = state[app.currentroom]; + const chatContent = state[app.currentRoomId]; if (!chatContent) { return null; @@ -31,11 +31,11 @@ export default (state: RoomType, app: AppType) => { return; } - const { senderId, room, message, time } = gottenMessage; + const { senderId, roomId, message, time } = gottenMessage; doSend({ senderId, - room, + roomId, message, time, tmpId: id, diff --git a/src/lib/chatSocket.ts b/src/lib/chatSocket.ts index e46de6e3..a7d57576 100644 --- a/src/lib/chatSocket.ts +++ b/src/lib/chatSocket.ts @@ -30,7 +30,7 @@ export default function useChatUtils(socket: Socket | undefined) { }); } - function deleteMessage({ id, room }: { id: string; room: string }) { + function deleteMessage({ id, roomId }: { id: string; roomId: string }) { return new Promise((resolve, reject) => { if (!socket?.connected) { reject(null); @@ -41,7 +41,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_DELETE_MESSAGE, - { id, room }, + { id, roomId }, (err: any, messageDeleted: any) => { if (err) { reject(err); @@ -56,13 +56,13 @@ export default function useChatUtils(socket: Socket | undefined) { function editMessage({ id, - room, + roomId, newMessage, oldMessage, isEdited, }: { id: string; - room: string | null; + roomId: string | null; newMessage: string; oldMessage: string | undefined; isEdited?: boolean; @@ -77,7 +77,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_EDIT_MESSAGE, - { id, room, newMessage, oldMessage, isEdited }, + { id, roomId, newMessage, oldMessage, isEdited }, (err: any, messageEdited: MessageType) => { if (err) { reject(err); @@ -92,10 +92,10 @@ export default function useChatUtils(socket: Socket | undefined) { function seenMessage({ messageId, - room, + roomId, }: { messageId: string; - room: string; + roomId: string; }) { return new Promise((resolve, reject) => { if (!socket?.connected) { @@ -107,7 +107,7 @@ export default function useChatUtils(socket: Socket | undefined) { .timeout(30000) .emit( events.NEW_EVENT_READ_MESSAGE, - { messageId, room }, + { messageId, roomId }, (err: any, messagedRead: any) => { if (err) { reject(err); diff --git a/src/pages/anonymous.tsx b/src/pages/anonymous.tsx index 833b1572..45e919f4 100644 --- a/src/pages/anonymous.tsx +++ b/src/pages/anonymous.tsx @@ -36,12 +36,12 @@ const centerItems = `flex items-center justify-center`; const Anonymous = () => { const { app, endSearch, updateConnection } = useApp(); - const { currentroom, onlineStatus, disconnected } = app; + const { currentRoomId, onlineStatus, disconnected } = app; const { clearTimer } = useCheckTimePassed(0, 0); const notification = useNotification({ settings: app.settings }); const { createChat, closeAllChats } = useChat(); - const currentroomRef = useRef(currentroom); + const currentroomRef = useRef(currentRoomId); const reconnectAttempts = useRef(0); const [isTyping, setIsTyping] = useState(false); @@ -63,9 +63,9 @@ const Anonymous = () => { socket?.on( events.NEW_EVENT_DISPLAY, - ({ isTyping, room }: { isTyping: boolean; room: string }) => { + ({ isTyping, roomId }: { isTyping: boolean; roomId: string }) => { // eslint-disable-next-line curly - if (room !== currentroom) return; + if (roomId !== currentRoomId) return; if (!isTyping) { setIsTyping(false); return; @@ -84,9 +84,9 @@ const Anonymous = () => { ); const closeChatHandler = (autoSearch = false) => { - const currentroom = currentroomRef.current; + const currentRoomId = currentroomRef.current; - if (!currentroom) { + if (!currentRoomId) { navigate.push('/'); return; } @@ -97,7 +97,7 @@ const Anonymous = () => { ?.timeout(30000) .emit( events.NEW_EVENT_CLOSE, - currentroom, + currentRoomId, (err: any, chatClosed: boolean) => { if (err) { alert('An error occured whiles closing chat.'); @@ -106,7 +106,7 @@ const Anonymous = () => { } if (chatClosed) { - closeChat(currentroom); + closeChat(currentRoomId); } endSearch(null); @@ -161,9 +161,9 @@ const Anonymous = () => { events.NEW_EVENT_EDIT_MESSAGE, ]; - socket?.on(events.NEW_EVENT_CLOSE, async room => { + socket?.on(events.NEW_EVENT_CLOSE, async roomId => { endSearch(null); - closeChat(room); + closeChat(roomId); await notification?.playNotification('chatClosed'); if ( @@ -255,7 +255,7 @@ const Anonymous = () => { function disconnect() { reconnectAttempts.current = 0; - if (app.currentroom) { + if (app.currentRoomId) { return; } @@ -308,7 +308,7 @@ const Anonymous = () => { socket?.off(event, value); } }; - }, [app.currentroom, navigate, socket]); + }, [app.currentRoomId, navigate, socket]); useEffect(() => { if (!onlineStatus) { @@ -317,9 +317,9 @@ const Anonymous = () => { socket?.timeout(5000).emit(events.NEW_EVENT_ONLINE_STATUS, { onlineStatus, - room: currentroom, + roomId: currentRoomId, }); - }, [onlineStatus, currentroom, socket]); + }, [onlineStatus, currentRoomId, socket]); return ( diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 87b7b227..cfcae7e7 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -39,7 +39,7 @@ export default function Home() { href='/searching' className={`${centerElement} hover:no-underline hover:text-black font-medium text-black text-[1.5em] w-[8em] h-[2.3em] mt-[-5px] rounded-[30px] transition duration-300 ease-in-out bg-[#FF9F1C] hover:bg-[#FBBF24]`} > - {app.currentroom ? 'Open Chat' : 'Start'} + {app.currentRoomId ? 'Open Chat' : 'Start'} diff --git a/src/pages/searching.tsx b/src/pages/searching.tsx index d34cde2f..a0c927ff 100644 --- a/src/pages/searching.tsx +++ b/src/pages/searching.tsx @@ -57,7 +57,7 @@ const Searching = () => { }, [isStoppingSearch]); useEffect(() => { - if (!app.currentroom) { + if (!app.currentRoomId) { startSearch(); } @@ -96,23 +96,15 @@ const Searching = () => { return () => { socket?.off(events.NEW_EVENT_STOP_SEARCH_SUCCESS); }; - }, [app.currentroom, authState.email, authState.loginId, router, socket]); + }, [app.currentRoomId, authState.email, authState.loginId, router, socket]); useEffect(() => { - if (!app.currentroom) { + if (!app.currentRoomId) { return; } router.push('/anonymous'); - }, [app.currentroom]); - - useEffect(() => { - if (!app.currentroom) { - return; - } - - router.push('/anonymous'); - }, [app.currentroom]); + }, [app.currentRoomId]); useEffect(() => { if (loadingText === defaultLoadingText) { diff --git a/src/reducer/appReducer.ts b/src/reducer/appReducer.ts index ce481a16..97e8ad34 100644 --- a/src/reducer/appReducer.ts +++ b/src/reducer/appReducer.ts @@ -8,7 +8,7 @@ export const initialState: AppType = { theme: true, }, tmpSettings: {}, - currentroom: null, + currentRoomId: null, isSearching: false, onlineStatus: null, disconnected: false, @@ -35,15 +35,15 @@ export default function appReducer(state: AppType, action: any) { case 'START_SEARCHING': { clonedState.isSearching = true; - clonedState.currentroom = null; + clonedState.currentRoomId = null; break; } case 'STOP_SEARCHING': { - const { currentroom } = action.payload; + const { currentRoomId } = action.payload; clonedState.isSearching = false; - clonedState.currentroom = currentroom; + clonedState.currentRoomId = currentRoomId; break; } diff --git a/src/reducer/chatReducer.ts b/src/reducer/chatReducer.ts index 95ed2be4..f8b51470 100644 --- a/src/reducer/chatReducer.ts +++ b/src/reducer/chatReducer.ts @@ -7,7 +7,7 @@ const messageInitial = { senderId: '', id: '', status: '', - room: '', + roomId: '', containsBadword: false, replyTo: '', isEdited: false, @@ -21,14 +21,14 @@ export default function chatReducer(state: RoomType, action: any) { switch (action.type) { case 'CREATE_CHAT': { const { - room, + roomId, userIds, messages = messageInitial, createdAt = new Date(), } = action.payload; - console.log('context', { room, userIds }); - clonedState[room] = { + console.log('context', { roomId, userIds }); + clonedState[roomId] = { userIds, messages, createdAt, @@ -38,15 +38,15 @@ export default function chatReducer(state: RoomType, action: any) { } case 'CLOSE_CHAT': { - const { room } = action.payload; + const { roomId } = action.payload; - delete clonedState[room]; + delete clonedState[roomId]; break; } case 'CLOSE_ALL_CHATS': { - for (const room in clonedState) { - delete clonedState[room]; + for (const roomId in clonedState) { + delete clonedState[roomId]; } break; } @@ -54,7 +54,7 @@ export default function chatReducer(state: RoomType, action: any) { case 'ADD_MESSAGE': { const { senderId, - room, + roomId, id, message, time, @@ -63,13 +63,13 @@ export default function chatReducer(state: RoomType, action: any) { replyTo, } = action.payload || {}; - if (!clonedState[room]) { + if (!clonedState[roomId]) { throw new Error('Room not found!'); } - clonedState[room].messages[id] = { + clonedState[roomId].messages[id] = { senderId, - room, + roomId, id, message, time, @@ -87,73 +87,73 @@ export default function chatReducer(state: RoomType, action: any) { const message = action.payload; const id = message.id; - if (!clonedState[message.room]) { + if (!clonedState[message.roomId]) { throw new Error('Room not found!'); } if (id !== message.id) { - delete clonedState[message.room].messages[id]; + delete clonedState[message.roomId].messages[id]; } - const room = message.room; + const roomId = message.roomId; const messageId = message.id; const updatedMessage = message; const oldMessages = message.oldMessages; // Assign the message to the cloned state - clonedState[room].messages[messageId] = updatedMessage; + clonedState[roomId].messages[messageId] = updatedMessage; // Update the 'isEdited' property if (message.isEdited === undefined || message.isEdited === null) { break; } - clonedState[room].messages[messageId].isEdited = message.isEdited; + clonedState[roomId].messages[messageId].isEdited = message.isEdited; if (oldMessages.length === 0) { break; } - clonedState[room].messages[messageId].oldMessages = oldMessages; + clonedState[roomId].messages[messageId].oldMessages = oldMessages; break; } case 'REMOVE_MESSAGE': { - const { id, room } = action.payload; + const { id, roomId } = action.payload; - if (!clonedState[room]) { + if (!clonedState[roomId]) { break; } - delete clonedState[room].messages[id]; + delete clonedState[roomId].messages[id]; break; } case 'RECEIVE_MESSAGE': { - const { id, room } = action.payload; + const { id, roomId } = action.payload; - if (!clonedState[room]) { + if (!clonedState[roomId]) { break; } - if (clonedState[room].messages[id].isRead) { + if (clonedState[roomId].messages[id].isRead) { break; } - clonedState[room].messages[id].isRead = true; + clonedState[roomId].messages[id].isRead = true; break; } case 'EDIT_TEXT': { - const { id, room, newText, oldMessage } = action.payload; - if (!clonedState[room]) { + const { id, roomId, newText, oldMessage } = action.payload; + if (!clonedState[roomId]) { break; } - clonedState[room].messages[id].message = newText; - clonedState[room].messages[id].isEdited = true; - if (!Array.isArray(clonedState[room].messages[id].oldMessages)) { - clonedState[room].messages[id].oldMessages = []; + clonedState[roomId].messages[id].message = newText; + clonedState[roomId].messages[id].isEdited = true; + if (!Array.isArray(clonedState[roomId].messages[id].oldMessages)) { + clonedState[roomId].messages[id].oldMessages = []; } - clonedState[room].messages[id].oldMessages?.push(oldMessage); + clonedState[roomId].messages[id].oldMessages?.push(oldMessage); break; } default: diff --git a/src/server/handlers.ts b/src/server/handlers.ts index f2536386..f52fb5a5 100644 --- a/src/server/handlers.ts +++ b/src/server/handlers.ts @@ -22,20 +22,23 @@ import { export const CloseChatHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_CLOSE, - async (room: string | string[], setChatClosed: (arg0: boolean) => void) => { + async ( + roomId: string | string[], + setChatClosed: (arg0: boolean) => void + ) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !chatExists(room as string)) { + if (!user || !chatExists(roomId as string)) { setChatClosed(false); return; } - const inactiveList = await closeChat(room as string); + const inactiveList = await closeChat(roomId as string); setChatClosed(true); - socket.broadcast.to(room).emit(constants.NEW_EVENT_CLOSE, room); + socket.broadcast.to(roomId).emit(constants.NEW_EVENT_CLOSE, roomId); inactiveList?.forEach((loginId: string) => { socket.broadcast.to(loginId).emit(constants.NEW_EVENT_INACTIVE); }); @@ -46,21 +49,21 @@ export const CloseChatHandler = (socket: Socket) => { export const DeleteManagerHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_DELETE_MESSAGE, - async ({ id: messageId, room }, messageWasDeletedSuccessfully) => { + async ({ id: messageId, roomId }, messageWasDeletedSuccessfully) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !messageId || !room) { + if (!user || !messageId || !roomId) { messageWasDeletedSuccessfully(false); return; } - const messageDeleted = await removeMessage(room, messageId); + const messageDeleted = await removeMessage(roomId, messageId); socket.broadcast - .to(room) - .emit(constants.NEW_EVENT_DELETE_MESSAGE, { id: messageId, room }); + .to(roomId) + .emit(constants.NEW_EVENT_DELETE_MESSAGE, { id: messageId, roomId }); messageWasDeletedSuccessfully(messageDeleted); } ); @@ -70,25 +73,25 @@ export const EditMessageHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_EDIT_MESSAGE, async ( - { id: messageId, room, newMessage, oldMessage }, + { id: messageId, roomId, newMessage, oldMessage }, messageWasEditedSuccessfully ) => { const user = getActiveUser({ socketId: socket.id, }); - if (!user || !messageId || !room) { + if (!user || !messageId || !roomId) { messageWasEditedSuccessfully(false); return; } - const messageEdited = await editMessage(room, { + const messageEdited = await editMessage(roomId, { id: messageId, message: newMessage, oldMessage, }); socket.broadcast - .to(room) + .to(roomId) .emit(constants.NEW_EVENT_EDIT_MESSAGE, messageEdited); messageWasEditedSuccessfully(messageEdited); } @@ -130,21 +133,21 @@ export const JoinHandler = (io: Server, socket: Socket) => { // First join the user to the last chat if (!user?.socketIds.includes(socket.id)) { - socket.join(user?.currentroom as string); + socket.join(user?.currentRoomId as string); user?.socketConnections.push(socket); user?.socketIds.push(socket.id); } const chats: RoomType = {}; - user?.rooms.forEach(room => { - chats[room] = getChat(room); + user?.rooms.forEach(roomId => { + chats[roomId] = getChat(roomId); }); // Then return all chat messages socket.emit(constants.NEW_EVENT_CHAT_RESTORE, { chats, - currentroom: user?.currentroom, + currentRoomId: user?.currentRoomId, }); return; } @@ -170,9 +173,9 @@ export const LogOutHandler = (io: Server, socket: Socket) => { // User is an anonymous user, so close all active chats if (!user.email) { - for (const room of user.rooms) { - const inactiveList = await closeChat(room); - io.to(room).emit(constants.NEW_EVENT_CLOSE, room); + for (const roomId of user.rooms) { + const inactiveList = await closeChat(roomId); + io.to(roomId).emit(constants.NEW_EVENT_CLOSE, roomId); inactiveList?.forEach(emailOrLoginId => { socket.broadcast .to(emailOrLoginId) @@ -188,13 +191,13 @@ export const OnlineStatusHandler = (socket: Socket) => { constants.NEW_EVENT_ONLINE_STATUS, ({ onlineStatus, - room, + roomId, }: { onlineStatus: OnlineStatus; - room: string; + roomId: string; }): void => { socket.broadcast - .to(room) + .to(roomId) .emit(constants.NEW_EVENT_ONLINE_STATUS, onlineStatus); } ); @@ -203,19 +206,19 @@ export const OnlineStatusHandler = (socket: Socket) => { export const SeenMessageHandler = (socket: Socket) => { socket.on( constants.NEW_EVENT_READ_MESSAGE, - async ({ messageId, room }, messageSuccessfullySeen) => { + async ({ messageId, roomId }, messageSuccessfullySeen) => { const user = getActiveUser({ socketId: socket.id }); - if (!user || !messageId || !room) { + if (!user || !messageId || !roomId) { messageSuccessfullySeen(false); return; } - const messageSeen = await seenMessage(room, messageId); + const messageSeen = await seenMessage(roomId, messageId); - socket.broadcast.to(room).emit(constants.NEW_EVENT_READ_MESSAGE, { + socket.broadcast.to(roomId).emit(constants.NEW_EVENT_READ_MESSAGE, { messageId, - room, + roomId, }); messageSuccessfullySeen(messageSeen); @@ -231,7 +234,7 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { socket.on( constants.NEW_EVENT_SEND_MESSAGE, async ( - { senderId, message, time, room: room, containsBadword, replyTo }, + { senderId, message, time, roomId: roomId, containsBadword, replyTo }, returnMessageToSender ) => { // Below line is just a failed message simulator for testing purposes. @@ -268,7 +271,7 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { /** * Cache the sent message in memory a nd persist to db */ - const sentMessage = await addMessage(room, { + const sentMessage = await addMessage(roomId, { message, time, senderId, @@ -279,14 +282,14 @@ export const SendMessageHandler = (io: Server, socket: Socket) => { const messageDetails = { ...sentMessage, - room, + roomId, status: 'sent', }; returnMessageToSender(messageDetails); socket.broadcast - .to(room) + .to(roomId) .emit(constants.NEW_EVENT_RECEIVE_MESSAGE, messageDetails); // Update the message count for the user @@ -312,10 +315,10 @@ export const StopSearchHandler = (socket: Socket) => { }; export const TypingHandler = (socket: Socket) => { - socket.on(constants.NEW_EVENT_TYPING, ({ room, isTyping }) => { + socket.on(constants.NEW_EVENT_TYPING, ({ roomId, isTyping }) => { socket - .to(room) + .to(roomId) .timeout(5000) - .emit(constants.NEW_EVENT_DISPLAY, { isTyping, room }); + .emit(constants.NEW_EVENT_DISPLAY, { isTyping, roomId }); }); }; diff --git a/src/server/lib/lib.ts b/src/server/lib/lib.ts index 7f9a3762..7f45a758 100644 --- a/src/server/lib/lib.ts +++ b/src/server/lib/lib.ts @@ -26,8 +26,8 @@ function addActiveUser(user: ActiveUserType) { activeUsers[user.loginId] = user; } -function getChat(room: string): ChatType { - return chats[room] ?? null; +function getChat(roomId: string): ChatType { + return chats[roomId] ?? null; } function getActiveUser( @@ -111,8 +111,7 @@ async function init() { loginId: string; socketConnections: Socket[]; socketIds: string[]; - currentChat?: string | null; - currentroom: string | null; + currentRoomId: string | null; rooms: string[]; }; @@ -125,12 +124,9 @@ async function init() { const obj: objType = { ...activeUser.optimizedVersion, - currentroom: activeUser.optimizedVersion.currentChat, rooms: chats.map(chat => chat._id.toString()) as string[], }; - delete obj.currentChat; - activeUsers[activeUser.loginId] = obj; } } @@ -146,7 +142,7 @@ async function createChat(users: ActiveUserType[]) { messages: [], }; - const room = _chat._id.toString(); + const roomId = _chat._id.toString(); // TODO: this shouldn't happen as now new users are added to active users collection instead of users collection. // find a way to take users from users and fill it in active users. @@ -161,10 +157,10 @@ async function createChat(users: ActiveUserType[]) { _chat.users.push(user.id); users[i].id = user._id.toString(); - users[i].currentroom = room; - users[i].rooms.push(room); + users[i].currentRoomId = roomId; + users[i].rooms.push(roomId); users[i].socketConnections.map(socket => { - socket.join(room); + socket.join(roomId); }); addActiveUser(users[i]); @@ -177,17 +173,17 @@ async function createChat(users: ActiveUserType[]) { userIds: users.map(user => user.loginId) as [string, string], }; - chats[room] = optimizedChat; + chats[roomId] = optimizedChat; - return { id: room, ...optimizedChat }; + return { id: roomId, ...optimizedChat }; } -async function closeChat(room: string) { +async function closeChat(roomId: string) { await Chat.deleteOne({ - _id: room, + _id: roomId, }); - const chat = getChat(room); + const chat = getChat(roomId); if (!chat) { return null; @@ -209,17 +205,17 @@ async function closeChat(room: string) { } user.rooms.forEach((id, i) => { - if (id === room) { + if (id === roomId) { user.rooms.splice(i, 1); } }); await Chat.deleteOne({ - _id: room, + _id: roomId, }); if (getChatsCount(userId) === 0) { - user.currentroom = null; + user.currentRoomId = null; await delActiveUser(user); if (!inactiveList.includes(user.loginId)) { @@ -228,17 +224,17 @@ async function closeChat(room: string) { } } - delete chats[room]; + delete chats[roomId]; return inactiveList; } -function chatExists(room: string) { - return Boolean(getChat(room)); +function chatExists(roomId: string) { + return Boolean(getChat(roomId)); } async function addMessage( - room: string, + roomId: string, { message, time, @@ -256,7 +252,7 @@ async function addMessage( return null; } - if (!chats[room]) { + if (!chats[roomId]) { return null; } @@ -276,7 +272,7 @@ async function addMessage( await Chat.updateOne( { - _id: room, + _id: roomId, }, { $push: { @@ -285,13 +281,13 @@ async function addMessage( } ); - chats[room].messages[optimizedMessage.id] = optimizedMessage; + chats[roomId].messages[optimizedMessage.id] = optimizedMessage; return optimizedMessage; } -async function removeMessage(room: string, messageId: string) { - if (!chats[room]) { +async function removeMessage(roomId: string, messageId: string) { + if (!chats[roomId]) { return false; } @@ -303,24 +299,24 @@ async function removeMessage(room: string, messageId: string) { return false; } - delete chats[room].messages[messageId]; + delete chats[roomId].messages[messageId]; return true; } async function editMessage( - room: string, + roomId: string, { id, message, oldMessage, }: { id: string; message: string; oldMessage: string } ) { - if (!chats[room]) { + if (!chats[roomId]) { return false; } - if (!chats[room].messages[id]) { + if (!chats[roomId].messages[id]) { return false; } @@ -336,20 +332,20 @@ async function editMessage( { new: true } ); - chats[room].messages[id].message = message; - chats[room].messages[id].isEdited = true; - if (!Array.isArray(chats[room].messages[id].oldMessages)) { - chats[room].messages[id].oldMessages = []; + chats[roomId].messages[id].message = message; + chats[roomId].messages[id].isEdited = true; + if (!Array.isArray(chats[roomId].messages[id].oldMessages)) { + chats[roomId].messages[id].oldMessages = []; } - chats[room].messages[id]?.oldMessages?.push(oldMessage); - return chats[room].messages[id]; + chats[roomId].messages[id]?.oldMessages?.push(oldMessage); + return chats[roomId].messages[id]; } catch { return false; } } -async function seenMessage(room: string, messageId: string) { - if (!chats[room]) { +async function seenMessage(roomId: string, messageId: string) { + if (!chats[roomId]) { return false; } @@ -368,7 +364,7 @@ async function seenMessage(room: string, messageId: string) { { new: true } ); - chats[room].messages[messageId].isRead = isRead; + chats[roomId].messages[messageId].isRead = isRead; } catch { return false; } @@ -416,7 +412,7 @@ function addToWaitingList({ socketConnections: [socket], socketIds: [socket.id], rooms: [], - currentroom: null, + currentRoomId: null, }, { get(target, prop, receiver) { diff --git a/src/server/models/ActiveUserModel.ts b/src/server/models/ActiveUserModel.ts index 932c01fe..eb7c689d 100644 --- a/src/server/models/ActiveUserModel.ts +++ b/src/server/models/ActiveUserModel.ts @@ -14,7 +14,7 @@ export interface ActiveUserSchemaDocument extends Document { loginId: string; socketConnections: Socket[]; socketIds: string[]; - currentChat: string | null; + currentRoomId: string | null; rooms: string[]; }; } @@ -48,7 +48,7 @@ activeUserSchema.virtual('optimizedVersion').get(function ( loginId: this.loginId, socketConnections: [], socketIds: [], - currentChat: this.currentChat?.toString() || null, + currentRoomId: this.currentChat?.toString() || null, rooms: [], }; }); diff --git a/src/types/contextTypes.ts b/src/types/contextTypes.ts index c97ddf3a..8bd36d46 100644 --- a/src/types/contextTypes.ts +++ b/src/types/contextTypes.ts @@ -18,20 +18,20 @@ export type DialogType = { export type ChatContextType = { createChat: ( - room: string, + roomId: string, userIds: [string, string], messages?: MessageIdType, createdAt?: Date ) => any; messages: RoomType; - removeMessage: (id: string, room: string) => void; + removeMessage: (id: string, roomId: string) => void; addMessage: (message: MessageType) => void; updateMessage: (message: any) => void; - closeChat: (room: string) => void; + closeChat: (roomId: string) => void; currentReplyMessage: MessageType | null; currentReplyMessageId: string; closeAllChats: () => void; - receiveMessage: (id: string, room: string) => void; + receiveMessage: (id: string, roomId: string) => void; startReply: (messageId: string) => void; cancelReply: () => void; }; @@ -43,7 +43,7 @@ export type AppContextType = { updateTmpSettings: (newSettings: SettingsType) => void; cancelSettingsUpdate: () => void; startSearch: () => undefined; - endSearch: (currentroom: null | string) => undefined; + endSearch: (currentRoomId: null | string) => undefined; loadUserSettings: (settings: SettingsType) => void; updateOnlineStatus: (onlineStatus: Date | string | null) => void; updateConnection: (isDisconnected: boolean) => void; diff --git a/src/types/types.ts b/src/types/types.ts index 56a4fa08..7715d003 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -20,7 +20,7 @@ export type SettingsType = { export type AppType = { settings: SettingsType; tmpSettings: {}; - currentroom: string | null; + currentRoomId: string | null; isSearching: boolean; onlineStatus: OnlineStatus; disconnected: boolean; @@ -37,7 +37,7 @@ export type MessageType = { senderId: string; message: string; time: number; - room?: string | null; + roomId?: string | null; id?: string | null; containsBadword: boolean; replyTo: string | null; @@ -68,7 +68,7 @@ export type ActiveUserType = { loginId: string; socketConnections: Socket[]; socketIds: string[]; - currentroom: null | string; + currentRoomId: null | string; rooms: string[]; };