ChatWindow component provides a floating chat interface for direct messaging with friends, featuring real-time message delivery and typing indicators.
Overview
This component renders as a fixed popup window in the bottom-right corner of the screen, displaying a conversation thread with a specific friend. It supports real-time message delivery via WebSocket events and includes typing indicators. Source:src/components/Social/ChatWindow.tsx:17-253
Props
| Prop | Type | Description |
|---|---|---|
friend | Friend | Friend object containing ID, name, avatar, and online status |
onClose | () => void | Callback when chat window is closed |
State Management
Core State
src/components/Social/ChatWindow.tsx:23-30
Message State
- messages: Array of chat messages in chronological order
- newMessage: Current input text
- isTyping: Whether friend is currently typing
- loading: Initial message load state
- error: Error message if loading/sending fails
- sending: Whether a message is currently being sent
WebSocket Events
The component subscribes to real-time chat events:chat_message
Receives incoming messages from the friend:src/components/Social/ChatWindow.tsx:65-70
chat_message_sent
Confirms when your own message is delivered:src/components/Social/ChatWindow.tsx:72-77
typing
Shows typing indicator when friend is typing:src/components/Social/ChatWindow.tsx:79-87
Typing indicator auto-hides after 3 seconds of inactivity.
Message Management
Loading Chat History
src/components/Social/ChatWindow.tsx:47-60
Appending Messages
Deduplicates messages by ID to prevent duplicates:src/components/Social/ChatWindow.tsx:32-39
Auto-scrolling
Automatically scrolls to bottom when new messages arrive:src/components/Social/ChatWindow.tsx:41-45
Sending Messages
Send Handler
src/components/Social/ChatWindow.tsx:99-117
Keyboard Handling
src/components/Social/ChatWindow.tsx:119-124
Sends message on Enter, prevents send on Shift+Enter (for multiline support).
Typing Indicator
src/components/Social/ChatWindow.tsx:126-131
Sends typing indicator to friend when typing non-empty text.
UI Layout
Window Structure
Fixed popup with slide-up animation:src/components/Social/ChatWindow.tsx:135-140
Dimensions: 320px wide (w-80), 384px tall (h-96)
Header
Displays friend info with online status:src/components/Social/ChatWindow.tsx:142-166
Message List
Scrollable message thread with grouped timestamps:src/components/Social/ChatWindow.tsx:169-222
Message Styling
- Own messages: Purple background, aligned right, rounded bottom-right corner sharp
- Friend messages: Dark gray background, aligned left, rounded bottom-left corner sharp
- Timestamps: Shown when 5+ minutes gap between messages
Input Area
Message input with send button:src/components/Social/ChatWindow.tsx:226-249
Empty States
Loading State
src/components/Social/ChatWindow.tsx:184-187
No Messages
src/components/Social/ChatWindow.tsx:188-193
Error Handling
Displays error state with retry button:src/components/Social/ChatWindow.tsx:170-183
Message Deduplication
The component prevents duplicate messages using ID-based filtering:src/components/Social/ChatWindow.tsx:32-39
This is important because both chat_message (incoming) and chat_message_sent (echo) events can fire for the same message.
Timestamp Grouping
Timestamps are displayed when there’s a 5-minute gap between messages:src/components/Social/ChatWindow.tsx:197-206
Best Practices
Cleanup Timeouts
Always clear typing indicator timeout on unmount:src/components/Social/ChatWindow.tsx:89-96
Optimistic Scrolling
UsesetTimeout with 0ms delay to scroll after DOM updates:
src/components/Social/ChatWindow.tsx:106-109
Prevent Empty Messages
Trim input and check for non-empty before sending:src/components/Social/ChatWindow.tsx:100
Related Components
- FriendsPanel - Opens chat windows
- MessageNotification - Shows new message alerts
API Functions
getChatHistory(friendId)- Retrieves message history with friendsendChatMessage(friendId, text)- Sends a chat messagesendTypingIndicator(friendId)- Broadcasts typing statusonSocialEvent(eventType, handler)- Subscribes to WebSocket eventsformatRelativeTime(timestamp)- Formats timestamp as relative time