import { useEffect, useState, useCallback } from 'react'; import { useParams } from 'react-router-dom'; import moment from 'moment'; import PM from './PM'; import MessageInput from './MessageInput'; import UserInfo from './UserInfo'; import { getChat, pm } from '../api'; import './Chat.css'; /** * @typedef {Object} ChatProps * @property {import('../api').SecureUser} visitor * @property {EventSource} connection */ /** * Chat component * @param {ChatProps} props */ export default function Chat(props) { const [chats, setChats] = useState([]); const params = useParams(); let loadChat = useCallback((uname) => { const { hash } = props.visitor; setChats([]); if (hash && uname) { getChat(uname) .then(response => { setChats(response.data); }); } }, [props.visitor]); let onMessage = useCallback((json) => { const msg = JSON.parse(json.data); if (msg.user.uname === params.user) { setChats((oldChat) => { return [msg, ...oldChat]; }); } }, [params.user]); let onSend = (template) => { pm(template.to.uname, template.body) .then(res => { loadChat(params.user); }).catch(console.log); }; useEffect(() => { if (props.connection.addEventListener) { props.connection.addEventListener('msg', onMessage); } loadChat(params.user); console.log(props.connection); return () => { if (props.connection.removeEventListener) { props.connection.removeEventListener('msg', onMessage); } }; }, [props.connection, onMessage, loadChat, params.user]); const uname = params.user; return ( <div className="msg-cont"> <UserInfo uname={uname} /> {uname ? ( <div className="chatroom"> <ul className="Chat_messages"> { chats.map((chat) => <PM key={moment.utc(chat.timestamp).valueOf()} chat={chat} {...props} /> ) } </ul> <MessageInput data={{ mid: 0, timestamp: '0', to: { uname: uname } }} onSend={onSend}> Reply... </MessageInput> </div> ) : ( <div className="chatroom no-selection"><p>No chat selected</p></div> ) } </div> ); }