Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
7317 stevensc 1
import React, { useEffect, useState } from 'react'
2
import { axios } from '../../../utils'
3
import { useSelector } from 'react-redux'
4
import AddIcon from '@mui/icons-material/Add'
5
import OpenInFullIcon from '@mui/icons-material/OpenInFull'
6
 
7
import PersonalChat from './PersonalChat'
8
import ContactsModal from './ContactsModal'
9
import ContactsFilters from './contactsFilters'
10
 
11
const notifyAudio = new Audio('/audio/chat.mp3')
12
 
13
const ChatHelper = () => {
14
  const [contacts, setContacts] = useState([])
15
  const [activeChats, setActiveChats] = useState([])
16
  const [isChatOpen, setIsChatOpen] = useState(false)
17
  const [isMuted, setIsMuted] = useState(false)
18
  const [showModal, setShowModal] = useState(false)
19
  const [loading, setLoading] = useState(false)
20
  const [pendingConversation, setPendingConversation] = useState('')
21
  const labels = useSelector(({ intl }) => intl.labels)
22
 
23
  const handleEntities = (entities) => {
24
    entities.map((entity) => {
25
      if (entity.not_received_messages) handleNewMessage(entity)
26
      if (entity.not_seen_messages) handleNotSeenMessage(entity)
27
      if (entity.is_open) handleOpenConversation(entity, false)
28
      if (entity.type === 'user') handleUpdateOnline(entity)
29
    })
30
    setContacts(entities)
31
  }
32
 
33
  const heartBeat = async () => {
34
    try {
35
      setLoading(true)
36
      const { data } = await axios.get('/chat/heart-beat')
37
      if (data.success) handleEntities(data.data)
38
      setLoading(false)
39
      return data.data
40
    } catch (error) {
41
      console.log('>>: chat error > ', error)
42
    }
43
  }
44
 
45
  const handleUpdateOnline = (entity) => {
46
    const existingChatId = activeChats.findIndex(
47
      (activeChat) => activeChat.id === entity.id
48
    )
49
    if (existingChatId >= 0) {
50
      if (activeChats[existingChatId].online !== entity.online) {
51
        const newActiveChats = [...activeChats]
52
        newActiveChats[existingChatId].online = entity.online
53
        setActiveChats(newActiveChats)
54
      }
55
    }
56
  }
57
 
58
  const handleNewMessage = async (unseeEntity) => {
59
    await axios.post(unseeEntity.url_mark_received)
60
    if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
61
      setActiveChats([...activeChats, { ...unseeEntity, minimized: false }])
62
      playNotifyAudio()
63
    } else {
64
      const existingChatId = activeChats.findIndex(
65
        (activeChat) => activeChat.id === unseeEntity.id
66
      )
67
      if (!activeChats[existingChatId].unsee_messages) {
68
        const newActiveChats = [...activeChats]
69
        newActiveChats[existingChatId].unsee_messages = true
70
        setActiveChats(newActiveChats)
71
        playNotifyAudio(newActiveChats[existingChatId].minimized)
72
      }
73
    }
74
  }
75
 
76
  const handleCloseConversation = async (entity) => {
77
    const { data } = await axios.post(entity.url_close)
78
    if (!data.success) console.log('Error in entity close')
79
    setActiveChats(
80
      activeChats.filter((prevActiveChats) => prevActiveChats.id !== entity.id)
81
    )
82
  }
83
 
84
  const handleOpenConversation = async (entity, minimized = false) => {
85
    if (activeChats.some((el) => el.id === entity.id)) {
86
      return null
87
    }
88
 
89
    if (activeChats.length >= 3) {
90
      await handleCloseConversation(activeChats[0])
91
      setActiveChats((prevActiveChats) => [
92
        ...prevActiveChats,
93
        { ...entity, minimized },
94
      ])
95
      return
96
    }
97
 
98
    setActiveChats((prevActiveChats) => [
99
      ...prevActiveChats,
100
      { ...entity, minimized },
101
    ])
102
  }
103
 
104
  const handleReadConversation = async (entity) => {
105
    try {
106
      const { data } = await axios.post(entity.url_mark_seen)
107
      if (!data.success) console.log('Ha ocurrido un error')
108
      setActiveChats((prevActiveChats) =>
109
        [...prevActiveChats].map((chat) => {
110
          if (entity.id === chat.id)
111
            return { ...chat, not_seen_messages: false }
112
          return chat
113
        })
114
      )
115
    } catch (error) {
116
      console.log(`Error: ${error}`)
117
    }
118
  }
119
 
120
  const handleMinimizeConversation = (entity, minimized = null) => {
121
    return setActiveChats((prevActiveChats) =>
122
      [...prevActiveChats].map((chat) => {
123
        if (entity.id === chat.id)
124
          return { ...chat, minimized: minimized ?? !chat.minimized }
125
        return chat
126
      })
127
    )
128
  }
129
 
130
  const handleNotSeenMessage = (entity) => {
131
    const index = activeChats.findIndex((chat) => chat.id === entity.id)
132
 
133
    if (index !== -1) {
134
      setActiveChats((prev) =>
135
        [...prev].map((chat) => {
136
          if (chat.id === entity.id) {
137
            return {
138
              ...chat,
139
              not_seen_messages: entity.not_seen_messages,
140
            }
141
          }
142
          return chat
143
        })
144
      )
145
    }
146
  }
147
 
148
  const playNotifyAudio = (minimized = true) => {
149
    if (!isMuted && minimized) {
150
      notifyAudio.play()
151
    }
152
  }
153
 
154
  const handleMute = () => {
155
    setIsMuted(!isMuted)
156
    if (isMuted) {
157
      notifyAudio.play()
158
    }
159
  }
160
 
161
  useEffect(() => {
162
    if (!loading) setTimeout(() => heartBeat(), 2000)
163
  }, [loading])
164
 
165
  useEffect(() => {
166
    if (pendingConversation) {
167
      const pendingChat = contacts.find(
168
        (contact) => contact.url_send === pendingConversation
169
      )
170
 
171
      if (pendingChat) {
172
        handleOpenConversation(pendingChat)
173
        setPendingConversation('')
174
      }
175
    }
176
  }, [pendingConversation, contacts])
177
 
178
  useEffect(() => {
179
    emojione.imageType = 'png'
180
    emojione.sprites = false
181
    emojione.ascii = true
182
    // emojione.imagePathPNG = emojiOnePath
183
  }, [])
184
 
185
  if (window.innerWidth < 1000 || window.location.pathname === '/chat')
186
    return null
187
 
188
  return (
189
    <div id="react-chat">
190
      <div className="chat-helper">
191
        <div
192
          className="subpanel_title"
193
          onClick={(e) =>
194
            e.currentTarget === e.target && setIsChatOpen(!isChatOpen)
195
          }
196
        >
197
          <a href="/chat" className="text-chat-title">
198
            {labels.chat}
199
            <OpenInFullIcon className="ml-3" />
200
          </a>
201
 
202
          <div className="subpanel_title-icons">
203
            <i
204
              className={`icon ${
205
                isMuted ? 'icon-volume-off' : 'icon-volume-2'
206
              } text-20`}
207
              onClick={handleMute}
208
            />
209
            <i
210
              className={`fa ${
211
                isChatOpen ? 'fa-angle-down' : 'fa-angle-up'
212
              } text-20`}
213
              onClick={() => setIsChatOpen(!isChatOpen)}
214
            />
215
          </div>
216
        </div>
217
        {isChatOpen && (
218
          <>
219
            <button className="action-btn" onClick={() => setShowModal(true)}>
220
              <AddIcon />
221
              {labels.start_conversation}
222
            </button>
223
            <ContactsFilters
224
              dataset={contacts}
225
              selectConversation={(entity) => handleOpenConversation(entity)}
226
            />
227
          </>
228
        )}
229
      </div>
230
 
231
      <div className="active_chats-list">
232
        {activeChats.map((entity, index) => (
233
          <PersonalChat
234
            index={index}
235
            key={entity.id}
236
            entity={entity}
237
            not_seen_messages={entity.not_seen_messages}
238
            minimized={entity.minimized}
239
            onClose={handleCloseConversation}
240
            onMinimize={handleMinimizeConversation}
241
            onRead={handleReadConversation}
242
          />
243
        ))}
244
      </div>
245
      <ContactsModal show={showModal} onClose={() => setShowModal(false)} />
246
    </div>
247
  )
248
}
249
 
250
export default ChatHelper