Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

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