Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

import React, { useEffect, useRef, useState } from 'react'
import { axios, scrollToBottom } from '../../utils'
import { useDispatch } from 'react-redux'
import { addNotification } from '../../redux/notification/notification.actions'
import InboxIcon from '@mui/icons-material/Inbox'

import Chat from './Chat'
import EmptySection from '../UI/EmptySection'

const CHAT_TABS = {
  CHAT: 'CHAT',
  DEFAULT: 'DEFAULT',
  GROUP_MEMBERS: 'GROUP_MEMBERS',
  ADD_GROUP_MEMBER: 'ADD_GROUP_MEMBER',
}

const ChatBox = ({ entity, changeTab }) => {
  const {
    url_get_all_messages,
    url_mark_received,
    not_received_messages,
    not_seen_messages,
    url_zoom,
    url_send,
    url_upload,
    url_mark_seen,
    url_close,
    url_add_user_to_group, // Group url
    url_delete, // Group url
    url_get_contact_group_list, // Group url
    url_leave, // Group url
    name,
    profile,
    type,
  } = entity

  const [oldMessages, setOldMessages] = useState([])
  const [newMessages, setNewMessages] = useState([])
  const [currentPage, setCurrentPage] = useState(1)
  const [pages, setPages] = useState(1)

  const [isShowConferenceModal, setisShowConferenceModal] = useState(false)
  const [loading, setLoading] = useState(false)

  const [isGetting, setIsGetting] = useState(false)
  const dispatch = useDispatch()
  const scrollRef = useRef(null)

  // Messages getters
  const getMessages = async () => {
    setLoading(true)
    axios
      .get(url_get_all_messages)
      .then(({ data: response }) => {
        const { data, success } = response

        if (!success) {
          return
        }

        const messageResponse = [...data.items]
        const updatedMessages = messageResponse.reduce(
          (acum, updatedMessage) => {
            if (
              newMessages.findIndex(
                (message) => message.id === updatedMessage.id
              ) === -1
            ) {
              acum = [...acum, updatedMessage]
            }
            return acum
          },
          []
        )

        if (updatedMessages.length > 0) {
          setNewMessages((prevMessages) => [
            ...updatedMessages,
            ...prevMessages,
          ])
          setPages(data.pages)
          scrollRef.current.scrollBy(0, 200)
        }
      })
      .finally(() => setLoading(false))
  }

  const loadOldMessages = () => {
    setIsGetting(true)
    axios
      .get(`${url_get_all_messages}?page=${currentPage}`)
      .then(({ data: response }) => {
        const { data, success } = response
        if (success && data.page > 1) {
          setOldMessages([...oldMessages, ...data.items.slice()])
          scrollRef.current.scrollBy(0, 200)
        }
      })
      .finally(() => setIsGetting(false))
  }

  // Modals handlers

  const toggleConferenceModal = () => {
    setisShowConferenceModal(!isShowConferenceModal)
  }

  // On interception handler
  const onIntersection = (entities) => {
    const target = entities[0]
    if (target.isIntersecting && currentPage < pages) {
      setIsGetting(true)
      setCurrentPage((prevState) => prevState + 1)
    }
  }

  const deleteGroup = async (url) => {
    setLoading(true)
    axios
      .post(url)
      .then(({ data: response }) => {
        const { data, success } = response
        if (!success) {
          const errorMessage =
            typeof data.data === 'string' ? data.data : 'Ha ocurrido un error'
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
          return
        }

        changeTab(CHAT_TABS.DEFAULT)
      })
      .finally(() => setLoading(false))
  }

  const options = [
    {
      url: url_zoom,
      label: 'Crear Conferencia',
      action: toggleConferenceModal,
    },
  ]

  const groupOptions = [
    {
      url: url_zoom,
      label: 'Crear Conferencia',
      action: toggleConferenceModal,
    },
    {
      url: url_get_contact_group_list,
      label: 'Integrantes',
      action: () => changeTab(CHAT_TABS.GROUP_MEMBERS),
    },
    {
      url: url_add_user_to_group,
      label: 'Agregar Contactos',
      action: () => changeTab(CHAT_TABS.ADD_GROUP_MEMBER),
    },
    {
      url: url_delete,
      label: 'Eliminar Grupo',
      action: () => deleteGroup(url_delete),
    },
    {
      url: url_leave,
      label: 'Dejar Grupo',
      action: () => deleteGroup(url_leave),
    },
  ]

  useEffect(() => {
    let getInterval = null
    if (loading) return
    getInterval = setTimeout(() => getMessages(), 2000)

    return () => {
      clearTimeout(getInterval)
    }
  }, [loading])

  useEffect(() => {
    loadOldMessages()
  }, [currentPage])

  useEffect(() => {
    if (not_seen_messages) axios.post(url_mark_seen)
    if (not_received_messages) axios.post(url_mark_received)

    return () => {
      axios.post(url_close)
    }
  }, [])

  useEffect(() => {
    setNewMessages([])
    setOldMessages([])
    setPages(1)
    setCurrentPage(1)
  }, [entity])

  return (
    <>
      <Chat>
        <Chat.Header
          onClose={() => changeTab(CHAT_TABS.DEFAULT)}
          options={type === 'group' ? groupOptions : options}
        >
          <Chat.Title url={profile}>{name}</Chat.Title>
        </Chat.Header>

        {![...newMessages, ...oldMessages].length ? (
          <EmptySection
            Icon={<InboxIcon />}
            message="No hay mensajes en esta conversación"
          />
        ) : (
          <Chat.List
            messages={[...newMessages, ...oldMessages]}
            onPagination={onIntersection}
            currentPage={currentPage}
            loading={isGetting}
            pages={pages}
            scrollRef={scrollRef}
          />
        )}

        <Chat.SubmitForm
          sendUrl={url_send}
          uploadUrl={url_upload}
          onSubmit={() => scrollToBottom(scrollRef)}
        />
      </Chat>
      {/* <ConferenceModal
        show={isShowConferenceModal}
        zoomUrl={url_zoom}
        timezones={timezones}
        onCreate={toggleConferenceModal}
      /> */}
    </>
  )
}

export default ChatBox