Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
4119 stevensc 1
/* eslint-disable react/prop-types */
3101 stevensc 2
import React 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";
2739 stevensc 9
import { FiMaximize2 } from 'react-icons/fi'
1 www 10
 
11
const notifyAudio = new Audio("/audio/chat.mp3");
12
 
13
const Chat = (props) => {
3101 stevensc 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) => {
3596 stevensc 77
    await axios.post(unseeEntity.url_mark_received)
1 www 78
    if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
79
      setActiveChats([...activeChats, { ...unseeEntity, minimized: false }]);
80
      playNotifyAudio();
81
    } else {
82
      const existingChatId = activeChats.findIndex(
83
        (activeChat) => activeChat.id === unseeEntity.id
84
      );
85
      if (!activeChats[existingChatId].unsee_messages) {
86
        const newActiveChats = [...activeChats];
87
        newActiveChats[existingChatId].unsee_messages = true;
88
        setActiveChats(newActiveChats);
89
        playNotifyAudio(newActiveChats[existingChatId].minimized);
90
      }
91
    }
92
  };
93
 
3122 stevensc 94
  const handleCloseConversation = async (entity) => {
3127 stevensc 95
    const { data } = await axios.post(entity.url_close)
96
    if (!data.success) console.log('Error in entity close')
97
    setActiveChats(activeChats.filter(prevActiveChats => prevActiveChats.id !== entity.id))
3122 stevensc 98
  }
99
 
100
  const handleOpenConversation = async (entity, minimized = false) => {
3129 stevensc 101
    if (activeChats.length < 3 && !activeChats.some((el) => el.id === entity.id)) {
102
      setActiveChats([...activeChats, { ...entity, minimized: minimized }]);
3127 stevensc 103
    }
3129 stevensc 104
    if (activeChats.length >= 3 && !activeChats.some((el) => el.id === entity.id)) {
105
      await handleCloseConversation(activeChats[0])
106
      setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized: minimized }]);
986 stevensc 107
    }
1 www 108
  };
109
 
3122 stevensc 110
  const handleReadConversation = async (entity) => {
111
    try {
112
      const { data } = await axios.post(entity.url_mark_seen)
113
      if (!data.success) console.log('Ha ocurrido un error')
114
      setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
115
        if (entity.id === chat.id) return { ...chat, not_seen_messages: false }
116
        return chat;
117
      }))
118
    } catch (error) {
119
      console.log(`Error: ${error}`)
1 www 120
    }
121
  };
122
 
3123 stevensc 123
  const handleMinimizeConversation = (entity, minimized = null) => {
124
    return setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
3130 stevensc 125
      if (entity.id === chat.id) return { ...chat, minimized: minimized ?? !chat.minimized }
3123 stevensc 126
      return chat
127
    }))
128
  }
1 www 129
 
3119 stevensc 130
  const handleNotSeenMessage = (entity) => {
3111 stevensc 131
    const index = activeChats.findIndex(chat => chat.id === entity.id)
132
 
133
    if (index !== -1) {
134
      setActiveChats(prev => [...prev].map(chat => {
135
        if (chat.id === entity.id) {
136
          return {
137
            ...chat,
138
            not_seen_messages: entity.not_seen_messages
139
          }
140
        }
141
        return chat;
142
      }))
143
    }
3119 stevensc 144
 
145
  }
146
 
1 www 147
  const playNotifyAudio = (minimized = true) => {
148
    if (!isMuted && minimized) {
149
      notifyAudio.play();
150
    }
151
  };
152
 
153
  const handleMute = () => {
154
    setIsMuted(!isMuted);
155
    if (isMuted) {
156
      notifyAudio.play();
157
    }
158
  };
159
 
160
  const handleChangeTab = (tab) => {
161
    setActiveTab(tab);
162
  };
163
 
164
  useEffect(() => {
2548 stevensc 165
    if (!loading) {
2973 stevensc 166
      const fetchData = async () => {
2966 stevensc 167
        setLoading(true)
2973 stevensc 168
        const entities = await heartBeat() || [];
2966 stevensc 169
        setLoading(false)
2973 stevensc 170
 
171
        return entities
2966 stevensc 172
      }
173
 
2989 stevensc 174
      setTimeout(() => {
175
        fetchData()
176
      }, "2000")
691 steven 177
    }
2965 stevensc 178
  }, [loading]);
978 stevensc 179
 
1 www 180
  useEffect(() => {
181
    emojione.imageType = "png";
182
    emojione.sprites = false;
183
    emojione.ascii = true;
184
    emojione.imagePathPNG = props.emojiOnePath;
185
  }, []);
186
 
2069 steven 187
  return (window.innerWidth > 1000 && window.location.pathname !== '/chat') ? (
1 www 188
    <React.Fragment>
189
      <div id="drupalchat-wrapper">
190
        <div id="drupalchat">
191
          <div className="item-list" id="chatbox_chatlist">
192
            <ul id="mainpanel">
193
              <li id="chatpanel" className="first last">
2550 stevensc 194
                <div className="subpanel">
1 www 195
                  <div
196
                    className="subpanel_title"
2554 stevensc 197
                    onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}
1 www 198
                  >
2554 stevensc 199
                    <a
200
                      href="/chat"
3596 stevensc 201
                      className="text-chat-title"
1 www 202
                    >
2554 stevensc 203
                      Chat
2739 stevensc 204
                      <FiMaximize2 className="ml-3" />
2554 stevensc 205
                    </a>
206
                    <div className="subpanel_title-icons">
2555 stevensc 207
                      <i
208
                        className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"} text-20`}
209
                        onClick={handleMute}
210
                      />
211
                      <i
212
                        className={`fa ${isChatOpen ? "fa-angle-down" : "fa-angle-up"} text-20`}
213
                        onClick={() => setIsChatOpen(!isChatOpen)}
214
                      />
1 www 215
                    </div>
216
                  </div>
217
                  <div
218
                    id="showhidechatlist"
2551 stevensc 219
                    style={{ display: isChatOpen ? "grid" : "none" }}
1 www 220
                  >
3595 stevensc 221
                    <div className="drupalchat_search_main chatboxinput">
2561 stevensc 222
                      <input
223
                        className="drupalchat_searchinput live-search-box"
224
                        id="live-search-box"
225
                        type="text"
226
                        name='search'
227
                        value={search}
228
                        onChange={e => setSearch(e.target.value || '')}
229
                      />
230
                      <i className="searchbutton fas fa-search" />
1 www 231
                    </div>
3595 stevensc 232
                    <div className="drupalchat_search_main chatboxinput">
2548 stevensc 233
                      <button
2549 stevensc 234
                        className={`${activeTab === 'user' ? 'active' : ''}`}
2548 stevensc 235
                        onClick={() => handleChangeTab("user")}
1 www 236
                      >
2548 stevensc 237
                        Contactos
238
                      </button>
239
                      <button
2549 stevensc 240
                        className={`${activeTab === 'group' ? 'active' : ''}`}
2548 stevensc 241
                        onClick={() => handleChangeTab("group")}
1 www 242
                      >
2548 stevensc 243
                        Grupos
244
                      </button>
1 www 245
                    </div>
246
                    <div
247
                      className="contact-list chatboxcontent"
3596 stevensc 248
                      style={{ display: activeTab === "user" ? "block" : "none", }}
1 www 249
                    >
250
                      <Contacts
976 stevensc 251
                        contacts={filtredContacts}
1 www 252
                        onOpenConversation={handleOpenConversation}
253
                      />
3058 stevensc 254
                    </div>
1 www 255
                    <div
256
                      className="group-list chatboxcontent"
3596 stevensc 257
                      style={{ display: activeTab === "group" ? "block" : "none", }}
1 www 258
                    >
259
                      <ul id="group-list-ul" className="live-search-list-group">
260
                        <Groups
988 stevensc 261
                          groups={filtredGroups}
1 www 262
                          onOpenConversation={handleOpenConversation}
263
                        />
264
                      </ul>
265
                    </div>
266
                    <div
267
                      className="group-contacts-list chatboxcontent"
268
                      style={{ display: "none" }}
269
                    >
270
                      <div style={{ textAlign: "center", fontSize: "13px" }}>
271
                        Integrantes del grupo
272
                      </div>
273
                      <ul
274
                        id="contact-group-list-ul"
275
                        className="live-search-list"
276
                      ></ul>
277
                    </div>
278
                  </div>
279
                </div>
280
              </li>
281
            </ul>
282
          </div>
283
        </div>
284
      </div>
3133 stevensc 285
      <div className="active_chats-list">
1 www 286
        {activeChats.map((entity, index) => (
287
          <PersonalChat
3131 stevensc 288
            index={index}
1 www 289
            key={entity.id}
290
            entity={entity}
3106 stevensc 291
            not_seen_messages={entity.not_seen_messages}
3131 stevensc 292
            minimized={entity.minimized}
3122 stevensc 293
            onClose={handleCloseConversation}
3123 stevensc 294
            onMinimize={handleMinimizeConversation}
3122 stevensc 295
            onRead={handleReadConversation}
4119 stevensc 296
            timezones={props.timezones}
1 www 297
          />
298
        ))}
299
      </div>
1335 stevensc 300
      <NotificationAlert />
1 www 301
    </React.Fragment>
302
  ) : (
303
    ""
304
  );
305
};
306
 
307
export default Chat;