2022-01-06 01:26:15 +00:00
|
|
|
import React, { useState, useRef, useEffect, useContext } from "react";
|
|
|
|
|
|
|
|
import { useHistory } from "react-router-dom";
|
|
|
|
import { format } from "date-fns";
|
|
|
|
import openSocket from "socket.io-client";
|
|
|
|
import useSound from "use-sound";
|
|
|
|
|
|
|
|
import Popover from "@material-ui/core/Popover";
|
2022-04-28 20:57:57 +00:00
|
|
|
//import IconButton from "@material-ui/core/IconButton";
|
2022-01-06 01:26:15 +00:00
|
|
|
import List from "@material-ui/core/List";
|
|
|
|
import ListItem from "@material-ui/core/ListItem";
|
|
|
|
import ListItemText from "@material-ui/core/ListItemText";
|
|
|
|
import { makeStyles } from "@material-ui/core/styles";
|
2022-04-28 20:57:57 +00:00
|
|
|
//import Badge from "@material-ui/core/Badge";
|
|
|
|
//import ChatIcon from "@material-ui/icons/Chat";
|
2022-01-06 01:26:15 +00:00
|
|
|
|
|
|
|
import TicketListItem from "../TicketListItem";
|
|
|
|
import { i18n } from "../../translate/i18n";
|
|
|
|
import useTickets from "../../hooks/useTickets";
|
|
|
|
import alertSound from "../../assets/sound.mp3";
|
|
|
|
import { AuthContext } from "../../context/Auth/AuthContext";
|
|
|
|
|
|
|
|
const useStyles = makeStyles(theme => ({
|
|
|
|
tabContainer: {
|
|
|
|
overflowY: "auto",
|
|
|
|
maxHeight: 350,
|
|
|
|
...theme.scrollbarStyles,
|
|
|
|
},
|
|
|
|
popoverPaper: {
|
|
|
|
width: "100%",
|
|
|
|
maxWidth: 350,
|
|
|
|
marginLeft: theme.spacing(2),
|
|
|
|
marginRight: theme.spacing(1),
|
|
|
|
[theme.breakpoints.down("sm")]: {
|
|
|
|
maxWidth: 270,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
noShadow: {
|
|
|
|
boxShadow: "none !important",
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
const NotificationsPopOver = () => {
|
|
|
|
const classes = useStyles();
|
|
|
|
|
|
|
|
const history = useHistory();
|
|
|
|
const { user } = useContext(AuthContext);
|
|
|
|
const ticketIdUrl = +history.location.pathname.split("/")[2];
|
|
|
|
const ticketIdRef = useRef(ticketIdUrl);
|
|
|
|
const anchorEl = useRef();
|
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
const [notifications, setNotifications] = useState([]);
|
|
|
|
|
|
|
|
const [, setDesktopNotifications] = useState([]);
|
|
|
|
|
|
|
|
const { tickets } = useTickets({ withUnreadMessages: "true" });
|
|
|
|
const [play] = useSound(alertSound);
|
|
|
|
const soundAlertRef = useRef();
|
|
|
|
|
|
|
|
const historyRef = useRef(history);
|
|
|
|
|
2022-05-16 02:48:06 +00:00
|
|
|
|
|
|
|
const { handleLogout } = useContext(AuthContext);
|
|
|
|
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
useEffect(() => {
|
|
|
|
soundAlertRef.current = play;
|
|
|
|
|
|
|
|
if (!("Notification" in window)) {
|
|
|
|
console.log("This browser doesn't support notifications");
|
|
|
|
} else {
|
|
|
|
Notification.requestPermission();
|
|
|
|
}
|
|
|
|
}, [play]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
setNotifications(tickets);
|
|
|
|
}, [tickets]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
ticketIdRef.current = ticketIdUrl;
|
|
|
|
}, [ticketIdUrl]);
|
|
|
|
|
2022-05-06 22:49:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
2022-05-16 02:48:06 +00:00
|
|
|
|
|
|
|
socket.on("onlineStatus", (data) => {
|
|
|
|
|
|
|
|
if(data.action === "logout"){
|
|
|
|
|
|
|
|
console.log('___________data.userId: ', data.userOnlineTime['status'])
|
|
|
|
|
|
|
|
if(`${user.id}` === data.userOnlineTime['userId']){
|
|
|
|
|
|
|
|
socket.emit("online", {logoutUserId: user.id})
|
|
|
|
handleLogout();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
});
|
2022-05-06 22:49:45 +00:00
|
|
|
|
|
|
|
socket.on("isOnline", (data) => {
|
|
|
|
|
|
|
|
// console.log('___________data.userId: ', data.userId)
|
|
|
|
|
|
|
|
if(data.action === "online"){
|
|
|
|
|
|
|
|
if(data.userId === user.id){
|
|
|
|
|
|
|
|
socket.emit("online", user.id)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
socket.disconnect();
|
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
useEffect(() => {
|
|
|
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
|
|
|
|
2022-05-06 22:49:45 +00:00
|
|
|
socket.on("connect", () => socket.emit("joinNotification"));
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
|
|
|
|
socket.on("ticket", data => {
|
|
|
|
if (data.action === "updateUnread" || data.action === "delete") {
|
|
|
|
setNotifications(prevState => {
|
|
|
|
const ticketIndex = prevState.findIndex(t => t.id === data.ticketId);
|
|
|
|
if (ticketIndex !== -1) {
|
|
|
|
prevState.splice(ticketIndex, 1);
|
|
|
|
return [...prevState];
|
|
|
|
}
|
|
|
|
return prevState;
|
|
|
|
});
|
|
|
|
|
|
|
|
setDesktopNotifications(prevState => {
|
|
|
|
const notfiticationIndex = prevState.findIndex(
|
|
|
|
n => n.tag === String(data.ticketId)
|
|
|
|
);
|
|
|
|
if (notfiticationIndex !== -1) {
|
|
|
|
prevState[notfiticationIndex].close();
|
|
|
|
prevState.splice(notfiticationIndex, 1);
|
|
|
|
return [...prevState];
|
|
|
|
}
|
|
|
|
return prevState;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("appMessage", data => {
|
|
|
|
if (
|
|
|
|
data.action === "create" &&
|
|
|
|
!data.message.read &&
|
|
|
|
(data.ticket.userId === user?.id || !data.ticket.userId)
|
|
|
|
) {
|
2022-04-28 20:57:57 +00:00
|
|
|
|
2022-05-06 22:49:45 +00:00
|
|
|
// console.log(`data.ticket.userId: ${data.ticket.userId }\n
|
|
|
|
// data.ticket.status: ${data.ticket.status}\n
|
|
|
|
// data.ticket.userId: ${data.ticket.userId }`)
|
2022-04-28 20:57:57 +00:00
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
setNotifications(prevState => {
|
|
|
|
const ticketIndex = prevState.findIndex(t => t.id === data.ticket.id);
|
|
|
|
if (ticketIndex !== -1) {
|
|
|
|
prevState[ticketIndex] = data.ticket;
|
|
|
|
return [...prevState];
|
|
|
|
}
|
|
|
|
return [data.ticket, ...prevState];
|
|
|
|
});
|
|
|
|
|
|
|
|
const shouldNotNotificate =
|
|
|
|
(data.message.ticketId === ticketIdRef.current &&
|
|
|
|
document.visibilityState === "visible") ||
|
2022-04-28 20:57:57 +00:00
|
|
|
(data.ticket.userId && data.ticket.userId !== user?.id) ||
|
|
|
|
data.ticket.isGroup || !data.ticket.userId;
|
2022-01-06 01:26:15 +00:00
|
|
|
|
2022-04-28 20:57:57 +00:00
|
|
|
if (shouldNotNotificate) return;
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
|
|
|
|
handleNotifications(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
socket.disconnect();
|
|
|
|
};
|
|
|
|
}, [user]);
|
|
|
|
|
|
|
|
const handleNotifications = data => {
|
|
|
|
const { message, contact, ticket } = data;
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
body: `${message.body} - ${format(new Date(), "HH:mm")}`,
|
|
|
|
icon: contact.profilePicUrl,
|
|
|
|
tag: ticket.id,
|
|
|
|
renotify: true,
|
|
|
|
};
|
|
|
|
|
|
|
|
const notification = new Notification(
|
|
|
|
`${i18n.t("tickets.notification.message")} ${contact.name}`,
|
|
|
|
options
|
|
|
|
);
|
|
|
|
|
|
|
|
notification.onclick = e => {
|
|
|
|
e.preventDefault();
|
|
|
|
window.focus();
|
|
|
|
historyRef.current.push(`/tickets/${ticket.id}`);
|
|
|
|
};
|
|
|
|
|
|
|
|
setDesktopNotifications(prevState => {
|
|
|
|
const notfiticationIndex = prevState.findIndex(
|
|
|
|
n => n.tag === notification.tag
|
|
|
|
);
|
|
|
|
if (notfiticationIndex !== -1) {
|
|
|
|
prevState[notfiticationIndex] = notification;
|
|
|
|
return [...prevState];
|
|
|
|
}
|
|
|
|
return [notification, ...prevState];
|
|
|
|
});
|
|
|
|
|
|
|
|
soundAlertRef.current();
|
|
|
|
};
|
|
|
|
|
2022-04-28 20:57:57 +00:00
|
|
|
// const handleClick = () => {
|
|
|
|
// setIsOpen(prevState => !prevState);
|
|
|
|
// };
|
2022-01-06 01:26:15 +00:00
|
|
|
|
|
|
|
const handleClickAway = () => {
|
|
|
|
setIsOpen(false);
|
|
|
|
};
|
|
|
|
|
|
|
|
const NotificationTicket = ({ children }) => {
|
|
|
|
return <div onClick={handleClickAway}>{children}</div>;
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2022-04-28 20:57:57 +00:00
|
|
|
{/* <IconButton
|
2022-01-06 01:26:15 +00:00
|
|
|
onClick={handleClick}
|
2022-02-27 20:05:21 +00:00
|
|
|
// buttonRef={anchorEl}
|
|
|
|
ref={anchorEl}
|
2022-01-06 01:26:15 +00:00
|
|
|
aria-label="Open Notifications"
|
|
|
|
color="inherit"
|
|
|
|
>
|
|
|
|
<Badge badgeContent={notifications.length} color="secondary">
|
|
|
|
<ChatIcon />
|
|
|
|
</Badge>
|
2022-04-28 20:57:57 +00:00
|
|
|
</IconButton> */}
|
2022-01-06 01:26:15 +00:00
|
|
|
<Popover
|
|
|
|
disableScrollLock
|
|
|
|
open={isOpen}
|
|
|
|
anchorEl={anchorEl.current}
|
|
|
|
anchorOrigin={{
|
|
|
|
vertical: "bottom",
|
|
|
|
horizontal: "right",
|
|
|
|
}}
|
|
|
|
transformOrigin={{
|
|
|
|
vertical: "top",
|
|
|
|
horizontal: "right",
|
|
|
|
}}
|
|
|
|
classes={{ paper: classes.popoverPaper }}
|
|
|
|
onClose={handleClickAway}
|
|
|
|
>
|
|
|
|
<List dense className={classes.tabContainer}>
|
|
|
|
{notifications.length === 0 ? (
|
|
|
|
<ListItem>
|
|
|
|
<ListItemText>{i18n.t("notifications.noTickets")}</ListItemText>
|
|
|
|
</ListItem>
|
|
|
|
) : (
|
|
|
|
notifications.map(ticket => (
|
|
|
|
<NotificationTicket key={ticket.id}>
|
|
|
|
<TicketListItem ticket={ticket} />
|
|
|
|
</NotificationTicket>
|
|
|
|
))
|
|
|
|
)}
|
|
|
|
</List>
|
|
|
|
</Popover>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default NotificationsPopOver;
|