/**
* MessageList Component
* Displays messages in a conversation
*/
import React, { useEffect, useRef } from 'react';
import './MessageList.css';
export default function MessageList({ messages, typingUsers }) {
const messagesEndRef = useRef(null);
// Auto-scroll to bottom when new messages arrive
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
const formatTime = (timestamp) => {
const date = new Date(timestamp);
return date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true
});
};
const getCurrentUserId = () => {
// In a real app, get this from auth context
return localStorage.getItem('userId');
};
const isOwnMessage = (message) => {
return message.senderId === getCurrentUserId();
};
if (messages.length === 0 && typingUsers.length === 0) {
return (
No messages yet
Send a message to start the conversation
);
}
return (
{messages.map((message, index) => {
const showAvatar = index === messages.length - 1 ||
messages[index + 1]?.senderId !== message.senderId;
const showTimestamp = index === 0 ||
new Date(message.createdAt) - new Date(messages[index - 1].createdAt) > 300000; // 5 mins
return (
{showTimestamp && (
{new Date(message.createdAt).toLocaleDateString()}
)}
{!isOwnMessage(message) && showAvatar && (
{message.senderAvatar ? (

) : (
{message.senderUsername?.[0]?.toUpperCase()}
)}
)}
{!isOwnMessage(message) && (
{message.senderDomain || message.senderUsername}
{message.senderDomain && ✓}
)}
{message.replyToId && (
Replying to a message
)}
{message.content}
{message.metadata?.attachments && message.metadata.attachments.length > 0 && (
{message.metadata.attachments.map((attachment, i) => (
📎 {attachment.filename}
))}
)}
{formatTime(message.createdAt)}
{message.editedAt && edited}
{message._sending && sending...}
{message.reactions && message.reactions.length > 0 && (
{message.reactions.map((reaction, i) => (
{reaction.emoji} {reaction.users.length > 1 && reaction.users.length}
))}
)}
);
})}
{typingUsers.length > 0 && (
)}
);
}