blob: 964d5bf101a86000f9b69e3df800e7263f1e15ab [file] [log] [blame]
Adrien Béraud5e9e19b2021-04-22 01:38:53 -04001import React, { useEffect, useState } from 'react';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -04002import MessageList from './MessageList';
3import SendMessageForm from './SendMessageForm';
4import authManager from '../AuthManager'
5import Conversation from '../../../model/Conversation';
Adrien Béraud150b4782021-04-21 19:40:59 -04006import LoadingPage from './loading';
Adrien Béraudabba2e52021-04-24 21:39:56 -04007import io from "socket.io-client";
idillonbef18a52022-09-01 01:51:40 -04008import { Box, Stack, Typography } from '@mui/material';
9import ConversationAvatar from './ConversationAvatar';
idillon08f77172022-09-13 19:14:17 -040010import { useConversationQuery, useMessagesQuery } from '../services/conversation';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040011
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040012const ConversationView = props => {
idillonbef18a52022-09-01 01:51:40 -040013 const [loadingMessages, setLoadingMessages] = useState(false)
idillon08f77172022-09-13 19:14:17 -040014 const [socket, setSocket] = useState()
15 const [conversation, setConversation] = useState()
16 const [messages, setMessages] = useState([])
17 const [loaded, setLoaded] = useState(true)
18 const [error, setError] = useState(false)
19
20 const conversationQuery = useConversationQuery(props.accountId, props.conversationId)
21 const messagesQuery = useMessagesQuery(props.accountId, props.conversationId)
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040022
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040023 useEffect(() => {
idillon08f77172022-09-13 19:14:17 -040024 if (conversationQuery.data) {
25 const conversation = Conversation.from(props.accountId, conversationQuery.data)
26 setConversation(conversation)
27 }
28 }, [conversationQuery.data])
29
30 useEffect(() => {
31 if (messagesQuery.data) {
32 const sortedMessages = sortMessages(messagesQuery.data)
33 setMessages(sortedMessages)
34 }
35 }, [messagesQuery.data])
36
37 useEffect(() => {
38 setLoaded(!(conversationQuery.isLoading || messagesQuery.isLoading))
39 }, [conversationQuery.isLoading, messagesQuery.isLoading])
40
41 useEffect(() => {
42 setError(conversationQuery.isError || messagesQuery.isError)
43 }, [conversationQuery.isError, messagesQuery.isError])
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040044
Adrien Béraudabba2e52021-04-24 21:39:56 -040045 useEffect(() => {
46 console.log("io.connect")
47 const socket = io()
48 setSocket(socket)
49 return () => {
50 console.log("io.disconnect")
51 socket.disconnect()
52 setSocket(undefined)
53 }
54 }, [])
55
56 useEffect(() => {
idillon08f77172022-09-13 19:14:17 -040057 if (!conversation)
Adrien Béraudabba2e52021-04-24 21:39:56 -040058 return
idillon08f77172022-09-13 19:14:17 -040059 console.log(`io set conversation ${props.conversationId} `+ socket)
Adrien Béraudabba2e52021-04-24 21:39:56 -040060 if (socket)
idillon08f77172022-09-13 19:14:17 -040061 socket.emit('conversation', { accountId: props.accountId, conversationId: props.conversationId })
Adrien Béraudabba2e52021-04-24 21:39:56 -040062 socket.off('newMessage')
63 socket.on('newMessage', (data) => {
64 console.log("newMessage")
65 console.log(data)
idillon08f77172022-09-13 19:14:17 -040066 setMessages(addMessage(messages, data))
Adrien Béraudabba2e52021-04-24 21:39:56 -040067 })
idillon08f77172022-09-13 19:14:17 -040068 }, [conversation ? props.conversationId : "", socket])
Adrien Béraudabba2e52021-04-24 21:39:56 -040069
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040070 const sendMessage = (message) => {
71 authManager.fetch(`/api/accounts/${props.accountId}/conversations/${props.conversationId}`, {
72 headers: {
73 'Accept': 'application/json',
74 'Content-Type': 'application/json'
75 },
76 method:"POST",
77 body: JSON.stringify({ message })
78 })
79 }
80
idillon08f77172022-09-13 19:14:17 -040081 if (!loaded) {
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040082 return <LoadingPage />
idillon08f77172022-09-13 19:14:17 -040083 } else if (error) {
84 return <div>Error loading {props.conversationId}</div>
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040085 }
idillonbef18a52022-09-01 01:51:40 -040086
87 return (
88 <Stack
89 flexGrow={1}
90 height="100%"
91 >
92 <Stack direction="row" flexGrow={0}>
93 <Box style={{ margin: 16, flexShrink: 0 }}>
idillon08f77172022-09-13 19:14:17 -040094 <ConversationAvatar displayName={conversation?.getDisplayNameNoFallback()} />
idillonbef18a52022-09-01 01:51:40 -040095 </Box>
96 <Box style={{ flex: "1 1 auto", overflow: 'hidden' }}>
idillon08f77172022-09-13 19:14:17 -040097 <Typography className="title" variant="h6">{conversation?.getDisplayName()}</Typography>
98 <Typography className="subtitle" variant="subtitle1" >{props.conversationId}</Typography>
idillonbef18a52022-09-01 01:51:40 -040099 </Box>
100 </Stack>
idillonaedab942022-09-01 14:29:43 -0400101 <Stack flexGrow={1} overflow="auto" direction="column-reverse">
idillonbef18a52022-09-01 01:51:40 -0400102 <MessageList
idillon08f77172022-09-13 19:14:17 -0400103 conversationId={props.conversationId}
idillonbef18a52022-09-01 01:51:40 -0400104 loading={loadingMessages}
105 loadMore={() => setLoadingMessages(true)}
idillon08f77172022-09-13 19:14:17 -0400106 messages={messages}
idillonbef18a52022-09-01 01:51:40 -0400107 />
108 </Stack>
109 <Stack flexGrow={0}>
110 <SendMessageForm onSend={sendMessage} />
111 </Stack>
112 </Stack>
113 )
Adrien Béraud35e7d7c2021-04-13 03:28:39 -0400114}
115
idillon08f77172022-09-13 19:14:17 -0400116const addMessage = (sortedMessages, message) => {
117 if (sortedMessages.length === 0) {
118 return [message]
119 } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
120 return [...sortedMessages, message]
121 } else if (message.linearizedParent === sortedMessages[0].id) {
122 return [message, ...sortedMessages]
123 } else {
124 console.log("Can't insert message " + message.id)
125 }
126}
127
128const sortMessages = (messages) => {
129 let sortedMessages = []
130 messages.forEach(message => sortedMessages = addMessage(sortedMessages, message))
131 return sortedMessages
132}
133
Adrien Béraud35e7d7c2021-04-13 03:28:39 -0400134export default ConversationView