Proyectos de Subversion LeadersLinked - Backend

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
11350 nelberth 1
import { async } from "postcss-js";
2
import React, { useCallback } from "react";
3
import { useState, useEffect } from "react";
4
import { axios } from "../../utils";
5
import Contacts from "./contacts/Contacts";
6
import NotificationAlert from "../../shared/notification/NotificationAlert";
7
import Groups from "./groups/Groups";
8
import PersonalChat from "./personal-chat/PersonalChat";
9
 
10
const notifyAudio = new Audio("/audio/chat.mp3");
11
 
12
const Chat = (props) => {
13
  // states
14
  const [fullChats, setFullChats] = useState([]);
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");
21
  const defaultChatInterval = 1500;
22
  const [chatInterval, setChatInterval] = useState(defaultChatInterval);
23
  const [search, setSearch] = useState('');
24
  const [loading, setLoading] = useState(false);
25
 
26
  const filtredContacts = contacts.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
27
  const filtredGroups = groups.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
28
 
29
  // Time intervals
30
  let heartBeatInterval;
31
  const handleEntities = entities => {
32
    setFullChats([...entities]);
33
    let newUserContacts = [];
34
    let newGroups = [];
35
    entities.map((entity) => {
36
      if (entity.is_open) {
37
        handleOpenConversation(entity, true);
38
      }
39
      if (entity.not_received_messages) {
40
        handleNewMessage(entity);
41
      }
42
      switch (entity.type) {
43
        case "user":
44
          newUserContacts = [...newUserContacts, entity];
45
          handleUpdateOnline(entity);
46
          break;
47
        case "group":
48
          newGroups = [...newGroups, entity];
49
          break;
50
        default:
51
          break;
52
      }
53
    });
54
    setContacts(newUserContacts);
55
    setGroups(newGroups);
56
  }
57
  const heartBeat = async () => {
58
    try {
59
      const res = await axios.get("/chat/heart-beat")
60
      let entities = [];
61
      const resData = res.data;
62
      if (resData.success) {
63
        entities = resData.data;
64
        handleEntities(entities);
65
      }
66
      return entities;
67
    } catch (error) {
68
      console.log('>>: chat error > ', error)
69
    }
70
  };
71
 
72
 
73
 
74
  const handleUpdateOnline = (entity) => {
75
    const existingChatId = activeChats.findIndex(
76
      (activeChat) => activeChat.id === entity.id
77
    );
78
    if (existingChatId >= 0) {
79
      if (activeChats[existingChatId].online !== entity.online) {
80
        const newActiveChats = [...activeChats];
81
        newActiveChats[existingChatId].online = entity.online;
82
        setActiveChats(newActiveChats);
83
      }
84
    }
85
  };
86
 
87
  const handleNewMessage = async (unseeEntity) => {
88
    await axios.post(unseeEntity.url_mark_received).then((response) => {
89
      ('')
90
    });
91
    if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
92
      setActiveChats([...activeChats, { ...unseeEntity, minimized: false }]);
93
      playNotifyAudio();
94
    } else {
95
      const existingChatId = activeChats.findIndex(
96
        (activeChat) => activeChat.id === unseeEntity.id
97
      );
98
      if (!activeChats[existingChatId].unsee_messages) {
99
        const newActiveChats = [...activeChats];
100
        newActiveChats[existingChatId].unsee_messages = true;
101
        setActiveChats(newActiveChats);
102
        playNotifyAudio(newActiveChats[existingChatId].minimized);
103
      }
104
    }
105
  };
106
 
107
  const handleOpenConversation = (entity, minimized = false) => {
108
    if (activeChats.length < 3 && !activeChats.some((el) => el.id === entity.id)) {
109
      setActiveChats([...activeChats, { ...entity, minimized: minimized }]);
110
    }
111
    if (activeChats.length >= 3 && !activeChats.some((el) => el.id === entity.id)) {
112
      activeChats.map((el, index) => {
113
        if (index === 0) {
114
          axios.post(el.url_close)
115
        }
116
      })
117
      const newActiveChats = activeChats.filter((el, index) => index !== 0)
118
      setActiveChats([...newActiveChats, { ...entity, minimized: minimized }]);
119
    }
120
  };
121
 
122
  const handleReadChat = (index) => {
123
    if (activeChats[index].unsee_messages) {
124
      const newActiveChats = [...activeChats];
125
      newActiveChats[index].unsee_messages = false;
126
      setActiveChats(newActiveChats);
127
    }
128
  };
129
 
130
  const handleMinimizeChat = (chatIndex, minimize) => {
131
    const newActiveChats = [...activeChats];
132
    switch (minimize) {
133
      case false:
134
        newActiveChats[chatIndex].minimized = false;
135
        break;
136
      default:
137
        newActiveChats[chatIndex].minimized =
138
          !newActiveChats[chatIndex].minimized;
139
        break;
140
    }
141
    setActiveChats(newActiveChats);
142
  };
143
 
144
  const handleCloseChat = (entityId, url_close) => {
145
    let newActiveChats = [];
146
    setLoading(true)
147
    axios.post(url_close).then((response) => {
148
      const resData = response.data;
149
    });
150
    newActiveChats = activeChats.filter(
151
      (activeChat) => activeChat.id !== entityId
152
      );
153
      setActiveChats(newActiveChats);
154
      setLoading(false)
155
  };
156
 
157
  const playNotifyAudio = (minimized = true) => {
158
    if (!isMuted && minimized) {
159
      notifyAudio.play();
160
    }
161
  };
162
 
163
  const handleMute = () => {
164
    setIsMuted(!isMuted);
165
    if (isMuted) {
166
      notifyAudio.play();
167
    }
168
  };
169
 
170
  const handleChangeTab = (tab) => {
171
    setActiveTab(tab);
172
  };
173
 
174
  useEffect(() => {
175
    if(!loading){
176
      let entities = [];
177
      clearInterval(heartBeatInterval);
178
      heartBeatInterval = setInterval(async () => {
179
        entities = await heartBeat() || [];
180
      }, chatInterval);
181
      if ((entities === fullChats) && (chatInterval !== defaultChatInterval * 2)) {
182
        clearInterval(heartBeatInterval);
183
        setChatInterval(defaultChatInterval * 2);
184
      }
185
    }
186
    return () => {
187
      clearInterval(heartBeatInterval);
188
    };
189
  }, [chatInterval, fullChats]);
190
 
191
  useEffect(() => {
192
    emojione.imageType = "png";
193
    emojione.sprites = false;
194
    emojione.ascii = true;
195
    emojione.imagePathPNG = props.emojiOnePath;
196
  }, []);
197
 
198
  return window.innerWidth > 1000 ? (
199
    <React.Fragment>
200
      <div id="drupalchat-wrapper">
201
        <div id="drupalchat">
202
          <div className="item-list" id="chatbox_chatlist">
203
            <ul id="mainpanel">
204
              <li id="chatpanel" className="first last">
205
                <div className="subpanel" style={{ display: "block" }}>
206
                  <div
207
                    className="subpanel_title"
208
                    onClick={(e) => {
209
                      if (e.currentTarget === e.target)
210
                        setIsChatOpen(!isChatOpen);
211
                    }}
212
                  >
213
                    <div
214
                      style={{ width: "89%", height: "100%" }}
215
                      id="minmaxchatlist"
216
                      onClick={() => {
217
                        setIsChatOpen(!isChatOpen);
218
                      }}
219
                    >
220
                      <a
221
                        href="/chat"
222
                        className="text-white"
223
                      >
224
                        Chat
225
                      </a>
226
                    </div>
227
                    <span
228
                      className="min localhost-icon-minus-1"
229
                      id="mute-sound"
230
                    >
231
                      <i
232
                        className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"
233
                          } text-20`}
234
                        aria-hidden="true"
235
                        onClick={handleMute}
236
                      ></i>
237
                    </span>
238
                    {/* <span
239
                      className="min localhost-icon-minus-1"
240
                      id="new-chat-group"
241
                      style={{ marginRight: "5%" }}
242
                      title="Crear grupo"
243
                    >
244
                      <i className="fa fa-edit"></i>
245
                    </span> */}
246
                  </div>
247
                  <div
248
                    id="showhidechatlist"
249
                    style={{ display: isChatOpen ? "block" : "none" }}
250
                  >
251
                    <div
252
                      className="drupalchat_search_main chatboxinput"
253
                      style={{ background: "#f9f9f9" }}
254
                    >
255
                      <div
256
                        className="drupalchat_search"
257
                        style={{ height: "auto" }}
258
                      >
259
                        <input
260
                          className="drupalchat_searchinput live-search-box"
261
                          id="live-search-box"
262
                          placeholder="Buscar"
263
                          size="24"
264
                          type="text"
265
                          name='search'
266
                          value={search}
267
                          onChange={e => {
268
                            setSearch(e.target.value || '')
269
                          }}
270
                        />
271
                        <button
272
                          className="searchbutton"
273
                          id="searchbutton"
274
                          title=""
275
                          style={{
276
                            height: "30px",
277
                            border: "none",
278
                            margin: "0px",
279
                            paddingRight: "13px",
280
                            verticalAlign: "middle",
281
                          }}
282
                          type="submit"
283
                        ></button>
284
                        <div
285
                          id="search_result"
286
                          style={{
287
                            textAlign: "center",
288
                            fontSize: "11px",
289
                            display: "none",
290
                          }}
291
                        >
292
                          Sin resultados
293
                        </div>
294
                      </div>
295
                    </div>
296
                    <div
297
                      className="drupalchat_search_main chatboxinput"
298
                      style={{ background: "#f9f9f9" }}
299
                    >
300
                      <div
301
                        style={{
302
                          width: "50%",
303
                          float: "left",
304
                          display: "inline-block",
305
                          padding: "5px",
306
                          textAlign: "center",
307
                          fontSize: "14px",
308
                        }}
309
                      >
310
                        <a
311
                          href="#"
312
                          className="blue-color chat-contacts"
313
                          onClick={(e) => {
314
                            e.preventDefault();
315
                            handleChangeTab("user");
316
                          }}
317
                        >
318
                          Contactos
319
                        </a>
320
                      </div>
321
                      <div
322
                        style={{
323
                          width: "50%",
324
                          display: "inline-block",
325
                          padding: "5px",
326
                          textAlign: "center",
327
                          fontSize: "14px",
328
                        }}
329
                      >
330
                        <a
331
                          href="#"
332
                          className="chat-groups"
333
                          onClick={(e) => {
334
                            e.preventDefault();
335
                            handleChangeTab("group");
336
                          }}
337
                        >
338
                          Grupos
339
                        </a>
340
                      </div>
341
                    </div>
342
                    <div
343
                      className="contact-list chatboxcontent"
344
                      style={{
345
                        display: activeTab === "user" ? "block" : "none",
346
                      }}
347
                    >
348
                      <Contacts
349
                        contacts={filtredContacts}
350
                        onOpenConversation={handleOpenConversation}
351
                      />
352
                    </div>
353
                    <div
354
                      className="group-list chatboxcontent"
355
                      style={{
356
                        display: activeTab === "group" ? "block" : "none",
357
                      }}
358
                    >
359
                      <ul id="group-list-ul" className="live-search-list-group">
360
                        <Groups
361
                          groups={filtredGroups}
362
                          onOpenConversation={handleOpenConversation}
363
                        />
364
                      </ul>
365
                    </div>
366
                    <div
367
                      className="group-contacts-list chatboxcontent"
368
                      style={{ display: "none" }}
369
                    >
370
                      <div style={{ textAlign: "center", fontSize: "13px" }}>
371
                        Integrantes del grupo
372
                      </div>
373
                      <ul
374
                        id="contact-group-list-ul"
375
                        className="live-search-list"
376
                      ></ul>
377
                    </div>
378
                  </div>
379
                </div>
380
              </li>
381
            </ul>
382
          </div>
383
        </div>
384
      </div>
385
      <div style={{ display: "flex" }}>
386
        {activeChats.map((entity, index) => (
387
          <PersonalChat
388
            key={entity.id}
389
            entity={entity}
390
            index={index}
391
            onClose={handleCloseChat}
392
            onMinimize={handleMinimizeChat}
393
            onRead={handleReadChat}
394
          />
395
        ))}
396
      </div>
397
      <NotificationAlert />
398
    </React.Fragment>
399
  ) : (
400
    ""
401
  );
402
};
403
 
404
export default Chat;