diff --git a/backend/src/controllers/MessageController.ts b/backend/src/controllers/MessageController.ts index cd16ec9..210790d 100644 --- a/backend/src/controllers/MessageController.ts +++ b/backend/src/controllers/MessageController.ts @@ -10,7 +10,6 @@ import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia"; import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage"; type IndexQuery = { - searchParam: string; pageNumber: string; }; @@ -22,10 +21,9 @@ type MessageData = { export const index = async (req: Request, res: Response): Promise => { const { ticketId } = req.params; - const { searchParam, pageNumber } = req.query as IndexQuery; + const { pageNumber } = req.query as IndexQuery; const { count, messages, ticket, hasMore } = await ListMessagesService({ - searchParam, pageNumber, ticketId }); diff --git a/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts b/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts new file mode 100644 index 0000000..8bfd56f --- /dev/null +++ b/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "quotedMsgId", { + type: DataTypes.STRING, + references: { model: "Messages", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "quotedMsgId"); + } +}; diff --git a/backend/src/models/Message.ts b/backend/src/models/Message.ts index 1ced76f..4f49b88 100644 --- a/backend/src/models/Message.ts +++ b/backend/src/models/Message.ts @@ -59,6 +59,13 @@ class Message extends Model { @Column(DataType.DATE(6)) updatedAt: Date; + @ForeignKey(() => Message) + @Column + quotedMsgId: string; + + @BelongsTo(() => Message, "quotedMsgId") + quotedMsg: Message; + @ForeignKey(() => Ticket) @Column ticketId: number; diff --git a/backend/src/services/MessageServices/CreateMessageService.ts b/backend/src/services/MessageServices/CreateMessageService.ts index 48e625c..cbdd5bb 100644 --- a/backend/src/services/MessageServices/CreateMessageService.ts +++ b/backend/src/services/MessageServices/CreateMessageService.ts @@ -28,7 +28,7 @@ const CreateMessageService = async ({ await Message.upsert(messageData); const message = await Message.findByPk(messageData.id, { - include: ["contact"] + include: ["contact", "quotedMsg"] }); if (!message) { diff --git a/backend/src/services/MessageServices/ListMessagesService.ts b/backend/src/services/MessageServices/ListMessagesService.ts index 60911a5..6824b3c 100644 --- a/backend/src/services/MessageServices/ListMessagesService.ts +++ b/backend/src/services/MessageServices/ListMessagesService.ts @@ -1,4 +1,3 @@ -import { where, fn, col } from "sequelize"; import AppError from "../../errors/AppError"; import Message from "../../models/Message"; import Ticket from "../../models/Ticket"; @@ -6,7 +5,6 @@ import ShowTicketService from "../TicketServices/ShowTicketService"; interface Request { ticketId: string; - searchParam?: string; pageNumber?: string; } @@ -18,7 +16,6 @@ interface Response { } const ListMessagesService = async ({ - searchParam = "", pageNumber = "1", ticketId }: Request): Promise => { @@ -28,23 +25,14 @@ const ListMessagesService = async ({ throw new AppError("ERR_NO_TICKET_FOUND", 404); } - const whereCondition = { - body: where( - fn("LOWER", col("body")), - "LIKE", - `%${searchParam.toLowerCase()}%` - ), - ticketId - }; - // await setMessagesAsRead(ticket); const limit = 20; const offset = limit * (+pageNumber - 1); const { count, rows: messages } = await Message.findAndCountAll({ - where: whereCondition, + where: { ticketId }, limit, - include: ["contact"], + include: ["contact", "quotedMsg"], offset, order: [["createdAt", "DESC"]] }); diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 5884391..6904fec 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -149,12 +149,20 @@ const handlMedia = async ( ticket: Ticket, contact: Contact ): Promise => { + let quotedMsg: Message | null = null; + const media = await msg.downloadMedia(); if (!media) { throw new AppError("ERR_WAPP_DOWNLOAD_MEDIA"); } + if (msg.hasQuotedMsg) { + const wbotQuotedMsg = await msg.getQuotedMessage(); + + quotedMsg = await Message.findByPk(wbotQuotedMsg.id.id); + } + if (!media.filename) { const ext = media.mimetype.split("/")[1].split(";")[0]; media.filename = `${new Date().getTime()}.${ext}`; @@ -178,7 +186,8 @@ const handlMedia = async ( fromMe: msg.fromMe, read: msg.fromMe, mediaUrl: media.filename, - mediaType: media.mimetype.split("/")[0] + mediaType: media.mimetype.split("/")[0], + quotedMsgId: quotedMsg?.id }; const newMessage = await CreateMessageService({ messageData }); @@ -193,6 +202,13 @@ const handleMessage = async ( contact: Contact ) => { let newMessage: Message | null; + let quotedMsg: Message | null = null; + + if (msg.hasQuotedMsg) { + const wbotQuotedMsg = await msg.getQuotedMessage(); + + quotedMsg = await Message.findByPk(wbotQuotedMsg.id.id); + } if (msg.hasMedia) { newMessage = await handlMedia(msg, ticket, contact); @@ -204,7 +220,8 @@ const handleMessage = async ( body: msg.body, fromMe: msg.fromMe, mediaType: msg.type, - read: msg.fromMe + read: msg.fromMe, + quotedMsgId: quotedMsg?.id }; newMessage = await CreateMessageService({ messageData }); diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js index c98e2d5..f768889 100644 --- a/frontend/src/components/MessagesList/index.js +++ b/frontend/src/components/MessagesList/index.js @@ -82,6 +82,30 @@ const useStyles = makeStyles(theme => ({ boxShadow: "0 1px 1px #b3b3b3", }, + quotedContainerLeft: { + margin: "-3px -80px 6px -6px", + overflow: "hidden", + backgroundColor: "#f0f0f0", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + quotedMsgLeft: { + padding: 10, + maxWidth: 300, + height: "auto", + display: "block", + whiteSpace: "pre-wrap", + overflow: "hidden", + }, + + quotedSideLeft: { + flex: "none", + width: "4px", + backgroundColor: "#6bcbef", + }, + messageRight: { marginLeft: 20, marginTop: 2, @@ -90,7 +114,6 @@ const useStyles = makeStyles(theme => ({ height: "auto", display: "block", position: "relative", - "&:hover #messageActionsButton": { display: "flex", position: "absolute", @@ -113,6 +136,28 @@ const useStyles = makeStyles(theme => ({ boxShadow: "0 1px 1px #b3b3b3", }, + quotedContainerRight: { + margin: "-3px -80px 6px -6px", + overflowY: "hidden", + backgroundColor: "#cfe9ba", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + quotedMsgRight: { + padding: 10, + maxWidth: 300, + height: "auto", + whiteSpace: "pre-wrap", + }, + + quotedSideRight: { + flex: "none", + width: "4px", + backgroundColor: "#35cd96", + }, + messageActionsButton: { display: "none", position: "relative", @@ -124,7 +169,6 @@ const useStyles = makeStyles(theme => ({ messageContactName: { display: "flex", - paddingLeft: 6, color: "#6bcbef", fontWeight: 500, }, @@ -476,6 +520,30 @@ const MessagesList = ({ ticketId, isGroup }) => { } }; + const renderQuotedMessage = message => { + return ( +
+ +
+ {!message.quotedMsg?.fromMe && ( + + {message.contact?.name} + + )} + {message.quotedMsg?.body} +
+
+ ); + }; + const renderMessages = () => { if (messagesList.length > 0) { const viewMessagesList = messagesList.map((message, index) => { @@ -492,6 +560,7 @@ const MessagesList = ({ ticketId, isGroup }) => { )} {message.mediaUrl && checkMessageMedia(message)}
+ {message.quotedMsg && renderQuotedMessage(message)} {message.body} {format(parseISO(message.createdAt), "HH:mm")} @@ -529,6 +598,7 @@ const MessagesList = ({ ticketId, isGroup }) => { className={classes.deletedIcon} /> )} + {message.quotedMsg && renderQuotedMessage(message)} {message.body} {format(parseISO(message.createdAt), "HH:mm")}