aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/ArticleList.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/ArticleList.tsx')
-rw-r--r--frontend/src/components/ArticleList.tsx71
1 files changed, 66 insertions, 5 deletions
diff --git a/frontend/src/components/ArticleList.tsx b/frontend/src/components/ArticleList.tsx
index afadb25..ccf7826 100644
--- a/frontend/src/components/ArticleList.tsx
+++ b/frontend/src/components/ArticleList.tsx
@@ -5,15 +5,27 @@ import type {
} from "../graphql/generated/graphql";
import { ArticleItem } from "./ArticleItem";
+type ArticleType =
+ | GetUnreadArticlesQuery["unreadArticles"]["articles"]
+ | GetReadArticlesQuery["readArticles"]["articles"];
+
interface Props {
- articles: NonNullable<
- | GetUnreadArticlesQuery["unreadArticles"]
- | GetReadArticlesQuery["readArticles"]
- >;
+ articles: ArticleType;
isReadView?: boolean;
+ isSingleFeed?: boolean;
+ hasNextPage?: boolean;
+ loadingMore?: boolean;
+ onLoadMore?: () => void;
}
-export function ArticleList({ articles, isReadView }: Props) {
+export function ArticleList({
+ articles,
+ isReadView,
+ isSingleFeed,
+ hasNextPage,
+ loadingMore,
+ onLoadMore,
+}: Props) {
const [hiddenArticleIds, setHiddenArticleIds] = useState<Set<string>>(
new Set(),
);
@@ -36,6 +48,25 @@ export function ArticleList({ articles, isReadView }: Props) {
);
}
+ if (isSingleFeed) {
+ return (
+ <div className="space-y-1">
+ {visibleArticles.map((article) => (
+ <ArticleItem
+ key={article.id}
+ article={article}
+ onReadChange={handleArticleReadChange}
+ />
+ ))}
+ <LoadMoreButton
+ hasNextPage={hasNextPage}
+ loadingMore={loadingMore}
+ onLoadMore={onLoadMore}
+ />
+ </div>
+ );
+ }
+
// Group articles by feed
const articlesByFeed = visibleArticles.reduce(
(acc, article) => {
@@ -77,6 +108,36 @@ export function ArticleList({ articles, isReadView }: Props) {
</div>
</div>
))}
+ <LoadMoreButton
+ hasNextPage={hasNextPage}
+ loadingMore={loadingMore}
+ onLoadMore={onLoadMore}
+ />
+ </div>
+ );
+}
+
+function LoadMoreButton({
+ hasNextPage,
+ loadingMore,
+ onLoadMore,
+}: {
+ hasNextPage?: boolean;
+ loadingMore?: boolean;
+ onLoadMore?: () => void;
+}) {
+ if (!hasNextPage || !onLoadMore) return null;
+
+ return (
+ <div className="pt-4 text-center">
+ <button
+ type="button"
+ onClick={onLoadMore}
+ disabled={loadingMore}
+ className="rounded-lg bg-stone-100 px-4 py-2 text-sm font-medium text-stone-700 transition-colors hover:bg-stone-200 disabled:opacity-50"
+ >
+ {loadingMore ? "Loading..." : "Load more"}
+ </button>
</div>
);
}