Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5617 | 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'
5601 stevensc 13
import ConfirmModal from '../../shared/confirm-modal/ConfirmModal'
5933 stevensc 14
import IconButton from '@mui/material/IconButton'
15
import MoreVertIcon from '@mui/icons-material/MoreVert'
1 www 16
 
5239 stevensc 17
const DEFAULT_PAGES = { current: 1, last: 1 }
18
 
3074 stevensc 19
const Chatmail = ({
5185 stevensc 20
  selectedConversation = null,
5601 stevensc 21
  setConversation = () => null,
1741 stevensc 22
}) => {
5239 stevensc 23
  const [oldMessages, setOldMessages] = useState([])
24
  const [messages, setMessages] = useState([])
25
  const [pages, setPages] = useState(DEFAULT_PAGES)
26
  const [loading, setLoading] = useState(false)
5601 stevensc 27
  const [displayOptions, setDisplayOptions] = useState(false)
28
  const [isShowConfirm, setIsShowConfirm] = useState(false)
5185 stevensc 29
  const lastMessage = useRef(null)
5250 stevensc 30
  const messagesList = useRef(null)
5239 stevensc 31
  const dispatch = useDispatch()
835 stevensc 32
 
5248 stevensc 33
  const getMoreMessages = async (url = '', page = pages.current) => {
5239 stevensc 34
    try {
35
      setLoading(true)
36
      const response = await fetchMessages(url, page)
37
      if (!response.success) {
38
        const errorMessage = response.data
39
 
5601 stevensc 40
        dispatch(
41
          addNotification({ style: 'danger', msg: errorMessage.message })
42
        )
5239 stevensc 43
        return
44
      }
45
 
5254 stevensc 46
      if (response.pagination.current > 1) {
5601 stevensc 47
        setOldMessages((prevOldMessages) => [
48
          ...prevOldMessages,
49
          ...response.data,
50
        ])
5254 stevensc 51
      }
5601 stevensc 52
      setPages((prevPages) => ({
53
        ...prevPages,
54
        last: response.pagination.last,
55
      }))
5239 stevensc 56
 
5247 stevensc 57
      return
58
    } catch (error) {
59
      const errorMessage = new Error(error)
60
      console.log('Request canceled', errorMessage)
61
    } finally {
62
      setLoading(false)
63
    }
64
  }
65
 
66
  const hearBeat = async () => {
67
    try {
68
      setLoading(true)
5601 stevensc 69
      const response = await fetchMessages(
70
        selectedConversation.messages_link,
71
        1
72
      )
5247 stevensc 73
 
74
      if (!response.success) {
75
        const errorMessage = response.data
76
 
5601 stevensc 77
        dispatch(
78
          addNotification({ style: 'danger', msg: errorMessage.message })
79
        )
5247 stevensc 80
        return
5239 stevensc 81
      }
82
 
5247 stevensc 83
      const newMessages = getMessagesDifferences(messages, response.data)
84
 
5239 stevensc 85
      if (newMessages.length) {
5248 stevensc 86
        setMessages([...newMessages, ...messages])
5239 stevensc 87
        scrollToBottom()
88
      } else {
89
        setMessages(response.data)
90
      }
91
 
5601 stevensc 92
      setPages((prevPages) => ({
93
        ...prevPages,
94
        last: response.pagination.last,
95
      }))
5239 stevensc 96
    } catch (error) {
97
      const errorMessage = new Error(error)
98
      console.log('Request canceled', errorMessage)
99
    } finally {
100
      setLoading(false)
101
    }
102
  }
103
 
104
  const handleSend = async (sendUrl = '', message = {}) => {
105
    try {
106
      const formData = new FormData()
107
 
5601 stevensc 108
      Object.entries(message).forEach(([key, value]) =>
109
        formData.append(key, value)
110
      )
5239 stevensc 111
 
112
      const { data: response } = await axios.post(sendUrl, formData)
5601 stevensc 113
      setMessages((prev) => [response.data, ...prev])
5239 stevensc 114
    } catch (error) {
115
      const errorMessage = new Error(error)
116
      dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
117
    }
118
  }
119
 
120
  const loadMore = async () => {
121
    setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))
122
  }
123
 
5601 stevensc 124
  const toggleConfirmModal = () => {
125
    setIsShowConfirm(!isShowConfirm)
126
  }
127
 
5603 stevensc 128
  const deleteConversation = () => {
5617 stevensc 129
    axios.post(selectedConversation.delete_link).then(({ data: response }) => {
130
      const { success, data } = response
5601 stevensc 131
 
5617 stevensc 132
      if (!success) {
133
        dispatch(addNotification({ style: 'danger', msg: data }))
134
        return
135
      }
5601 stevensc 136
 
5617 stevensc 137
      dispatch(addNotification({ style: 'success', msg: data }))
138
      setConversation(null)
139
    })
5601 stevensc 140
  }
141
 
5185 stevensc 142
  useEffect(() => {
5247 stevensc 143
    if (!loading && selectedConversation) setTimeout(() => hearBeat(), 3000)
5239 stevensc 144
  }, [loading, selectedConversation])
145
 
5242 stevensc 146
  useEffect(() => {
5248 stevensc 147
    if (messages) setMessages([])
5250 stevensc 148
    scrollToBottom(messagesList)
5247 stevensc 149
    setPages(DEFAULT_PAGES)
150
  }, [selectedConversation])
151
 
152
  useEffect(() => {
5601 stevensc 153
    if (selectedConversation)
154
      getMoreMessages(selectedConversation?.messages_link, pages.current)
5239 stevensc 155
  }, [pages.current])
156
 
5242 stevensc 157
  useEffect(() => {
5197 stevensc 158
    const observer = new IntersectionObserver(([entry]) => {
5252 stevensc 159
      if (entry.isIntersecting) {
160
        loadMore()
161
      }
5197 stevensc 162
    })
163
 
5253 stevensc 164
    if (lastMessage.current) {
165
      observer.observe(lastMessage.current)
166
    }
167
  }, [messages])
917 stevensc 168
 
5185 stevensc 169
  if (!selectedConversation) {
5601 stevensc 170
    return (
171
      <EmptySection
172
        message={LABELS.SELECT_CONVERSATION}
173
        Icon={<QuestionAnswerRoundedIcon />}
174
      />
175
    )
5185 stevensc 176
  }
177
 
178
  return (
5933 stevensc 179
    <>
180
      <div className="chat">
181
        <span className="icon-hide" onClick={() => setConversation(null)}>
182
          <ArrowLeft />
183
          {LABELS.RETURN}
184
        </span>
185
        <div className="chat_header">
186
          <a href={selectedConversation.profile}>
187
            <h2 className="chat-header">{selectedConversation.name}</h2>
188
          </a>
189
          <div className="header-options">
190
            <IconButton onClick={() => setDisplayOptions(!displayOptions)}>
191
              <MoreVertIcon />
192
            </IconButton>
193
            <div className="position-relative">
194
              <div className={`feed-options ${displayOptions ? 'active' : ''}`}>
195
                <ul>
196
                  <li>
197
                    <button className="option-btn" onClick={toggleConfirmModal}>
198
                      <i className="fa fa-trash-o mr-1" />
199
                      Borrar
200
                    </button>
201
                  </li>
202
                </ul>
203
              </div>
204
            </div>
5601 stevensc 205
          </div>
206
        </div>
5933 stevensc 207
        <div className="messages-line" ref={messagesList}>
208
          {messages.length ? (
209
            [...oldMessages, ...messages].map((element, index) => (
210
              <MessageTemplate
211
                key={index}
212
                message={element}
213
                date={element.date}
214
              />
215
            ))
216
          ) : (
217
            <EmptySection
218
              message={LABELS.NO_MESSAGE_CONVERSATION}
219
              Icon={<SpeakerNotesOffRoundedIcon />}
5601 stevensc 220
            />
5933 stevensc 221
          )}
222
          {pages.current < pages.last && (
223
            <hr ref={lastMessage} style={{ opacity: 0, margin: 0 }} />
224
          )}
225
        </div>
226
        <MessageBox
227
          onSend={handleSend}
228
          sendUrl={selectedConversation.send_link}
229
        />
5185 stevensc 230
      </div>
5933 stevensc 231
      <ConfirmModal
232
        show={isShowConfirm}
233
        onClose={toggleConfirmModal}
234
        onAccept={deleteConversation}
235
        acceptLabel="Aceptar"
5601 stevensc 236
      />
5933 stevensc 237
    </>
5185 stevensc 238
  )
3074 stevensc 239
}
240
 
5185 stevensc 241
export default Chatmail