Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 83 lines 2.3 kB view raw
1import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline"; 2import { 3 PageSize, 4 type PostFragment, 5 type PostReferencesRequest, 6 PostReferenceType, 7 usePostReferencesQuery 8} from "@hey/indexer"; 9import { useCallback } from "react"; 10import { WindowVirtualizer } from "virtua"; 11import BackButton from "@/components/Shared/BackButton"; 12import PostsShimmer from "@/components/Shared/Shimmer/PostsShimmer"; 13import { 14 Card, 15 CardHeader, 16 EmptyState, 17 ErrorMessage 18} from "@/components/Shared/UI"; 19import useLoadMoreOnIntersect from "@/hooks/useLoadMoreOnIntersect"; 20import SinglePost from "./SinglePost"; 21 22interface QuotesProps { 23 post: PostFragment; 24} 25 26const Quotes = ({ post }: QuotesProps) => { 27 const request: PostReferencesRequest = { 28 pageSize: PageSize.Fifty, 29 referencedPost: post.id, 30 referenceTypes: [PostReferenceType.QuoteOf] 31 }; 32 33 const { data, error, fetchMore, loading } = usePostReferencesQuery({ 34 skip: !post.id, 35 variables: { request } 36 }); 37 38 const quotes = data?.postReferences?.items ?? []; 39 const pageInfo = data?.postReferences?.pageInfo; 40 const hasMore = pageInfo?.next; 41 42 const handleEndReached = useCallback(async () => { 43 if (hasMore) { 44 await fetchMore({ 45 variables: { request: { ...request, cursor: pageInfo?.next } } 46 }); 47 } 48 }, [fetchMore, hasMore, pageInfo?.next, request]); 49 50 const loadMoreRef = useLoadMoreOnIntersect(handleEndReached); 51 52 if (error) { 53 return <ErrorMessage error={error} title="Failed to load comment feed" />; 54 } 55 56 return ( 57 <Card> 58 <CardHeader icon={<BackButton />} title="Quotes" /> 59 {loading ? ( 60 <PostsShimmer hideCard /> 61 ) : error ? ( 62 <ErrorMessage error={error} title="Failed to load comment feed" /> 63 ) : quotes.length ? ( 64 <div className="virtual-divider-list-window"> 65 <WindowVirtualizer> 66 {quotes.map((quote) => ( 67 <SinglePost key={quote.id} post={quote} showType={false} /> 68 ))} 69 {hasMore && <span ref={loadMoreRef} />} 70 </WindowVirtualizer> 71 </div> 72 ) : ( 73 <EmptyState 74 hideCard 75 icon={<ChatBubbleBottomCenterTextIcon className="size-8" />} 76 message="Be the first one to quote!" 77 /> 78 )} 79 </Card> 80 ); 81}; 82 83export default Quotes;