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