diff --git a/All CSS Files Used in this Project.zip b/All CSS Files Used in this Project.zip deleted file mode 100644 index 0f2a7cc..0000000 Binary files a/All CSS Files Used in this Project.zip and /dev/null differ diff --git a/backend/app.js b/backend/app.js index 27f594f..ef4de1d 100644 --- a/backend/app.js +++ b/backend/app.js @@ -19,7 +19,7 @@ const fileStorage = multer.diskStorage({ cb(null, "public"); }, filename: (req, file, cb) => { - cb(null, new Date().getTime() + "-" + file.originalname); + cb(null, new Date().getTime() + "-" + file.originalname.replace(/\s/g, "")); }, }); diff --git a/backend/controllers/contact.js b/backend/controllers/contact.js index 0f4309a..c40b590 100644 --- a/backend/controllers/contact.js +++ b/backend/controllers/contact.js @@ -5,19 +5,22 @@ const Sequelize = require("sequelize"); exports.getContacts = async (req, res) => { try { const contacts = await Contact.findAll({ - include: { model: Message, attributes: [] }, + include: { + model: Message, + attributes: ["messageBody"], + }, attributes: { include: [ [ Sequelize.literal(`( - SELECT COUNT(*) - FROM messages AS message - WHERE - message.contactId = contact.id - AND - message.read = 0 - - )`), + SELECT COUNT(*) + FROM messages AS message + WHERE + message.contactId = contact.id + AND + message.read = 0 + + )`), "unreadMessages", ], ], diff --git a/backend/controllers/message.js b/backend/controllers/message.js index 5c1e078..d1c9781 100644 --- a/backend/controllers/message.js +++ b/backend/controllers/message.js @@ -81,15 +81,7 @@ exports.getContactMessages = async (req, res, next) => { const serializedMessages = contactMessages.map(message => { return { - id: message.id, - createdAt: message.createdAt, - updatedAt: message.updatedAt, - messageBody: message.messageBody, - userId: message.userId, - ack: message.ack, - read: message.read, - mediaType: message.mediaType, - contactId: message.contactId, + ...message.dataValues, mediaUrl: `${ message.mediaUrl ? `http://localhost:8080/public/${message.mediaUrl}` @@ -117,7 +109,7 @@ exports.postCreateContactMessage = async (req, res, next) => { const contact = await Contact.findByPk(contactId); if (media) { const newMedia = MessageMedia.fromFilePath(req.file.path); - message.mediaUrl = req.file.filename; + message.mediaUrl = req.file.filename.replace(/\s/g, ""); if (newMedia.mimetype) { message.mediaType = newMedia.mimetype.split("/")[0]; } else { @@ -143,7 +135,14 @@ exports.postCreateContactMessage = async (req, res, next) => { io.to(contactId).emit("appMessage", { action: "create", - message: newMessage, + message: { + ...newMessage.dataValues, + mediaUrl: `${ + message.mediaUrl + ? `http://localhost:8080/public/${message.mediaUrl}` + : "" + }`, + }, }); await setMessagesAsRead(contactId); diff --git a/backend/controllers/session.json b/backend/controllers/session.json index 3be9c34..33e96ac 100644 --- a/backend/controllers/session.json +++ b/backend/controllers/session.json @@ -1 +1 @@ -{"WABrowserId":"\"E9dnt9Mm/JiFDCMJQHkXBw==\"","WASecretBundle":"{\"key\":\"fHTKtoDcxidboASIs5WV5JKyRrF+SfMktqHXmq/KBJU=\",\"encKey\":\"FrM3OnnEbuEr1JrtKypw5CPSc6rSD5bjbOGstv8ijk4=\",\"macKey\":\"fHTKtoDcxidboASIs5WV5JKyRrF+SfMktqHXmq/KBJU=\"}","WAToken1":"\"Q+xBrzEsm9SAVo3hRyKwC3L/kvNfieq45Jt6/pFePbw=\"","WAToken2":"\"1@WlcfjMFEzc0c9JcHHHAK5BfaDDxigchRdN+GrHmVWsix+b7Od5d9Ls21/JC5ojCqbFBwnzQ5zZ/Fbg==\""} \ No newline at end of file +{"WABrowserId":"\"E9dnt9Mm/JiFDCMJQHkXBw==\"","WASecretBundle":"{\"key\":\"fHTKtoDcxidboASIs5WV5JKyRrF+SfMktqHXmq/KBJU=\",\"encKey\":\"FrM3OnnEbuEr1JrtKypw5CPSc6rSD5bjbOGstv8ijk4=\",\"macKey\":\"fHTKtoDcxidboASIs5WV5JKyRrF+SfMktqHXmq/KBJU=\"}","WAToken1":"\"9leF1nILpG4UaO0PWCoKA48h8dSn8UdIPNYZg3bpZv4=\"","WAToken2":"\"1@6OzeSH6s5Y8ozcOu4+l2N7wfaSk6C5Aop8h2BN08xAvvuGCfcuMzctLlOMNDaSw1j2qfFNM4CGjKdA==\""} \ No newline at end of file diff --git a/frontend/src/pages/Chat-Material/components/ContactsList/ContactsList.js b/frontend/src/pages/Chat-Material/components/ContactsList/ContactsList.js index a1b9a8c..4cc9ba0 100644 --- a/frontend/src/pages/Chat-Material/components/ContactsList/ContactsList.js +++ b/frontend/src/pages/Chat-Material/components/ContactsList/ContactsList.js @@ -184,7 +184,7 @@ const ContactsList = ({ selectedContact, setSelectedContact }) => { {contact.unreadMessages > 0 && ( diff --git a/frontend/src/pages/Chat-Material/components/MessagesInput/MessagesInput.js b/frontend/src/pages/Chat-Material/components/MessagesInput/MessagesInput.js index 168a853..679292f 100644 --- a/frontend/src/pages/Chat-Material/components/MessagesInput/MessagesInput.js +++ b/frontend/src/pages/Chat-Material/components/MessagesInput/MessagesInput.js @@ -1,21 +1,23 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; +import api from "../../../../util/api"; +import { Picker } from "emoji-mart"; import { makeStyles } from "@material-ui/core/styles"; import Paper from "@material-ui/core/Paper"; import InputBase from "@material-ui/core/InputBase"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import { green } from "@material-ui/core/colors"; import AttachFileIcon from "@material-ui/icons/AttachFile"; import MoodIcon from "@material-ui/icons/Mood"; import SendIcon from "@material-ui/icons/Send"; +import CancelIcon from "@material-ui/icons/Cancel"; const useStyles = makeStyles(theme => ({ - root: { - flexGrow: 1, - }, - newMessageBox: { background: "#eee", display: "flex", + position: "relative", padding: "10px 13px", borderTopLeftRadius: 0, borderTopRightRadius: 0, @@ -35,33 +37,201 @@ const useStyles = makeStyles(theme => ({ width: "80%", }, - sendMessageIcon: { - opacity: "80%", + sendMessageIcons: { + color: "grey", margin: 4, - alignSelf: "middle", cursor: "pointer", "&:hover": { opacity: "70%", }, }, + + viewMediaInputWrapper: { + display: "flex", + padding: "10px 13px", + position: "relative", + borderTopLeftRadius: 0, + borderTopRightRadius: 0, + borderBottomLeftRadius: 0, + justifyContent: "space-between", + backgroundColor: "#eee", + }, + + emojiBox: { + position: "absolute", + bottom: 50, + borderTop: "1px solid #e8e8e8", + }, + + circleLoading: { + color: green[500], + position: "absolute", + top: 0, + left: "50%", + marginTop: 6, + marginBottom: 6, + marginLeft: -12, + }, })); -const MessagesInput = () => { +const MessagesInput = ({ selectedContact }) => { const classes = useStyles(); + const contactId = selectedContact.id; + const userId = localStorage.getItem("userId"); + const username = localStorage.getItem("username"); + const token = localStorage.getItem("token"); - return ( - - - -
- { + return () => { + setInputMessage(""); + setShowEmoji(false); + setMedia({}); + }; + }, [selectedContact]); + + const handleChangeInput = e => { + setInputMessage(e.target.value); + }; + + const handleAddEmoji = e => { + let emoji = e.native; + setInputMessage(prevState => prevState + emoji); + }; + + const handleChangeMedia = e => { + if (e.target.files.length) { + setMedia({ + preview: URL.createObjectURL(e.target.files[0]), + raw: e.target.files[0], + name: e.target.files[0].name, + }); + } + }; + + const handleInputPaste = e => { + if (e.clipboardData.files[0]) { + setMedia({ + preview: URL.createObjectURL(e.clipboardData.files[0]), + raw: e.clipboardData.files[0], + name: e.clipboardData.files[0].name, + }); + } + }; + + const handleUploadMedia = async e => { + setLoading(true); + e.preventDefault(); + const formData = new FormData(); + formData.append("media", media.raw); + formData.append("userId", userId); + formData.append("messageBody", media.name); + + try { + await api.post(`/messages/${contactId}`, formData, { + headers: { Authorization: "Bearer " + token }, + }); + } catch (err) { + console.log(err); + alert(err); + } + setLoading(false); + setMedia(mediaInitialState); + }; + + const handleSendMessage = async () => { + if (inputMessage.trim() === "") return; + const message = { + read: 1, + userId: userId, + mediaUrl: "", + messageBody: `${username}: ${inputMessage.trim()}`, + }; + try { + await api.post(`/messages/${contactId}`, message, { + headers: { Authorization: "Bearer " + token }, + }); + } catch (err) { + alert(err); + } + setInputMessage(""); + setShowEmoji(false); + }; + + if (media.preview) + return ( + + setMedia(mediaInitialState)} /> -
- -
- ); + + {media.name} + {/* */} + + {loading ? ( +
+ +
+ ) : null} + + + ); + else { + return ( + + setShowEmoji(prevState => !prevState)} + /> + {showEmoji ? ( +
+ +
+ ) : null} + + +
+ { + if (e.key === "Enter") { + handleSendMessage(); + } + }} + /> +
+ +
+ ); + } }; export default MessagesInput; diff --git a/frontend/src/pages/Chat-Material/components/MessagesList/MessagesList.js b/frontend/src/pages/Chat-Material/components/MessagesList/MessagesList.js index f7d3edb..9d5119d 100644 --- a/frontend/src/pages/Chat-Material/components/MessagesList/MessagesList.js +++ b/frontend/src/pages/Chat-Material/components/MessagesList/MessagesList.js @@ -129,6 +129,12 @@ const useStyles = makeStyles(theme => ({ boxShadow: "0 2px 2px #808888", }, + textContentItem: { + alignSelf: "middle", + overflowWrap: "break-word", + padding: "3px 80px 6px 6px", + }, + messageMedia: { objectFit: "cover", width: 250, @@ -139,11 +145,6 @@ const useStyles = makeStyles(theme => ({ borderBottomRightRadius: 8, }, - textContentItem: { - overflowWrap: "break-word", - padding: "0px 60px 10px 0px", - }, - timestamp: { fontSize: 11, position: "absolute", @@ -168,6 +169,15 @@ const useStyles = makeStyles(theme => ({ alignSelf: "center", marginLeft: "0px", }, + + ackIcons: { + fontSize: 18, + }, + + ackDoneAllIcon: { + color: green[500], + fontSize: 18, + }, })); const MessagesList = ({ selectedContact }) => { @@ -264,8 +274,9 @@ const MessagesList = ({ selectedContact }) => { setMessagesList(prevState => { let aux = [...prevState]; let messageIndex = aux.findIndex(message => message.id === id); - aux[messageIndex].ack = message.ack; - + if (messageIndex) { + aux[messageIndex].ack = message.ack; + } return aux; }); }; @@ -307,16 +318,18 @@ const MessagesList = ({ selectedContact }) => { const renderMessageAck = message => { if (message.ack === 0) { - return ; + return ; } if (message.ack === 1) { - return ; + return ; } if (message.ack === 2) { - return ; + return ; } if (message.ack === 3) { - return ; + return ( + + ); } }; @@ -372,10 +385,9 @@ const MessagesList = ({ selectedContact }) => { const renderMessages = () => { if (messagesList.length > 0) { - let viewMessagesList = []; - messagesList.forEach((message, index) => { + const viewMessagesList = messagesList.map((message, index) => { if (message.userId === 0) { - viewMessagesList.push( + return [ renderDailyTimestamps(message, index),
{message.mediaUrl && checkMessaageMedia(message)} @@ -387,10 +399,10 @@ const MessagesList = ({ selectedContact }) => { .format("HH:mm")}
- - ); + , + ]; } else { - viewMessagesList.push( + return [ renderDailyTimestamps(message, index),
{message.mediaUrl && checkMessaageMedia(message)} @@ -403,8 +415,8 @@ const MessagesList = ({ selectedContact }) => { {renderMessageAck(message)}
- - ); + , + ]; } }); return viewMessagesList;