Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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