blob: 075e96a52bc327ec7adb1e5041cb8605b98dfed2 [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';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040010
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040011const ConversationView = props => {
idillonbef18a52022-09-01 01:51:40 -040012 const [loadingMessages, setLoadingMessages] = useState(false)
Adrien Béraudabba2e52021-04-24 21:39:56 -040013 const [socket, setSocket] = useState(undefined)
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040014 const [state, setState] = useState({
Adrien Béraud4e287b92021-04-24 16:15:56 -040015 loaded: false,
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040016 error: false,
17 conversation: undefined
18 })
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040019
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040020 useEffect(() => {
21 const controller = new AbortController()
22 authManager.fetch(`/api/accounts/${props.accountId}/conversations/${props.conversationId}`, {signal: controller.signal})
23 .then(res => res.json())
24 .then(result => {
25 console.log(result)
26 setState({
27 loaded: true,
Adrien Béraudabba2e52021-04-24 21:39:56 -040028 conversation: Conversation.from(props.accountId, result)
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040029 })
30 }, error => {
31 console.log(`get error ${error}`)
32 setState({
33 loaded: true,
34 error: true
35 })
36 })
37 return () => controller.abort()
38 }, [props.accountId, props.conversationId])
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040039
Adrien Béraudabba2e52021-04-24 21:39:56 -040040 useEffect(() => {
41 console.log("io.connect")
42 const socket = io()
43 setSocket(socket)
44 return () => {
45 console.log("io.disconnect")
46 socket.disconnect()
47 setSocket(undefined)
48 }
49 }, [])
50
51 useEffect(() => {
52 if (!state.conversation)
53 return
54 console.log(`io set conversation ${state.conversation.getId()} `+ socket)
55 if (socket)
56 socket.emit('conversation', { accountId: state.conversation.getAccountId(), conversationId: state.conversation.getId() })
57 socket.off('newMessage')
58 socket.on('newMessage', (data) => {
59 console.log("newMessage")
60 console.log(data)
61 setState(state => {
62 if (state.conversation)
63 state.conversation.addMessage(data)
Adrien Béraud86986032021-04-25 12:04:53 -040064 return {...state}
Adrien Béraudabba2e52021-04-24 21:39:56 -040065 })
66 })
67 }, [state.conversation ? state.conversation.getId() : "", socket])
68
69 useEffect(() => {
idillonbef18a52022-09-01 01:51:40 -040070 if (!loadingMessages || !state.conversation)
Adrien Béraudabba2e52021-04-24 21:39:56 -040071 return
72 console.log(`Load more messages`)
73 const controller = new AbortController()
74 authManager.fetch(`/api/accounts/${state.conversation.getAccountId()}/conversations/${state.conversation.getId()}/messages`, {signal: controller.signal})
75 .then(res => res.json())
76 .then(messages => {
77 console.log(messages)
idillonbef18a52022-09-01 01:51:40 -040078 setLoadingMessages(false)
Adrien Béraud86986032021-04-25 12:04:53 -040079 setState(state => {
80 if (state.conversation)
Adrien Béraudabba2e52021-04-24 21:39:56 -040081 state.conversation.addLoadedMessages(messages)
Adrien Béraud86986032021-04-25 12:04:53 -040082 return {...state}
83 })
Adrien Béraudabba2e52021-04-24 21:39:56 -040084 }).catch(e => console.log(e))
85 return () => controller.abort()
idillonbef18a52022-09-01 01:51:40 -040086 }, [state, loadingMessages])
Adrien Béraudabba2e52021-04-24 21:39:56 -040087
Adrien Béraud5e9e19b2021-04-22 01:38:53 -040088 const sendMessage = (message) => {
89 authManager.fetch(`/api/accounts/${props.accountId}/conversations/${props.conversationId}`, {
90 headers: {
91 'Accept': 'application/json',
92 'Content-Type': 'application/json'
93 },
94 method:"POST",
95 body: JSON.stringify({ message })
96 })
97 }
98
99 if (state.loaded === false) {
100 return <LoadingPage />
101 } else if (state.error === true) {
102 return <div>Error loding {props.conversationId}</div>
Adrien Béraud5e9e19b2021-04-22 01:38:53 -0400103 }
idillonbef18a52022-09-01 01:51:40 -0400104
105 return (
106 <Stack
107 flexGrow={1}
108 height="100%"
109 >
110 <Stack direction="row" flexGrow={0}>
111 <Box style={{ margin: 16, flexShrink: 0 }}>
112 <ConversationAvatar displayName={state.conversation.getDisplayNameNoFallback()} />
113 </Box>
114 <Box style={{ flex: "1 1 auto", overflow: 'hidden' }}>
115 <Typography className="title" variant="h6">{state.conversation.getDisplayName()}</Typography>
116 <Typography className="subtitle" variant="subtitle1" >{state.conversation.getId()}</Typography>
117 </Box>
118 </Stack>
119 <Stack flexGrow={1} overflow="auto">
120 <MessageList
121 conversationId={state.conversation.getId()}
122 loading={loadingMessages}
123 loadMore={() => setLoadingMessages(true)}
124 messages={state.conversation.getMessages()}
125 />
126 </Stack>
127 <Stack flexGrow={0}>
128 <SendMessageForm onSend={sendMessage} />
129 </Stack>
130 </Stack>
131 )
Adrien Béraud35e7d7c2021-04-13 03:28:39 -0400132}
133
134export default ConversationView