set styles for messages
Change-Id: I8b86255a55a745a305f953f77122a98970de0958
diff --git a/client/src/components/MessageList.js b/client/src/components/MessageList.js
index 3ae1b1c..3f16e46 100644
--- a/client/src/components/MessageList.js
+++ b/client/src/components/MessageList.js
@@ -1,33 +1,157 @@
-import Message from './Message'
+import dayjs from "dayjs"
import React, { useEffect } from 'react'
-import { Box, Divider, Typography } from '@mui/material'
-import ConversationAvatar from './ConversationAvatar'
+import dayOfYear from 'dayjs/plugin/dayOfYear'
+import isBetween from 'dayjs/plugin/isBetween'
+import { Stack } from "@mui/system"
+import { MessageCall, MessageDate, MessageInitial, MessageMember, MessageBubblesGroup, MessageTime, MessageMerge } from "./Message"
+
+dayjs.extend(dayOfYear)
+dayjs.extend(isBetween)
export default function MessageList(props) {
- const displayName = props.conversation.getDisplayName()
- const messages = props.conversation.getMessages()
+ const messagesComponents = buildMessagesList(props.messages)
useEffect(() => {
if (!props.loading)
props.loadMore()
- }, [props.conversation.getId()])
+ }, [props.conversationId])
return (
- <React.Fragment>
- <Box className="conversation-header">
- <Box style={{ margin: 16, flexShrink: 0 }}>
- <ConversationAvatar displayName={props.conversation.getDisplayNameNoFallback()} />
- </Box>
- <Box style={{ flex: "1 1 auto", overflow: 'hidden' }}>
- <Typography className="title" variant="h6">{displayName}</Typography>
- <Typography className="subtitle" variant="subtitle1" >{props.conversation.getId()}</Typography>
- </Box>
- <Divider orientation="horizontal" />
- </Box>
- <div className="message-list">
- {messages.map((message) => <Message key={message.id} message={message} />)}
- <div style={{ border: "1px solid transparent" }}/>
- </div>
- </React.Fragment>
+ <Stack
+ marginLeft="16px"
+ marginRight="16px"
+ direction="column-reverse"
+ >
+ {messagesComponents?.map(
+ ({Component, id, props}) => <Component key={id} {...props}/>
+ )}
+ </Stack>
)
-}
\ No newline at end of file
+}
+
+const buildMessagesList = (messages) => {
+ if (messages.length == 0) {
+ return null;
+ }
+
+ const components = []
+ let lastTime = dayjs.unix(messages[0].timestamp)
+ let lastAuthor = messages[0].author
+ let messageBubblesGroup = []
+
+ const pushMessageBubblesGroup = () => {
+ if (messageBubblesGroup.length == 0) {
+ return
+ }
+ components.push({
+ id: `group-${messageBubblesGroup[0].id}`,
+ Component: MessageBubblesGroup,
+ props: { messages: messageBubblesGroup },
+ })
+ messageBubblesGroup = []
+ }
+
+ const pushMessageCall = (message) => {
+ components.push({
+ id: `call-${message.id}`,
+ Component: MessageCall,
+ props: { message },
+ })
+ }
+
+ const pushMessageMember = (message) => {
+ components.push({
+ id: `member-${message.id}`,
+ Component: MessageMember,
+ props: { message },
+ })
+ }
+
+ const pushMessageMerge = (message) => {
+ components.push({
+ id: `merge-${message.id}`,
+ Component: MessageMerge,
+ props: { message },
+ })
+ }
+
+ const pushMessageTime = (message, time, hasDateOnTop=false) => {
+ components.push({
+ id: `time-${message.id}`,
+ Component: MessageTime,
+ props: { time, hasDateOnTop },
+ })
+ }
+
+ const pushMessageDate = (message, time) => {
+ components.push({
+ id: `date-${message.id}`,
+ Component: MessageDate,
+ props: { time }
+ })
+ }
+
+ const pushMessageInitial = (message) => {
+ components.push({
+ id: `initial-${message.id}`,
+ Component: MessageInitial,
+ props: { message }
+ })
+ }
+
+ messages.forEach(message => { // most recent messages first
+ switch (message.type) {
+ case "text/plain":
+ case "application/data-transfer+json":
+ if (lastAuthor != message.author) {
+ pushMessageBubblesGroup()
+ }
+ messageBubblesGroup.push(message)
+ break
+ case "application/call-history+json":
+ pushMessageBubblesGroup()
+ pushMessageCall(message)
+ break
+ case "member":
+ pushMessageBubblesGroup()
+ pushMessageMember(message)
+ break
+ case "merge":
+ pushMessageBubblesGroup()
+ pushMessageMerge(message)
+ break
+ case "initial":
+ default:
+ break
+ }
+
+ const time = dayjs.unix(message.timestamp)
+ if (message.type == "initial") {
+ pushMessageBubblesGroup()
+ pushMessageTime(message, time, true)
+ pushMessageDate(message, time)
+ pushMessageInitial(message)
+ }
+ else {
+ if ( // If the date is different
+ lastTime?.year() != time.year()
+ || lastTime?.dayOfYear() != time.dayOfYear()
+ ) {
+ pushMessageBubblesGroup()
+ pushMessageTime(message, time, true)
+ pushMessageDate(message, time)
+ }
+ else if ( // If more than 5 minutes have passed since the last message
+ !lastTime.isBetween(time, time?.add(5, "minute"))
+ ) {
+ pushMessageBubblesGroup()
+ pushMessageTime(message, time)
+ }
+
+ lastTime = time
+ lastAuthor = message.author
+ }
+ })
+
+ return components
+}