All files / app/features/connections/friends AddFriendButton.tsx

90.9% Statements 40/44
66.66% Branches 4/6
80% Functions 8/10
90.9% Lines 40/44

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 1194x 4x 4x 4x 4x 4x 4x 4x 4x   4x 4x 4x 4x 4x 4x                 8x 25x 25x 25x 25x   25x   25x 3x   3x 3x   3x       3x   3x           3x       1x 1x           1x           25x 6x 1x   5x       25x 3x 3x                                                     1x                            
import { Link } from "@mui/material";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import Button from "components/Button";
import { Dialog, DialogActions, DialogContent, DialogTitle } from "components/Dialog";
import { PersonAddIcon } from "components/Icons";
import ProfileIncompleteDialog from "components/ProfileIncompleteDialog/ProfileIncompleteDialog";
import { doAntibot } from "features/antibot/antibot";
import useAccountInfo from "features/auth/useAccountInfo";
import { userKey } from "features/queryKeys";
import { Empty } from "google-protobuf/google/protobuf/empty_pb";
import { Trans, useTranslation } from "i18n";
import { CONNECTIONS, GLOBAL, PROFILE } from "i18n/namespaces";
import { User } from "proto/api_pb";
import React, { useState } from "react";
import { helpCenterFriendRequestsURL } from "routes";
import { service } from "service";
 
import { SetMutationError } from ".";
 
interface AddFriendButtonProps {
  setMutationError: SetMutationError;
  userId: number;
}
 
export default function AddFriendButton({ setMutationError, userId }: AddFriendButtonProps) {
  const queryClient = useQueryClient();
  const { t } = useTranslation([PROFILE, CONNECTIONS, GLOBAL]);
  const [showCantFriendDialog, setShowCantFriendDialog] = useState<boolean>(false);
  const [showConfirmDialog, setShowConfirmDialog] = useState<boolean>(false);
 
  const { data: accountInfo, isLoading: isAccountInfoLoading } = useAccountInfo();
 
  const { isPending, mutate: sendFriendRequest } = useMutation<Empty, Error, AddFriendButtonProps>({
    mutationFn: ({ userId }) => service.api.sendFriendRequest(userId),
    onMutate: async ({ setMutationError }) => {
      setMutationError("");
      doAntibot("friend_request");
 
      await queryClient.cancelQueries({
        queryKey: userKey(userId),
      });
 
      const cachedUser = queryClient.getQueryData<User.AsObject>(userKey(userId));
 
      Iif (cachedUser) {
        queryClient.setQueryData<User.AsObject>(userKey(userId), {
          ...cachedUser,
          friends: User.FriendshipStatus.PENDING,
        });
      }
      return cachedUser;
    },
 
    onError: (error, { setMutationError }, cachedUser) => {
      setMutationError(error.message);
      Iif (cachedUser) {
        queryClient.setQueryData(userKey(userId), cachedUser);
      }
    },
 
    onSuccess: (_, { userId }) => {
      queryClient.invalidateQueries({
        queryKey: userKey(userId),
      });
    },
  });
 
  const onClick = () => {
    if (!accountInfo?.profileComplete) {
      setShowCantFriendDialog(true);
    } else {
      setShowConfirmDialog(true);
    }
  };
 
  const onConfirm = () => {
    setShowConfirmDialog(false);
    sendFriendRequest({ setMutationError, userId });
  };
 
  return (
    <>
      <ProfileIncompleteDialog
        open={showCantFriendDialog}
        onClose={() => setShowCantFriendDialog(false)}
        attempted_action="send_friend_request"
      />
      <Dialog
        aria-labelledby="add-friend-confirm-dialog"
        open={showConfirmDialog}
        onClose={() => setShowConfirmDialog(false)}
      >
        <DialogTitle id="add-friend-confirm-dialog">
          {t("connections:add_friend_confirmation_dialog.title")}
        </DialogTitle>
        <DialogContent>
          <Trans
            i18nKey="connections:add_friend_confirmation_dialog.message"
            components={{
              helpCenterLink: <Link href={helpCenterFriendRequestsURL} target="_blank" rel="noopener noreferrer" />,
            }}
          />
        </DialogContent>
        <DialogActions>
          <Button variant="outlined" onClick={() => setShowConfirmDialog(false)}>
            {t("global:cancel")}
          </Button>
          <Button variant="contained" loading={isPending} onClick={onConfirm}>
            {t("connections:add_friend_confirmation_dialog.confirm")}
          </Button>
        </DialogActions>
      </Dialog>
      <Button startIcon={<PersonAddIcon />} onClick={onClick} loading={isPending} disabled={isAccountInfoLoading}>
        {t("profile:actions.add_friend")}
      </Button>
    </>
  );
}