diff --git a/src/components/Drawers.tsx b/src/components/Drawers.tsx index 736b772..58ccf2f 100644 --- a/src/components/Drawers.tsx +++ b/src/components/Drawers.tsx @@ -40,7 +40,10 @@ function Drawers() { const siteReadyPayCart = allTypesOfPurchases(state => state.siteReadyPayCart) const notificationsCount = tickets.filter( - ({ user, top_message }) => user !== top_message.user_id && top_message.shown.me !== 1 + ({ user, top_message }) => + user !== top_message.user_id && + top_message.shown.me !== 1 && + !top_message.system ).length; async function handlePayClick() { @@ -134,7 +137,10 @@ function Drawers() { setOpen={setOpenNotificationsModal} anchorElement={bellRef.current} notifications={tickets - .filter(({ user, top_message }) => user !== top_message.user_id) + .filter(({ user, top_message }) => + user !== top_message.user_id && + !top_message.system + ) .map((ticket) => ({ text: "У вас новое сообщение от техподдержки", date: new Date(ticket.updated_at).toLocaleDateString(), diff --git a/src/components/FloatingSupportChat/Chat.tsx b/src/components/FloatingSupportChat/Chat.tsx index 8d3cd25..b16200c 100644 --- a/src/components/FloatingSupportChat/Chat.tsx +++ b/src/components/FloatingSupportChat/Chat.tsx @@ -250,41 +250,42 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) { useEffect(() => { if (open && messages.length > 1) { + // Ищем последнее непрочитанное сообщение НЕ от текущего пользователя let lastUnreadMessage = null; - // Ищем последнее непрочитанное чужое сообщение до первого прочитанного или своего for (let i = messages.length - 1; i >= 0; i--) { const message = messages[i]; - const isOwnMessage = (ticket.sessionData?.sessionId || user) === message.user_id; - // Пропускаем системные сообщения - if (message.ticket_id === "111") { + // Пропускаем системные сообщения (приветствие) + if (message.ticket_id === "111" || message.system) { continue; } - // Если встретили своё сообщение - прерываем поиск + // Определяем, является ли сообщение от текущего пользователя + const currentUserId = user || ticket.sessionData?.sessionId; + const isOwnMessage = currentUserId === message.user_id; + + // Если сообщение от нас - пропускаем if (isOwnMessage) { - break; + continue; } - // Если встретили прочитанное сообщение - прерываем поиск + // Если сообщение уже прочитано - пропускаем if (message.shown?.me === 1) { - break; + continue; } - // Если сообщение чужое и не прочитано - запоминаем его - if (!isOwnMessage && message.shown?.me !== 1) { - lastUnreadMessage = message; - break; - } + // Нашли непрочитанное сообщение не от нас - запоминаем его + lastUnreadMessage = message; + break; } - // Если нашли непрочитанное сообщение - отмечаем его как прочитанное + // Отправляем shown только на последнее непрочитанное сообщение не от нас if (lastUnreadMessage) { shownMessage(lastUnreadMessage.id); } } - }, [open, messages]); + }, [open, messages, user, ticket.sessionData?.sessionId]); const loadNewMessages = ( event: WheelEvent | TouchEvent diff --git a/src/components/FloatingSupportChat/FloatingSupportChat.tsx b/src/components/FloatingSupportChat/FloatingSupportChat.tsx index 043d702..af12472 100644 --- a/src/components/FloatingSupportChat/FloatingSupportChat.tsx +++ b/src/components/FloatingSupportChat/FloatingSupportChat.tsx @@ -42,7 +42,7 @@ export default function FloatingSupportChat() { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(800)); const user = useUserStore((state) => state.user?._id); - const { messages } = useTicketStore( + const { messages, sessionData } = useTicketStore( (state) => state[user ? "authData" : "unauthData"] ); @@ -72,17 +72,44 @@ export default function FloatingSupportChat() { }; const unreadMessagesCount = useMemo(() => { - let count = 0; + if (messages.length === 0) return 0; - // Идём с конца массива к началу - for (let i = messages.length - 1; i >= 0; i--) { + // Получаем последнее сообщение + const lastMessage = messages[messages.length - 1]; + + // Определяем, является ли сообщение от текущего пользователя + const currentUserId = user || sessionData?.sessionId; + const isLastMessageOwn = currentUserId === lastMessage.user_id; + + // Если последнее сообщение моё - не показываем количество + if (isLastMessageOwn) { + return 0; + } + + // Если последнее сообщение не моё, но прочитано - не показываем количество + if (lastMessage.shown?.me === 1) { + return 0; + } + + // Если последнее сообщение не моё и не прочитано - считаем его +1 + let count = 1; + + // Считаем все предыдущие непрочитанные сообщения до своего + for (let i = messages.length - 2; i >= 0; i--) { const message = messages[i]; - - // Пропускаем сообщение с id "111" - if (message.id === "111") continue; - - // Если сообщение не прочитано (shown.me !== 1) - if (message.shown.me !== 1) { + + // Пропускаем системные сообщения + if (message.id === "111" || message.system) { + continue; + } + + // Если встретили своё сообщение - прекращаем подсчёт + if (currentUserId === message.user_id) { + break; + } + + // Если сообщение не прочитано - увеличиваем счетчик + if (message.shown?.me !== 1) { count++; } else { // Встретили прочитанное сообщение - прекращаем подсчёт @@ -91,7 +118,7 @@ export default function FloatingSupportChat() { } return count; - }, [messages]); // Зависимость от messages - пересчитывается при их изменении + }, [messages, user, sessionData?.sessionId]); useEffect(() => { const onResize = () => { diff --git a/src/components/NavbarSite/NavbarCollapsed.tsx b/src/components/NavbarSite/NavbarCollapsed.tsx index 8461096..5463e12 100644 --- a/src/components/NavbarSite/NavbarCollapsed.tsx +++ b/src/components/NavbarSite/NavbarCollapsed.tsx @@ -48,7 +48,9 @@ export default function NavbarCollapsed({ children }: Props) { const notificationsCount = tickets.filter( ({ user, top_message }) => - user !== top_message.user_id && top_message.shown.me !== 1 + user !== top_message.user_id && + top_message.shown.me !== 1 && + !top_message.system ).length useEffect(() => { @@ -186,7 +188,10 @@ export default function NavbarCollapsed({ children }: Props) { setOpen={setOpenNotificationsModal} anchorElement={bellRef.current} notifications={tickets - .filter(({ user, top_message }) => user !== top_message.user_id) + .filter(({ user, top_message }) => + user !== top_message.user_id && + !top_message.system + ) .map((ticket) => ({ text: "У вас новое сообщение от техподдержки", date: new Date(ticket.updated_at).toLocaleDateString(), diff --git a/src/pages/Support/TicketList/TicketList.tsx b/src/pages/Support/TicketList/TicketList.tsx index 2e6c011..8762e24 100644 --- a/src/pages/Support/TicketList/TicketList.tsx +++ b/src/pages/Support/TicketList/TicketList.tsx @@ -23,6 +23,7 @@ function TicketList() { const fetchState = useTicketStore(state => state.ticketsFetchState) const sortedTickets = tickets + .filter(ticket => !ticket?.top_message?.system) .sort(sortTicketsByUpdateTime) .slice( ticketApiPage * ticketsPerPage, diff --git a/src/stores/tickets.ts b/src/stores/tickets.ts index 51a3fcf..a4e48fd 100644 --- a/src/stores/tickets.ts +++ b/src/stores/tickets.ts @@ -44,7 +44,7 @@ const initialState: TicketStore = { ticketCount: 0, tickets: [], apiPage: 0, - ticketsPerPage: 10, + ticketsPerPage: 100, ticketsFetchState: "idle", authData: initAuthData, unauthData: initAuthData,