Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

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