Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3432 | Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3208 stevensc 1
import { useEffect, useState } from 'react'
2
import { useDispatch } from 'react-redux'
3
 
4
import { axios } from '@app/utils'
5
import { addNotification } from '@app/redux/notification/notification.actions'
6
import { showReportModal } from '@app/redux/report/report.actions'
7
 
8
export function useMessages(messagesUrl) {
9
  const [loading, setLoading] = useState(false)
10
  const [messages, setMessages] = useState([])
11
  const [currentPage, setCurrentPage] = useState(1)
12
  const [pages, setPages] = useState(1)
13
  const dispatch = useDispatch()
14
 
15
  function compareMessages(ref = [], newValue = []) {
16
    const set = new Set(ref.map((obj) => obj.id))
17
    const difference = newValue.filter((obj) => !set.has(obj.id))
18
    return difference
19
  }
20
 
21
  const messagesAdapter = (message) => {
22
    const {
23
      u,
24
      side,
25
      type,
26
      filename,
27
      m,
28
      mtype,
29
      date,
30
      time,
31
      id,
32
      uuid,
33
      message: content
34
    } = message
35
 
36
    return {
37
      id: id ?? uuid,
38
      content: m || content || filename || '',
39
      send: u === 1 || side === 'left',
40
      contentType: mtype || type,
41
      time: time || date,
42
      ...message
43
    }
44
  }
45
 
46
  const getMessages = async ({ url = '', page = 1 }) => {
47
    if (!url) return
48
    setLoading(true)
49
    return axios
50
      .get(`${url}?page=${page}`)
51
      .then(({ data: response }) => {
52
        const { data, success, pagination } = response
53
 
54
        if (!success) {
55
          throw new Error('Ha ocurrido un error al obtener los mensajes')
56
        }
57
 
58
        const resMessages = data.items ?? data
59
        const adapterMessages = resMessages.map((mes) => messagesAdapter(mes))
60
 
61
        return {
62
          currentPage: pagination ? pagination.current : data.page,
63
          messages: adapterMessages,
64
          lastPage: pagination ? pagination.last : data.pages
65
        }
66
      })
67
      .finally(() => setLoading(false))
68
  }
69
 
70
  const loadMoreMessages = async ({ url = '', page = 2 }) => {
71
    try {
72
      const response = await getMessages({ url, page })
73
      const { messages } = response
74
 
75
      setMessages((prevState) => [...prevState, ...messages])
76
    } catch (error) {
77
      dispatch(addNotification({ style: 'danger', msg: error.message }))
78
    }
79
  }
80
 
81
  const heartBeat = async ({ url }) => {
82
    try {
83
      const { lastPage, messages: resMessages } = await getMessages({ url })
84
 
85
      setPages(lastPage)
86
      setMessages((prevState) => {
87
        const diff = compareMessages(prevState, resMessages)
88
        if (!diff.length) return prevState
89
        return [...diff, ...prevState]
90
      })
91
    } catch (error) {
92
      dispatch(addNotification({ style: 'danger', msg: error.message }))
93
    }
94
  }
95
 
96
  const changePage = () => {
97
    if (currentPage >= pages) return
98
    setCurrentPage((prevState) => prevState + 1)
99
  }
100
 
101
  const markReport = (id) => {
102
    setMessages((prevMessages) => {
103
      return prevMessages.map((message) =>
104
        message.id === id
105
          ? {
106
              ...message,
107
              content: 'Contenido reportado',
108
              url_abuse_report: '',
109
              contentType: 'text'
110
            }
111
          : message
112
      )
113
    })
114
  }
115
 
116
  const handleReport = ({ url, id }) => {
117
    dispatch(
118
      showReportModal({
119
        reportUrl: url,
120
        type: 'mensaje',
121
        onComplete: () => markReport(id)
122
      })
123
    )
124
  }
125
 
126
  useEffect(() => {
127
    setMessages([])
128
    setCurrentPage(1)
129
    setPages(1)
130
  }, [messagesUrl])
131
 
132
  useEffect(() => {
133
    if (currentPage === 1) return
134
    loadMoreMessages({ url: messagesUrl, page: currentPage })
135
  }, [messagesUrl, currentPage, loading])
136
 
137
  useEffect(() => {
138
    const messagesInterval = setTimeout(() => {
139
      heartBeat({ url: messagesUrl })
140
    }, 2000)
141
 
142
    return () => {
143
      clearTimeout(messagesInterval)
144
    }
145
  }, [messagesUrl, loading])
146
 
147
  return {
148
    messages,
149
    loading,
150
    loadMore: changePage,
151
    report: handleReport
152
  }
153
}