blob: 3f16e4649459fd2c72c5af05212958bd565200af [file] [log] [blame]
idillonbef18a52022-09-01 01:51:40 -04001import dayjs from "dayjs"
Adrien Béraud4e287b92021-04-24 16:15:56 -04002import React, { useEffect } from 'react'
idillonbef18a52022-09-01 01:51:40 -04003import dayOfYear from 'dayjs/plugin/dayOfYear'
4import isBetween from 'dayjs/plugin/isBetween'
5import { Stack } from "@mui/system"
6import { MessageCall, MessageDate, MessageInitial, MessageMember, MessageBubblesGroup, MessageTime, MessageMerge } from "./Message"
7
8dayjs.extend(dayOfYear)
9dayjs.extend(isBetween)
Larbi Gharibe9af9732021-03-31 15:08:01 +010010
Adrien Béraudaf09a462021-04-15 18:02:29 -040011export default function MessageList(props) {
idillonbef18a52022-09-01 01:51:40 -040012 const messagesComponents = buildMessagesList(props.messages)
Adrien Béraud4e287b92021-04-24 16:15:56 -040013
14 useEffect(() => {
Adrien Béraudabba2e52021-04-24 21:39:56 -040015 if (!props.loading)
16 props.loadMore()
idillonbef18a52022-09-01 01:51:40 -040017 }, [props.conversationId])
Adrien Béraud4e287b92021-04-24 16:15:56 -040018
Adrien Béraud150b4782021-04-21 19:40:59 -040019 return (
idillonbef18a52022-09-01 01:51:40 -040020 <Stack
21 marginLeft="16px"
22 marginRight="16px"
23 direction="column-reverse"
24 >
25 {messagesComponents?.map(
26 ({Component, id, props}) => <Component key={id} {...props}/>
27 )}
28 </Stack>
Adrien Béraud150b4782021-04-21 19:40:59 -040029 )
idillonbef18a52022-09-01 01:51:40 -040030}
31
32const buildMessagesList = (messages) => {
33 if (messages.length == 0) {
34 return null;
35 }
36
37 const components = []
38 let lastTime = dayjs.unix(messages[0].timestamp)
39 let lastAuthor = messages[0].author
40 let messageBubblesGroup = []
41
42 const pushMessageBubblesGroup = () => {
43 if (messageBubblesGroup.length == 0) {
44 return
45 }
46 components.push({
47 id: `group-${messageBubblesGroup[0].id}`,
48 Component: MessageBubblesGroup,
49 props: { messages: messageBubblesGroup },
50 })
51 messageBubblesGroup = []
52 }
53
54 const pushMessageCall = (message) => {
55 components.push({
56 id: `call-${message.id}`,
57 Component: MessageCall,
58 props: { message },
59 })
60 }
61
62 const pushMessageMember = (message) => {
63 components.push({
64 id: `member-${message.id}`,
65 Component: MessageMember,
66 props: { message },
67 })
68 }
69
70 const pushMessageMerge = (message) => {
71 components.push({
72 id: `merge-${message.id}`,
73 Component: MessageMerge,
74 props: { message },
75 })
76 }
77
78 const pushMessageTime = (message, time, hasDateOnTop=false) => {
79 components.push({
80 id: `time-${message.id}`,
81 Component: MessageTime,
82 props: { time, hasDateOnTop },
83 })
84 }
85
86 const pushMessageDate = (message, time) => {
87 components.push({
88 id: `date-${message.id}`,
89 Component: MessageDate,
90 props: { time }
91 })
92 }
93
94 const pushMessageInitial = (message) => {
95 components.push({
96 id: `initial-${message.id}`,
97 Component: MessageInitial,
98 props: { message }
99 })
100 }
101
102 messages.forEach(message => { // most recent messages first
103 switch (message.type) {
104 case "text/plain":
105 case "application/data-transfer+json":
106 if (lastAuthor != message.author) {
107 pushMessageBubblesGroup()
108 }
109 messageBubblesGroup.push(message)
110 break
111 case "application/call-history+json":
112 pushMessageBubblesGroup()
113 pushMessageCall(message)
114 break
115 case "member":
116 pushMessageBubblesGroup()
117 pushMessageMember(message)
118 break
119 case "merge":
120 pushMessageBubblesGroup()
121 pushMessageMerge(message)
122 break
123 case "initial":
124 default:
125 break
126 }
127
128 const time = dayjs.unix(message.timestamp)
129 if (message.type == "initial") {
130 pushMessageBubblesGroup()
131 pushMessageTime(message, time, true)
132 pushMessageDate(message, time)
133 pushMessageInitial(message)
134 }
135 else {
136 if ( // If the date is different
137 lastTime?.year() != time.year()
138 || lastTime?.dayOfYear() != time.dayOfYear()
139 ) {
140 pushMessageBubblesGroup()
141 pushMessageTime(message, time, true)
142 pushMessageDate(message, time)
143 }
144 else if ( // If more than 5 minutes have passed since the last message
145 !lastTime.isBetween(time, time?.add(5, "minute"))
146 ) {
147 pushMessageBubblesGroup()
148 pushMessageTime(message, time)
149 }
150
151 lastTime = time
152 lastAuthor = message.author
153 }
154 })
155
156 return components
157}