Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 100 lines 2.5 kB view raw
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;