This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / feeds / containers / myFeedContainer / MyFeedContainer.tsx
3.6 kB 116 lines
1'use client'; 2 3import useGlobalFeed from '@/features/feeds/lib/queries/useGlobalFeed'; 4import useFollowingFeed from '@/features/feeds/lib/queries/useFollowingFeed'; 5import FeedItem from '@/features/feeds/components/feedItem/FeedItem'; 6import { Stack, Text, Center, Container, Box, Loader } from '@mantine/core'; 7import MyFeedContainerSkeleton from './Skeleton.MyFeedContainer'; 8import MyFeedContainerError from './Error.MyFeedContainer'; 9import InfiniteScroll from '@/components/contentDisplay/infiniteScroll/InfiniteScroll'; 10import RefetchButton from '@/components/navigation/refetchButton/RefetchButton'; 11import { UrlType, ActivitySource } from '@semble/types'; 12import { useSearchParams, useRouter, usePathname } from 'next/navigation'; 13import { CardSaveSource } from '@/features/analytics/types'; 14 15export default function MyFeedContainer() { 16 const router = useRouter(); 17 const pathname = usePathname(); 18 const searchParams = useSearchParams(); 19 const selectedUrlType = searchParams.get('type') as UrlType; 20 const selectedSource = searchParams.get('source') as ActivitySource; 21 const selectedFeed = 22 (searchParams.get('feed') as 'global' | 'following') || 'global'; 23 24 const globalFeed = useGlobalFeed({ 25 urlType: selectedUrlType, 26 source: selectedSource, 27 }); 28 const followingFeed = useFollowingFeed({ 29 urlType: selectedUrlType, 30 source: selectedSource, 31 }); 32 33 // Use the appropriate feed based on selection 34 const activeFeed = selectedFeed === 'following' ? followingFeed : globalFeed; 35 36 const { 37 data, 38 error, 39 isPending, 40 fetchNextPage, 41 hasNextPage, 42 isFetchingNextPage, 43 isRefetching, 44 refetch, 45 } = activeFeed; 46 47 const allActivities = 48 data?.pages.flatMap((page) => page.activities ?? []) ?? []; 49 50 if (isPending) { 51 return <MyFeedContainerSkeleton />; 52 } 53 54 if (error) { 55 return <MyFeedContainerError />; 56 } 57 58 return ( 59 <Container p="xs" size="xl"> 60 <Stack align="center"> 61 {isRefetching && ( 62 <Stack align="center" gap={'xs'}> 63 <Loader color={'gray'} /> 64 <Text fw={600} c={'gray'}> 65 Fetching the latest activities... 66 </Text> 67 </Stack> 68 )} 69 {allActivities.length === 0 ? ( 70 <Center> 71 <Text fz="h3" fw={600} c="gray"> 72 No activity to show yet 73 </Text> 74 </Center> 75 ) : ( 76 <InfiniteScroll 77 dataLength={allActivities.length} 78 hasMore={!!hasNextPage} 79 isInitialLoading={isPending} 80 isLoading={isFetchingNextPage} 81 loadMore={fetchNextPage} 82 > 83 <Stack gap={'xl'} mx={'auto'} maw={600} w={'100%'}> 84 <Stack gap={60}> 85 {allActivities.map((item) => ( 86 <FeedItem 87 key={item.id} 88 item={item} 89 analyticsContext={{ 90 saveSource: CardSaveSource.FEED, 91 activeFilters: { 92 urlType: selectedUrlType, 93 }, 94 pagePath: pathname, 95 }} 96 /> 97 ))} 98 </Stack> 99 </Stack> 100 </InfiniteScroll> 101 )} 102 </Stack> 103 104 <Box 105 pos={'fixed'} 106 bottom={0} 107 mt={'md'} 108 mx={{ base: 10, sm: 2.5 }} 109 mb={{ base: 100, sm: 'md' }} 110 style={{ zIndex: 2 }} 111 > 112 <RefetchButton onRefetch={() => refetch()} /> 113 </Box> 114 </Container> 115 ); 116}