Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5329 | Rev 5345 | 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
 
15
const Chat = ({ defaultNetwork, emojiOnePath, timezones }) => {
16
  const [contacts, setContacts] = useState([])
17
  const [activeChats, setActiveChats] = useState([])
18
 
19
  const [isChatOpen, setIsChatOpen] = useState(false)
20
  const [isMuted, setIsMuted] = useState(false)
5320 stevensc 21
 
5064 stevensc 22
  const [showModal, setShowModal] = useState(false)
23
  const [loading, setLoading] = useState(false)
24
 
25
  const [pendingConversation, setPendingConversation] = useState('')
26
 
27
  const handleEntities = entities => {
28
    entities.map((entity) => {
29
      if (entity.not_received_messages) handleNewMessage(entity)
30
      if (entity.not_seen_messages) handleNotSeenMessage(entity)
31
      if (entity.is_open) handleOpenConversation(entity, false)
32
      if (entity.type === 'user') handleUpdateOnline(entity)
33
    })
34
    setContacts(entities)
35
  }
36
 
37
  const heartBeat = async () => {
38
    try {
5195 stevensc 39
      const { data } = await axios.get('/chat/heart-beat')
5064 stevensc 40
      if (data.success) handleEntities(data.data)
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')
81
    setActiveChats(activeChats.filter(prevActiveChats => prevActiveChats.id !== entity.id))
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])
5195 stevensc 91
      setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized }])
5064 stevensc 92
      return
93
    }
94
 
5195 stevensc 95
    setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized }])
5064 stevensc 96
  }
97
 
98
  const handleReadConversation = async (entity) => {
99
    try {
100
      const { data } = await axios.post(entity.url_mark_seen)
101
      if (!data.success) console.log('Ha ocurrido un error')
102
      setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
103
        if (entity.id === chat.id) return { ...chat, not_seen_messages: false }
104
        return chat
105
      }))
106
    } catch (error) {
107
      console.log(`Error: ${error}`)
108
    }
109
  }
110
 
111
  const handleMinimizeConversation = (entity, minimized = null) => {
112
    return setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
113
      if (entity.id === chat.id) return { ...chat, minimized: minimized ?? !chat.minimized }
114
      return chat
115
    }))
116
  }
117
 
118
  const handleNotSeenMessage = (entity) => {
119
    const index = activeChats.findIndex(chat => chat.id === entity.id)
120
 
121
    if (index !== -1) {
122
      setActiveChats(prev => [...prev].map(chat => {
123
        if (chat.id === entity.id) {
124
          return {
125
            ...chat,
126
            not_seen_messages: entity.not_seen_messages
127
          }
128
        }
129
        return chat
130
      }))
131
    }
132
  }
133
 
134
  const playNotifyAudio = (minimized = true) => {
135
    if (!isMuted && minimized) {
136
      notifyAudio.play()
137
    }
138
  }
139
 
140
  const handleMute = () => {
141
    setIsMuted(!isMuted)
142
    if (isMuted) {
143
      notifyAudio.play()
144
    }
145
  }
146
 
147
  useEffect(() => {
148
    if (!loading) {
149
      const fetchData = async () => {
150
        setLoading(true)
151
        const entities = await heartBeat() || []
152
        setLoading(false)
153
 
154
        return entities
155
      }
156
 
157
      setTimeout(() => {
158
        fetchData()
5195 stevensc 159
      }, '2000')
5064 stevensc 160
    }
161
  }, [loading])
162
 
163
  useEffect(() => {
164
    if (pendingConversation) {
165
      const pendingChat = contacts.find(contact => contact.url_send === pendingConversation)
166
 
167
      if (pendingChat) {
168
        handleOpenConversation(pendingChat)
169
        setPendingConversation('')
170
      }
171
    }
172
  }, [pendingConversation, contacts])
173
 
174
  useEffect(() => {
5195 stevensc 175
    emojione.imageType = 'png'
5064 stevensc 176
    emojione.sprites = false
177
    emojione.ascii = true
178
    emojione.imagePathPNG = emojiOnePath
179
  }, [])
180
 
181
  if (window.innerWidth < 1000 || window.location.pathname === '/chat') return null
182
 
183
  return (
184
    <>
185
      <div className="chat-helper">
5320 stevensc 186
 
5064 stevensc 187
        <div className="subpanel_title" onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}>
5206 stevensc 188
 
5064 stevensc 189
          <a href="/chat" className="text-chat-title">
5195 stevensc 190
            {CHAT_LABELS.CHAT}
5064 stevensc 191
            <FiMaximize2 className="ml-3" />
192
          </a>
5206 stevensc 193
 
5064 stevensc 194
          <div className="subpanel_title-icons">
195
            <i
5195 stevensc 196
              className={`icon ${isMuted ? 'icon-volume-off' : 'icon-volume-2'} text-20`}
5064 stevensc 197
              onClick={handleMute}
198
            />
199
            <i
5195 stevensc 200
              className={`fa ${isChatOpen ? 'fa-angle-down' : 'fa-angle-up'} text-20`}
5064 stevensc 201
              onClick={() => setIsChatOpen(!isChatOpen)}
202
            />
203
          </div>
204
        </div>
5206 stevensc 205
 
5064 stevensc 206
        {isChatOpen &&
5333 stevensc 207
          <>
208
            <button className="action-btn" onClick={() => setShowModal(true)}>
209
              <AddIcon />
210
              {CHAT_LABELS.START_CONVERSATION}
211
            </button>
212
            <ContactsFilters
213
              dataset={contacts}
214
              selectConversation={(entity) => handleOpenConversation(entity)}
215
            />
216
          </>
5064 stevensc 217
        }
218
 
219
      </div>
220
 
221
      <div className="active_chats-list">
222
        {activeChats.map((entity, index) => (
223
          <PersonalChat
224
            index={index}
225
            key={entity.id}
226
            entity={entity}
227
            not_seen_messages={entity.not_seen_messages}
228
            minimized={entity.minimized}
229
            onClose={handleCloseConversation}
230
            onMinimize={handleMinimizeConversation}
231
            onRead={handleReadConversation}
232
            timezones={timezones}
233
          />
234
        ))}
235
      </div>
236
 
237
      <ContactsModal
238
        show={showModal}
239
        setConversation={(url) => setPendingConversation(url)}
240
      />
241
      <NotificationAlert />
242
    </>
243
  )
244
}
245
 
246
export default Chat