From c768b15bd72bae9d56bcbd19becc9cb3c31f52f1 Mon Sep 17 00:00:00 2001 From: Ahmet Kilinc Date: Sat, 20 Dec 2025 11:44:42 +0000 Subject: [PATCH] suspense all the things --- .../[username]/[repo]/blob/[...path]/page.tsx | 60 ++++--- .../[repo]/commits/[[...branch]]/page.tsx | 156 +++++++++--------- .../[username]/[repo]/tree/[...path]/page.tsx | 51 +++--- app/(main)/[username]/page.tsx | 51 ++++-- 4 files changed, 184 insertions(+), 134 deletions(-) diff --git a/app/(main)/[username]/[repo]/blob/[...path]/page.tsx b/app/(main)/[username]/[repo]/blob/[...path]/page.tsx index 46ee6b0..d236a61 100644 --- a/app/(main)/[username]/[repo]/blob/[...path]/page.tsx +++ b/app/(main)/[username]/[repo]/blob/[...path]/page.tsx @@ -1,10 +1,11 @@ +import { Suspense } from "react"; import { notFound } from "next/navigation"; import Link from "next/link"; import { getRepository, getRepoFile, getRepoBranches } from "@/actions/repositories"; import { CodeViewer } from "@/components/code-viewer"; import { BranchSelector } from "@/components/branch-selector"; import { Badge } from "@/components/ui/badge"; -import { Lock, Globe, ChevronRight, Home, FileCode } from "lucide-react"; +import { Lock, Globe, ChevronRight, Home, FileCode, Loader2 } from "lucide-react"; const LANGUAGE_MAP: Record = { ts: "typescript", @@ -32,30 +33,40 @@ function getLanguage(filename: string): string { return LANGUAGE_MAP[ext] || "text"; } -export default async function BlobPage({ params }: { params: Promise<{ username: string; repo: string; path: string[] }> }) { - const { username, repo: repoName, path: pathSegments } = await params; - const branch = pathSegments[0]; - const filePath = pathSegments.slice(1).join("/"); - - const repo = await getRepository(username, repoName); - - if (!repo) { - notFound(); - } - - const [file, branches] = await Promise.all([ - getRepoFile(username, repoName, branch, filePath), - getRepoBranches(username, repoName), - ]); +async function FileContent({ username, repoName, branch, filePath }: { username: string; repoName: string; branch: string; filePath: string }) { + const file = await getRepoFile(username, repoName, branch, filePath); if (!file) { notFound(); } + const fileName = filePath.split("/").pop() || ""; + const language = getLanguage(fileName); + + return ; +} + +function CodeSkeleton() { + return ( +
+ +
+ ); +} + +export default async function BlobPage({ params }: { params: Promise<{ username: string; repo: string; path: string[] }> }) { + const { username, repo: repoName, path: pathSegments } = await params; + const branch = pathSegments[0]; + const filePath = pathSegments.slice(1).join("/"); + + const [repo, branches] = await Promise.all([getRepository(username, repoName), getRepoBranches(username, repoName)]); + + if (!repo) { + notFound(); + } + const pathParts = filePath.split("/").filter(Boolean); const fileName = pathParts[pathParts.length - 1]; - const language = getLanguage(fileName); - const lineCount = file.content.split("\n").length; return (
@@ -86,12 +97,7 @@ export default async function BlobPage({ params }: { params: Promise<{ username:
- +
); diff --git a/app/(main)/[username]/[repo]/commits/[[...branch]]/page.tsx b/app/(main)/[username]/[repo]/commits/[[...branch]]/page.tsx index 2a7dc3a..240556c 100644 --- a/app/(main)/[username]/[repo]/commits/[[...branch]]/page.tsx +++ b/app/(main)/[username]/[repo]/commits/[[...branch]]/page.tsx @@ -1,3 +1,4 @@ +import { Suspense } from "react"; import { notFound } from "next/navigation"; import Link from "next/link"; import { getRepository, getRepoCommits, getRepoBranches } from "@/actions/repositories"; @@ -5,9 +6,82 @@ import { BranchSelector } from "@/components/branch-selector"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; -import { Lock, Globe, GitCommit, ChevronLeft, ChevronRight } from "lucide-react"; +import { Lock, Globe, GitCommit, ChevronLeft, ChevronRight, Loader2 } from "lucide-react"; import { formatDistanceToNow } from "date-fns"; +async function CommitsList({ username, repoName, branch, page, perPage }: { username: string; repoName: string; branch: string; page: number; perPage: number }) { + const skip = (page - 1) * perPage; + const { commits, hasMore } = await getRepoCommits(username, repoName, branch, perPage, skip); + + if (commits.length === 0) { + return ( +
+ +

No commits yet

+

This branch doesn't have any commits.

+
+ ); + } + + return ( + <> +
+ {commits.map((commit) => ( +
+ + {commit.author.name.charAt(0).toUpperCase()} + +
+

{commit.message.split("\n")[0]}

+
+ {commit.author.name} + committed + {formatDistanceToNow(new Date(commit.timestamp), { addSuffix: true })} +
+
+ {commit.oid.slice(0, 7)} +
+ ))} +
+ + {(page > 1 || hasMore) && ( +
+ + Page {page} + +
+ )} + + ); +} + +function CommitsSkeleton() { + return ( +
+ {[...Array(5)].map((_, i) => ( +
+
+
+
+
+
+
+
+ ))} +
+ ); +} + export default async function CommitsPage({ params, searchParams, @@ -18,7 +92,7 @@ export default async function CommitsPage({ const { username, repo: repoName, branch: branchSegments } = await params; const { page: pageParam } = await searchParams; - const repo = await getRepository(username, repoName); + const [repo, branches] = await Promise.all([getRepository(username, repoName), getRepoBranches(username, repoName)]); if (!repo) { notFound(); @@ -27,12 +101,6 @@ export default async function CommitsPage({ const branch = branchSegments?.[0] || repo.defaultBranch; const page = parseInt(pageParam || "1", 10); const perPage = 30; - const skip = (page - 1) * perPage; - - const [{ commits, hasMore }, branches] = await Promise.all([ - getRepoCommits(username, repoName, branch, perPage, skip), - getRepoBranches(username, repoName), - ]); return (
@@ -64,12 +132,7 @@ export default async function CommitsPage({
- +
Commits @@ -77,69 +140,10 @@ export default async function CommitsPage({
- {commits.length === 0 ? ( -
- -

No commits yet

-

- This branch doesn't have any commits. -

-
- ) : ( -
- {commits.map((commit) => ( -
- - - {commit.author.name.charAt(0).toUpperCase()} - - -
-

{commit.message.split("\n")[0]}

-
- {commit.author.name} - committed - - {formatDistanceToNow(new Date(commit.timestamp), { addSuffix: true })} - -
-
- - {commit.oid.slice(0, 7)} - -
- ))} -
- )} - - {(page > 1 || hasMore) && ( -
- - Page {page} - -
- )} + }> + +
); } - diff --git a/app/(main)/[username]/[repo]/tree/[...path]/page.tsx b/app/(main)/[username]/[repo]/tree/[...path]/page.tsx index 39ee218..2e7020a 100644 --- a/app/(main)/[username]/[repo]/tree/[...path]/page.tsx +++ b/app/(main)/[username]/[repo]/tree/[...path]/page.tsx @@ -1,31 +1,48 @@ +import { Suspense } from "react"; import { notFound } from "next/navigation"; import Link from "next/link"; import { getRepository, getRepoFileTree, getRepoBranches } from "@/actions/repositories"; import { FileTree } from "@/components/file-tree"; import { BranchSelector } from "@/components/branch-selector"; import { Badge } from "@/components/ui/badge"; -import { Lock, Globe, ChevronRight, Home } from "lucide-react"; +import { Lock, Globe, ChevronRight, Home, Loader2 } from "lucide-react"; + +async function TreeContent({ username, repoName, branch, dirPath }: { username: string; repoName: string; branch: string; dirPath: string }) { + const fileTree = await getRepoFileTree(username, repoName, branch, dirPath); + + if (!fileTree) { + notFound(); + } + + return ; +} + +function TreeSkeleton() { + return ( +
+ {[...Array(5)].map((_, i) => ( +
+
+
+
+
+
+ ))} +
+ ); +} export default async function TreePage({ params }: { params: Promise<{ username: string; repo: string; path: string[] }> }) { const { username, repo: repoName, path: pathSegments } = await params; const branch = pathSegments[0]; const dirPath = pathSegments.slice(1).join("/"); - const repo = await getRepository(username, repoName); + const [repo, branches] = await Promise.all([getRepository(username, repoName), getRepoBranches(username, repoName)]); if (!repo) { notFound(); } - const [fileTree, branches] = await Promise.all([ - getRepoFileTree(username, repoName, branch, dirPath), - getRepoBranches(username, repoName), - ]); - - if (!fileTree) { - notFound(); - } - const pathParts = dirPath.split("/").filter(Boolean); return ( @@ -57,13 +74,7 @@ export default async function TreePage({ params }: { params: Promise<{ username:
- +
- + }> + +
); diff --git a/app/(main)/[username]/page.tsx b/app/(main)/[username]/page.tsx index df5c4b6..d7004a1 100644 --- a/app/(main)/[username]/page.tsx +++ b/app/(main)/[username]/page.tsx @@ -1,3 +1,4 @@ +import { Suspense } from "react"; import { notFound } from "next/navigation"; import { db } from "@/db"; import { users } from "@/db/schema"; @@ -5,11 +6,44 @@ import { eq } from "drizzle-orm"; import { getUserRepositoriesWithStars } from "@/actions/repositories"; import { RepoList } from "@/components/repo-list"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; -import { CalendarDays, GitBranch, MapPin, Link as LinkIcon } from "lucide-react"; +import { CalendarDays, GitBranch, MapPin, Link as LinkIcon, Loader2 } from "lucide-react"; import { format } from "date-fns"; import Link from "next/link"; import { GithubIcon, XIcon, LinkedInIcon } from "@/components/icons"; +async function RepoSection({ username }: { username: string }) { + const repos = await getUserRepositoriesWithStars(username); + + if (repos.length === 0) { + return ( +
+ +

No repositories yet

+

This user hasn't created any public repositories.

+
+ ); + } + + return ; +} + +function RepoSkeleton() { + return ( +
+ {[...Array(3)].map((_, i) => ( +
+
+
+
+
+
+
+
+ ))} +
+ ); +} + export default async function ProfilePage({ params }: { params: Promise<{ username: string }> }) { const { username } = await params; @@ -21,8 +55,6 @@ export default async function ProfilePage({ params }: { params: Promise<{ userna notFound(); } - const repos = await getUserRepositoriesWithStars(username); - return (
@@ -93,18 +125,11 @@ export default async function ProfilePage({ params }: { params: Promise<{ userna

Repositories

- ({repos.length})
- {repos.length === 0 ? ( -
- -

No repositories yet

-

{user.name} hasn't created any public repositories.

-
- ) : ( - - )} + }> + +