Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5198 | Rev 5240 | Ir a la última revisión | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 5198 Rev 5239
Línea 1... Línea 1...
1
/* eslint-disable react/prop-types */
1
/* eslint-disable react/prop-types */
2
import React, { useEffect, useRef } from 'react'
2
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'
3
import EmptySection from '../../shared/empty-section/EmptySection'
3
import EmptySection from '../../shared/empty-section/EmptySection'
4
import MessageBox from './MessageBox'
4
import MessageBox from './MessageBox'
5
import MessageTemplate from './MessageTemplate'
5
import MessageTemplate from './MessageTemplate'
6
import SpeakerNotesOffRoundedIcon from '@mui/icons-material/SpeakerNotesOffRounded'
6
import SpeakerNotesOffRoundedIcon from '@mui/icons-material/SpeakerNotesOffRounded'
7
import QuestionAnswerRoundedIcon from '@mui/icons-material/QuestionAnswerRounded'
7
import QuestionAnswerRoundedIcon from '@mui/icons-material/QuestionAnswerRounded'
-
 
8
import { useDispatch } from 'react-redux'
-
 
9
import { fetchMessages, getMessagesDifferences } from '../../services/chat'
-
 
10
import { addNotification } from '../../redux/notification/notification.actions'
-
 
11
import { axios, scrollToBottom } from '../../utils'
-
 
12
import { ArrowLeft } from '@mui/icons-material'
-
 
13
 
-
 
14
const DEFAULT_PAGES = { current: 1, last: 1 }
Línea 8... Línea 15...
8
 
15
 
9
const Chatmail = ({
16
const Chatmail = ({
10
  selectedConversation = null,
-
 
11
  messages = [],
17
  selectedConversation = null,
12
  setConversation = () => { },
-
 
13
  getMoreMessages = () => { },
-
 
14
  onSend = () => { }
18
  setConversation = () => null
-
 
19
}) => {
-
 
20
  const [oldMessages, setOldMessages] = useState([])
-
 
21
  const [messages, setMessages] = useState([])
-
 
22
  const [pages, setPages] = useState(DEFAULT_PAGES)
15
}) => {
23
  const [loading, setLoading] = useState(false)
-
 
24
  const lastMessage = useRef(null)
-
 
25
  const dispatch = useDispatch()
-
 
26
 
-
 
27
  const getMessages = async (url = '', page = DEFAULT_PAGES.current) => {
-
 
28
    try {
-
 
29
      setLoading(true)
-
 
30
      const response = await fetchMessages(url, page)
-
 
31
      if (!response.success) {
-
 
32
        const errorMessage = response.data
-
 
33
 
-
 
34
        dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
-
 
35
        return
-
 
36
      }
-
 
37
 
-
 
38
      const newMessages = getMessagesDifferences(messages, response.data)
-
 
39
 
-
 
40
      if (response.pagination.current > 1) {
-
 
41
        setOldMessages([...response.data, ...oldMessages])
-
 
42
      }
-
 
43
 
-
 
44
      if (newMessages.length) {
-
 
45
        setMessages([...messages, ...newMessages])
-
 
46
        scrollToBottom()
-
 
47
      } else {
-
 
48
        setMessages(response.data)
-
 
49
      }
-
 
50
 
-
 
51
      setPages((prevPages) => ({ ...prevPages, last: response.pagination.last }))
-
 
52
    } catch (error) {
-
 
53
      const errorMessage = new Error(error)
-
 
54
      console.log('Request canceled', errorMessage)
-
 
55
    } finally {
-
 
56
      setLoading(false)
-
 
57
    }
-
 
58
  }
-
 
59
 
-
 
60
  const handleSend = async (sendUrl = '', message = {}) => {
-
 
61
    try {
-
 
62
      const formData = new FormData()
-
 
63
 
-
 
64
      Object.entries(message).forEach(([key, value]) => formData.append(key, value))
-
 
65
 
-
 
66
      const { data: response } = await axios.post(sendUrl, formData)
-
 
67
      setMessages(prev => [response.data, ...prev])
-
 
68
    } catch (error) {
-
 
69
      const errorMessage = new Error(error)
-
 
70
      dispatch(addNotification({ style: 'danger', msg: errorMessage.message }))
-
 
71
    }
-
 
72
  }
-
 
73
 
-
 
74
  const changeConversation = (conversation) => {
-
 
75
    setPages(DEFAULT_PAGES)
-
 
76
    setConversation(conversation)
-
 
77
    getMessages(selectedConversation.messages_link)
-
 
78
  }
-
 
79
 
-
 
80
  const loadMore = async () => {
-
 
81
    setPages((prevPages) => ({ ...prevPages, current: prevPages.current + 1 }))
Línea 16... Línea 82...
16
  const lastMessage = useRef(null)
82
  }
-
 
83
 
-
 
84
  useEffect(() => {
-
 
85
    let timer
-
 
86
    if (!loading && selectedConversation) {
-
 
87
      timer = setTimeout(() => getMessages(selectedConversation.messages_link), 2000)
-
 
88
    }
-
 
89
    return () => {
-
 
90
      clearTimeout(timer)
-
 
91
    }
-
 
92
  }, [loading, selectedConversation])
-
 
93
 
-
 
94
  useLayoutEffect(() => {
-
 
95
    getMessages(selectedConversation.messages_link, pages.current)
-
 
96
  }, [pages.current])
17
 
97
 
18
  useEffect(() => {
98
  useLayoutEffect(() => {
19
    const observer = new IntersectionObserver(([entry]) => {
99
    const observer = new IntersectionObserver(([entry]) => {
20
      if (entry.isIntersecting) {
100
      if (entry.isIntersecting) {
21
        getMoreMessages()
101
        loadMore()
Línea 22... Línea -...
22
      }
-
 
23
    })
102
      }
24
 
-
 
25
    if (lastMessage.current) {
103
    })
Línea 26... Línea 104...
26
      observer.observe(lastMessage.current)
104
 
27
    }
105
    observer.observe(lastMessage.current)
28
  }, [messages])
106
  }, [messages])
Línea 29... Línea 107...
29
 
107
 
30
  if (!selectedConversation) {
108
  if (!selectedConversation) {
31
    return <EmptySection message={LABELS.SELECT_CONVERSATION} Icon={<QuestionAnswerRoundedIcon/>} />
109
    return <EmptySection message={LABELS.SELECT_CONVERSATION} Icon={<QuestionAnswerRoundedIcon/>} />
32
  }
110
  }
33
 
111
 
34
  return (
112
  return (
35
    <div className='chat'>
113
    <div className='chat'>
36
      <div className='icon-hide' onClick={() => setConversation(null)}>
114
      <span className='icon-hide' onClick={() => changeConversation(null)}>
37
        <i className="fas fa-angle-left" />
115
        <ArrowLeft />
38
        <span>{LABELS.RETURN}</span>
116
        {LABELS.RETURN}
39
      </div>
117
      </span>
40
      <a href={selectedConversation.profile}>
118
      <a href={selectedConversation.profile}>
41
        <h2 className='chat-header'>{selectedConversation.name}</h2>
119
        <h2 className='chat-header'>{selectedConversation.name}</h2>
42
      </a>
120
      </a>
43
      <div className="messages-line">
121
      <div className="messages-line">
44
        {messages.length
122
        {messages.length
45
          ? messages.map((element, index) =>
123
          ? [...oldMessages, ...messages].map((element, index) =>
46
            <MessageTemplate
124
            <MessageTemplate
47
              key={index}
125
              key={index}
48
              message={element}
126
              message={element}
49
              date={element.date}
127
              date={element.date}
50
            />)
128
            />)
51
          : <EmptySection message={LABELS.NO_MESSAGE_CONVERSATION} Icon={<SpeakerNotesOffRoundedIcon/>} />
129
          : <EmptySection message={LABELS.NO_MESSAGE_CONVERSATION} Icon={<SpeakerNotesOffRoundedIcon/>} />
52
        }
130
        }
53
        <hr ref={lastMessage} style={{ visibility: 'hidden' }} />
131
        {pages.current < pages.last && <hr ref={lastMessage} style={{ visibility: 'hidden' }} />}
Línea 54... Línea 132...
54
      </div>
132
      </div>