From 230a9560a54e9a02f58c2ae7edbb21643739e507 Mon Sep 17 00:00:00 2001 From: Alexander Daichendt Date: Wed, 12 Feb 2025 12:29:16 +0100 Subject: [PATCH] feat: add system messages --- client/src/components/ChatProvider.tsx | 6 ++-- client/src/components/MessageDisplay.tsx | 42 ++++++++++++++++++++---- client/src/contexts/ChatContext.tsx | 18 +++++++--- client/src/hooks/useWebSocket.ts | 6 ++-- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/client/src/components/ChatProvider.tsx b/client/src/components/ChatProvider.tsx index d250e83..b98ee68 100644 --- a/client/src/components/ChatProvider.tsx +++ b/client/src/components/ChatProvider.tsx @@ -1,6 +1,6 @@ import React, { useReducer } from "react"; -import { ChatMessage, User } from "../../../shared"; -import { ChatContext } from "../contexts/ChatContext"; +import { User } from "../../../shared"; +import { ChatContext, Message } from "../contexts/ChatContext"; import { chatReducer } from "../reducers/chatReducers"; export function ChatProvider({ children }: { children: React.ReactNode }) { @@ -14,7 +14,7 @@ export function ChatProvider({ children }: { children: React.ReactNode }) { state, dispatch, actions: { - addMessage: (message: ChatMessage) => + addMessage: (message: Message) => dispatch({ type: "ADD_MESSAGE", payload: message }), setUser: (user: User) => dispatch({ type: "SET_USER", payload: user }), setConnected: (isConnected: boolean) => diff --git a/client/src/components/MessageDisplay.tsx b/client/src/components/MessageDisplay.tsx index 177f0ed..e0a837d 100644 --- a/client/src/components/MessageDisplay.tsx +++ b/client/src/components/MessageDisplay.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { ServerMessage } from "../../../shared"; import { useChatState } from "../contexts/ChatContext"; import ChatMessage from "./ChatMessage"; @@ -6,13 +7,40 @@ function ChatMessages() { const { state } = useChatState(); const userId = state.currentUser?.userId; - return ( - <> - {state.messages.map((message) => ( - - ))} - - ); + function renderMessage(message: ServerMessage) { + switch (message.type) { + case "CHAT_MESSAGE": + return ( + + ); + case "USER_JOINED": + return ( +
+ {message.payload.user.name} joined! +
+ ); + case "USER_LEFT": + return ( +
+ {message.payload.user.name} left! +
+ ); + default: + return null; + } + } + + return <>{state.messages.map(renderMessage)}; } export default React.memo(ChatMessages); diff --git a/client/src/contexts/ChatContext.tsx b/client/src/contexts/ChatContext.tsx index 771f464..8d2288a 100644 --- a/client/src/contexts/ChatContext.tsx +++ b/client/src/contexts/ChatContext.tsx @@ -1,20 +1,30 @@ import { createContext, useContext, Dispatch } from "react"; -import { ChatMessage, User } from "../../../shared"; +import { + ServerChatMessage, + ServerUserJoinedMessage, + ServerUserLeftMessage, + User, +} from "../../../shared"; + +export type Message = + | ServerChatMessage + | ServerUserJoinedMessage + | ServerUserLeftMessage; export type ChatState = { - messages: ChatMessage[]; + messages: Message[]; currentUser: User | null; isConnected: boolean; }; export type ChatAction = - | { type: "ADD_MESSAGE"; payload: ChatMessage } + | { type: "ADD_MESSAGE"; payload: Message } | { type: "SET_USER"; payload: User } | { type: "SET_CONNECTED"; payload: boolean } | { type: "CLEAR_MESSAGES" }; export type ChatActions = { - addMessage: (message: ChatMessage) => void; + addMessage: (message: Message) => void; setUser: (user: User) => void; setConnected: (isConnected: boolean) => void; }; diff --git a/client/src/hooks/useWebSocket.ts b/client/src/hooks/useWebSocket.ts index c805b3b..f9ef96d 100644 --- a/client/src/hooks/useWebSocket.ts +++ b/client/src/hooks/useWebSocket.ts @@ -21,11 +21,11 @@ export function useWebSocket(roomId: string) { actions.setUser(message.payload.user); break; + // intentional fallthrough case "USER_JOINED": - break; - + case "USER_LEFT": case "CHAT_MESSAGE": - actions.addMessage(message.payload); + actions.addMessage(message); break; default: