diff --git a/backend/src/services/wbotMessageListener.js b/backend/src/services/wbotMessageListener.js
index bf860d2..99dab36 100644
--- a/backend/src/services/wbotMessageListener.js
+++ b/backend/src/services/wbotMessageListener.js
@@ -9,7 +9,7 @@ const Ticket = require("../models/Ticket");
const Message = require("../models/Message");
const { getIO } = require("../libs/socket");
-const { getWbot } = require("../libs/wbot");
+const { getWbot, init } = require("../libs/wbot");
const verifyContact = async (msgContact, profilePicUrl) => {
let contact = await Contact.findOne({
@@ -66,7 +66,7 @@ const verifyTicket = async contact => {
const handlMedia = async (msg, ticket) => {
const media = await msg.downloadMedia();
let newMessage;
-
+ console.log("criando midia");
if (media) {
if (!media.filename) {
let ext = media.mimetype.split("/")[1].split(";")[0];
@@ -150,14 +150,6 @@ const wbotMessageListener = () => {
let msgContact;
if (msg.fromMe) {
- const alreadyExists = await Message.findOne({
- where: { id: msg.id.id },
- });
- // return if message was already created by messagesController
- if (alreadyExists) {
- return;
- }
-
msgContact = await wbot.getContactById(msg.to);
} else {
msgContact = await msg.getContact();
@@ -167,6 +159,17 @@ const wbotMessageListener = () => {
const contact = await verifyContact(msgContact, profilePicUrl);
const ticket = await verifyTicket(contact);
+ //return if message was already created by messageController
+ if (msg.fromMe) {
+ const alreadyExists = await Message.findOne({
+ where: { id: msg.id.id },
+ });
+
+ if (alreadyExists) {
+ return;
+ }
+ }
+
await handleMessage(msg, ticket, contact);
} catch (err) {
Sentry.captureException(err);
@@ -179,11 +182,9 @@ const wbotMessageListener = () => {
const messageToUpdate = await Message.findOne({
where: { id: msg.id.id },
});
-
if (!messageToUpdate) {
return;
}
-
await messageToUpdate.update({ ack: ack });
io.to(messageToUpdate.ticketId).emit("appMessage", {
diff --git a/frontend/src/components/_layout/MainListItems.js b/frontend/src/components/_layout/MainListItems.js
new file mode 100644
index 0000000..41dd8c7
--- /dev/null
+++ b/frontend/src/components/_layout/MainListItems.js
@@ -0,0 +1,60 @@
+import React from "react";
+import { Link as RouterLink } from "react-router-dom";
+
+import ListItem from "@material-ui/core/ListItem";
+import ListItemIcon from "@material-ui/core/ListItemIcon";
+import ListItemText from "@material-ui/core/ListItemText";
+import DashboardIcon from "@material-ui/icons/Dashboard";
+import WhatsAppIcon from "@material-ui/icons/WhatsApp";
+import SyncAltIcon from "@material-ui/icons/SyncAlt";
+
+import ContactPhoneIcon from "@material-ui/icons/ContactPhone";
+
+import { i18n } from "../../translate/i18n";
+
+function ListItemLink(props) {
+ const { icon, primary, to, className } = props;
+
+ const renderLink = React.useMemo(
+ () =>
+ React.forwardRef((itemProps, ref) => (
+
+ )),
+ [to]
+ );
+
+ return (
+
+
+ {icon ? {icon} : null}
+
+
+
+ );
+}
+
+const MainListItems = () => {
+ return (
+
+ } />
+ }
+ />
+ }
+ />
+
+ }
+ />
+
+ );
+};
+
+export default MainListItems;
diff --git a/frontend/src/components/_layout/index.js b/frontend/src/components/_layout/index.js
new file mode 100644
index 0000000..abbd9ae
--- /dev/null
+++ b/frontend/src/components/_layout/index.js
@@ -0,0 +1,302 @@
+import React, { useState, useContext, useEffect } from "react";
+import clsx from "clsx";
+import { makeStyles } from "@material-ui/core/styles";
+
+import Drawer from "@material-ui/core/Drawer";
+
+import AppBar from "@material-ui/core/AppBar";
+import Toolbar from "@material-ui/core/Toolbar";
+import List from "@material-ui/core/List";
+import Typography from "@material-ui/core/Typography";
+import Divider from "@material-ui/core/Divider";
+import IconButton from "@material-ui/core/IconButton";
+import Badge from "@material-ui/core/Badge";
+
+import MenuIcon from "@material-ui/icons/Menu";
+import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
+import NotificationsIcon from "@material-ui/icons/Notifications";
+import MainListItems from "./MainListItems";
+import AccountCircle from "@material-ui/icons/AccountCircle";
+
+import MenuItem from "@material-ui/core/MenuItem";
+import Menu from "@material-ui/core/Menu";
+
+import openSocket from "socket.io-client";
+import { format } from "date-fns";
+import { toast } from "react-toastify";
+import { useHistory, useParams } from "react-router-dom";
+import { i18n } from "../../translate/i18n";
+
+import { AuthContext } from "../../context/Auth/AuthContext";
+
+const drawerWidth = 240;
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ display: "flex",
+ height: "100vh",
+ },
+
+ toolbar: {
+ paddingRight: 24, // keep right padding when drawer closed
+ },
+ toolbarIcon: {
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "flex-end",
+ padding: "0 8px",
+ minHeight: "48px",
+ },
+ appBar: {
+ zIndex: theme.zIndex.drawer + 1,
+ transition: theme.transitions.create(["width", "margin"], {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ },
+ appBarShift: {
+ marginLeft: drawerWidth,
+ width: `calc(100% - ${drawerWidth}px)`,
+ transition: theme.transitions.create(["width", "margin"], {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ },
+ menuButton: {
+ marginRight: 36,
+ },
+ menuButtonHidden: {
+ display: "none",
+ },
+ title: {
+ flexGrow: 1,
+ },
+ drawerPaper: {
+ position: "relative",
+ whiteSpace: "nowrap",
+ width: drawerWidth,
+ transition: theme.transitions.create("width", {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ },
+ drawerPaperClose: {
+ overflowX: "hidden",
+ transition: theme.transitions.create("width", {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ width: theme.spacing(7),
+ [theme.breakpoints.up("sm")]: {
+ width: theme.spacing(9),
+ },
+ },
+ appBarSpacer: {
+ minHeight: "48px",
+ },
+ content: {
+ flex: 1,
+ overflow: "auto",
+ },
+ container: {
+ paddingTop: theme.spacing(4),
+ paddingBottom: theme.spacing(4),
+ },
+ paper: {
+ padding: theme.spacing(2),
+ display: "flex",
+ overflow: "auto",
+ flexDirection: "column",
+ },
+}));
+
+const MainDrawer = ({ appTitle, children }) => {
+ const { handleLogout } = useContext(AuthContext);
+ const classes = useStyles();
+ const [open, setOpen] = useState(true);
+ const [anchorEl, setAnchorEl] = React.useState(null);
+ const menuOpen = Boolean(anchorEl);
+ const drawerState = localStorage.getItem("drawerOpen");
+
+ const history = useHistory();
+ const userId = +localStorage.getItem("userId");
+ const { ticketId } = useParams();
+ const [notifications, setNotifications] = useState([]);
+
+ useEffect(() => {
+ if (!("Notification" in window)) {
+ console.log("This browser doesn't support notifications");
+ } else {
+ Notification.requestPermission();
+ }
+ }, []);
+
+ useEffect(() => {
+ if (drawerState === "0") {
+ setOpen(false);
+ }
+ }, [drawerState]);
+
+ useEffect(() => {
+ const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
+ socket.emit("joinNotification");
+
+ socket.on("appMessage", data => {
+ if (data.action === "create") {
+ if (
+ (ticketId &&
+ data.message.ticketId === +ticketId &&
+ document.visibilityState === "visible") ||
+ (data.ticket.userId !== userId && data.ticket.userId)
+ )
+ return;
+ showDesktopNotification(data);
+ }
+ });
+
+ return () => {
+ socket.disconnect();
+ };
+ }, [history, ticketId, userId]);
+
+ const showDesktopNotification = ({ message, contact, ticket }) => {
+ const options = {
+ body: `${message.body} - ${format(new Date(), "HH:mm")}`,
+ icon: contact.profilePicUrl,
+ tag: ticket.id,
+ };
+ let notification = new Notification(
+ `${i18n.t("tickets.notification.message")} ${contact.name}`,
+ options
+ );
+
+ notification.onclick = function (event) {
+ event.preventDefault(); //
+ window.open(`/chat/${ticket.id}`, "_self");
+ };
+
+ document.addEventListener("visibilitychange", () => {
+ if (document.visibilityState === "visible") {
+ notification.close();
+ }
+ });
+
+ document.getElementById("sound").play();
+ };
+
+ const handleDrawerOpen = () => {
+ setOpen(true);
+ localStorage.setItem("drawerOpen", 1);
+ };
+ const handleDrawerClose = () => {
+ setOpen(false);
+ localStorage.setItem("drawerOpen", 0);
+ };
+
+ const handleMenu = event => {
+ setAnchorEl(event.currentTarget);
+ };
+
+ const handleClose = () => {
+ setAnchorEl(null);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {appTitle}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {children ? children : null}
+
+
+
+ );
+};
+
+export default MainDrawer;