blob: bf459ea1af68b890f401797b2e648394420662d0 [file] [log] [blame]
idillonea465602022-09-13 19:58:51 -04001import React, { useCallback, useEffect, useState } from 'react';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -04002import MessageList from './MessageList';
3import SendMessageForm from './SendMessageForm';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -04004import Conversation from '../../../model/Conversation';
Adrien Béraud150b4782021-04-21 19:40:59 -04005import LoadingPage from './loading';
Adrien Béraudabba2e52021-04-24 21:39:56 -04006import io from "socket.io-client";
idillonbef18a52022-09-01 01:51:40 -04007import { Box, Stack, Typography } from '@mui/material';
8import ConversationAvatar from './ConversationAvatar';
idillonea465602022-09-13 19:58:51 -04009import { useConversationQuery, useMessagesQuery, useSendMessageMutation } from '../services/conversation';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040010
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040011const ConversationView = props => {
idillon08f77172022-09-13 19:14:17 -040012 const [socket, setSocket] = useState()
13 const [conversation, setConversation] = useState()
14 const [messages, setMessages] = useState([])
idillonea465602022-09-13 19:58:51 -040015 const [isLoading, setIsLoading] = useState(true)
idillon08f77172022-09-13 19:14:17 -040016 const [error, setError] = useState(false)
17
18 const conversationQuery = useConversationQuery(props.accountId, props.conversationId)
19 const messagesQuery = useMessagesQuery(props.accountId, props.conversationId)
idillonea465602022-09-13 19:58:51 -040020 const sendMessageMutation = useSendMessageMutation(props.accountId, props.conversationId)
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040021
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040022 useEffect(() => {
idillonea465602022-09-13 19:58:51 -040023 if (conversationQuery.isSuccess) {
idillon08f77172022-09-13 19:14:17 -040024 const conversation = Conversation.from(props.accountId, conversationQuery.data)
25 setConversation(conversation)
26 }
27 }, [conversationQuery.data])
28
29 useEffect(() => {
idillonea465602022-09-13 19:58:51 -040030 if (messagesQuery.isSuccess) {
idillon08f77172022-09-13 19:14:17 -040031 const sortedMessages = sortMessages(messagesQuery.data)
32 setMessages(sortedMessages)
33 }
34 }, [messagesQuery.data])
35
36 useEffect(() => {
idillonea465602022-09-13 19:58:51 -040037 setIsLoading(conversationQuery.isLoading || messagesQuery.isLoading)
idillon08f77172022-09-13 19:14:17 -040038 }, [conversationQuery.isLoading, messagesQuery.isLoading])
39
40 useEffect(() => {
41 setError(conversationQuery.isError || messagesQuery.isError)
42 }, [conversationQuery.isError, messagesQuery.isError])
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040043
idillonea465602022-09-13 19:58:51 -040044 const sendMessage = useCallback(
45 (message) => sendMessageMutation.mutate(message),
46 [sendMessageMutation]
47 )
48
Adrien Béraudabba2e52021-04-24 21:39:56 -040049 useEffect(() => {
50 console.log("io.connect")
51 const socket = io()
52 setSocket(socket)
53 return () => {
54 console.log("io.disconnect")
55 socket.disconnect()
56 setSocket(undefined)
57 }
58 }, [])
59
60 useEffect(() => {
idillon08f77172022-09-13 19:14:17 -040061 if (!conversation)
Adrien Béraudabba2e52021-04-24 21:39:56 -040062 return
idillon08f77172022-09-13 19:14:17 -040063 console.log(`io set conversation ${props.conversationId} `+ socket)
Adrien Béraudabba2e52021-04-24 21:39:56 -040064 if (socket)
idillon08f77172022-09-13 19:14:17 -040065 socket.emit('conversation', { accountId: props.accountId, conversationId: props.conversationId })
Adrien Béraudabba2e52021-04-24 21:39:56 -040066 socket.off('newMessage')
67 socket.on('newMessage', (data) => {
68 console.log("newMessage")
69 console.log(data)
idillon08f77172022-09-13 19:14:17 -040070 setMessages(addMessage(messages, data))
Adrien Béraudabba2e52021-04-24 21:39:56 -040071 })
idillon08f77172022-09-13 19:14:17 -040072 }, [conversation ? props.conversationId : "", socket])
Adrien Béraudabba2e52021-04-24 21:39:56 -040073
idillonea465602022-09-13 19:58:51 -040074 if (isLoading) {
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040075 return <LoadingPage />
idillon08f77172022-09-13 19:14:17 -040076 } else if (error) {
77 return <div>Error loading {props.conversationId}</div>
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040078 }
idillonbef18a52022-09-01 01:51:40 -040079
80 return (
81 <Stack
82 flexGrow={1}
83 height="100%"
84 >
85 <Stack direction="row" flexGrow={0}>
86 <Box style={{ margin: 16, flexShrink: 0 }}>
idillon08f77172022-09-13 19:14:17 -040087 <ConversationAvatar displayName={conversation?.getDisplayNameNoFallback()} />
idillonbef18a52022-09-01 01:51:40 -040088 </Box>
89 <Box style={{ flex: "1 1 auto", overflow: 'hidden' }}>
idillon08f77172022-09-13 19:14:17 -040090 <Typography className="title" variant="h6">{conversation?.getDisplayName()}</Typography>
91 <Typography className="subtitle" variant="subtitle1" >{props.conversationId}</Typography>
idillonbef18a52022-09-01 01:51:40 -040092 </Box>
93 </Stack>
idillonaedab942022-09-01 14:29:43 -040094 <Stack flexGrow={1} overflow="auto" direction="column-reverse">
idillonbef18a52022-09-01 01:51:40 -040095 <MessageList
idillon08f77172022-09-13 19:14:17 -040096 messages={messages}
idillonbef18a52022-09-01 01:51:40 -040097 />
98 </Stack>
99 <Stack flexGrow={0}>
100 <SendMessageForm onSend={sendMessage} />
101 </Stack>
102 </Stack>
103 )
Adrien Béraud35e7d7c2021-04-13 03:28:39 -0400104}
105
idillon08f77172022-09-13 19:14:17 -0400106const addMessage = (sortedMessages, message) => {
107 if (sortedMessages.length === 0) {
108 return [message]
109 } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
110 return [...sortedMessages, message]
111 } else if (message.linearizedParent === sortedMessages[0].id) {
112 return [message, ...sortedMessages]
113 } else {
114 console.log("Can't insert message " + message.id)
115 }
116}
117
118const sortMessages = (messages) => {
119 let sortedMessages = []
120 messages.forEach(message => sortedMessages = addMessage(sortedMessages, message))
121 return sortedMessages
122}
123
Adrien Béraud35e7d7c2021-04-13 03:28:39 -0400124export default ConversationView