In-Game Chat
Relevant source files
The following files were used as context for generating this wiki page:The In-Game Chat system provides players with the ability to communicate during a poker game. It supports sending text messages and emojis, displays system-level announcements, and provides visual feedback for new messages both in a dedicated chat panel and temporarily over each player's avatar on the poker table.
The system is designed to be a core part of the user experience, enhancing social interaction and providing crucial game-related information, such as actions taken by AI opponents. It is primarily composed of a central state management hook (useChat) and several React components that consume this state to render the UI.
Architecture
The chat feature is built around a centralized state management hook, useChat, which provides the state and actions to various UI components. The ChatPanel is the main interface for viewing the message history and sending new messages, while the ChatBubble provides contextual, short-lived message previews on the main game screen.
Component Interaction
The following diagram illustrates how the major parts of the chat system interact with each other.
This diagram shows that useChat is the central hub. ChatPanel and PlayerPosition consume its state. useAIOpponents uses its sendMessage function to post AI actions into the chat.
Sources: hooks/use-chat.tsx, components/chat-panel.tsx, components/chat-bubble.tsx, components/player-position.tsx, hooks/use-ai-opponents.tsx
State Management (useChat)
The core logic and state for the chat system are encapsulated in the useChat hook, which is provided to the component tree via ChatProvider.
Sources: hooks/use-chat.tsx
ChatProvider
This provider wraps parts of the application that need access to the chat functionality. It initializes the chat with a welcome message from the "System".
Sources: hooks/use-chat.tsx:14-23
useChat Hook
This hook exposes the chat state and methods to interact with it.
| Function/Property | Description |
|---|---|
messages | An array of ChatMessage objects representing the chat history. |
sendMessage(...) | A function to add a new message to the state. |
clearMessages() | A function to clear all messages from the history. |
unreadCount | A number representing how many messages have been received and not yet read. |
markAsRead() | A function to reset the unreadCount to zero. |
Sources: hooks/use-chat.tsx:6-12
ChatMessage Data Structure
All messages in the system conform to the ChatMessage interface.
| Property | Type | Description |
|---|---|---|
id | string | A unique identifier for the message, generated from Date.now(). |
playerId | string | The ID of the player who sent the message (e.g., "local", "system", or a unique player ID). |
playerName | string | The display name of the sender. |
message | string | The content of the message or an emoji. |
timestamp | Date | The time the message was created. |
type | "text" | "system" | "emoji" | The type of message, which affects its rendering style. Defaults to "text". |
Sources: hooks/use-chat.tsx:3, hooks/use-chat.tsx:25-34
Sending a Message Flow
The sequence diagram below shows the process of a user sending a message.
UI Components
The chat interface is composed of several key React components.
ChatPanel.tsx
This is the main chat interface, presented as a slide-out sheet.
Key Features:
- Trigger Button: A
<Button>with aMessageCircleicon that displays a badge with theunreadCountfromuseChat. Clicking it opens the chat panel. - Message Display: A
<ScrollArea>that automatically scrolls to the bottom when new messages arrive. It maps over themessagesarray to render each message. - Message Styling: Messages are styled differently based on their
typeandplayerId.systemmessages are centered and have a muted appearance.- Messages from the
localplayer are aligned to the right with a primary background color. - Messages from other players are aligned to the left with a muted background and include the sender's name.
emojimessages are rendered with a larger font size.
- Input Area: An
<Input>field for typing messages, a<Button>to toggle theEmojiPicker, and a "Send" button. Messages can be sent by clicking the button or pressing "Enter".
Sources: components/chat-panel.tsx:68-185
ChatBubble.tsx
This component displays a temporary chat message above a player's avatar on the poker table.
- It becomes visible when a new message is received for a specific player.
- It automatically hides itself after 5 seconds using a
setTimeouteffect. - The position of the bubble is determined by the
positionprop to ensure it doesn't obscure other UI elements.
Sources: components/chat-bubble.tsx:12-20, components/player-position.tsx:38-46
EmojiPicker.tsx
This component (whose internal code is not provided but is referenced) allows users to select an emoji. When an emoji is selected, the handleEmojiSelect function in ChatPanel is called, which then uses sendMessage to send a message of type emoji.
Sources: components/chat-panel.tsx:58-62, components/chat-panel.tsx:135-139
Integrations
The chat system is integrated into other parts of the game to provide a cohesive experience.
AI Opponents (use-ai-opponents.tsx)
The AI logic uses the useChat hook to announce its actions. When an AI player decides to "fold", "call", "raise", or go "all-in", it calls the sendMessage function to post a corresponding message to the chat. This provides transparency and makes the AI players feel more interactive.
// Example from use-ai-opponents.tsx
// ... AI decision logic ...
action = "raise"
amount = Math.min(currentBet * 2, chips + bet)
sendMessage(currentPlayer.id, player.name, `Raise to $${amount}`, "text")
Sources: hooks/use-ai-opponents.tsx:5, hooks/use-ai-opponents.tsx:66-67
Player Position (player-position.tsx)
The PlayerPosition component, which represents a player at the poker table, uses the useChat hook to monitor for new messages from the player it represents.
- An effect hook filters the
messagesarray to find the latest message from the correspondingplayerId. - When a new message is found, it is stored in a local state variable, which triggers the rendering of a
ChatBubblecomponent with the message content.
Sources: components/player-position.tsx:19-28, components/player-position.tsx:102-110
Conclusion
The In-Game Chat is a well-integrated feature that serves a dual purpose: facilitating player-to-player communication and acting as a log for important game events, such as AI actions. Its architecture, centered around the useChat hook, provides a clean and reusable way to manage chat state across different parts of the application, from the main ChatPanel to the dynamic ChatBubbles on the game table.