improvement: moved notification logic to backend

This commit is contained in:
canove
2020-09-24 21:00:57 -03:00
parent c58baf3470
commit c7d3807219
5 changed files with 57 additions and 42 deletions

View File

@@ -12,6 +12,7 @@ type IndexQuery = {
status: string; status: string;
date: string; date: string;
showAll: string; showAll: string;
withUnreadMessages: string;
}; };
interface TicketData { interface TicketData {
@@ -25,7 +26,8 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
status, status,
date, date,
searchParam, searchParam,
showAll showAll,
withUnreadMessages
} = req.query as IndexQuery; } = req.query as IndexQuery;
const userId = req.user.id; const userId = req.user.id;
@@ -36,7 +38,8 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
status, status,
date, date,
showAll, showAll,
userId userId,
withUnreadMessages
}); });
return res.status(200).json({ tickets, count, hasMore }); return res.status(200).json({ tickets, count, hasMore });

View File

@@ -12,6 +12,7 @@ interface Request {
date?: string; date?: string;
showAll?: string; showAll?: string;
userId: string; userId: string;
withUnreadMessages?: string;
} }
interface Response { interface Response {
@@ -26,24 +27,24 @@ const ListTicketsService = async ({
status, status,
date, date,
showAll, showAll,
userId userId,
withUnreadMessages
}: Request): Promise<Response> => { }: Request): Promise<Response> => {
let whereCondition: Filterable["where"]; let whereCondition: Filterable["where"] = {
[Op.or]: [{ userId }, { status: "pending" }]
};
let includeCondition: Includeable[]; let includeCondition: Includeable[];
includeCondition = [ includeCondition = [
{ {
model: Contact, model: Contact,
as: "contact", as: "contact",
attributes: ["id", "name", "number", "profilePicUrl"], attributes: ["id", "name", "number", "profilePicUrl"]
include: ["extraInfo"]
} }
]; ];
if (showAll === "true") { if (showAll === "true") {
whereCondition = {}; whereCondition = {};
} else {
whereCondition = { userId };
} }
if (status) { if (status) {
@@ -102,6 +103,21 @@ const ListTicketsService = async ({
}; };
} }
if (withUnreadMessages === "true") {
includeCondition = [
...includeCondition,
{
model: Message,
as: "messages",
attributes: [],
where: {
read: false,
fromMe: false
}
}
];
}
const limit = 20; const limit = 20;
const offset = limit * (+pageNumber - 1); const offset = limit * (+pageNumber - 1);

View File

@@ -167,8 +167,6 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => {
const io = getIO(); const io = getIO();
wbot.on("message_create", async msg => { wbot.on("message_create", async msg => {
console.log(msg.type);
if (!isValidMsg(msg)) { if (!isValidMsg(msg)) {
return; return;
} }

View File

@@ -49,7 +49,7 @@ const NotificationsPopOver = () => {
const ticketId = +history.location.pathname.split("/")[2]; const ticketId = +history.location.pathname.split("/")[2];
const anchorEl = useRef(); const anchorEl = useRef();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [notifications, setNotifications] = useState([]); // const [notifications, setNotifications] = useState([]);
useEffect(() => { useEffect(() => {
if (!("Notification" in window)) { if (!("Notification" in window)) {
@@ -81,30 +81,7 @@ const NotificationsPopOver = () => {
}; };
}, [history, ticketId, userId]); }, [history, ticketId, userId]);
const { tickets: openTickets } = useTickets({ status: "open" }); const { tickets: notifications } = useTickets({ withUnreadMessages: "true" });
const { tickets: pendingTickets } = useTickets({
status: "pending",
showAll: true,
});
useEffect(() => {
if (openTickets.length > 0 || pendingTickets.length > 0) {
let aux = [];
openTickets.forEach(ticket => {
if (ticket.unreadMessages > 0) {
aux.push(ticket);
}
});
pendingTickets.forEach(ticket => {
if (ticket.unreadMessages > 0) {
aux.push(ticket);
}
});
setNotifications(aux);
}
}, [openTickets, pendingTickets]);
const showDesktopNotification = ({ message, contact, ticket }) => { const showDesktopNotification = ({ message, contact, ticket }) => {
const options = { const options = {
@@ -176,6 +153,8 @@ const NotificationsPopOver = () => {
<ListItemText>No tickets with unread messages.</ListItemText> <ListItemText>No tickets with unread messages.</ListItemText>
</ListItem> </ListItem>
) : ( ) : (
notifications &&
notifications.length > 0 &&
notifications.map(ticket => ( notifications.map(ticket => (
<NotificationTicket key={ticket.id}> <NotificationTicket key={ticket.id}>
<TicketListItem ticket={ticket} /> <TicketListItem ticket={ticket} />

View File

@@ -24,7 +24,7 @@ const reducer = (state, action) => {
} }
if (action.type === "UPDATE_TICKETS") { if (action.type === "UPDATE_TICKETS") {
const { ticket, status, loggedUser } = action.payload; const { ticket, status, loggedUser, withUnreadMessages } = action.payload;
const ticketIndex = state.findIndex(t => t.id === ticket.id); const ticketIndex = state.findIndex(t => t.id === ticket.id);
if (ticketIndex !== -1) { if (ticketIndex !== -1) {
@@ -41,6 +41,8 @@ const reducer = (state, action) => {
ticket.status === "closed") ticket.status === "closed")
) { ) {
state.unshift(ticket); state.unshift(ticket);
} else if (withUnreadMessages) {
state.unshift(ticket);
} }
return [...state]; return [...state];
} }
@@ -56,11 +58,14 @@ const reducer = (state, action) => {
} }
if (action.type === "RESET_UNREAD") { if (action.type === "RESET_UNREAD") {
const ticketId = action.payload; const { ticketId, withUnreadMessages } = action.payload;
const ticketIndex = state.findIndex(t => t.id === ticketId); const ticketIndex = state.findIndex(t => t.id === ticketId);
if (ticketIndex !== -1) { if (ticketIndex !== -1) {
state[ticketIndex].unreadMessages = 0; state[ticketIndex].unreadMessages = 0;
if (withUnreadMessages) {
state.splice(ticketIndex, 1);
}
} }
return [...state]; return [...state];
} }
@@ -70,7 +75,14 @@ const reducer = (state, action) => {
} }
}; };
const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { const useTickets = ({
searchParam,
pageNumber,
status,
date,
showAll,
withUnreadMessages,
}) => {
const userId = +localStorage.getItem("userId"); const userId = +localStorage.getItem("userId");
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [hasMore, setHasMore] = useState(false); const [hasMore, setHasMore] = useState(false);
@@ -79,7 +91,6 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
useEffect(() => { useEffect(() => {
setLoading(true); setLoading(true);
const delayDebounceFn = setTimeout(() => { const delayDebounceFn = setTimeout(() => {
console.log(showAll);
const fetchTickets = async () => { const fetchTickets = async () => {
try { try {
const { data } = await api.get("/tickets", { const { data } = await api.get("/tickets", {
@@ -89,6 +100,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
status, status,
date, date,
showAll, showAll,
withUnreadMessages,
}, },
}); });
dispatch({ dispatch({
@@ -107,7 +119,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
fetchTickets(); fetchTickets();
}, 500); }, 500);
return () => clearTimeout(delayDebounceFn); return () => clearTimeout(delayDebounceFn);
}, [searchParam, pageNumber, status, date, showAll]); }, [searchParam, pageNumber, status, date, showAll, withUnreadMessages]);
useEffect(() => { useEffect(() => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL); const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
@@ -115,7 +127,13 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
socket.on("ticket", data => { socket.on("ticket", data => {
if (data.action === "updateUnread") { if (data.action === "updateUnread") {
dispatch({ type: "RESET_UNREAD", payload: data.ticketId }); dispatch({
type: "RESET_UNREAD",
payload: {
ticketId: data.ticketId,
withUnreadMessages: withUnreadMessages,
},
});
} }
if (data.action === "updateStatus" || data.action === "create") { if (data.action === "updateStatus" || data.action === "create") {
@@ -141,6 +159,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
payload: { payload: {
ticket: data.ticket, ticket: data.ticket,
status: status, status: status,
withUnreadMessages: withUnreadMessages,
loggedUser: userId, loggedUser: userId,
}, },
}); });
@@ -150,7 +169,7 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => {
return () => { return () => {
socket.disconnect(); socket.disconnect();
}; };
}, [status, userId]); }, [status, withUnreadMessages, userId]);
return { loading, tickets, hasMore, dispatch }; return { loading, tickets, hasMore, dispatch };
}; };