blob: c286f8a3cd17de9335ad74c211fdd46b5fdd26ac [file] [log] [blame]
simond47ef9e2022-09-28 22:24:28 -04001import { useCallback, useContext, 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';
idillonbef18a52022-09-01 01:51:40 -04006import { Box, Stack, Typography } from '@mui/material';
7import ConversationAvatar from './ConversationAvatar';
idillonea465602022-09-13 19:58:51 -04008import { useConversationQuery, useMessagesQuery, useSendMessageMutation } from '../services/conversation';
idillon322e4ac2022-09-14 12:48:43 -04009import { SocketContext } from '../contexts/socket';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040010
simond47ef9e2022-09-28 22:24:28 -040011const ConversationView = (props) => {
12 const socket = useContext(SocketContext);
13 const [conversation, setConversation] = useState();
14 const [messages, setMessages] = useState([]);
15 const [isLoading, setIsLoading] = useState(true);
16 const [error, setError] = useState(false);
idillon08f77172022-09-13 19:14:17 -040017
simond47ef9e2022-09-28 22:24:28 -040018 const conversationQuery = useConversationQuery(props.accountId, props.conversationId);
19 const messagesQuery = useMessagesQuery(props.accountId, props.conversationId);
20 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) {
simond47ef9e2022-09-28 22:24:28 -040024 const conversation = Conversation.from(props.accountId, conversationQuery.data);
25 setConversation(conversation);
idillon08f77172022-09-13 19:14:17 -040026 }
simond47ef9e2022-09-28 22:24:28 -040027 }, [conversationQuery.data]);
idillon08f77172022-09-13 19:14:17 -040028
29 useEffect(() => {
idillonea465602022-09-13 19:58:51 -040030 if (messagesQuery.isSuccess) {
simond47ef9e2022-09-28 22:24:28 -040031 const sortedMessages = sortMessages(messagesQuery.data);
32 setMessages(sortedMessages);
idillon08f77172022-09-13 19:14:17 -040033 }
simond47ef9e2022-09-28 22:24:28 -040034 }, [messagesQuery.data]);
idillon08f77172022-09-13 19:14:17 -040035
36 useEffect(() => {
simond47ef9e2022-09-28 22:24:28 -040037 setIsLoading(conversationQuery.isLoading || messagesQuery.isLoading);
38 }, [conversationQuery.isLoading, messagesQuery.isLoading]);
idillonea465602022-09-13 19:58:51 -040039
Adrien Béraudabba2e52021-04-24 21:39:56 -040040 useEffect(() => {
simond47ef9e2022-09-28 22:24:28 -040041 setError(conversationQuery.isError || messagesQuery.isError);
42 }, [conversationQuery.isError, messagesQuery.isError]);
43
44 const sendMessage = useCallback((message) => sendMessageMutation.mutate(message), [sendMessageMutation]);
45
46 useEffect(() => {
47 if (!conversation) return;
48 console.log(`io set conversation ${props.conversationId} ` + socket);
49 if (socket) socket.emit('conversation', { accountId: props.accountId, conversationId: props.conversationId });
50 socket.off('newMessage');
Adrien Béraudabba2e52021-04-24 21:39:56 -040051 socket.on('newMessage', (data) => {
simond47ef9e2022-09-28 22:24:28 -040052 console.log('newMessage');
53 setMessages((messages) => addMessage(messages, data));
54 });
55 }, [socket, setMessages]);
Adrien Béraudabba2e52021-04-24 21:39:56 -040056
idillonea465602022-09-13 19:58:51 -040057 if (isLoading) {
simond47ef9e2022-09-28 22:24:28 -040058 return <LoadingPage />;
idillon08f77172022-09-13 19:14:17 -040059 } else if (error) {
simond47ef9e2022-09-28 22:24:28 -040060 return <div>Error loading {props.conversationId}</div>;
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040061 }
idillonbef18a52022-09-01 01:51:40 -040062
63 return (
simond47ef9e2022-09-28 22:24:28 -040064 <Stack flexGrow={1} height="100%">
idillonbef18a52022-09-01 01:51:40 -040065 <Stack direction="row" flexGrow={0}>
66 <Box style={{ margin: 16, flexShrink: 0 }}>
idillon08f77172022-09-13 19:14:17 -040067 <ConversationAvatar displayName={conversation?.getDisplayNameNoFallback()} />
idillonbef18a52022-09-01 01:51:40 -040068 </Box>
simond47ef9e2022-09-28 22:24:28 -040069 <Box style={{ flex: '1 1 auto', overflow: 'hidden' }}>
70 <Typography className="title" variant="h6">
71 {conversation?.getDisplayName()}
72 </Typography>
73 <Typography className="subtitle" variant="subtitle1">
74 {props.conversationId}
75 </Typography>
idillonbef18a52022-09-01 01:51:40 -040076 </Box>
77 </Stack>
idillonaedab942022-09-01 14:29:43 -040078 <Stack flexGrow={1} overflow="auto" direction="column-reverse">
simond47ef9e2022-09-28 22:24:28 -040079 <MessageList messages={messages} />
idillonbef18a52022-09-01 01:51:40 -040080 </Stack>
81 <Stack flexGrow={0}>
82 <SendMessageForm onSend={sendMessage} />
83 </Stack>
84 </Stack>
simond47ef9e2022-09-28 22:24:28 -040085 );
86};
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040087
idillon08f77172022-09-13 19:14:17 -040088const addMessage = (sortedMessages, message) => {
89 if (sortedMessages.length === 0) {
simond47ef9e2022-09-28 22:24:28 -040090 return [message];
idillon08f77172022-09-13 19:14:17 -040091 } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
simond47ef9e2022-09-28 22:24:28 -040092 return [...sortedMessages, message];
idillon08f77172022-09-13 19:14:17 -040093 } else if (message.linearizedParent === sortedMessages[0].id) {
simond47ef9e2022-09-28 22:24:28 -040094 return [message, ...sortedMessages];
idillon08f77172022-09-13 19:14:17 -040095 } else {
simond47ef9e2022-09-28 22:24:28 -040096 console.log("Can't insert message " + message.id);
idillon08f77172022-09-13 19:14:17 -040097 }
simond47ef9e2022-09-28 22:24:28 -040098};
idillon08f77172022-09-13 19:14:17 -040099
100const sortMessages = (messages) => {
simond47ef9e2022-09-28 22:24:28 -0400101 let sortedMessages = [];
102 messages.forEach((message) => (sortedMessages = addMessage(sortedMessages, message)));
103 return sortedMessages;
104};
idillon08f77172022-09-13 19:14:17 -0400105
simond47ef9e2022-09-28 22:24:28 -0400106export default ConversationView;