diff --git a/backend/controllers/message.js b/backend/controllers/message.js
index 2429696..e773eff 100644
--- a/backend/controllers/message.js
+++ b/backend/controllers/message.js
@@ -48,7 +48,7 @@ exports.getContactMessages = async (req, res, next) => {
),
};
- let limit = 10;
+ let limit = 20;
let offset = limit * (pageNumber - 1);
try {
diff --git a/backend/controllers/session.json b/backend/controllers/session.json
index 2fd99be..aa161d2 100644
--- a/backend/controllers/session.json
+++ b/backend/controllers/session.json
@@ -1 +1 @@
-{"WABrowserId":"\"W5pw0Llb60mSeV7WOHnk8A==\"","WASecretBundle":"{\"key\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\",\"encKey\":\"FQ1MZ2eIH9hKV4dqFoBYTv1/89aopcMAa4CXgh/9csM=\",\"macKey\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\"}","WAToken1":"\"SNPReadfNoQL/i4IzN6BWtMxFsAkB5S1rvYwNsEywWs=\"","WAToken2":"\"1@6K32SNdV0LtNeieRuXYWmwUaGMsC18JBxEIlraW3rBgxeZ4DbiD2WtYs1Ekv/QO5RDPieBfHuWzZPw==\""}
\ No newline at end of file
+{"WABrowserId":"\"W5pw0Llb60mSeV7WOHnk8A==\"","WASecretBundle":"{\"key\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\",\"encKey\":\"FQ1MZ2eIH9hKV4dqFoBYTv1/89aopcMAa4CXgh/9csM=\",\"macKey\":\"alDLbPjonDFzCh5PEPql9cy59LNh1HFG/AZJVoucuYI=\"}","WAToken1":"\"fpvmzsdJ0KcZfIl5G4ZTqGxvg474wEfhECz4btE0TDc=\"","WAToken2":"\"1@ueYAfj0uRoSok18uTv8xzCWlvo45N3cefA6tAkUX2iJXP+AQY35sLDxyv1F+q34Ntf9vUcoc4tQG2Q==\""}
\ No newline at end of file
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index acea429..594d0e1 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -11118,6 +11118,14 @@
"camelcase": "^5.0.0"
}
},
+ "react-infinite-scroll-reverse": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/react-infinite-scroll-reverse/-/react-infinite-scroll-reverse-1.0.3.tgz",
+ "integrity": "sha512-sbACmGs42B06eVnsqlCh3z5Qs7/RepuFSEPc31ByrLDFXurhZYdVT4lCB/IvMugevIWwVIOsiN/Pr0JBfhm+IQ==",
+ "requires": {
+ "prop-types": "15.7.2"
+ }
+ },
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 308b5af..7420d10 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -17,6 +17,7 @@
"react-bootstrap": "^1.0.1",
"react-dom": "^16.13.1",
"react-icons": "^3.10.0",
+ "react-infinite-scroll-reverse": "^1.0.3",
"react-loading": "^2.0.3",
"react-modal-image": "^2.5.0",
"react-moment": "^0.9.7",
diff --git a/frontend/src/components/MessageSearch/useMessageSerach.js b/frontend/src/components/MessageSearch/useMessageSerach.js
deleted file mode 100644
index 988c01e..0000000
--- a/frontend/src/components/MessageSearch/useMessageSerach.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useEffect, useState } from "react";
-import api from "../../util/api";
-
-const useMessageSerach = (query, pageNumber, token, contactId) => {
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(false);
- const [listMessages, setListMessages] = useState([]);
- const [hasMore, setHasMore] = useState(false);
-
- 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;
diff --git a/frontend/src/pages/Chat/Chat.css b/frontend/src/pages/Chat/Chat.css
index 93bc603..0edecf9 100644
--- a/frontend/src/pages/Chat/Chat.css
+++ b/frontend/src/pages/Chat/Chat.css
@@ -47,6 +47,18 @@
font: 14px Arial, sans-serif;
}
+.viewLoading {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ /* background-color: rgba(255, 255, 255, 0.5); */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
/* List user */
.viewListUser {
diff --git a/frontend/src/pages/ChatBox/ChatBox.css b/frontend/src/pages/ChatBox/ChatBox.css
index 491581a..99453ce 100644
--- a/frontend/src/pages/ChatBox/ChatBox.css
+++ b/frontend/src/pages/ChatBox/ChatBox.css
@@ -168,6 +168,35 @@ input::placeholder {
color: rgb(199, 199, 199);
}
+.rootsearchbar {
+ padding: 10px;
+ width: 300px;
+ margin-bottom: 10px;
+ background-color: #f7f7f7;
+}
+
+.input-container {
+ /* IE10 */
+ display: flex;
+ width: 300px;
+ margin-bottom: 15px;
+}
+
+.input-field {
+ width: 300px;
+
+ border-radius: 10px;
+
+ /* margin-right: 85%; */
+ border: none !important;
+ box-shadow: none !important;
+ outline: none !important;
+
+ width: 100%;
+ padding: 10px;
+ text-align: center;
+}
+
/* View item message */
.viewItemRight {
@@ -227,7 +256,7 @@ input::placeholder {
}
.viewWrapItemLeft {
- width: 300px;
+ /* width: 300px; */
text-align: left;
align-self: flex-start;
margin-left: 20px;
@@ -235,13 +264,13 @@ input::placeholder {
margin-bottom: -15px;
}
-.viewWrapItemLeft2 {
+.viewWrapItemRight {
width: 300px;
- align-self: flex-start;
+ align-self: flex-end;
text-align: left;
- margin-left: 20px;
+ /* margin-left: 20px;
margin-top: 10px;
- margin-bottom: -15px;
+ margin-bottom: -15px; */
}
.viewWrapItemLeft3 {
@@ -304,20 +333,7 @@ input::placeholder {
border-bottom-right-radius: 8px;
color: white;
}
-.time {
- display: flex;
- align-items: center;
- text-align: center;
- margin-left: 400px;
- font: italic small-caps bold 15px/30px Georgia, serif;
- width: 110px;
- background-color: #e1f3fb;
- padding-top: 5px;
- padding-bottom: 5px;
- padding-left: 5px;
- padding-right: 5px;
- border-radius: 10px;
-}
+
.timesetup {
align-items: center;
}
@@ -379,11 +395,27 @@ input::placeholder {
border-bottom-right-radius: 8px;
}
-.textTimeLeft {
+.time {
+ align-items: center;
+ text-align: center;
+ align-self: center;
+ font: italic small-caps bold 15px/30px Georgia, serif;
+ width: 110px;
+ background-color: #e1f3fb;
+ margin: 10px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ border-radius: 10px;
+}
+
+.textTime {
color: #808888;
font-size: 12px;
font-style: italic;
- margin-left: 50px;
+ align-self: center;
+ margin-left: 0px;
}
/* Stickers */
diff --git a/frontend/src/pages/ChatBox/ChatBox.js b/frontend/src/pages/ChatBox/ChatBox.js
index 43dc952..ca70cb9 100644
--- a/frontend/src/pages/ChatBox/ChatBox.js
+++ b/frontend/src/pages/ChatBox/ChatBox.js
@@ -1,10 +1,16 @@
-import React, { useState, useEffect, useRef, useCallback } from "react";
-// import { Card } from "react-bootstrap"; alterei pra DIV, remover caso não dê problemas
-import { FiPaperclip, FiSend, FiX, FiSmile } from "react-icons/fi";
-import { RiSendPlane2Line } from "react-icons/ri";
+import React, { useState, useEffect } from "react";
+import InfiniteScrollReverse from "react-infinite-scroll-reverse";
+import ReactLoading from "react-loading";
+import {
+ FiPaperclip,
+ FiSend,
+ FiTrash2,
+ FiSmile,
+ FiFastForward,
+ FiFile,
+} from "react-icons/fi";
import { BsCheck, BsCheckAll, BsClock } from "react-icons/bs";
-import { FaFileDownload } from "react-icons/fa";
-import "emoji-mart/css/emoji-mart.css";
+
import { Picker } from "emoji-mart";
import ModalImage from "react-modal-image";
import moment from "moment-timezone";
@@ -14,17 +20,9 @@ import openSocket from "socket.io-client";
import profileDefaultPic from "../../Images/profile_default.png";
import ReactAudioPlayer from "react-audio-player";
-import ScrollToBottom from "react-scroll-to-bottom";
-
import "react-toastify/dist/ReactToastify.css";
+import "emoji-mart/css/emoji-mart.css";
import "./ChatBox.css";
-import useMessageSerach from "../../components/MessageSearch/useMessageSerach";
-
-// const executeScroll = myRef =>
-// myRef.current.scrollIntoView({
-// // behavior: "smooth",
-// block: "end",
-// });
const ChatBox = ({ currentPeerContact }) => {
const SERVER_URL = "http://localhost:8080/";
@@ -35,43 +33,42 @@ const ChatBox = ({ currentPeerContact }) => {
const token = localStorage.getItem("token");
const mediaInitialState = { preview: "", raw: "", name: "" };
-
const [inputMessage, setInputMessage] = useState("");
const [media, setMedia] = useState(mediaInitialState);
const [showEmoji, setShowEmoji] = useState(false);
+ const [loading, setLoading] = useState(true);
+ const [listMessages, setListMessages] = useState([]);
+ const [hasMore, setHasMore] = useState(false);
+ const [searchParam, setSearchParam] = useState("");
+ const [pageNumber, setPageNumber] = useState(0);
- const [query, setQuery] = useState("");
- const [pageNumber, setPageNumber] = useState(1);
+ useEffect(() => setListMessages([]), [searchParam]);
- 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);
+ useEffect(() => {
+ setLoading(true);
+ const delayDebounceFn = setTimeout(() => {
+ console.log(searchParam);
+ const fetchMessages = async () => {
+ try {
+ const res = await api.get("/messages/" + contactId, {
+ headers: { Authorization: "Bearer " + token },
+ params: { searchParam, 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);
+ alert(err);
}
- });
- if (node) observer.current.observe(node);
- },
- [loading, hasMore]
- );
-
- // let lastMessageRef = useRef();
-
- // useEffect(() => {
- // executeScroll(lastMessageRef);
- // }, [loading]);
+ };
+ fetchMessages();
+ }, 1000);
+ return () => clearTimeout(delayDebounceFn);
+ }, [searchParam, pageNumber, contactId, token]);
useEffect(() => {
const socket = openSocket(SERVER_URL);
@@ -79,25 +76,28 @@ const ChatBox = ({ currentPeerContact }) => {
socket.emit("joinChatBox", contactId, () => {});
socket.on("appMessage", data => {
- // setIsLoading(true);
if (data.action === "create") {
addMessage(data.message);
} else if (data.action === "update") {
updateMessageAck(data.message);
}
- // setIsLoading(false);
});
return () => {
socket.disconnect();
setInputMessage("");
- setQuery("");
+ setSearchParam("");
setShowEmoji(false);
setPageNumber(1);
setMedia({});
+ setListMessages([]);
};
}, [contactId]);
+ const loadMore = () => {
+ setPageNumber(prevPageNumber => prevPageNumber + 1);
+ };
+
const updateMessageAck = message => {
let id = message.id;
setListMessages(prevState => {
@@ -180,10 +180,34 @@ const ChatBox = ({ currentPeerContact }) => {
};
const handleSearch = e => {
- setQuery(e.target.value);
+ setSearchParam(e.target.value);
setPageNumber(1);
};
+ const checkMessageDay = (message, index) => {
+ if (index < listMessages.length - 1) {
+ let messageDay = moment(listMessages[index].createdAt)
+ .tz("America/Sao_Paulo")
+ .format("DD");
+
+ let nextMessageDay = moment(listMessages[index + 1].createdAt)
+ .tz("America/Sao_Paulo")
+ .format("DD");
+
+ if (messageDay < nextMessageDay) {
+ return (
+
+
{currentPeerContact.name}
Status do contato
+