Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5603 | 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'
1 www 14
 
5239 stevensc 15
const DEFAULT_PAGES = { current: 1, last: 1 }
16
 
3074 stevensc 17
const Chatmail = ({
5185 stevensc 18
  selectedConversation = null,
5601 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)
5601 stevensc 25
  const [displayOptions, setDisplayOptions] = useState(false)
26
  const [isShowConfirm, setIsShowConfirm] = useState(false)
5185 stevensc 27
  const lastMessage = useRef(null)
5250 stevensc 28
  const messagesList = useRef(null)
5239 stevensc 29
  const dispatch = useDispatch()
835 stevensc 30
 
5248 stevensc 31
  const getMoreMessages = async (url = '', page = pages.current) => {
5239 stevensc 32
    try {
33
      setLoading(true)
34
      const response = await fetchMessages(url, page)
35
      if (!response.success) {
36
        const errorMessage = response.data
37
 
5601 stevensc 38
        dispatch(
39
          addNotification({ style: 'danger', msg: errorMessage.message })
40
        )
5239 stevensc 41
        return
42
      }
43
 
5254 stevensc 44
      if (response.pagination.current > 1) {
5601 stevensc 45
        setOldMessages((prevOldMessages) => [
46
          ...prevOldMessages,
47
          ...response.data,
48
        ])
5254 stevensc 49
      }
5601 stevensc 50
      setPages((prevPages) => ({
51
        ...prevPages,
52
        last: response.pagination.last,
53
      }))
5239 stevensc 54
 
5247 stevensc 55
      return
56
    } catch (error) {
57
      const errorMessage = new Error(error)
58
      console.log('Request canceled', errorMessage)
59
    } finally {
60
      setLoading(false)
61
    }
62
  }
63
 
64
  const hearBeat = async () => {
65
    try {
66
      setLoading(true)
5601 stevensc 67
      const response = await fetchMessages(
68
        selectedConversation.messages_link,
69
        1
70
      )
5247 stevensc 71
 
72
      if (!response.success) {
73
        const errorMessage = response.data
74
 
5601 stevensc 75
        dispatch(
76
          addNotification({ style: 'danger', msg: errorMessage.message })
77
        )
5247 stevensc 78
        return
5239 stevensc 79
      }
80
 
5247 stevensc 81
      const newMessages = getMessagesDifferences(messages, response.data)
82
 
5239 stevensc 83
      if (newMessages.length) {
5248 stevensc 84
        setMessages([...newMessages, ...messages])
5239 stevensc 85
        scrollToBottom()
86
      } else {
87
        setMessages(response.data)
88
      }
89
 
5601 stevensc 90
      setPages((prevPages) => ({
91
        ...prevPages,
92
        last: response.pagination.last,
93
      }))
5239 stevensc 94
    } catch (error) {
95
      const errorMessage = new Error(error)
96
      console.log('Request canceled', errorMessage)
97
    } finally {
98
      setLoading(false)
99
    }
100
  }
101
 
102
  const handleSend = async (sendUrl = '', message = {}) => {
103
    try {
104
      const formData = new FormData()
105
 
5601 stevensc 106
      Object.entries(message).forEach(([key, value]) =>
107
        formData.append(key, value)
108
      )
5239 stevensc 109
 
110
      const { data: response } = await axios.post(sendUrl, formData)
5601 stevensc 111
      setMessages((prev) => [response.data, ...prev])
5239 stevensc 112
    } catch (error) {
113
      const errorMessage = new Error(error)
114
      dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
115
    }
116
  }
117
 
118
  const loadMore = async () => {
119
    setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))
120
  }
121
 
5601 stevensc 122
  const toggleConfirmModal = () => {
123
    setIsShowConfirm(!isShowConfirm)
124
  }
125
 
5603 stevensc 126
  const deleteConversation = () => {
5606 stevensc 127
    axios
128
      .post(selectedConversation.feed_delete_url)
129
      .then(({ data: response }) => {
130
        const { success, data } = response
5601 stevensc 131
 
5606 stevensc 132
        if (!success) {
133
          dispatch(addNotification({ style: 'danger', msg: data }))
134
          return
135
        }
5601 stevensc 136
 
5606 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 (
5601 stevensc 179
    <div className="chat">
180
      <span className="icon-hide" onClick={() => setConversation(null)}>
5239 stevensc 181
        <ArrowLeft />
182
        {LABELS.RETURN}
183
      </span>
5601 stevensc 184
      <div className="d-flex align-items-center justify-content-center position-relative">
185
        <a href={selectedConversation.profile}>
186
          <h2 className="chat-header">{selectedConversation.name}</h2>
187
        </a>
188
        <div
189
          className="cursor-pointer d-flex align-items-center"
190
          style={{ position: 'absolute', right: '1rem' }}
191
        >
192
          <img
193
            src="/images/icons/options.png"
194
            className="cursor-pointer img-icon options"
195
            onClick={() => setDisplayOptions(!displayOptions)}
196
          />
197
          <div className={`feed-options ${displayOptions ? 'active' : ''}`}>
198
            <ul>
199
              <li>
200
                <button className="option-btn" onClick={toggleConfirmModal}>
201
                  <i className="fa fa-trash-o mr-1" />
202
                  Borrar
203
                </button>
204
              </li>
205
            </ul>
206
          </div>
207
          <ConfirmModal
208
            show={isShowConfirm}
209
            onClose={toggleConfirmModal}
210
            onAccept={deleteConversation}
211
            acceptLabel="Aceptar"
212
          />
213
        </div>
214
      </div>
5250 stevensc 215
      <div className="messages-line" ref={messagesList}>
5601 stevensc 216
        {messages.length ? (
217
          [...oldMessages, ...messages].map((element, index) => (
5185 stevensc 218
            <MessageTemplate
219
              key={index}
220
              message={element}
221
              date={element.date}
5601 stevensc 222
            />
223
          ))
224
        ) : (
225
          <EmptySection
226
            message={LABELS.NO_MESSAGE_CONVERSATION}
227
            Icon={<SpeakerNotesOffRoundedIcon />}
228
          />
229
        )}
230
        {pages.current < pages.last && (
231
          <hr ref={lastMessage} style={{ opacity: 0, margin: 0 }} />
232
        )}
5185 stevensc 233
      </div>
5601 stevensc 234
      <MessageBox
235
        onSend={handleSend}
236
        sendUrl={selectedConversation.send_link}
237
      />
5185 stevensc 238
    </div>
239
  )
3074 stevensc 240
}
241
 
5185 stevensc 242
export default Chatmail