diff --git a/src/webapp/components/contentDisplay/infiniteScroll/InfiniteScroll.tsx b/src/webapp/components/contentDisplay/infiniteScroll/InfiniteScroll.tsx
new file mode 100644
index 00000000..1d6c3ad0
--- /dev/null
+++ b/src/webapp/components/contentDisplay/infiniteScroll/InfiniteScroll.tsx
@@ -0,0 +1,43 @@
+'use client';
+
+import { ReactNode, useEffect, startTransition } from 'react';
+import { Center, Button, Stack } from '@mantine/core';
+import { useInViewport } from '@mantine/hooks';
+
+interface Props {
+ children: ReactNode;
+ dataLength: number;
+ hasMore: boolean;
+ isInitialLoading: boolean;
+ isLoading: boolean;
+ loadMore: () => void;
+ loader?: ReactNode;
+ manualLoadButton?: boolean;
+}
+
+export default function InfiniteScroll(props: Props) {
+ const { ref, inViewport } = useInViewport();
+
+ useEffect(() => {
+ startTransition(() => {
+ if (inViewport && props.hasMore && !props.isLoading) {
+ props.loadMore();
+ }
+ });
+ }, [inViewport, props.hasMore, props.isLoading, props.loadMore]);
+
+ return (
+
+ {props.children}
+ {props.isLoading && props.loader}
+
+
+ {!props.isLoading && props.hasMore && props.manualLoadButton && (
+
+ )}
+
+
+ );
+}
diff --git a/src/webapp/features/cards/containers/cardsContainer/CardsContainer.tsx b/src/webapp/features/cards/containers/cardsContainer/CardsContainer.tsx
index 37631fe5..b5cee771 100644
--- a/src/webapp/features/cards/containers/cardsContainer/CardsContainer.tsx
+++ b/src/webapp/features/cards/containers/cardsContainer/CardsContainer.tsx
@@ -1,13 +1,13 @@
'use client';
-import { Container, Grid, Stack, Button, Text, Center } from '@mantine/core';
+import { Center, Container, Grid, Loader, Stack } from '@mantine/core';
import useCards from '../../lib/queries/useCards';
import UrlCard from '@/features/cards/components/urlCard/UrlCard';
import CardsContainerError from './Error.CardsContainer';
import CardsContainerSkeleton from './Skeleton.CardsContainer';
-import { Fragment, useState } from 'react';
import ProfileEmptyTab from '@/features/profile/components/profileEmptyTab/ProfileEmptyTab';
import { FaRegNoteSticky } from 'react-icons/fa6';
+import InfiniteScroll from '@/components/contentDisplay/infiniteScroll/InfiniteScroll';
interface Props {
handle: string;
@@ -43,39 +43,34 @@ export default function CardsContainer(props: Props) {
return (
-
-
-
- {allCards.map((card) => (
-
-
-
- ))}
-
-
- {hasNextPage && (
-
-
-
- )}
-
-
+
+
+
+ }
+ >
+
+ {allCards.map((card) => (
+
+
+
+ ))}
+
+
);
}
diff --git a/src/webapp/features/collections/containers/collectionsContainer/CollectionsContainer.tsx b/src/webapp/features/collections/containers/collectionsContainer/CollectionsContainer.tsx
index b7ecb4c5..5b9be3b4 100644
--- a/src/webapp/features/collections/containers/collectionsContainer/CollectionsContainer.tsx
+++ b/src/webapp/features/collections/containers/collectionsContainer/CollectionsContainer.tsx
@@ -1,12 +1,13 @@
'use client';
-import { Button, Container, Stack, SimpleGrid, Center } from '@mantine/core';
+import { Button, Container, Stack, SimpleGrid } from '@mantine/core';
import useCollections from '../../lib/queries/useCollections';
import CollectionCard from '../../components/collectionCard/CollectionCard';
import CreateCollectionDrawer from '../../components/createCollectionDrawer/CreateCollectionDrawer';
import { useState } from 'react';
import ProfileEmptyTab from '@/features/profile/components/profileEmptyTab/ProfileEmptyTab';
import { BiCollection } from 'react-icons/bi';
+import InfiniteLoadTrigger from '@/components/contentDisplay/infiniteScroll/InfiniteScroll';
interface Props {
handle: string;
@@ -32,28 +33,21 @@ export default function CollectionsContainer(props: Props) {
return (
-
+ Loading...} // replace with your loader component if you want
+ >
{collections.map((collection) => (
))}
-
- {hasNextPage && (
-
-
-
- )}
-
+
) : (
-
-
- {allActivities.map((item, i) => (
-
- ))}
+
+
+
+ }
+ >
+
+
+ {allActivities.map((item) => (
+
+ ))}
+
-
- {hasNextPage && (
-
-
-
- )}
-
+
)}