Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3432 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3719 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 { u, side, type, filename, m, mtype, date, time, id, uuid, message: content } = message;
23
 
24
    return {
25
      id: id ?? uuid,
26
      content: m || content || filename || '',
27
      send: u === 1 || side === 'left',
28
      contentType: mtype || type,
29
      time: time || date,
30
      ...message
31
    };
32
  };
33
 
34
  const getMessages = async ({ url = '', page = 1 }) => {
35
    if (!url) return;
36
    setLoading(true);
37
    return axios
38
      .get(`${url}?page=${page}`)
39
      .then((response) => {
40
        const { data, success, pagination } = response.data;
41
 
42
        if (!success) {
43
          throw new Error('Ha ocurrido un error al obtener los mensajes');
44
        }
45
 
46
        const resMessages = data.items ?? data;
47
        const adapterMessages = resMessages.map((mes) => messagesAdapter(mes));
48
 
49
        return {
50
          currentPage: pagination ? pagination.current : data.page,
51
          messages: adapterMessages,
52
          lastPage: pagination ? pagination.last : data.pages
53
        };
54
      })
55
      .finally(() => setLoading(false));
56
  };
57
 
58
  const loadMoreMessages = async ({ url = '', page = 2 }) => {
59
    try {
60
      const response = await getMessages({ url, page });
61
      const { messages } = response;
62
 
63
      setMessages((prevState) => [...prevState, ...messages]);
64
    } catch (error) {
65
      dispatch(addNotification({ style: 'danger', msg: error.message }));
66
    }
67
  };
68
 
69
  const heartBeat = async ({ url }) => {
70
    try {
71
      const { lastPage, messages: resMessages } = await getMessages({ url });
72
 
73
      setPages(lastPage);
74
      setMessages((prevState) => {
75
        const diff = compareMessages(prevState, resMessages);
76
        if (!diff.length) return prevState;
77
        return [...diff, ...prevState];
78
      });
79
    } catch (error) {
80
      dispatch(addNotification({ style: 'danger', msg: error.message }));
81
    }
82
  };
83
 
84
  const changePage = () => {
85
    if (currentPage >= pages) return;
86
    setCurrentPage((prevState) => prevState + 1);
87
  };
88
 
89
  const markReport = (id) => {
90
    setMessages((prevMessages) => {
91
      return prevMessages.map((message) =>
92
        message.id === id
93
          ? {
94
              ...message,
95
              content: 'Contenido reportado',
96
              url_abuse_report: '',
97
              contentType: 'text'
98
            }
99
          : message
100
      );
101
    });
102
  };
103
 
104
  const handleReport = ({ url, id }) => {
105
    dispatch(
106
      showReportModal({
107
        reportUrl: url,
108
        type: 'mensaje',
109
        onComplete: () => markReport(id)
110
      })
111
    );
112
  };
113
 
114
  useEffect(() => {
115
    setMessages([]);
116
    setCurrentPage(1);
117
    setPages(1);
118
  }, [messagesUrl]);
119
 
120
  useEffect(() => {
121
    if (currentPage === 1) return;
122
    loadMoreMessages({ url: messagesUrl, page: currentPage });
123
  }, [messagesUrl, currentPage, loading]);
124
 
125
  useEffect(() => {
126
    const messagesInterval = setTimeout(() => {
127
      heartBeat({ url: messagesUrl });
128
    }, 2000);
129
 
130
    return () => {
131
      clearTimeout(messagesInterval);
132
    };
133
  }, [messagesUrl, loading]);
134
 
135
  return {
136
    messages,
137
    loading,
138
    loadMore: changePage,
139
    report: handleReport
140
  };
141
}