Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 14150 | Autoría | Ultima modificación | Ver Log |

import { async } from 'postcss-js'
import React, { useCallback } from 'react'
import { useState, useEffect } from 'react'
import { axios } from '../../utils'
import Contacts from './contacts/Contacts'
import NotificationAlert from '../../shared/notification/NotificationAlert'
import Groups from './groups/Groups'
import PersonalChat from './personal-chat/PersonalChat'

const notifyAudio = new Audio('/audio/chat.mp3')

const Chat = (props) => {
        // states
        const [fullChats, setFullChats] = useState([])
        const [contacts, setContacts] = useState([])
        const [groups, setGroups] = useState([])
        const [activeChats, setActiveChats] = useState([])
        const [isChatOpen, setIsChatOpen] = useState(false)
        const [isMuted, setIsMuted] = useState(false)
        const [activeTab, setActiveTab] = useState('user')
        const defaultChatInterval = 1500
        const [chatInterval, setChatInterval] = useState(defaultChatInterval)
        const [search, setSearch] = useState('')
        const [loading, setLoading] = useState(false)

        const filtredContacts = contacts.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))
        const filtredGroups = groups.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase()))

        // Time intervals
        let heartBeatInterval
        const handleEntities = entities => {
                setFullChats([...entities])
                let newUserContacts = []
                let newGroups = []
                entities.map((entity) => {
                        if (entity.is_open) {
                                handleOpenConversation(entity, true)
                        }
                        if (entity.not_received_messages) {
                                handleNewMessage(entity)
                        }
                        switch (entity.type) {
                        case 'user':
                                newUserContacts = [...newUserContacts, entity]
                                handleUpdateOnline(entity)
                                break
                        case 'group':
                                newGroups = [...newGroups, entity]
                                break
                        default:
                                break
                        }
                })
                setContacts(newUserContacts)
                setGroups(newGroups)
        }
        const heartBeat = async () => {
                try {
                        const res = await axios.get('/chat/heart-beat')
                        let entities = []
                        const resData = res.data
                        if (resData.success) {
                                entities = resData.data
                                handleEntities(entities)
                        }
                        return entities
                } catch (error) {
                        console.log('>>: chat error > ', error)
                }
        }



        const handleUpdateOnline = (entity) => {
                const existingChatId = activeChats.findIndex(
                        (activeChat) => activeChat.id === entity.id
                )
                if (existingChatId >= 0) {
                        if (activeChats[existingChatId].online !== entity.online) {
                                const newActiveChats = [...activeChats]
                                newActiveChats[existingChatId].online = entity.online
                                setActiveChats(newActiveChats)
                        }
                }
        }

        const handleNewMessage = async (unseeEntity) => {
                await axios.post(unseeEntity.url_mark_received).then((response) => {
                        ('')
                })
                if (!activeChats.some((activeChat) => activeChat.id === unseeEntity.id)) {
                        setActiveChats([...activeChats, { ...unseeEntity, minimized: false }])
                        playNotifyAudio()
                } else {
                        const existingChatId = activeChats.findIndex(
                                (activeChat) => activeChat.id === unseeEntity.id
                        )
                        if (!activeChats[existingChatId].unsee_messages) {
                                const newActiveChats = [...activeChats]
                                newActiveChats[existingChatId].unsee_messages = true
                                setActiveChats(newActiveChats)
                                playNotifyAudio(newActiveChats[existingChatId].minimized)
                        }
                }
        }

        const handleOpenConversation = (entity, minimized = false) => {
                if (activeChats.length < 3 && !activeChats.some((el) => el.id === entity.id)) {
                        setActiveChats([...activeChats, { ...entity, minimized: minimized }])
                }
                if (activeChats.length >= 3 && !activeChats.some((el) => el.id === entity.id)) {
                        activeChats.map((el, index) => {
                                if (index === 0) {
                                        axios.post(el.url_close)
                                }
                        })
                        const newActiveChats = activeChats.filter((el, index) => index !== 0)
                        setActiveChats([...newActiveChats, { ...entity, minimized: minimized }])
                }
        }

        const handleReadChat = (index) => {
                if (activeChats[index].unsee_messages) {
                        const newActiveChats = [...activeChats]
                        newActiveChats[index].unsee_messages = false
                        setActiveChats(newActiveChats)
                }
        }

        const handleMinimizeChat = (chatIndex, minimize) => {
                const newActiveChats = [...activeChats]
                switch (minimize) {
                case false:
                        newActiveChats[chatIndex].minimized = false
                        break
                default:
                        newActiveChats[chatIndex].minimized =
          !newActiveChats[chatIndex].minimized
                        break
                }
                setActiveChats(newActiveChats)
        }

        const handleCloseChat = (entityId, url_close) => {
                let newActiveChats = []
                setLoading(true)
                axios.post(url_close).then((response) => {
                        const resData = response.data
                })
                newActiveChats = activeChats.filter(
                        (activeChat) => activeChat.id !== entityId
                )
                setActiveChats(newActiveChats)
                setLoading(false)
        }

        const playNotifyAudio = (minimized = true) => {
                if (!isMuted && minimized) {
                        notifyAudio.play()
                }
        }

        const handleMute = () => {
                setIsMuted(!isMuted)
                if (isMuted) {
                        notifyAudio.play()
                }
        }

        const handleChangeTab = (tab) => {
                setActiveTab(tab)
        }

        useEffect(() => {
                if (!loading) {
                        let entities = []
                        clearInterval(heartBeatInterval)
                        heartBeatInterval = setInterval(async () => {
                                entities = await heartBeat() || []
                        }, chatInterval)
                        if ((entities === fullChats) && (chatInterval !== defaultChatInterval * 2)) {
                                clearInterval(heartBeatInterval)
                                setChatInterval(defaultChatInterval * 2)
                        }
                }
                return () => {
                        clearInterval(heartBeatInterval)
                }
        }, [chatInterval, fullChats])

        useEffect(() => {
                emojione.imageType = 'png'
                emojione.sprites = false
                emojione.ascii = true
                emojione.imagePathPNG = props.emojiOnePath
        }, [])

        return window.innerWidth > 1000 ? (
                <React.Fragment>
                        <div id="drupalchat-wrapper">
                                <div id="drupalchat">
                                        <div className="item-list" id="chatbox_chatlist">
                                                <ul id="mainpanel">
                                                        <li id="chatpanel" className="first last">
                                                                <div className="subpanel" style={{ display: 'block' }}>
                                                                        <div
                                                                                className="subpanel_title"
                                                                                onClick={(e) => {
                                                                                        if (e.currentTarget === e.target)
                                                                                                setIsChatOpen(!isChatOpen)
                                                                                }}
                                                                        >
                                                                                <div
                                                                                        style={{ width: '89%', height: '100%' }}
                                                                                        id="minmaxchatlist"
                                                                                        onClick={() => {
                                                                                                setIsChatOpen(!isChatOpen)
                                                                                        }}
                                                                                >
                                                                                        <a
                                                                                                href="/chat"
                                                                                                className="text-white"
                                                                                        >
                        Chat
                                                                                        </a>
                                                                                </div>
                                                                                <span
                                                                                        className="min localhost-icon-minus-1"
                                                                                        id="mute-sound"
                                                                                >
                                                                                        <i
                                                                                                className={`icon ${isMuted ? 'icon-volume-off' : 'icon-volume-2'
                                                                                                } text-20`}
                                                                                                aria-hidden="true"
                                                                                                onClick={handleMute}
                                                                                        ></i>
                                                                                </span>
                                                                                {/* <span
                      className="min localhost-icon-minus-1"
                      id="new-chat-group"
                      style={{ marginRight: "5%" }}
                      title="Crear grupo"
                    >
                      <i className="fa fa-edit"></i>
                    </span> */}
                                                                        </div>
                                                                        <div
                                                                                id="showhidechatlist"
                                                                                style={{ display: isChatOpen ? 'block' : 'none' }}
                                                                        >
                                                                                <div
                                                                                        className="drupalchat_search_main chatboxinput"
                                                                                        style={{ background: '#f9f9f9' }}
                                                                                >
                                                                                        <div
                                                                                                className="drupalchat_search"
                                                                                                style={{ height: 'auto' }}
                                                                                        >
                                                                                                <input
                                                                                                        className="drupalchat_searchinput live-search-box"
                                                                                                        id="live-search-box"
                                                                                                        placeholder="Buscar"
                                                                                                        size="24"
                                                                                                        type="text"
                                                                                                        name='search'
                                                                                                        value={search}
                                                                                                        onChange={e => {
                                                                                                                setSearch(e.target.value || '')
                                                                                                        }}
                                                                                                />
                                                                                                <button
                                                                                                        className="searchbutton"
                                                                                                        id="searchbutton"
                                                                                                        title=""
                                                                                                        style={{
                                                                                                                height: '30px',
                                                                                                                border: 'none',
                                                                                                                margin: '0px',
                                                                                                                paddingRight: '13px',
                                                                                                                verticalAlign: 'middle',
                                                                                                        }}
                                                                                                        type="submit"
                                                                                                ></button>
                                                                                                <div
                                                                                                        id="search_result"
                                                                                                        style={{
                                                                                                                textAlign: 'center',
                                                                                                                fontSize: '11px',
                                                                                                                display: 'none',
                                                                                                        }}
                                                                                                >
                          Sin resultados
                                                                                                </div>
                                                                                        </div>
                                                                                </div>
                                                                                <div
                                                                                        className="drupalchat_search_main chatboxinput"
                                                                                        style={{ background: '#f9f9f9' }}
                                                                                >
                                                                                        <div
                                                                                                style={{
                                                                                                        width: '50%',
                                                                                                        float: 'left',
                                                                                                        display: 'inline-block',
                                                                                                        padding: '5px',
                                                                                                        textAlign: 'center',
                                                                                                        fontSize: '14px',
                                                                                                }}
                                                                                        >
                                                                                                <a
                                                                                                        href="#"
                                                                                                        className="blue-color chat-contacts"
                                                                                                        onClick={(e) => {
                                                                                                                e.preventDefault()
                                                                                                                handleChangeTab('user')
                                                                                                        }}
                                                                                                >
                          Contactos
                                                                                                </a>
                                                                                        </div>
                                                                                        <div
                                                                                                style={{
                                                                                                        width: '50%',
                                                                                                        display: 'inline-block',
                                                                                                        padding: '5px',
                                                                                                        textAlign: 'center',
                                                                                                        fontSize: '14px',
                                                                                                }}
                                                                                        >
                                                                                                <a
                                                                                                        href="#"
                                                                                                        className="chat-groups"
                                                                                                        onClick={(e) => {
                                                                                                                e.preventDefault()
                                                                                                                handleChangeTab('group')
                                                                                                        }}
                                                                                                >
                          Grupos
                                                                                                </a>
                                                                                        </div>
                                                                                </div>
                                                                                <div
                                                                                        className="contact-list chatboxcontent"
                                                                                        style={{
                                                                                                display: activeTab === 'user' ? 'block' : 'none',
                                                                                        }}
                                                                                >
                                                                                        <Contacts
                                                                                                contacts={filtredContacts}
                                                                                                onOpenConversation={handleOpenConversation}
                                                                                        />
                                                                                </div>
                                                                                <div
                                                                                        className="group-list chatboxcontent"
                                                                                        style={{
                                                                                                display: activeTab === 'group' ? 'block' : 'none',
                                                                                        }}
                                                                                >
                                                                                        <ul id="group-list-ul" className="live-search-list-group">
                                                                                                <Groups
                                                                                                        groups={filtredGroups}
                                                                                                        onOpenConversation={handleOpenConversation}
                                                                                                />
                                                                                        </ul>
                                                                                </div>
                                                                                <div
                                                                                        className="group-contacts-list chatboxcontent"
                                                                                        style={{ display: 'none' }}
                                                                                >
                                                                                        <div style={{ textAlign: 'center', fontSize: '13px' }}>
                        Integrantes del grupo
                                                                                        </div>
                                                                                        <ul
                                                                                                id="contact-group-list-ul"
                                                                                                className="live-search-list"
                                                                                        ></ul>
                                                                                </div>
                                                                        </div>
                                                                </div>
                                                        </li>
                                                </ul>
                                        </div>
                                </div>
                        </div>
                        <div className="personal_chat-container">
                                {activeChats.map((entity, index) => (
                                        <PersonalChat
                                                key={entity.id}
                                                entity={entity}
                                                index={index}
                                                onClose={handleCloseChat}
                                                onMinimize={handleMinimizeChat}
                                                onRead={handleReadChat}
                                        />
                                ))}
                        </div>
                        <NotificationAlert />
                </React.Fragment>
        ) : (
                ''
        )
}

export default Chat