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