Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5244 | Rev 5247 | 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'
5246 stevensc 13
import { Spinner } from 'react-bootstrap'
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)
5239 stevensc 26
  const dispatch = useDispatch()
835 stevensc 27
 
5240 stevensc 28
  const getMessages = 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
 
39
      const newMessages = getMessagesDifferences(messages, response.data)
40
 
41
      if (response.pagination.current > 1) {
42
        setOldMessages([...response.data, ...oldMessages])
43
      }
44
 
45
      if (newMessages.length) {
46
        setMessages([...messages, ...newMessages])
47
        scrollToBottom()
48
      } else {
49
        setMessages(response.data)
50
      }
51
 
52
      setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))
53
    } catch (error) {
54
      const errorMessage = new Error(error)
55
      console.log('Request canceled', errorMessage)
56
    } finally {
57
      setLoading(false)
58
    }
59
  }
60
 
61
  const handleSend = async (sendUrl = '', message = {}) => {
62
    try {
63
      const formData = new FormData()
64
 
65
      Object.entries(message).forEach(([key, value]) => formData.append(key, value))
66
 
67
      const { data: response } = await axios.post(sendUrl, formData)
68
      setMessages(prev => [response.data, ...prev])
69
    } catch (error) {
70
      const errorMessage = new Error(error)
71
      dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
72
    }
73
  }
74
 
75
  const changeConversation = (conversation) => {
76
    setPages(DEFAULT_PAGES)
77
    setConversation(conversation)
78
    getMessages(selectedConversation.messages_link)
79
  }
80
 
81
  const loadMore = async () => {
82
    setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))
83
  }
84
 
5185 stevensc 85
  useEffect(() => {
5239 stevensc 86
    let timer
5246 stevensc 87
    if (!loading && selectedConversation) timer = setTimeout(() => getMessages(selectedConversation.messages_link), 2000)
5239 stevensc 88
    return () => {
89
      clearTimeout(timer)
90
    }
91
  }, [loading, selectedConversation])
92
 
5242 stevensc 93
  useEffect(() => {
5246 stevensc 94
    if (selectedConversation) getMessages(selectedConversation?.messages_link)
5239 stevensc 95
  }, [pages.current])
96
 
5242 stevensc 97
  useEffect(() => {
5197 stevensc 98
    const observer = new IntersectionObserver(([entry]) => {
99
      if (entry.isIntersecting) {
5239 stevensc 100
        loadMore()
5246 stevensc 101
        lastMessage.current.scrollTop += 100
5197 stevensc 102
      }
103
    })
104
 
5242 stevensc 105
    if (lastMessage.current) observer.observe(lastMessage.current)
5197 stevensc 106
  }, [messages])
917 stevensc 107
 
5185 stevensc 108
  if (!selectedConversation) {
5187 stevensc 109
    return <EmptySection message={LABELS.SELECT_CONVERSATION} Icon={<QuestionAnswerRoundedIcon/>} />
5185 stevensc 110
  }
111
 
112
  return (
113
    <div className='chat'>
5239 stevensc 114
      <span className='icon-hide' onClick={() => changeConversation(null)}>
115
        <ArrowLeft />
116
        {LABELS.RETURN}
117
      </span>
5185 stevensc 118
      <a href={selectedConversation.profile}>
119
        <h2 className='chat-header'>{selectedConversation.name}</h2>
120
      </a>
121
      <div className="messages-line">
122
        {messages.length
5239 stevensc 123
          ? [...oldMessages, ...messages].map((element, index) =>
5185 stevensc 124
            <MessageTemplate
125
              key={index}
126
              message={element}
127
              date={element.date}
128
            />)
5187 stevensc 129
          : <EmptySection message={LABELS.NO_MESSAGE_CONVERSATION} Icon={<SpeakerNotesOffRoundedIcon/>} />
876 stevensc 130
        }
5246 stevensc 131
        {loading && <Spinner />}
132
        {pages.current < pages.last && <hr ref={lastMessage} style={{ visibility: 'hidden' }} />}
5185 stevensc 133
      </div>
5239 stevensc 134
      <MessageBox onSend={handleSend} sendUrl={selectedConversation.send_link}/>
5185 stevensc 135
    </div>
136
  )
3074 stevensc 137
}
138
 
5185 stevensc 139
export default Chatmail