From b602c32fd9eeea4db9fa88cea640bbab3f4d28e3 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 14:56:38 +1000 Subject: [PATCH 1/9] feat: add contributors section to documentation pages and update .gitignore --- .gitignore | 8 ++++- app/components/Contributors.tsx | 45 ++++++++++++++++++++++++++ app/docs/[...slug]/page.tsx | 12 +++++++ lib/github.ts | 57 +++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 app/components/Contributors.tsx create mode 100644 lib/github.ts diff --git a/.gitignore b/.gitignore index 0b304ce..21065ee 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,10 @@ next-env.d.ts .source # package管理 -.package-lock.json \ No newline at end of file +.package-lock.json + +# Agents.md +Agents.md + +# Environment variables +.env \ No newline at end of file diff --git a/app/components/Contributors.tsx b/app/components/Contributors.tsx new file mode 100644 index 0000000..bddb5e2 --- /dev/null +++ b/app/components/Contributors.tsx @@ -0,0 +1,45 @@ +import Image from "next/image"; +import Link from "next/link"; + +// Define contributor data structure +interface Contributor { + login: string; + avatar_url: string; + html_url: string; +} + +export function Contributors({ + contributors, +}: { + contributors: Contributor[]; +}) { + if (contributors.length === 0) { + return null; // Don't render anything if no contributors + } + + return ( +
+

贡献者

+
+ {contributors.map((contributor) => ( + + {contributor.login} + {contributor.login} + + ))} +
+
+ ); +} diff --git a/app/docs/[...slug]/page.tsx b/app/docs/[...slug]/page.tsx index f243b8a..964c265 100644 --- a/app/docs/[...slug]/page.tsx +++ b/app/docs/[...slug]/page.tsx @@ -4,6 +4,8 @@ import { notFound } from "next/navigation"; import type { Metadata } from "next"; import { getMDXComponents } from "@/mdx-components"; import { GiscusComments } from "@/app/components/GiscusComments"; +import { getContributors } from "@/lib/github"; +import { Contributors } from "@/app/components/Contributors"; interface Param { params: Promise<{ @@ -12,6 +14,7 @@ interface Param { } export default async function DocPage({ params }: Param) { + console.log("[DocPage] Starting DocPage rendering"); const { slug } = await params; const page = source.getPage(slug); @@ -19,6 +22,14 @@ export default async function DocPage({ params }: Param) { notFound(); } + // Get file path for contributors + const filePath = "app/docs/" + page.file.path; + console.log(`[DocPage] Document file path: ${filePath}`); + + // Fetch contributors data on server side + const contributors = await getContributors(filePath); + console.log(`[DocPage] Fetched ${contributors.length} contributors`); + const Mdx = page.data.body; return ( @@ -28,6 +39,7 @@ export default async function DocPage({ params }: Param) { {page.data.title} +
diff --git a/lib/github.ts b/lib/github.ts new file mode 100644 index 0000000..bb248ec --- /dev/null +++ b/lib/github.ts @@ -0,0 +1,57 @@ +import { cache } from "react"; + +// Define contributor data structure +interface Contributor { + login: string; + avatar_url: string; + html_url: string; +} + +// Use React's cache function for request caching and deduplication +export const getContributors = cache( + async (filePath: string): Promise => { + try { + // Use GITHUB_TOKEN environment variable for authorization to increase API rate limit + const headers: HeadersInit = {}; + if (process.env.GITHUB_TOKEN) { + headers.Authorization = `token ${process.env.GITHUB_TOKEN}`; + } + + const response = await fetch( + `https://api.github.com/repos/InvolutionHell/involutionhell.github.io/commits?path=${filePath}`, + { + headers, + // Use next.revalidate to configure cache strategy (e.g., revalidate every hour) + next: { revalidate: 3600 }, + }, + ); + + if (!response.ok) { + // If request fails, return empty array + console.error( + `Failed to fetch contributors for ${filePath}: ${response.statusText}`, + ); + return []; + } + + const commits = await response.json(); + + // Use Map to deduplicate contributors + const uniqueContributors = new Map(); + commits.forEach((commit: { author?: Contributor }) => { + if (commit.author) { + uniqueContributors.set(commit.author.login, { + login: commit.author.login, + avatar_url: commit.author.avatar_url, + html_url: commit.author.html_url, + }); + } + }); + + return Array.from(uniqueContributors.values()); + } catch (error) { + console.error(`Error fetching contributors for ${filePath}:`, error); + return []; + } + }, +); From c0c7584c1c989d281ca6266640ef40cf63f86a75 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 15:11:46 +1000 Subject: [PATCH 2/9] refactor: enhance Contributors component with improved semantics and styling --- app/components/Contributors.tsx | 48 +++++++++++++++++---------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/app/components/Contributors.tsx b/app/components/Contributors.tsx index bddb5e2..6028b11 100644 --- a/app/components/Contributors.tsx +++ b/app/components/Contributors.tsx @@ -1,7 +1,6 @@ import Image from "next/image"; import Link from "next/link"; -// Define contributor data structure interface Contributor { login: string; avatar_url: string; @@ -14,32 +13,35 @@ export function Contributors({ contributors: Contributor[]; }) { if (contributors.length === 0) { - return null; // Don't render anything if no contributors + return null; } return ( -
-

贡献者

-
+
+
+

{"\u8d21\u732e\u8005"}

+
    {contributors.map((contributor) => ( - - {contributor.login} - {contributor.login} - +
  • + + {contributor.login} + {contributor.login} + +
  • ))} -
-
+ +
+ ); } From d38723f338f0deb60cd4eb932f5cad3054f1a6d2 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 16:17:44 +1000 Subject: [PATCH 3/9] refactor: remove global rounded corners style from CSS --- app/globals.css | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/app/globals.css b/app/globals.css index 405c963..1aa5565 100644 --- a/app/globals.css +++ b/app/globals.css @@ -203,25 +203,6 @@ --tracking-normal: 0em; } -/* Force remove rounded corners globally for research style */ -@layer base { - .rounded, - .rounded-sm, - .rounded-md, - .rounded-lg, - .rounded-xl, - .rounded-2xl, - .rounded-3xl, - .rounded-full, - .rounded-none { - border-radius: 0 !important; - } -} - -/* - ---break--- -*/ - .dark { --background: oklch(0.2077 0.0398 265.7549); --foreground: oklch(0.9288 0.0126 255.5078); From b92cbb56a0c9ff839f84455ce87dc0df9eb93c5c Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 16:41:59 +1000 Subject: [PATCH 4/9] refactor: adjust spacing and styling in Contributors component --- app/components/Contributors.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/components/Contributors.tsx b/app/components/Contributors.tsx index 6028b11..494fd4d 100644 --- a/app/components/Contributors.tsx +++ b/app/components/Contributors.tsx @@ -18,7 +18,7 @@ export function Contributors({ return (
-
+

{"\u8d21\u732e\u8005"}

    {contributors.map((contributor) => ( @@ -27,21 +27,21 @@ export function Contributors({ href={contributor.html_url} target="_blank" rel="noopener noreferrer" - className="inline-flex items-center gap-3 text-base font-medium text-primary transition-colors hover:text-primary/80" + className="inline-flex items-center gap-3 text-base font-medium text-primary transition-colors hover:text-primary/80 no-underline" > {contributor.login} {contributor.login} ))}
-
+
); } From 72e829d736c1785a74156deea90b24617304198b Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 16:50:47 +1000 Subject: [PATCH 5/9] refactor: improve layout and accessibility in Contributors component --- .env.sample | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env.sample diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..b33e72d --- /dev/null +++ b/.env.sample @@ -0,0 +1 @@ +GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxx From c8c50fdff49836b688fa8108aad44c6832e0c149 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 16:58:41 +1000 Subject: [PATCH 6/9] Update app/components/Contributors.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/components/Contributors.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/Contributors.tsx b/app/components/Contributors.tsx index 494fd4d..f41aebd 100644 --- a/app/components/Contributors.tsx +++ b/app/components/Contributors.tsx @@ -19,7 +19,7 @@ export function Contributors({ return (

-

{"\u8d21\u732e\u8005"}

+

贡献者

    {contributors.map((contributor) => (
  • From 1d69f3526fc200e280b682c1401f55892824a406 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 17:01:20 +1000 Subject: [PATCH 7/9] Update app/docs/[...slug]/page.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/docs/[...slug]/page.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/docs/[...slug]/page.tsx b/app/docs/[...slug]/page.tsx index 964c265..7599779 100644 --- a/app/docs/[...slug]/page.tsx +++ b/app/docs/[...slug]/page.tsx @@ -28,7 +28,6 @@ export default async function DocPage({ params }: Param) { // Fetch contributors data on server side const contributors = await getContributors(filePath); - console.log(`[DocPage] Fetched ${contributors.length} contributors`); const Mdx = page.data.body; From c92d15b916ade6fd040c9e4b8500127c66b1d917 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 17:01:28 +1000 Subject: [PATCH 8/9] Update app/docs/[...slug]/page.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/docs/[...slug]/page.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/docs/[...slug]/page.tsx b/app/docs/[...slug]/page.tsx index 7599779..6617fca 100644 --- a/app/docs/[...slug]/page.tsx +++ b/app/docs/[...slug]/page.tsx @@ -24,7 +24,6 @@ export default async function DocPage({ params }: Param) { // Get file path for contributors const filePath = "app/docs/" + page.file.path; - console.log(`[DocPage] Document file path: ${filePath}`); // Fetch contributors data on server side const contributors = await getContributors(filePath); From 45933bb89c1fa963f800cd8ee3eee44057ec6338 Mon Sep 17 00:00:00 2001 From: Crokily Date: Thu, 18 Sep 2025 17:54:05 +1000 Subject: [PATCH 9/9] refactor: remove console log from DocPage rendering --- app/docs/[...slug]/page.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/docs/[...slug]/page.tsx b/app/docs/[...slug]/page.tsx index 6617fca..a71654f 100644 --- a/app/docs/[...slug]/page.tsx +++ b/app/docs/[...slug]/page.tsx @@ -14,7 +14,6 @@ interface Param { } export default async function DocPage({ params }: Param) { - console.log("[DocPage] Starting DocPage rendering"); const { slug } = await params; const page = source.getPage(slug);