Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 125 lines 3.0 kB view raw
1import { useApolloClient } from "@apollo/client"; 2import { 3 type GroupFragment, 4 useJoinGroupMutation, 5 useRequestGroupMembershipMutation 6} from "@hey/indexer"; 7import type { ApolloClientError } from "@hey/types/errors"; 8import { useCallback, useState } from "react"; 9import { toast } from "sonner"; 10import { Button } from "@/components/Shared/UI"; 11import errorToast from "@/helpers/errorToast"; 12import useTransactionLifecycle from "@/hooks/useTransactionLifecycle"; 13 14interface JoinProps { 15 group: GroupFragment; 16 small: boolean; 17 className?: string; 18 title?: string; 19 onSuccess?: () => void; 20} 21 22const Join = ({ 23 group, 24 small, 25 className = "", 26 title = "Join", 27 onSuccess 28}: JoinProps) => { 29 const [isSubmitting, setIsSubmitting] = useState(false); 30 const { cache } = useApolloClient(); 31 const handleTransactionLifecycle = useTransactionLifecycle(); 32 const updateCache = () => { 33 if (!group.operations) { 34 return; 35 } 36 37 cache.modify({ 38 fields: { 39 hasRequestedMembership: () => group.membershipApprovalEnabled, 40 isMember: () => !group.membershipApprovalEnabled 41 }, 42 id: cache.identify(group.operations) 43 }); 44 }; 45 46 const onCompleted = () => { 47 updateCache(); 48 setIsSubmitting(false); 49 onSuccess?.(); 50 toast.success( 51 group.membershipApprovalEnabled ? "Request sent" : "Joined group" 52 ); 53 }; 54 55 const onError = useCallback((error: ApolloClientError) => { 56 setIsSubmitting(false); 57 errorToast(error); 58 }, []); 59 60 const [joinGroup] = useJoinGroupMutation({ 61 onCompleted: async ({ joinGroup }) => { 62 if (joinGroup.__typename === "JoinGroupResponse") { 63 return onCompleted(); 64 } 65 66 if (joinGroup.__typename === "GroupOperationValidationFailed") { 67 return onError({ message: joinGroup.reason }); 68 } 69 70 return await handleTransactionLifecycle({ 71 onCompleted, 72 onError, 73 transactionData: joinGroup 74 }); 75 }, 76 onError 77 }); 78 79 const [requestGroupMembership] = useRequestGroupMembershipMutation({ 80 onCompleted: async ({ requestGroupMembership }) => { 81 if ( 82 requestGroupMembership.__typename === "RequestGroupMembershipResponse" 83 ) { 84 return onCompleted(); 85 } 86 87 return await handleTransactionLifecycle({ 88 onCompleted, 89 onError, 90 transactionData: joinGroup 91 }); 92 }, 93 onError 94 }); 95 96 const handleJoin = async () => { 97 setIsSubmitting(true); 98 99 if (group.membershipApprovalEnabled) { 100 return await requestGroupMembership({ 101 variables: { request: { group: group.address } } 102 }); 103 } 104 105 return await joinGroup({ 106 variables: { request: { group: group.address } } 107 }); 108 }; 109 110 return ( 111 <Button 112 aria-label="Join" 113 className={className} 114 disabled={isSubmitting} 115 loading={isSubmitting} 116 onClick={handleJoin} 117 outline 118 size={small ? "sm" : "md"} 119 > 120 {title} 121 </Button> 122 ); 123}; 124 125export default Join;