import { useEffect, useRef, useState } from 'react'; import { ChatMessage } from 'js-waku'; import { Message, MessageText, MessageGroup, MessageList, } from '@livechat/ui-kit'; interface Props { archivedMessages: ChatMessage[]; newMessages: ChatMessage[]; } export default function ChatList(props: Props) { const [messages, setMessages] = useState([]); let updatedMessages; if (IsThereNewMessages(props.newMessages, messages)) { updatedMessages = messages.slice().concat(props.newMessages); if (IsThereNewMessages(props.archivedMessages, updatedMessages)) { updatedMessages = copyMergeUniqueReplace( props.archivedMessages, updatedMessages ); } } else { if (IsThereNewMessages(props.archivedMessages, messages)) { updatedMessages = copyMergeUniqueReplace( props.archivedMessages, messages ); } } if (updatedMessages) { setMessages(updatedMessages); } const messagesGroupedBySender = groupMessagesBySender(messages).map( (currentMessageGroup) => ( {currentMessageGroup.map((currentMessage) => ( {currentMessage.payloadAsUtf8} ))} ) ); return ( {messagesGroupedBySender} ); } 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 { return message.timestamp.toLocaleString([], { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: false, }); } const AlwaysScrollToBottom = (props: { newMessages: ChatMessage[] }) => { const elementRef = useRef(); useEffect(() => { // @ts-ignore elementRef.current.scrollIntoView(); }, [props.newMessages]); // @ts-ignore return
; }; function IsThereNewMessages( newValues: ChatMessage[], currentValues: ChatMessage[] ): boolean { if (newValues.length === 0) return false; if (currentValues.length === 0) return true; return !newValues.find((newMsg) => currentValues.find(isEqual.bind({}, newMsg)) ); } function copyMergeUniqueReplace( newValues: ChatMessage[], currentValues: ChatMessage[] ) { const copy = currentValues.slice(); newValues.forEach((msg) => { if (!copy.find(isEqual.bind({}, msg))) { copy.push(msg); } }); copy.sort((a, b) => a.timestamp.valueOf() - b.timestamp.valueOf()); return copy; } function isEqual(lhs: ChatMessage, rhs: ChatMessage): boolean { return ( lhs.nick === rhs.nick && lhs.payloadAsUtf8 === rhs.payloadAsUtf8 && lhs.timestamp.toString() === rhs.timestamp.toString() ); }