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