feat: add system messages

This commit is contained in:
Alexander Daichendt 2025-02-12 12:29:16 +01:00
parent 748e154ec4
commit 230a9560a5
4 changed files with 55 additions and 17 deletions

View file

@ -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) =>

View file

@ -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;
function renderMessage(message: ServerMessage) {
switch (message.type) {
case "CHAT_MESSAGE":
return (
<>
{state.messages.map((message) => (
<ChatMessage message={message} userId={userId} />
))}
</>
<ChatMessage
message={message.payload}
userId={userId}
key={message.payload.id}
/>
);
case "USER_JOINED":
return (
<div
className="text-center text-gray-500 my-2"
key={`join-${message.payload.user.name}-${new Date()}`}
>
{message.payload.user.name} joined!
</div>
);
case "USER_LEFT":
return (
<div
className="text-center text-gray-500 my-2"
key={`leave-${message.payload.user.name}-${new Date()}`}
>
{message.payload.user.name} left!
</div>
);
default:
return null;
}
}
return <>{state.messages.map(renderMessage)}</>;
}
export default React.memo(ChatMessages);

View file

@ -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;
};

View file

@ -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: