mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 20:59:16 +00:00
before remove infinity scrol
This commit is contained in:
@@ -3,6 +3,7 @@ const Message = require("../models/Message");
|
|||||||
const Contact = require("../models/Contact");
|
const Contact = require("../models/Contact");
|
||||||
const { getIO } = require("../socket");
|
const { getIO } = require("../socket");
|
||||||
const { getWbot } = require("./wbot");
|
const { getWbot } = require("./wbot");
|
||||||
|
const sequelize = require("sequelize");
|
||||||
|
|
||||||
const { MessageMedia } = require("whatsapp-web.js");
|
const { MessageMedia } = require("whatsapp-web.js");
|
||||||
|
|
||||||
@@ -35,10 +36,20 @@ exports.getContactMessages = async (req, res, next) => {
|
|||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
|
||||||
const { contactId } = req.params;
|
const { contactId } = req.params;
|
||||||
const { search, page = 1 } = req.query;
|
const { searchParam, pageNumber = 1 } = req.query;
|
||||||
|
|
||||||
let limit = 5;
|
const lowerSerachParam = searchParam.toLowerCase();
|
||||||
let offset = limit * (page - 1);
|
|
||||||
|
const whereCondition = {
|
||||||
|
messageBody: sequelize.where(
|
||||||
|
sequelize.fn("LOWER", sequelize.col("messageBody")),
|
||||||
|
"LIKE",
|
||||||
|
"%" + lowerSerachParam + "%"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let limit = 10;
|
||||||
|
let offset = limit * (pageNumber - 1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const contact = await Contact.findByPk(contactId);
|
const contact = await Contact.findByPk(contactId);
|
||||||
@@ -50,13 +61,17 @@ exports.getContactMessages = async (req, res, next) => {
|
|||||||
|
|
||||||
setMessagesAsRead(contactId);
|
setMessagesAsRead(contactId);
|
||||||
|
|
||||||
|
const messagesFound = await contact.countMessages({
|
||||||
|
where: whereCondition,
|
||||||
|
});
|
||||||
const contactMessages = await contact.getMessages({
|
const contactMessages = await contact.getMessages({
|
||||||
|
where: whereCondition,
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
order: [["createdAt", "DESC"]],
|
order: [["createdAt", "DESC"]],
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json(contactMessages.reverse());
|
return res.json({ messages: contactMessages.reverse(), messagesFound });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"WABrowserId":"\"W5pw0Llb60mSeV7WOHnk8A==\"","WASecretBundle":"{\"key\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\",\"encKey\":\"FQ1MZ2eIH9hKV4dqFoBYTv1/89aopcMAa4CXgh/9csM=\",\"macKey\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\"}","WAToken1":"\"GvHbBS6HkZD8f5nYpOxt5qsna4XaDx3JPsjoxwKiM6g=\"","WAToken2":"\"1@P1h9eDyW0m0ILzNfgs6sEF35E66OndfdlOjm3oYzeV13cg82FjBbRvhsma9+p5+/R7zjMUv6L+l/gg==\""}
|
{"WABrowserId":"\"W5pw0Llb60mSeV7WOHnk8A==\"","WASecretBundle":"{\"key\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\",\"encKey\":\"FQ1MZ2eIH9hKV4dqFoBYTv1/89aopcMAa4CXgh/9csM=\",\"macKey\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\"}","WAToken1":"\"SNPReadfNoQL/i4IzN6BWtMxFsAkB5S1rvYwNsEywWs=\"","WAToken2":"\"1@6K32SNdV0LtNeieRuXYWmwUaGMsC18JBxEIlraW3rBgxeZ4DbiD2WtYs1Ekv/QO5RDPieBfHuWzZPw==\""}
|
||||||
@@ -1,22 +1,43 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import api from "../../util/api";
|
import api from "../../util/api";
|
||||||
|
|
||||||
const useMessageSerach = (query, pageNumber) => {
|
const useMessageSerach = (query, pageNumber, token, contactId) => {
|
||||||
useEffect(() => {
|
const [loading, setLoading] = useState(true);
|
||||||
const fetchMessages = async () => {
|
const [error, setError] = useState(false);
|
||||||
try {
|
const [listMessages, setListMessages] = useState([]);
|
||||||
const res = await api.get("/messages/" + contactId, {
|
const [hasMore, setHasMore] = useState(false);
|
||||||
headers: { Authorization: "Bearer " + token },
|
|
||||||
params: { serach: query, page: pageNumber },
|
|
||||||
});
|
|
||||||
setListMessages(res.data);
|
|
||||||
} catch (err) {
|
|
||||||
alert(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [query, pageNumber]);
|
|
||||||
|
|
||||||
return null;
|
useEffect(() => setListMessages([]), [contactId, query]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(pageNumber);
|
||||||
|
setLoading(true);
|
||||||
|
setError(false);
|
||||||
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
console.log(query);
|
||||||
|
const fetchMessages = async () => {
|
||||||
|
try {
|
||||||
|
const res = await api.get("/messages/" + contactId, {
|
||||||
|
headers: { Authorization: "Bearer " + token },
|
||||||
|
params: { searchParam: query, pageNumber: pageNumber },
|
||||||
|
});
|
||||||
|
setListMessages(prevMessages => {
|
||||||
|
return [...res.data.messages, ...prevMessages];
|
||||||
|
});
|
||||||
|
setHasMore(res.data.messages.length > 0);
|
||||||
|
setLoading(false);
|
||||||
|
console.log(res.data);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
setError(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchMessages();
|
||||||
|
}, 1000);
|
||||||
|
return () => clearTimeout(delayDebounceFn);
|
||||||
|
}, [query, pageNumber, contactId, token]);
|
||||||
|
|
||||||
|
return { loading, error, listMessages, hasMore, setListMessages };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useMessageSerach;
|
export default useMessageSerach;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||||
// import { Card } from "react-bootstrap"; alterei pra DIV, remover caso não dê problemas
|
// import { Card } from "react-bootstrap"; alterei pra DIV, remover caso não dê problemas
|
||||||
import { FiPaperclip, FiSend, FiX, FiSmile } from "react-icons/fi";
|
import { FiPaperclip, FiSend, FiX, FiSmile } from "react-icons/fi";
|
||||||
import { RiSendPlane2Line } from "react-icons/ri";
|
import { RiSendPlane2Line } from "react-icons/ri";
|
||||||
@@ -18,6 +18,7 @@ import ScrollToBottom from "react-scroll-to-bottom";
|
|||||||
|
|
||||||
import "react-toastify/dist/ReactToastify.css";
|
import "react-toastify/dist/ReactToastify.css";
|
||||||
import "./ChatBox.css";
|
import "./ChatBox.css";
|
||||||
|
import useMessageSerach from "../../components/MessageSearch/useMessageSerach";
|
||||||
|
|
||||||
// const executeScroll = myRef =>
|
// const executeScroll = myRef =>
|
||||||
// myRef.current.scrollIntoView({
|
// myRef.current.scrollIntoView({
|
||||||
@@ -28,47 +29,49 @@ import "./ChatBox.css";
|
|||||||
const ChatBox = ({ currentPeerContact }) => {
|
const ChatBox = ({ currentPeerContact }) => {
|
||||||
const SERVER_URL = "http://localhost:8080/";
|
const SERVER_URL = "http://localhost:8080/";
|
||||||
const contactId = currentPeerContact.id;
|
const contactId = currentPeerContact.id;
|
||||||
const unreadMessages = currentPeerContact.messages;
|
|
||||||
const userId = localStorage.getItem("userId");
|
const userId = localStorage.getItem("userId");
|
||||||
const username = localStorage.getItem("username");
|
const username = localStorage.getItem("username");
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
const mediaInitialState = { preview: "", raw: "", name: "" };
|
|
||||||
// const [isLoading, setIsLoading] = useState(true);
|
|
||||||
|
|
||||||
const [listMessages, setListMessages] = useState([]);
|
const mediaInitialState = { preview: "", raw: "", name: "" };
|
||||||
|
|
||||||
const [inputMessage, setInputMessage] = useState("");
|
const [inputMessage, setInputMessage] = useState("");
|
||||||
const [media, setMedia] = useState(mediaInitialState);
|
const [media, setMedia] = useState(mediaInitialState);
|
||||||
const [showEmoji, setShowEmoji] = useState(false);
|
const [showEmoji, setShowEmoji] = useState(false);
|
||||||
|
|
||||||
|
const [query, setQuery] = useState("");
|
||||||
|
const [pageNumber, setPageNumber] = useState(1);
|
||||||
|
|
||||||
|
const {
|
||||||
|
listMessages,
|
||||||
|
setListMessages,
|
||||||
|
hasMore,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
} = useMessageSerach(query, pageNumber, token, contactId);
|
||||||
|
|
||||||
|
const scrollPosition = useRef();
|
||||||
|
const observer = useRef();
|
||||||
|
const firstMessageRef = useCallback(
|
||||||
|
node => {
|
||||||
|
if (observer.current) observer.current.disconnect();
|
||||||
|
observer.current = new IntersectionObserver(entries => {
|
||||||
|
if (entries[0].isIntersecting && hasMore) {
|
||||||
|
console.log("Visible");
|
||||||
|
setPageNumber(prevPageNumber => prevPageNumber + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (node) observer.current.observe(node);
|
||||||
|
},
|
||||||
|
[loading, hasMore]
|
||||||
|
);
|
||||||
|
|
||||||
// let lastMessageRef = useRef();
|
// let lastMessageRef = useRef();
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// executeScroll(lastMessageRef);
|
// executeScroll(lastMessageRef);
|
||||||
// }, [isLoading]);
|
// }, [loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchMessages = async () => {
|
|
||||||
// setIsLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await api.get("/messages/" + contactId, {
|
|
||||||
headers: { Authorization: "Bearer " + token },
|
|
||||||
params: { page: 3 },
|
|
||||||
});
|
|
||||||
setListMessages(res.data);
|
|
||||||
// setIsLoading(false);
|
|
||||||
} catch (err) {
|
|
||||||
alert(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchMessages();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
setInputMessage("");
|
|
||||||
setShowEmoji(false);
|
|
||||||
setMedia({});
|
|
||||||
};
|
|
||||||
}, [contactId, unreadMessages, token]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(SERVER_URL);
|
const socket = openSocket(SERVER_URL);
|
||||||
@@ -87,13 +90,17 @@ const ChatBox = ({ currentPeerContact }) => {
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
|
setInputMessage("");
|
||||||
|
setQuery("");
|
||||||
|
setShowEmoji(false);
|
||||||
|
setPageNumber(1);
|
||||||
|
setMedia({});
|
||||||
};
|
};
|
||||||
}, [contactId]);
|
}, [contactId]);
|
||||||
|
|
||||||
const updateMessageAck = message => {
|
const updateMessageAck = message => {
|
||||||
let id = message.id;
|
let id = message.id;
|
||||||
setListMessages(prevState => {
|
setListMessages(prevState => {
|
||||||
console.log("mudando o ack da mensagem");
|
|
||||||
let aux = [...prevState];
|
let aux = [...prevState];
|
||||||
let messageIndex = aux.findIndex(message => message.id === id);
|
let messageIndex = aux.findIndex(message => message.id === id);
|
||||||
aux[messageIndex].ack = message.ack;
|
aux[messageIndex].ack = message.ack;
|
||||||
@@ -172,7 +179,10 @@ const ChatBox = ({ currentPeerContact }) => {
|
|||||||
setShowEmoji(false);
|
setShowEmoji(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(listMessages);
|
const handleSearch = e => {
|
||||||
|
setQuery(e.target.value);
|
||||||
|
setPageNumber(1);
|
||||||
|
};
|
||||||
|
|
||||||
const renderMsgAck = message => {
|
const renderMsgAck = message => {
|
||||||
//todo remove timestamp logic from main return and adopt moment to timestamps
|
//todo remove timestamp logic from main return and adopt moment to timestamps
|
||||||
@@ -353,6 +363,24 @@ const ChatBox = ({ currentPeerContact }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else if (index === 3) {
|
||||||
|
viewListMessages.push(
|
||||||
|
<div
|
||||||
|
ref={firstMessageRef}
|
||||||
|
className="viewItemRight"
|
||||||
|
key={message.id}
|
||||||
|
>
|
||||||
|
<div className="textContentItem">
|
||||||
|
{message.messageBody}
|
||||||
|
<span className="timestamp">
|
||||||
|
{moment(message.createdAt)
|
||||||
|
.tz("America/Sao_Paulo")
|
||||||
|
.format("HH:mm")}{" "}
|
||||||
|
{renderMsgAck(message)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
viewListMessages.push(
|
viewListMessages.push(
|
||||||
<div className="viewItemRight" key={message.id}>
|
<div className="viewItemRight" key={message.id}>
|
||||||
@@ -394,13 +422,17 @@ const ChatBox = ({ currentPeerContact }) => {
|
|||||||
<div className="aboutme">
|
<div className="aboutme">
|
||||||
<span>Status do contato</span>
|
<span>Status do contato</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
<ScrollToBottom className="viewListContentChat">
|
<input type="serch" value={query} onChange={handleSearch} />
|
||||||
<div className="viewListContentChat">
|
|
||||||
{renderMessages()}
|
|
||||||
{/* <div ref={lastMessageRef}> </div> */}
|
|
||||||
</div>
|
</div>
|
||||||
</ScrollToBottom>
|
</div>
|
||||||
|
{/* <ScrollToBottom className="viewListContentChat"> */}
|
||||||
|
<div className="viewListContentChat">
|
||||||
|
{renderMessages()}
|
||||||
|
|
||||||
|
{/* <div ref={lastMessageRef}>Last Message</div> */}
|
||||||
|
</div>
|
||||||
|
{/* </ScrollToBottom> */}
|
||||||
{media.preview ? (
|
{media.preview ? (
|
||||||
<div className="viewMediaBottom">
|
<div className="viewMediaBottom">
|
||||||
<FiX
|
<FiX
|
||||||
|
|||||||
Reference in New Issue
Block a user