SanYeCao-blog/src/components/Posts/PostList.astro

117 lines
2.6 KiB
Text
Raw Normal View History

2026-03-24 17:33:01 +00:00
---
2026-03-24 18:01:45 +00:00
import { getCollection } from "astro:content";
2026-03-24 17:33:01 +00:00
import PostItem from "./PostItem.astro";
2026-03-25 08:43:02 +00:00
import { getLangFromUrl } from "@/i18n";
2026-03-24 17:33:01 +00:00
2026-03-24 22:50:33 +00:00
const lang = getLangFromUrl(Astro.url);
2026-03-24 18:01:45 +00:00
const allPosts = await getCollection("blog");
2026-03-25 08:43:02 +00:00
type ReactionGroup = {
users?: {
totalCount?: number;
};
};
type DiscussionNode = {
title: string;
comments?: {
totalCount?: number;
};
reactionGroups?: ReactionGroup[];
};
function normalizePath(path: string) {
return path.replace(/^\/+|\/+$/g, "");
}
async function fetchDiscussionStats(): Promise<DiscussionNode[]> {
const token = import.meta.env.GITHUB_TOKEN;
if (!token) return [];
const query = `
query($owner: String!, $name: String!, $categoryId: ID!) {
repository(owner: $owner, name: $name) {
discussions(first: 100, categoryId: $categoryId) {
nodes {
title
comments(first: 0) {
totalCount
}
reactionGroups {
users {
totalCount
}
}
}
}
}
}
`;
const res = await fetch("https://api.github.com/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
query,
variables: {
owner: "ClovertaTheTrilobita",
name: "SanYeCao-blog",
categoryId: "DIC_kwDORvuVpM4C5MDE",
},
}),
});
const json = await res.json();
return (json?.data?.repository?.discussions?.nodes ?? []) as DiscussionNode[];
}
const discussions = await fetchDiscussionStats();
2026-03-24 17:33:01 +00:00
---
<ul>
2026-03-24 18:01:45 +00:00
{
allPosts.map((post: any) => {
const formattedDate = new Date(post.data.pubDate)
.toISOString()
.split("T")[0];
2026-03-24 17:33:01 +00:00
2026-03-25 08:43:02 +00:00
const pathname = `/${lang}/posts/${post.id}/`;
const matchedDiscussion = discussions.find((d: DiscussionNode) => {
return normalizePath(d.title) === normalizePath(pathname);
});
const reactionCount =
matchedDiscussion?.reactionGroups?.reduce(
(sum: number, group: ReactionGroup) =>
sum + (group.users?.totalCount ?? 0),
0,
) ?? 0;
const commentCount = matchedDiscussion?.comments?.totalCount ?? 0;
2026-03-24 18:01:45 +00:00
return (
<PostItem
2026-03-24 22:50:33 +00:00
url={`/${lang}/posts/${post.id}/`}
2026-03-24 18:01:45 +00:00
title={post.data.title}
description={post.data.description}
2026-03-24 18:01:45 +00:00
date={formattedDate}
2026-03-24 23:40:19 +00:00
img={post.data.image.url}
2026-03-25 08:43:02 +00:00
commentCount={commentCount}
reactionCount={reactionCount}
2026-03-24 18:01:45 +00:00
/>
);
})
}
2026-03-24 17:33:01 +00:00
</ul>
2026-03-24 23:40:19 +00:00
<style>
ul {
margin: 0;
padding-left: 0;
}
</style>