Rev 5617 | 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'import ConfirmModal from '../../shared/confirm-modal/ConfirmModal'import IconButton from '@mui/material/IconButton'import MoreVertIcon from '@mui/icons-material/MoreVert'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 [displayOptions, setDisplayOptions] = useState(false)const [isShowConfirm, setIsShowConfirm] = 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 }))}const toggleConfirmModal = () => {setIsShowConfirm(!isShowConfirm)}const deleteConversation = () => {axios.post(selectedConversation.delete_link).then(({ data: response }) => {const { success, data } = responseif (!success) {dispatch(addNotification({ style: 'danger', msg: data }))return}dispatch(addNotification({ style: 'success', msg: data }))setConversation(null)})}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 (<EmptySectionmessage={LABELS.SELECT_CONVERSATION}Icon={<QuestionAnswerRoundedIcon />}/>)}return (<><div className="chat"><span className="icon-hide" onClick={() => setConversation(null)}><ArrowLeft />{LABELS.RETURN}</span><div className="chat_header"><a href={selectedConversation.profile}><h2 className="chat-header">{selectedConversation.name}</h2></a><div className="header-options"><IconButton onClick={() => setDisplayOptions(!displayOptions)}><MoreVertIcon /></IconButton><div className="position-relative"><div className={`feed-options ${displayOptions ? 'active' : ''}`}><ul><li><button className="option-btn" onClick={toggleConfirmModal}><i className="fa fa-trash-o mr-1" />Borrar</button></li></ul></div></div></div></div><div className="messages-line" ref={messagesList}>{messages.length ? ([...oldMessages, ...messages].map((element, index) => (<MessageTemplatekey={index}message={element}date={element.date}/>))) : (<EmptySectionmessage={LABELS.NO_MESSAGE_CONVERSATION}Icon={<SpeakerNotesOffRoundedIcon />}/>)}{pages.current < pages.last && (<hr ref={lastMessage} style={{ opacity: 0, margin: 0 }} />)}</div><MessageBoxonSend={handleSend}sendUrl={selectedConversation.send_link}/></div><ConfirmModalshow={isShowConfirm}onClose={toggleConfirmModal}onAccept={deleteConversation}acceptLabel="Aceptar"/></>)}export default Chatmail