Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 93 lines 2.4 kB view raw
1import { UserGroupIcon } from "@heroicons/react/24/outline"; 2import { GroupsFeedType } from "@hey/data/enums"; 3import { 4 GroupsOrderBy, 5 type GroupsRequest, 6 PageSize, 7 useGroupsQuery 8} from "@hey/indexer"; 9import { useCallback } from "react"; 10import { WindowVirtualizer } from "virtua"; 11import SingleGroup from "@/components/Shared/Group/SingleGroup"; 12import GroupListShimmer from "@/components/Shared/Shimmer/GroupListShimmer"; 13import { EmptyState, ErrorMessage } from "@/components/Shared/UI"; 14import useLoadMoreOnIntersect from "@/hooks/useLoadMoreOnIntersect"; 15import { useAccountStore } from "@/store/persisted/useAccountStore"; 16 17interface ListProps { 18 feedType: GroupsFeedType; 19} 20 21const List = ({ feedType }: ListProps) => { 22 const { currentAccount } = useAccountStore(); 23 24 const request: GroupsRequest = { 25 filter: { 26 ...(feedType === GroupsFeedType.Member && { 27 member: currentAccount?.address 28 }), 29 ...(feedType === GroupsFeedType.Managed && { 30 managedBy: { address: currentAccount?.address } 31 }) 32 }, 33 orderBy: GroupsOrderBy.LatestFirst, 34 pageSize: PageSize.Fifty 35 }; 36 37 const { data, error, fetchMore, loading } = useGroupsQuery({ 38 variables: { request } 39 }); 40 41 const groups = data?.groups?.items; 42 const pageInfo = data?.groups?.pageInfo; 43 const hasMore = pageInfo?.next; 44 45 const handleEndReached = useCallback(async () => { 46 if (hasMore) { 47 await fetchMore({ 48 variables: { request: { ...request, cursor: pageInfo?.next } } 49 }); 50 } 51 }, [fetchMore, hasMore, pageInfo?.next, request]); 52 53 const loadMoreRef = useLoadMoreOnIntersect(handleEndReached); 54 55 if (loading) { 56 return <GroupListShimmer />; 57 } 58 59 if (!groups?.length) { 60 return ( 61 <EmptyState 62 hideCard 63 icon={<UserGroupIcon className="size-8" />} 64 message="No groups." 65 /> 66 ); 67 } 68 69 if (error) { 70 return ( 71 <ErrorMessage 72 className="m-5" 73 error={error} 74 title="Failed to load groups" 75 /> 76 ); 77 } 78 79 return ( 80 <div className="virtual-divider-list-window"> 81 <WindowVirtualizer> 82 {groups.map((group) => ( 83 <div className="p-5" key={group.address}> 84 <SingleGroup group={group} isBig showDescription /> 85 </div> 86 ))} 87 {hasMore && <span ref={loadMoreRef} />} 88 </WindowVirtualizer> 89 </div> 90 ); 91}; 92 93export default List;