Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
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;