| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import moment from 'moment'
- import type { Message as MessageType } from '@/features/chat/context/chat-context'
- import { useUserContext } from '@/shared/context/user-context'
- import { User } from '../../../../../types/user'
- import MessageGroup from '@/features/chat/components/message-group'
- const FIVE_MINUTES = 5 * 60 * 1000
- const TIMESTAMP_GROUP_SIZE = FIVE_MINUTES
- function formatTimestamp(date: moment.MomentInput) {
- if (!date) {
- return 'N/A'
- } else {
- return `${moment(date).format('h:mm a')} ${moment(date).calendar()}`
- }
- }
- interface MessageListProps {
- messages: MessageType[]
- resetUnreadMessages(...args: unknown[]): unknown
- }
- type MessageGroupType = {
- messages: MessageType[]
- id: string
- user?: User
- }
- // Group messages by the same author that were sent within 5 minutes of each
- // other
- function groupMessages(messages: MessageType[]) {
- const groups: MessageGroupType[] = []
- let currentGroup: MessageGroupType | null = null
- let previousMessage: MessageType | null = null
- for (const message of messages) {
- if (message.deleted) {
- continue
- }
- if (
- currentGroup &&
- previousMessage &&
- !message.pending &&
- message.user &&
- message.user.id &&
- message.user.id === previousMessage.user?.id &&
- message.timestamp - previousMessage.timestamp < TIMESTAMP_GROUP_SIZE
- ) {
- currentGroup.messages.push(message)
- } else {
- currentGroup = {
- messages: [message],
- id: String(message.timestamp),
- user: message.user,
- }
- groups.push(currentGroup)
- }
- previousMessage = message
- }
- return groups
- }
- function MessageList({ messages, resetUnreadMessages }: MessageListProps) {
- const user = useUserContext()
- function shouldRenderDate(messageIndex: number) {
- if (messageIndex === 0) {
- return true
- } else {
- const message = messages[messageIndex]
- const previousMessage = messages[messageIndex - 1]
- return (
- message.timestamp &&
- previousMessage.timestamp &&
- message.timestamp - previousMessage.timestamp > FIVE_MINUTES
- )
- }
- }
- const messageGroups = groupMessages(messages)
- return (
- // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
- <ul
- className="list-unstyled"
- onClick={resetUnreadMessages}
- onKeyDown={resetUnreadMessages}
- >
- {messageGroups.map((group, index) => (
- <li key={group.id} className="message">
- {shouldRenderDate(index) && (
- <div className="date">
- <time
- dateTime={
- group.messages[0].timestamp
- ? moment(group.messages[0].timestamp).format()
- : undefined
- }
- >
- {formatTimestamp(group.messages[0].timestamp)}
- </time>
- </div>
- )}
- <MessageGroup
- messages={group.messages}
- user={group.user}
- fromSelf={user ? group.user?.id === user.id : false}
- />
- </li>
- ))}
- </ul>
- )
- }
- export default MessageList
|