This commit is contained in:
Joe Chen
2026-05-27 16:48:31 -04:00
parent 6188e01752
commit 87a7e5a80b
6 changed files with 14 additions and 94 deletions
+3 -3
View File
@@ -158,7 +158,7 @@ func mountWebAPIRoutes(f *flamego.Flame) {
})
f.Post("/sign-out", postUserSignOut)
})
f.Group("/{owner}/{name}", func() {
f.Group("/{owner}/{repo}", func() {
f.Get("/header", getRepoHeader)
f.Get("/commit/{sha: /[0-9a-f]{7,40}/}", getRepoCommit)
f.Combo("/watch").Post(postRepoWatch).Delete(deleteRepoWatch)
@@ -166,8 +166,8 @@ func mountWebAPIRoutes(f *flamego.Flame) {
})
}, webAPIBodyLimiter)
f.Get("/{owner}/{name}/commit/{sha: /[0-9a-f]{7,40}/}.{ext: /(diff|patch)/}", getRepoCommitRaw)
f.Get("/{owner}/{name}/raw/{ref}/{filepath: **}", getRepoRaw)
f.Get("/{owner}/{repo}/commit/{sha: /[0-9a-f]{7,40}/}.{ext: /(diff|patch)/}", getRepoCommitRaw)
f.Get("/{owner}/{repo}/raw/{ref}/{filepath: **}", getRepoRaw)
}
// fieldErrors maps JSON field names to per-field localized messages. A non-nil
+5 -5
View File
@@ -47,7 +47,7 @@ func getRepoHeader(c flamego.Context, r *http.Request, user *database.User) (sta
ctx := r.Context()
params := c.Params()
ownerName := params["owner"]
repoName := params["name"]
repoName := params["repo"]
owner, err := database.Handle.Users().GetByUsername(ctx, ownerName)
if err != nil {
@@ -186,7 +186,7 @@ func getRepoCommit(c flamego.Context, r *http.Request, user *database.User) (sta
ctx := r.Context()
params := c.Params()
ownerName := params["owner"]
repoName := params["name"]
repoName := params["repo"]
commitID := params["sha"]
owner, err := database.Handle.Users().GetByUsername(ctx, ownerName)
@@ -291,7 +291,7 @@ func getRepoCommitRaw(c flamego.Context, r *http.Request, user *database.User) {
ctx := r.Context()
params := c.Params()
ownerName := params["owner"]
repoName := params["name"]
repoName := params["repo"]
commitID := params["sha"]
ext := params["ext"]
@@ -375,7 +375,7 @@ func getRepoCommitRaw(c flamego.Context, r *http.Request, user *database.User) {
}
}
// resolveRepoForViewer loads the repo identified by `{owner}/{name}` path
// resolveRepoForViewer loads the repo identified by `{owner}/{repo}` path
// params and asserts the viewer has at least read access. Returns the repo or
// a (statusCode, error) tuple suitable for short-circuiting a handler.
func resolveRepoForViewer(c flamego.Context, ctx stdctx.Context, user *database.User) (*database.Repository, int, error) {
@@ -387,7 +387,7 @@ func resolveRepoForViewer(c flamego.Context, ctx stdctx.Context, user *database.
}
return nil, http.StatusInternalServerError, errors.Wrap(err, "get user by username")
}
repo, err := database.Handle.Repositories().GetByName(ctx, owner.ID, params["name"])
repo, err := database.Handle.Repositories().GetByName(ctx, owner.ID, params["repo"])
if err != nil {
if database.IsErrRepoNotExist(err) {
return nil, http.StatusNotFound, nil
+3 -1
View File
@@ -97,6 +97,8 @@ export function DiffToolbar({
onClick={onToggleTreeDesktop}
aria-label={desktopTreeOpen ? t("diff.hide_file_tree") : t("diff.show_file_tree")}
aria-pressed={desktopTreeOpen}
// `pl-1` nudges the icon right so it visually aligns with
// the sidebar's collapsed-rail edge on desktop.
className="hidden size-6 cursor-pointer place-items-center rounded text-(--color-muted-foreground) hover:bg-(--color-surface) hover:text-(--color-foreground) lg:grid pl-1"
>
{desktopTreeOpen ? (
@@ -195,7 +197,7 @@ export function DiffToolbar({
const ToolbarButton = forwardRef<
HTMLButtonElement,
{
icon: typeof Settings2;
icon: typeof SlidersHorizontal;
label: string;
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type">
>(function ToolbarButton({ icon: Icon, label, className, ...rest }, ref) {
+2 -2
View File
@@ -328,7 +328,7 @@ interface SplitActionButtonProps {
// Tooltip text shown when signed out. Should explain the gated action,
// e.g. "Sign in to watch this repository".
signInTooltip?: string;
icon: ComponentType<{ className?: string; "aria-hidden"?: boolean }>;
icon: ComponentType<{ className?: string; "aria-hidden"?: boolean; fill?: string }>;
label: string;
count: number;
ariaLabel: string;
@@ -357,7 +357,7 @@ function SplitActionButton({
);
const actionContent = (
<>
<Icon className="size-3.5" aria-hidden />
<Icon className="size-3.5" aria-hidden fill={active ? "currentColor" : "none"} />
<span>{label}</span>
</>
);
-70
View File
@@ -1,70 +0,0 @@
import { parsePatchFiles } from "@pierre/diffs";
import { CodeView, type CodeViewItem } from "@pierre/diffs/react";
import { useTheme } from "@/lib/theme-context";
const SAMPLE_PATCH = `diff --git a/internal/route/repo/commit.go b/internal/route/repo/commit.go
index 1111111..2222222 100644
--- a/internal/route/repo/commit.go
+++ b/internal/route/repo/commit.go
@@ -16,7 +16,7 @@ import (
)
const (
- COMMITS = "repo/commits"
+ COMMITS = "repo/commits_table"
DIFF = "repo/diff/page"
)
@@ -160,6 +160,9 @@ func Diff(c *context.Context) {
c.Data["Commit"] = commit
c.Data["Author"] = tryGetUserByEmail(c.Req.Context(), commit.Author.Email)
c.Data["Diff"] = diff
+ c.Data["Parents"] = parents
+ c.Data["DiffNotAvailable"] = diff.NumFiles() == 0
+ c.Data["SourcePath"] = path.Join(userName, repoName, "src", commitID)
c.Success(DIFF)
}
diff --git a/web/src/pages/Hello.tsx b/web/src/pages/Hello.tsx
new file mode 100644
index 0000000..3333333
--- /dev/null
+++ b/web/src/pages/Hello.tsx
@@ -0,0 +1,5 @@
+export function Hello() {
+ return <h1>hello, pierre/diffs</h1>;
+}
+
+export default Hello;
`;
const items: CodeViewItem[] = parsePatchFiles(SAMPLE_PATCH).flatMap((parsed, patchIndex) =>
parsed.files.map<CodeViewItem>((fileDiff, fileIndex) => ({
id: `${patchIndex}:${fileIndex}:${fileDiff.name}`,
type: "diff",
fileDiff,
})),
);
export function DiffSpike() {
const { theme } = useTheme();
return (
<main className="mx-auto w-full max-w-5xl px-4 py-8">
<h1 className="mb-4 text-lg font-medium">@pierre/diffs spike</h1>
<p className="mb-6 text-sm text-(--color-muted-foreground)">
Throwaway page for evaluating the Pierre diff library against the Gogs shell. Remove once a real diff page
exists.
</p>
<CodeView
items={items}
options={{
theme: { light: "pierre-light", dark: "pierre-dark" },
themeType: theme,
diffStyle: "unified",
stickyHeaders: true,
}}
/>
</main>
);
}
+1 -13
View File
@@ -16,7 +16,6 @@ import { LoaderResponseError, loaderResponseError } from "@/lib/loader-error";
import { repoHeaderQuery } from "@/lib/queries/repo";
import { subUrl } from "@/lib/url";
import type { UserInfo } from "@/lib/user-info";
import { DiffSpike } from "@/pages/DiffSpike";
import { Landing } from "@/pages/Landing";
import { NotFound } from "@/pages/NotFound";
import { ServerError } from "@/pages/ServerError";
@@ -56,12 +55,6 @@ const landingRoute = createRoute({
component: Landing,
});
const diffSpikeRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/_diff-spike",
component: DiffSpike,
});
const repoCommitRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/$owner/$repo/commit/$sha",
@@ -112,12 +105,7 @@ const repoCommitRoute = createRoute({
component: RepoCommit,
});
const routeTree = rootRoute.addChildren([
landingRoute,
...createUserRoutes(rootRoute),
diffSpikeRoute,
repoCommitRoute,
]);
const routeTree = rootRoute.addChildren([landingRoute, ...createUserRoutes(rootRoute), repoCommitRoute]);
function makeRouter(context: RouterContext) {
return createRouter({