Proyectos de Subversion LeadersLinked - Backend

Rev

| Ultima modificación | Ver Log |

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