All files / app/features/messages/requests MarkAllReadButton.tsx

100% Statements 33/33
100% Branches 11/11
100% Functions 12/12
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 1132x 2x 2x 2x 2x         2x 2x 2x 2x 2x   6x             6x         3x         6x 6x 6x   3x 2x     4x 3x   1x   3x                   1x     3x       3x   1x   3x                         2x     2x       2x                             3x                      
import { styled, Typography } from "@mui/material";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import Button from "components/Button";
import { DoneAllIcon } from "components/Icons";
import Snackbar from "components/Snackbar";
import {
  groupChatsListKey,
  hostRequestsListKey,
  pingQueryKey,
} from "features/queryKeys";
import { useTranslation } from "i18n";
import { MESSAGES } from "i18n/namespaces";
import { service } from "service";
import getAllPages from "utils/getAllPages";
 
const MarkAsReadButtonStyled = styled(Button)(({ theme }) => ({
  border: `1px solid var(--mui-palette-grey-800)`,
  borderRadius: theme.shape.borderRadius,
  marginBottom: theme.spacing(1),
  color: "var(--mui-palette-text-primary)",
}));
 
const MarkAsReadIconStyled = styled(DoneAllIcon)(({ theme }) => ({
  marginInlineEnd: theme.spacing(1),
  fontSize: theme.typography.body1.fontSize,
}));
 
export default function MarkAllReadButton({
  type,
}: {
  type: "chats" | "hosting" | "surfing";
}) {
  const { t } = useTranslation(MESSAGES);
  const queryClient = useQueryClient();
  const markAll = useMutation({
    mutationFn: async () => {
      if (type === "chats") {
        const data = await getAllPages({
          serviceFunction: service.conversations.listGroupChats,
          listKey: "groupChatsList",
          params: (previousData) => previousData?.lastMessageId,
          hasMore: (previousData) => !previousData.noMore,
        });
        await Promise.all(
          data.map<void>((chat) =>
            chat.latestMessage &&
            chat.lastSeenMessageId < chat.latestMessage.messageId
              ? service.conversations.markLastSeenGroupChat(
                  chat.groupChatId,
                  chat.latestMessage.messageId,
                )
              : Promise.resolve(),
          ),
        );
      } else {
        const data = await getAllPages({
          serviceFunction: service.requests.listHostRequests,
          listKey: "hostRequestsList",
          params: (previousData) => ({
            lastRequestId: previousData?.lastRequestId,
            type,
          }),
          hasMore: (previousData) => !previousData.noMore,
        });
        await Promise.all(
          data.map<void>((request) =>
            request.latestMessage &&
            request.lastSeenMessageId < request.latestMessage.messageId
              ? service.requests.markLastRequestSeen(
                  request.hostRequestId,
                  request.latestMessage.messageId,
                )
              : Promise.resolve(),
          ),
        );
      }
    },
 
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: hostRequestsListKey(),
      });
      queryClient.invalidateQueries({
        queryKey: [groupChatsListKey],
      });
      // Invalidate ping to update badge counts in tabs
      queryClient.invalidateQueries({
        queryKey: [pingQueryKey],
      });
    },
  });
 
  return (
    <>
      {markAll.error && (
        <Snackbar severity="error">{markAll.error.message}</Snackbar>
      )}
 
      <MarkAsReadButtonStyled
        loading={markAll.isPending}
        variant="text"
        onClick={() => markAll.mutate()}
        sx={{ color: "var(--mui-palette-text-primary)" }}
      >
        <MarkAsReadIconStyled />
        <Typography component="span">
          {t(`mark_all_read_button_text_${type}`)}
        </Typography>
      </MarkAsReadButtonStyled>
    </>
  );
}