85 lines
2.2 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef } from 'react';
2021-05-04 16:54:32 +10:00
import { ChatMessage } from './ChatMessage';
import {
Message,
MessageText,
MessageGroup,
MessageList,
} from '@livechat/ui-kit';
interface Props {
messages: ChatMessage[];
}
export default function ChatList(props: Props) {
const messages = props.messages;
const messagesGroupedBySender = groupMessagesBySender(props.messages).map(
(currentMessageGroup) => (
<MessageGroup onlyFirstWithMeta>
{currentMessageGroup.map((currentMessage) => (
<Message
// We assume that the same user is not sending two messages in the same second
2021-05-04 16:54:32 +10:00
key={
currentMessage.receivedTimestampMs.valueOf() +
currentMessage.nick +
currentMessage.message
}
authorName={currentMessage.nick}
date={formatDisplayDate(currentMessage)}
>
<MessageText>{currentMessage.message}</MessageText>
</Message>
))}
</MessageGroup>
)
);
2021-04-27 14:55:30 +10:00
return (
<MessageList active containScrollInSubtree>
{messagesGroupedBySender}
2021-04-27 14:55:30 +10:00
<AlwaysScrollToBottom messages={messages} />
</MessageList>
2021-04-27 14:55:30 +10:00
);
}
function groupMessagesBySender(messageArray: ChatMessage[]): ChatMessage[][] {
let currentSender = -1;
let lastNick = '';
let messagesBySender: ChatMessage[][] = [];
let currentSenderMessage = 0;
for (let currentMessage of messageArray) {
if (lastNick !== currentMessage.nick) {
currentSender++;
messagesBySender[currentSender] = [];
currentSenderMessage = 0;
lastNick = currentMessage.nick;
}
messagesBySender[currentSender][currentSenderMessage++] = currentMessage;
}
return messagesBySender;
}
function formatDisplayDate(message: ChatMessage): string {
2021-05-04 16:54:32 +10:00
return message.sentTimestamp.toLocaleString([], {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: false,
});
}
2021-04-27 14:55:30 +10:00
const AlwaysScrollToBottom = (props: Props) => {
const elementRef = useRef<HTMLDivElement>();
useEffect(() => {
// @ts-ignore
elementRef.current.scrollIntoView();
}, [props.messages]);
// @ts-ignore
return <div ref={elementRef} />;
};