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