Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 111 lines 3.1 kB view raw
1import { UsersIcon } from "@heroicons/react/24/outline"; 2import { 3 type FollowersYouKnowRequest, 4 useFollowersYouKnowQuery 5} from "@hey/indexer"; 6import { motion } from "motion/react"; 7import { useCallback } from "react"; 8import { Virtualizer } from "virtua"; 9import SingleAccount from "@/components/Shared/Account/SingleAccount"; 10import AccountListShimmer from "@/components/Shared/Shimmer/AccountListShimmer"; 11import { EmptyState, ErrorMessage } from "@/components/Shared/UI"; 12import cn from "@/helpers/cn"; 13import useLoadMoreOnIntersect from "@/hooks/useLoadMoreOnIntersect"; 14import { useAccountStore } from "@/store/persisted/useAccountStore"; 15import { accountsList } from "@/variants"; 16 17interface FollowersYouKnowProps { 18 username: string; 19 address: string; 20} 21 22const FollowersYouKnow = ({ username, address }: FollowersYouKnowProps) => { 23 const { currentAccount } = useAccountStore(); 24 25 const request: FollowersYouKnowRequest = { 26 observer: currentAccount?.address, 27 target: address 28 }; 29 30 const { data, error, fetchMore, loading } = useFollowersYouKnowQuery({ 31 skip: !address, 32 variables: { request } 33 }); 34 35 const followersYouKnow = data?.followersYouKnow?.items; 36 const pageInfo = data?.followersYouKnow?.pageInfo; 37 const hasMore = pageInfo?.next; 38 39 const handleEndReached = useCallback(async () => { 40 if (hasMore) { 41 await fetchMore({ 42 variables: { request: { ...request, cursor: pageInfo?.next } } 43 }); 44 } 45 }, [fetchMore, hasMore, pageInfo?.next, request]); 46 47 const loadMoreRef = useLoadMoreOnIntersect(handleEndReached); 48 49 if (loading) { 50 return <AccountListShimmer />; 51 } 52 53 if (!followersYouKnow?.length) { 54 return ( 55 <EmptyState 56 hideCard 57 icon={<UsersIcon className="size-8" />} 58 message={ 59 <div> 60 <span className="mr-1 font-bold">{username}</span> 61 <span>doesn't have any mutual followers.</span> 62 </div> 63 } 64 /> 65 ); 66 } 67 68 if (error) { 69 return ( 70 <ErrorMessage 71 className="m-5" 72 error={error} 73 title="Failed to load mutual followers" 74 /> 75 ); 76 } 77 78 return ( 79 <div className="max-h-[80vh] overflow-y-auto"> 80 <Virtualizer> 81 {followersYouKnow.map((follower, index) => ( 82 <motion.div 83 animate="visible" 84 className={cn( 85 "divider p-5", 86 index === followersYouKnow.length - 1 && "border-b-0" 87 )} 88 initial="hidden" 89 key={follower.follower.address} 90 variants={accountsList} 91 > 92 <SingleAccount 93 account={follower.follower} 94 hideFollowButton={ 95 currentAccount?.address === follower.follower.address 96 } 97 hideUnfollowButton={ 98 currentAccount?.address === follower.follower.address 99 } 100 showBio 101 showUserPreview={false} 102 /> 103 </motion.div> 104 ))} 105 {hasMore && <span ref={loadMoreRef} />} 106 </Virtualizer> 107 </div> 108 ); 109}; 110 111export default FollowersYouKnow;