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

100% Statements 32/32
90.9% Branches 20/22
100% Functions 10/10
100% Lines 32/32

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 113 114 115 116 117 118 1192x 2x 2x 2x         2x 2x 2x 2x 2x   5x         8x 8x 8x   3x   3x   3x 2x     4x 3x   1x   3x                     2x   1x 1x     3x       3x   1x   3x                         2x     2x       2x                         3x                                                
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";
 
export default function MarkAllReadButton({
  type,
}: {
  type: "chats" | "hosting" | "surfing" | "all";
}) {
  const { t } = useTranslation(MESSAGES);
  const queryClient = useQueryClient();
  const markAll = useMutation({
    mutationFn: async () => {
      const shouldMarkChats = type === "chats" || type === "all";
      const shouldMarkRequests =
        type === "hosting" || type === "surfing" || type === "all";
 
      if (shouldMarkChats) {
        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(),
          ),
        );
      }
 
      if (shouldMarkRequests) {
        const requestType: "all" | "hosting" | "surfing" =
          type === "hosting" || type === "surfing" ? type : "all";
        const data = await getAllPages({
          serviceFunction: service.requests.listHostRequests,
          listKey: "hostRequestsList",
          params: (previousData) => ({
            lastRequestId: previousData?.lastRequestId,
            type: requestType,
          }),
          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>
      )}
 
      <Button
        onClick={() => markAll.mutate()}
        loading={markAll.isPending}
        variant="text"
        size="small"
        startIcon={<DoneAllIcon sx={{ fontSize: "0.875rem" }} />}
        sx={{
          textTransform: "none",
          color: "var(--mui-palette-text-secondary)",
          fontSize: "0.875rem",
          paddingX: 1,
          paddingY: 0.5,
          "&:hover": {
            backgroundColor: "var(--mui-palette-action-hover)",
            color: "var(--mui-palette-text-primary)",
          },
        }}
      >
        {type === "all"
          ? t("mark_all_read_button_text")
          : t(`mark_all_read_button_text_${type}`)}
      </Button>
    </>
  );
}