Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5065 | Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
5064 stevensc 1
/* eslint-disable react/prop-types */
2
import React from "react"
3
import { useState, useEffect } from "react"
4
import { axios } from "../../utils"
5
import { FiMaximize2 } from 'react-icons/fi'
6
import AddIcon from '@mui/icons-material/Add'
7
 
8
// Components
9
import NotificationAlert from "../../shared/notification/NotificationAlert"
10
import PersonalChat from "./personal-chat/PersonalChat"
11
import ContactsModal from "./components/ContactsModal"
12
import ContactsFilters from "./components/contactsFilters"
13
 
14
const notifyAudio = new Audio("/audio/chat.mp3")
15
 
16
const Chat = ({ defaultNetwork, emojiOnePath, timezones }) => {
17
  const [contacts, setContacts] = useState([])
18
  const [activeChats, setActiveChats] = useState([])
19
 
20
  const [isChatOpen, setIsChatOpen] = useState(false)
21
  const [isMuted, setIsMuted] = useState(false)
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 {
39
      const { data } = await axios.get("/chat/heart-beat")
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
 
86
    console.log(activeChats.some(el => el.id === entity.id))
87
    console.log(activeChats.length)
88
    console.log(activeChats)
89
    console.log(entity)
90
 
91
    if (activeChats.some(el => el.id === entity.id)) {
92
      return null
93
    }
94
 
95
    if (activeChats.length >= 3) {
96
      await handleCloseConversation(activeChats[0])
97
      setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized: minimized }])
98
      return
99
    }
100
 
101
    console.log('Paso')
102
 
103
    setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized: minimized }])
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')
110
      setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
111
        if (entity.id === chat.id) return { ...chat, not_seen_messages: false }
112
        return chat
113
      }))
114
    } catch (error) {
115
      console.log(`Error: ${error}`)
116
    }
117
  }
118
 
119
  const handleMinimizeConversation = (entity, minimized = null) => {
120
    return setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
121
      if (entity.id === chat.id) return { ...chat, minimized: minimized ?? !chat.minimized }
122
      return chat
123
    }))
124
  }
125
 
126
  const handleNotSeenMessage = (entity) => {
127
    const index = activeChats.findIndex(chat => chat.id === entity.id)
128
 
129
    if (index !== -1) {
130
      setActiveChats(prev => [...prev].map(chat => {
131
        if (chat.id === entity.id) {
132
          return {
133
            ...chat,
134
            not_seen_messages: entity.not_seen_messages
135
          }
136
        }
137
        return chat
138
      }))
139
    }
140
 
141
  }
142
 
143
  const playNotifyAudio = (minimized = true) => {
144
    if (!isMuted && minimized) {
145
      notifyAudio.play()
146
    }
147
  }
148
 
149
  const handleMute = () => {
150
    setIsMuted(!isMuted)
151
    if (isMuted) {
152
      notifyAudio.play()
153
    }
154
  }
155
 
156
  useEffect(() => {
157
    if (!loading) {
158
      const fetchData = async () => {
159
        setLoading(true)
160
        const entities = await heartBeat() || []
161
        setLoading(false)
162
 
163
        return entities
164
      }
165
 
166
      setTimeout(() => {
167
        fetchData()
168
      }, "2000")
169
    }
170
  }, [loading])
171
 
172
  useEffect(() => {
173
    if (pendingConversation) {
174
      const pendingChat = contacts.find(contact => contact.url_send === pendingConversation)
175
 
176
      if (pendingChat) {
177
        handleOpenConversation(pendingChat)
178
        setPendingConversation('')
179
      }
180
 
181
    }
182
  }, [pendingConversation, contacts])
183
 
184
  useEffect(() => {
185
    emojione.imageType = "png"
186
    emojione.sprites = false
187
    emojione.ascii = true
188
    emojione.imagePathPNG = emojiOnePath
189
  }, [])
190
 
191
  if (window.innerWidth < 1000 || window.location.pathname === '/chat') return null
192
 
193
  return (
194
    <>
195
      <div className="chat-helper">
196
        <div className="subpanel_title" onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}>
197
          <a href="/chat" className="text-chat-title">
198
            Chat
199
            <FiMaximize2 className="ml-3" />
200
          </a>
201
          <div className="subpanel_title-icons">
202
            <i
203
              className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"} text-20`}
204
              onClick={handleMute}
205
            />
206
            <i
207
              className={`fa ${isChatOpen ? "fa-angle-down" : "fa-angle-up"} text-20`}
208
              onClick={() => setIsChatOpen(!isChatOpen)}
209
            />
210
          </div>
211
        </div>
212
        {defaultNetwork !== 'y' &&
213
          <button className="action-btn" onClick={() => setShowModal(true)}>
214
            <AddIcon />
215
            Iniciar conversación
216
          </button>
217
        }
218
        {isChatOpen &&
219
          <ContactsFilters
220
            dataset={contacts}
221
            selectConversation={(entity) => handleOpenConversation(entity)}
222
          />
223
        }
224
 
225
      </div>
226
 
227
      <div className="active_chats-list">
228
        {activeChats.map((entity, index) => (
229
          <PersonalChat
230
            index={index}
231
            key={entity.id}
232
            entity={entity}
233
            not_seen_messages={entity.not_seen_messages}
234
            minimized={entity.minimized}
235
            onClose={handleCloseConversation}
236
            onMinimize={handleMinimizeConversation}
237
            onRead={handleReadConversation}
238
            timezones={timezones}
239
          />
240
        ))}
241
      </div>
242
 
243
      <ContactsModal
244
        show={showModal}
245
        setConversation={(url) => setPendingConversation(url)}
246
      />
247
      <NotificationAlert />
248
    </>
249
  )
250
}
251
 
252
export default Chat