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