Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

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