Proyectos de Subversion LeadersLinked - Backend

Rev

| Ultima modificación | Ver Log |

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