Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5064 | Rev 5206 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

/* eslint-disable react/prop-types */
import React from "react"
import { useState, useEffect } from "react"
import { axios } from "../../utils"
import { FiMaximize2 } from 'react-icons/fi'
import AddIcon from '@mui/icons-material/Add'

// Components
import NotificationAlert from "../../shared/notification/NotificationAlert"
import PersonalChat from "./personal-chat/PersonalChat"
import ContactsModal from "./components/ContactsModal"
import ContactsFilters from "./components/contactsFilters"

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

const Chat = ({ defaultNetwork, emojiOnePath, timezones }) => {
  const [contacts, setContacts] = useState([])
  const [activeChats, setActiveChats] = useState([])

  const [isChatOpen, setIsChatOpen] = useState(false)
  const [isMuted, setIsMuted] = useState(false)
  const [showModal, setShowModal] = useState(false)
  const [loading, setLoading] = useState(false)

  const [pendingConversation, setPendingConversation] = useState('')

  const handleEntities = entities => {
    entities.map((entity) => {
      if (entity.not_received_messages) handleNewMessage(entity)
      if (entity.not_seen_messages) handleNotSeenMessage(entity)
      if (entity.is_open) handleOpenConversation(entity, false)
      if (entity.type === 'user') handleUpdateOnline(entity)
    })
    setContacts(entities)
  }

  const heartBeat = async () => {
    try {
      const { data } = await axios.get("/chat/heart-beat")
      if (data.success) handleEntities(data.data)
      return data.data
    } 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)
    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 handleCloseConversation = async (entity) => {
    const { data } = await axios.post(entity.url_close)
    if (!data.success) console.log('Error in entity close')
    setActiveChats(activeChats.filter(prevActiveChats => prevActiveChats.id !== entity.id))
  }

  const handleOpenConversation = async (entity, minimized = false) => {
    if (activeChats.some(el => el.id === entity.id)) {
      return null
    }

    if (activeChats.length >= 3) {
      await handleCloseConversation(activeChats[0])
      setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized: minimized }])
      return
    }

    setActiveChats(prevActiveChats => [...prevActiveChats, { ...entity, minimized: minimized }])
  }

  const handleReadConversation = async (entity) => {
    try {
      const { data } = await axios.post(entity.url_mark_seen)
      if (!data.success) console.log('Ha ocurrido un error')
      setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
        if (entity.id === chat.id) return { ...chat, not_seen_messages: false }
        return chat
      }))
    } catch (error) {
      console.log(`Error: ${error}`)
    }
  }

  const handleMinimizeConversation = (entity, minimized = null) => {
    return setActiveChats(prevActiveChats => [...prevActiveChats].map(chat => {
      if (entity.id === chat.id) return { ...chat, minimized: minimized ?? !chat.minimized }
      return chat
    }))
  }

  const handleNotSeenMessage = (entity) => {
    const index = activeChats.findIndex(chat => chat.id === entity.id)

    if (index !== -1) {
      setActiveChats(prev => [...prev].map(chat => {
        if (chat.id === entity.id) {
          return {
            ...chat,
            not_seen_messages: entity.not_seen_messages
          }
        }
        return chat
      }))
    }

  }

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

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

  useEffect(() => {
    if (!loading) {
      const fetchData = async () => {
        setLoading(true)
        const entities = await heartBeat() || []
        setLoading(false)

        return entities
      }

      setTimeout(() => {
        fetchData()
      }, "2000")
    }
  }, [loading])

  useEffect(() => {
    if (pendingConversation) {
      const pendingChat = contacts.find(contact => contact.url_send === pendingConversation)

      if (pendingChat) {
        handleOpenConversation(pendingChat)
        setPendingConversation('')
      }

    }
  }, [pendingConversation, contacts])

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

  if (window.innerWidth < 1000 || window.location.pathname === '/chat') return null

  return (
    <>
      <div className="chat-helper">
        <div className="subpanel_title" onClick={(e) => (e.currentTarget === e.target) && setIsChatOpen(!isChatOpen)}>
          <a href="/chat" className="text-chat-title">
            Chat
            <FiMaximize2 className="ml-3" />
          </a>
          <div className="subpanel_title-icons">
            <i
              className={`icon ${isMuted ? "icon-volume-off" : "icon-volume-2"} text-20`}
              onClick={handleMute}
            />
            <i
              className={`fa ${isChatOpen ? "fa-angle-down" : "fa-angle-up"} text-20`}
              onClick={() => setIsChatOpen(!isChatOpen)}
            />
          </div>
        </div>
        {defaultNetwork !== 'y' &&
          <button className="action-btn" onClick={() => setShowModal(true)}>
            <AddIcon />
            Iniciar conversación
          </button>
        }
        {isChatOpen &&
          <ContactsFilters
            dataset={contacts}
            selectConversation={(entity) => handleOpenConversation(entity)}
          />
        }

      </div>

      <div className="active_chats-list">
        {activeChats.map((entity, index) => (
          <PersonalChat
            index={index}
            key={entity.id}
            entity={entity}
            not_seen_messages={entity.not_seen_messages}
            minimized={entity.minimized}
            onClose={handleCloseConversation}
            onMinimize={handleMinimizeConversation}
            onRead={handleReadConversation}
            timezones={timezones}
          />
        ))}
      </div>

      <ContactsModal
        show={showModal}
        setConversation={(url) => setPendingConversation(url)}
      />
      <NotificationAlert />
    </>
  )
}

export default Chat