Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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