Rev 5253 | Rev 5603 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
/* eslint-disable react/prop-types */import React, { useEffect, useRef, useState } from 'react'import { ArrowLeft } from '@mui/icons-material'import { useDispatch } from 'react-redux'import { addNotification } from '../../redux/notification/notification.actions'import { axios, scrollToBottom } from '../../utils'import { fetchMessages, getMessagesDifferences } from '../../services/chat'import QuestionAnswerRoundedIcon from '@mui/icons-material/QuestionAnswerRounded'import SpeakerNotesOffRoundedIcon from '@mui/icons-material/SpeakerNotesOffRounded'import EmptySection from '../../shared/empty-section/EmptySection'import MessageBox from './MessageBox'import MessageTemplate from './MessageTemplate'const DEFAULT_PAGES = { current: 1, last: 1 }const Chatmail = ({selectedConversation = null,setConversation = () => null}) => {const [oldMessages, setOldMessages] = useState([])const [messages, setMessages] = useState([])const [pages, setPages] = useState(DEFAULT_PAGES)const [loading, setLoading] = useState(false)const lastMessage = useRef(null)const messagesList = useRef(null)const dispatch = useDispatch()const getMoreMessages = async (url = '', page = pages.current) => {try {setLoading(true)const response = await fetchMessages(url, page)if (!response.success) {const errorMessage = response.datadispatch(addNotification({ style: 'danger', msg: errorMessage.message }))return}if (response.pagination.current > 1) {setOldMessages((prevOldMessages) => [...prevOldMessages, ...response.data])}setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))return} catch (error) {const errorMessage = new Error(error)console.log('Request canceled', errorMessage)} finally {setLoading(false)}}const hearBeat = async () => {try {setLoading(true)const response = await fetchMessages(selectedConversation.messages_link, 1)if (!response.success) {const errorMessage = response.datadispatch(addNotification({ style: 'danger', msg: errorMessage.message }))return}const newMessages = getMessagesDifferences(messages, response.data)if (newMessages.length) {setMessages([...newMessages, ...messages])scrollToBottom()} else {setMessages(response.data)}setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))} catch (error) {const errorMessage = new Error(error)console.log('Request canceled', errorMessage)} finally {setLoading(false)}}const handleSend = async (sendUrl = '', message = {}) => {try {const formData = new FormData()Object.entries(message).forEach(([key, value]) => formData.append(key, value))const { data: response } = await axios.post(sendUrl, formData)setMessages(prev => [response.data, ...prev])} catch (error) {const errorMessage = new Error(error)dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))}}const loadMore = async () => {setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))}useEffect(() => {if (!loading && selectedConversation) setTimeout(() => hearBeat(), 3000)}, [loading, selectedConversation])useEffect(() => {if (messages) setMessages([])scrollToBottom(messagesList)setPages(DEFAULT_PAGES)}, [selectedConversation])useEffect(() => {if (selectedConversation) getMoreMessages(selectedConversation?.messages_link, pages.current)}, [pages.current])useEffect(() => {const observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {loadMore()}})if (lastMessage.current) {observer.observe(lastMessage.current)}}, [messages])if (!selectedConversation) {return <EmptySection message={LABELS.SELECT_CONVERSATION} Icon={<QuestionAnswerRoundedIcon />} />}return (<div className='chat'><span className='icon-hide' onClick={() => setConversation(null)}><ArrowLeft />{LABELS.RETURN}</span><a href={selectedConversation.profile}><h2 className='chat-header'>{selectedConversation.name}</h2></a><div className="messages-line" ref={messagesList}>{messages.length? [...oldMessages, ...messages].map((element, index) =><MessageTemplatekey={index}message={element}date={element.date}/>): <EmptySection message={LABELS.NO_MESSAGE_CONVERSATION} Icon={<SpeakerNotesOffRoundedIcon />} />}{pages.current < pages.last && <hr ref={lastMessage} style={{ opacity: 0, margin: 0 }} />}</div><MessageBox onSend={handleSend} sendUrl={selectedConversation.send_link} /></div>)}export default Chatmail