Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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