Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5358 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

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