Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 109 lines 3.3 kB view raw
1import { XMarkIcon } from "@heroicons/react/24/outline"; 2import { 3 type AccountFragment, 4 PageSize, 5 useAccountRecommendationsQuery 6} from "@hey/indexer"; 7import { memo, useState } from "react"; 8import Suggested from "@/components/Home/Suggested"; 9import DismissRecommendedAccount from "@/components/Shared/Account/DismissRecommendedAccount"; 10import SingleAccount from "@/components/Shared/Account/SingleAccount"; 11import SingleAccountShimmer from "@/components/Shared/Shimmer/SingleAccountShimmer"; 12import Skeleton from "@/components/Shared/Skeleton"; 13import { Card, ErrorMessage, H5, Modal } from "@/components/Shared/UI"; 14import { useAccountStore } from "@/store/persisted/useAccountStore"; 15 16const Title = memo(() => <H5>Who to Follow</H5>); 17 18const WhoToFollow = () => { 19 const { currentAccount } = useAccountStore(); 20 const [showMore, setShowMore] = useState(false); 21 22 const { data, error, loading } = useAccountRecommendationsQuery({ 23 variables: { 24 request: { 25 account: currentAccount?.address, 26 pageSize: PageSize.Fifty, 27 shuffle: true 28 } 29 } 30 }); 31 32 if (loading) { 33 return ( 34 <Card className="space-y-4 p-5"> 35 <Title /> 36 {Array.from({ length: 5 }, (_, index) => `placeholder-${index}`).map( 37 (id) => ( 38 <div className="flex items-center gap-x-3" key={id}> 39 <div className="w-full"> 40 <SingleAccountShimmer showFollowUnfollowButton /> 41 </div> 42 <XMarkIcon className="size-4 text-gray-500" /> 43 </div> 44 ) 45 )} 46 <div className="pt-2 pb-1"> 47 <Skeleton className="h-3 w-5/12 rounded-full" /> 48 </div> 49 </Card> 50 ); 51 } 52 53 if (!data?.mlAccountRecommendations.items.length) { 54 return null; 55 } 56 57 const recommendedAccounts = data?.mlAccountRecommendations.items.filter( 58 (account) => 59 !account.operations?.isBlockedByMe && 60 !account.operations?.isFollowedByMe && 61 !account.operations?.hasBlockedMe 62 ) as AccountFragment[]; 63 64 if (!recommendedAccounts?.length) { 65 return null; 66 } 67 68 return ( 69 <> 70 <Card className="space-y-4 p-5"> 71 <Title /> 72 <ErrorMessage error={error} title="Failed to load recommendations" /> 73 {recommendedAccounts?.slice(0, 5).map((account) => ( 74 <div 75 className="flex items-center gap-x-3 truncate" 76 key={account?.address} 77 > 78 <div className="w-full"> 79 <SingleAccount 80 account={account} 81 hideFollowButton={currentAccount?.address === account.address} 82 hideUnfollowButton={currentAccount?.address === account.address} 83 /> 84 </div> 85 <DismissRecommendedAccount account={account} /> 86 </div> 87 ))} 88 {recommendedAccounts.length > 5 && ( 89 <button 90 className="font-bold text-gray-500 dark:text-gray-200" 91 onClick={() => setShowMore(true)} 92 type="button" 93 > 94 Show more 95 </button> 96 )} 97 </Card> 98 <Modal 99 onClose={() => setShowMore(false)} 100 show={showMore} 101 title="Suggested for you" 102 > 103 <Suggested accounts={recommendedAccounts} /> 104 </Modal> 105 </> 106 ); 107}; 108 109export default memo(WhoToFollow);