Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5251 | Rev 5253 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3710 stevensc 1
/* eslint-disable react/prop-types */
5242 stevensc 2
import React, { useEffect, useRef, useState } from 'react'
5185 stevensc 3
import EmptySection from '../../shared/empty-section/EmptySection'
4
import MessageBox from './MessageBox'
5
import MessageTemplate from './MessageTemplate'
6
import SpeakerNotesOffRoundedIcon from '@mui/icons-material/SpeakerNotesOffRounded'
7
import QuestionAnswerRoundedIcon from '@mui/icons-material/QuestionAnswerRounded'
5239 stevensc 8
import { useDispatch } from 'react-redux'
5246 stevensc 9
import { fetchMessages, getMessagesDifferences } from '../../services/chat'
5239 stevensc 10
import { addNotification } from '../../redux/notification/notification.actions'
11
import { axios, scrollToBottom } from '../../utils'
12
import { ArrowLeft } from '@mui/icons-material'
5248 stevensc 13
import Spinner from '../../shared/loading-spinner/Spinner'
1 www 14
 
5239 stevensc 15
const DEFAULT_PAGES = { current: 1, last: 1 }
16
 
3074 stevensc 17
const Chatmail = ({
5185 stevensc 18
  selectedConversation = null,
5239 stevensc 19
  setConversation = () => null
1741 stevensc 20
}) => {
5239 stevensc 21
  const [oldMessages, setOldMessages] = useState([])
22
  const [messages, setMessages] = useState([])
23
  const [pages, setPages] = useState(DEFAULT_PAGES)
24
  const [loading, setLoading] = useState(false)
5185 stevensc 25
  const lastMessage = useRef(null)
5250 stevensc 26
  const messagesList = useRef(null)
5239 stevensc 27
  const dispatch = useDispatch()
835 stevensc 28
 
5248 stevensc 29
  const getMoreMessages = async (url = '', page = pages.current) => {
5239 stevensc 30
    try {
31
      setLoading(true)
32
      const response = await fetchMessages(url, page)
33
      if (!response.success) {
34
        const errorMessage = response.data
35
 
36
        dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
37
        return
38
      }
39
 
5247 stevensc 40
      if (response.pagination.current > 1) setOldMessages([...response.data, ...oldMessages])
41
      setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))
5239 stevensc 42
 
5247 stevensc 43
      return
44
    } catch (error) {
45
      const errorMessage = new Error(error)
46
      console.log('Request canceled', errorMessage)
47
    } finally {
48
      setLoading(false)
49
    }
50
  }
51
 
52
  const hearBeat = async () => {
53
    try {
54
      setLoading(true)
55
      const response = await fetchMessages(selectedConversation.messages_link, 1)
56
 
57
      if (!response.success) {
58
        const errorMessage = response.data
59
 
60
        dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
61
        return
5239 stevensc 62
      }
63
 
5247 stevensc 64
      const newMessages = getMessagesDifferences(messages, response.data)
65
 
5239 stevensc 66
      if (newMessages.length) {
5248 stevensc 67
        setMessages([...newMessages, ...messages])
5239 stevensc 68
        scrollToBottom()
69
      } else {
70
        setMessages(response.data)
71
      }
72
 
73
      setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))
74
    } catch (error) {
75
      const errorMessage = new Error(error)
76
      console.log('Request canceled', errorMessage)
77
    } finally {
78
      setLoading(false)
79
    }
80
  }
81
 
82
  const handleSend = async (sendUrl = '', message = {}) => {
83
    try {
84
      const formData = new FormData()
85
 
86
      Object.entries(message).forEach(([key, value]) => formData.append(key, value))
87
 
88
      const { data: response } = await axios.post(sendUrl, formData)
5249 stevensc 89
      setMessages(prev => [response.data, ...prev])
5239 stevensc 90
    } catch (error) {
91
      const errorMessage = new Error(error)
92
      dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
93
    }
94
  }
95
 
96
  const loadMore = async () => {
97
    setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))
98
  }
99
 
5185 stevensc 100
  useEffect(() => {
5247 stevensc 101
    if (!loading && selectedConversation) setTimeout(() => hearBeat(), 3000)
5239 stevensc 102
  }, [loading, selectedConversation])
103
 
5242 stevensc 104
  useEffect(() => {
5248 stevensc 105
    if (messages) setMessages([])
5250 stevensc 106
    scrollToBottom(messagesList)
5247 stevensc 107
    setPages(DEFAULT_PAGES)
108
  }, [selectedConversation])
109
 
110
  useEffect(() => {
5252 stevensc 111
    if (selectedConversation) getMoreMessages(selectedConversation?.messages_link, pages.current)
5239 stevensc 112
  }, [pages.current])
113
 
5242 stevensc 114
  useEffect(() => {
5197 stevensc 115
    const observer = new IntersectionObserver(([entry]) => {
5252 stevensc 116
      if (entry.isIntersecting) {
117
        loadMore()
118
      }
5197 stevensc 119
    })
120
 
5242 stevensc 121
    if (lastMessage.current) observer.observe(lastMessage.current)
5248 stevensc 122
  }, [selectedConversation])
917 stevensc 123
 
5185 stevensc 124
  if (!selectedConversation) {
5248 stevensc 125
    return <EmptySection message={LABELS.SELECT_CONVERSATION} Icon={<QuestionAnswerRoundedIcon />} />
5185 stevensc 126
  }
127
 
128
  return (
129
    <div className='chat'>
5247 stevensc 130
      <span className='icon-hide' onClick={() => setConversation(null)}>
5239 stevensc 131
        <ArrowLeft />
132
        {LABELS.RETURN}
133
      </span>
5185 stevensc 134
      <a href={selectedConversation.profile}>
135
        <h2 className='chat-header'>{selectedConversation.name}</h2>
136
      </a>
5250 stevensc 137
      <div className="messages-line" ref={messagesList}>
5185 stevensc 138
        {messages.length
5239 stevensc 139
          ? [...oldMessages, ...messages].map((element, index) =>
5185 stevensc 140
            <MessageTemplate
141
              key={index}
142
              message={element}
143
              date={element.date}
144
            />)
5248 stevensc 145
          : <EmptySection message={LABELS.NO_MESSAGE_CONVERSATION} Icon={<SpeakerNotesOffRoundedIcon />} />
876 stevensc 146
        }
5251 stevensc 147
        {pages.current < pages.last && <hr ref={lastMessage} style={{ opacity: 0, margin: 0 }}/>}
5185 stevensc 148
      </div>
5248 stevensc 149
      <MessageBox onSend={handleSend} sendUrl={selectedConversation.send_link} />
5185 stevensc 150
    </div>
151
  )
3074 stevensc 152
}
153
 
5185 stevensc 154
export default Chatmail