Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3101 stevensc 1
import React from "react";
1 www 2
import { useState, useEffect } from "react";
976 stevensc 3
import { axios } from "../../utils";
1 www 4
import Contacts from "./contacts/Contacts";
1335 stevensc 5
import NotificationAlert from "../../shared/notification/NotificationAlert";
1 www 6
import Groups from "./groups/Groups";
7
import PersonalChat from "./personal-chat/PersonalChat";
2739 stevensc 8
import { FiMaximize2 } from 'react-icons/fi'
1 www 9
 
10
const notifyAudio = new Audio("/audio/chat.mp3");
11
 
12
const Chat = (props) => {
3101 stevensc 13
 
1 www 14
  // states
15
  const [contacts, setContacts] = useState([]);
16
  const [groups, setGroups] = useState([]);
17
  const [activeChats, setActiveChats] = useState([]);
18
  const [isChatOpen, setIsChatOpen] = useState(false);
19
  const [isMuted, setIsMuted] = useState(false);
20
  const [activeTab, setActiveTab] = useState("user");
976 stevensc 21
  const [search, setSearch] = useState('');
1775 stevensc 22
  const [loading, setLoading] = useState(false);
976 stevensc 23
 
994 stevensc 24
  const filtredContacts = contacts.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
25
  const filtredGroups = groups.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
976 stevensc 26
 
27
  const handleEntities = entities => {
687 steven 28
    let newUserContacts = [];
29
    let newGroups = [];
30
    entities.map((entity) => {
3111 stevensc 31
      if (entity.not_received_messages) handleNewMessage(entity)
32
      if (entity.not_seen_messages) handleNotSeenMessage(entity)
3119 stevensc 33
      if (entity.is_open) handleOpenConversation(entity, false);
687 steven 34
      switch (entity.type) {
35
        case "user":
36
          newUserContacts = [...newUserContacts, entity];
37
          handleUpdateOnline(entity);
38
          break;
39
        case "group":
40
          newGroups = [...newGroups, entity];
41
          break;
42
        default:
43
          break;
44
      }
45
    });
46
    setContacts(newUserContacts);
47
    setGroups(newGroups);
48
  }
2790 stevensc 49
 
687 steven 50
  const heartBeat = async () => {
689 steven 51
    try {
3119 stevensc 52
      const { data } = await axios.get("/chat/heart-beat")
53
      if (data.success) {
54
        handleEntities(data.data)
1 www 55
      }
3119 stevensc 56
      return data.data;
689 steven 57
    } catch (error) {
976 stevensc 58
      console.log('>>: chat error > ', error)
689 steven 59
    }
687 steven 60
  };
1 www 61
 
62
  const handleUpdateOnline = (entity) => {
63
    const existingChatId = activeChats.findIndex(
64
      (activeChat) => activeChat.id === entity.id
65
    );
66
    if (existingChatId >= 0) {
67
      if (activeChats[existingChatId].online !== entity.online) {
68
        const newActiveChats = [...activeChats];
69
        newActiveChats[existingChatId].online = entity.online;
70
        setActiveChats(newActiveChats);
71
      }
72
    }
73
  };
74
 
75
  const handleNewMessage = async (unseeEntity) => {
76
    await axios.post(unseeEntity.url_mark_received).then((response) => {
976 stevensc 77
      ('')
1 www 78
    });
79
    if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
80
      setActiveChats([...activeChats, { ...unseeEntity, minimized: false }]);
81
      playNotifyAudio();
82
    } else {
83
      const existingChatId = activeChats.findIndex(
84
        (activeChat) => activeChat.id === unseeEntity.id
85
      );
86
      if (!activeChats[existingChatId].unsee_messages) {
87
        const newActiveChats = [...activeChats];
88
        newActiveChats[existingChatId].unsee_messages = true;
89
        setActiveChats(newActiveChats);
90
        playNotifyAudio(newActiveChats[existingChatId].minimized);
91
      }
92
    }
93
  };
94
 
3122 stevensc 95
  const handleCloseConversation = async (entity) => {
96
    try {
97
      const { data } = await axios.post(entity.url_close)
98
      if (!data.success) console.log('Error in entity close')
3123 stevensc 99
      setActiveChats(activeChats.filter(prevActiveChats => prevActiveChats.id !== entity.id))
100
      return true
3122 stevensc 101
    } catch (error) {
102
      console.log(error)
1 www 103
    }
3122 stevensc 104
  }
105
 
106
  const handleOpenConversation = async (entity, minimized = false) => {
107
    if (activeChats.length >= 3) {
3123 stevensc 108
      const closeComplete = handleCloseConversation(activeChats[0]).then((result)=> result)
109
      !closeComplete && false
986 stevensc 110
    }
3122 stevensc 111
    try {
112
      const { data } = await axios.post(entity.url_open)
113
      if (!data.success) console.log('Error in open conversation')
3123 stevensc 114
      const notRepeatActiveChats = new Set([...activeChats, { ...entity, minimized: minimized }])
115
      setActiveChats(notRepeatActiveChats)
116
      return true
3122 stevensc 117
    } catch (error) {
118
      console.log(error)
119
    }
1 www 120
  };
121
 
3122 stevensc 122
  const handleReadConversation = async (entity) => {
123
    try {
124
      const { data } = await axios.post(entity.url_mark_seen)
125
      if (!data.success) console.log('Ha ocurrido un error')
126
      setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
127
        if (entity.id === chat.id) return { ...chat, not_seen_messages: false }
128
        return chat;
129
      }))
130
    } catch (error) {
131
      console.log(`Error: ${error}`)
1 www 132
    }
133
  };
134
 
3123 stevensc 135
  const handleMinimizeConversation = (entity, minimized = null) => {
136
    return setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
137
      if (entity.id === chat.id) return { ...chat, minimized: minimized ?? !entity.minimized }
138
      return chat
139
    }))
140
  }
1 www 141
 
3119 stevensc 142
  const handleNotSeenMessage = (entity) => {
3111 stevensc 143
    const index = activeChats.findIndex(chat => chat.id === entity.id)
144
 
145
    if (index !== -1) {
146
      setActiveChats(prev => [...prev].map(chat => {
147
        if (chat.id === entity.id) {
148
          return {
149
            ...chat,
150
            not_seen_messages: entity.not_seen_messages
151
          }
152
        }
153
        return chat;
154
      }))
155
    }
3119 stevensc 156
 
157
  }
158
 
1 www 159
  const playNotifyAudio = (minimized = true) => {
160
    if (!isMuted && minimized) {
161
      notifyAudio.play();
162
    }
163
  };
164
 
165
  const handleMute = () => {
166
    setIsMuted(!isMuted);
167
    if (isMuted) {
168
      notifyAudio.play();
169
    }
170
  };
171
 
172
  const handleChangeTab = (tab) => {
173
    setActiveTab(tab);
174
  };
175
 
176
  useEffect(() => {
2548 stevensc 177
    if (!loading) {
2973 stevensc 178
      const fetchData = async () => {
2966 stevensc 179
        setLoading(true)
2973 stevensc 180
        const entities = await heartBeat() || [];
2966 stevensc 181
        setLoading(false)
2973 stevensc 182
 
183
        return entities
2966 stevensc 184
      }
185
 
2989 stevensc 186
      setTimeout(() => {
187
        fetchData()
188
      }, "2000")
691 steven 189
    }
2965 stevensc 190
  }, [loading]);
978 stevensc 191
 
1 www 192
  useEffect(() => {
193
    emojione.imageType = "png";
194
    emojione.sprites = false;
195
    emojione.ascii = true;
196
    emojione.imagePathPNG = props.emojiOnePath;
197
  }, []);
198
 
2069 steven 199
  return (window.innerWidth > 1000 && window.location.pathname !== '/chat') ? (
1 www 200
    <React.Fragment>
201
      <div id="drupalchat-wrapper">
202
        <div id="drupalchat">
203
          <div className="item-list" id="chatbox_chatlist">
204
            <ul id="mainpanel">
205
              <li id="chatpanel" className="first last">
2550 stevensc 206
                <div className="subpanel">
1 www 207
                  <div
208
                    className="subpanel_title"
2554 stevensc 209
                    onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}
1 www 210
                  >
2554 stevensc 211
                    <a
212
                      href="/chat"
213
                      className="text-gray text-chat-title"
1 www 214
                    >
2554 stevensc 215
                      Chat
2739 stevensc 216
                      <FiMaximize2 className="ml-3" />
2554 stevensc 217
                    </a>
218
                    <div className="subpanel_title-icons">
2555 stevensc 219
                      <i
220
                        className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"} text-20`}
221
                        onClick={handleMute}
222
                      />
223
                      <i
224
                        className={`fa ${isChatOpen ? "fa-angle-down" : "fa-angle-up"} text-20`}
225
                        onClick={() => setIsChatOpen(!isChatOpen)}
226
                      />
1 www 227
                    </div>
228
                  </div>
229
                  <div
230
                    id="showhidechatlist"
2551 stevensc 231
                    style={{ display: isChatOpen ? "grid" : "none" }}
1 www 232
                  >
233
                    <div
234
                      className="drupalchat_search_main chatboxinput"
235
                      style={{ background: "#f9f9f9" }}
236
                    >
2561 stevensc 237
                      <input
238
                        className="drupalchat_searchinput live-search-box"
239
                        id="live-search-box"
240
                        type="text"
241
                        name='search'
242
                        value={search}
243
                        onChange={e => setSearch(e.target.value || '')}
244
                      />
245
                      <i className="searchbutton fas fa-search" />
1 www 246
                    </div>
247
                    <div
248
                      className="drupalchat_search_main chatboxinput"
249
                      style={{ background: "#f9f9f9" }}
250
                    >
2548 stevensc 251
                      <button
2549 stevensc 252
                        className={`${activeTab === 'user' ? 'active' : ''}`}
2548 stevensc 253
                        onClick={() => handleChangeTab("user")}
1 www 254
                      >
2548 stevensc 255
                        Contactos
256
                      </button>
257
                      <button
2549 stevensc 258
                        className={`${activeTab === 'group' ? 'active' : ''}`}
2548 stevensc 259
                        onClick={() => handleChangeTab("group")}
1 www 260
                      >
2548 stevensc 261
                        Grupos
262
                      </button>
1 www 263
                    </div>
264
                    <div
265
                      className="contact-list chatboxcontent"
266
                      style={{
267
                        display: activeTab === "user" ? "block" : "none",
268
                      }}
269
                    >
270
                      <Contacts
976 stevensc 271
                        contacts={filtredContacts}
1 www 272
                        onOpenConversation={handleOpenConversation}
273
                      />
3058 stevensc 274
                    </div>
1 www 275
                    <div
276
                      className="group-list chatboxcontent"
277
                      style={{
278
                        display: activeTab === "group" ? "block" : "none",
279
                      }}
280
                    >
281
                      <ul id="group-list-ul" className="live-search-list-group">
282
                        <Groups
988 stevensc 283
                          groups={filtredGroups}
1 www 284
                          onOpenConversation={handleOpenConversation}
285
                        />
286
                      </ul>
287
                    </div>
288
                    <div
289
                      className="group-contacts-list chatboxcontent"
290
                      style={{ display: "none" }}
291
                    >
292
                      <div style={{ textAlign: "center", fontSize: "13px" }}>
293
                        Integrantes del grupo
294
                      </div>
295
                      <ul
296
                        id="contact-group-list-ul"
297
                        className="live-search-list"
298
                      ></ul>
299
                    </div>
300
                  </div>
301
                </div>
302
              </li>
303
            </ul>
304
          </div>
305
        </div>
306
      </div>
307
      <div style={{ display: "flex" }}>
308
        {activeChats.map((entity, index) => (
309
          <PersonalChat
310
            key={entity.id}
311
            entity={entity}
3106 stevensc 312
            not_seen_messages={entity.not_seen_messages}
1 www 313
            index={index}
3122 stevensc 314
            onClose={handleCloseConversation}
3123 stevensc 315
            onMinimize={handleMinimizeConversation}
3122 stevensc 316
            onRead={handleReadConversation}
3120 stevensc 317
            loading={loading}
1 www 318
          />
319
        ))}
320
      </div>
1335 stevensc 321
      <NotificationAlert />
1 www 322
    </React.Fragment>
323
  ) : (
324
    ""
325
  );
326
};
327
 
328
export default Chat;