Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { useApolloClient } from "@apollo/client";
2import { type AccountFragment, useFollowMutation } from "@hey/indexer";
3import type { ApolloClientError } from "@hey/types/errors";
4import { useCallback, useState } from "react";
5import { Button } from "@/components/Shared/UI";
6import errorToast from "@/helpers/errorToast";
7import useTransactionLifecycle from "@/hooks/useTransactionLifecycle";
8import { useAuthModalStore } from "@/store/non-persisted/modal/useAuthModalStore";
9import { useAccountStore } from "@/store/persisted/useAccountStore";
10
11interface FollowProps {
12 onFollow?: () => void;
13 buttonClassName: string;
14 account: AccountFragment;
15 small: boolean;
16 title?: string;
17}
18
19const Follow = ({
20 onFollow,
21 buttonClassName,
22 account,
23 small,
24 title = "Follow"
25}: FollowProps) => {
26 const { currentAccount } = useAccountStore();
27 const { setShowAuthModal } = useAuthModalStore();
28 const [isSubmitting, setIsSubmitting] = useState(false);
29 const { cache } = useApolloClient();
30 const handleTransactionLifecycle = useTransactionLifecycle();
31
32 const updateCache = () => {
33 if (!account.operations) {
34 return;
35 }
36
37 cache.modify({
38 fields: { isFollowedByMe: () => true },
39 id: cache.identify(account.operations)
40 });
41 };
42
43 const onCompleted = () => {
44 updateCache();
45 setIsSubmitting(false);
46 onFollow?.();
47 };
48
49 const onError = useCallback((error: ApolloClientError) => {
50 setIsSubmitting(false);
51 errorToast(error);
52 }, []);
53
54 const [follow] = useFollowMutation({
55 onCompleted: async ({ follow }) => {
56 if (follow.__typename === "FollowResponse") {
57 return onCompleted();
58 }
59
60 if (follow.__typename === "AccountFollowOperationValidationFailed") {
61 return onError({ message: follow.reason });
62 }
63
64 return await handleTransactionLifecycle({
65 onCompleted,
66 onError,
67 transactionData: follow
68 });
69 },
70 onError
71 });
72
73 const handleCreateFollow = async () => {
74 if (!currentAccount) {
75 return setShowAuthModal(true);
76 }
77
78 setIsSubmitting(true);
79
80 return await follow({
81 variables: { request: { account: account.address } }
82 });
83 };
84
85 return (
86 <Button
87 aria-label={title}
88 className={buttonClassName}
89 disabled={isSubmitting}
90 loading={isSubmitting}
91 onClick={handleCreateFollow}
92 outline
93 size={small ? "sm" : "md"}
94 >
95 {title}
96 </Button>
97 );
98};
99
100export default Follow;