Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

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