mirror of
https://github.com/gogs/gogs.git
synced 2026-05-28 21:30:36 +00:00
312
This commit is contained in:
@@ -96,10 +96,10 @@ export function DiffToolbar({
|
||||
type="button"
|
||||
onClick={onToggleTreeDesktop}
|
||||
aria-label={desktopTreeOpen ? t("repo.hide_file_tree") : t("repo.show_file_tree")}
|
||||
aria-pressed={desktopTreeOpen}
|
||||
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"
|
||||
className="hidden size-6 cursor-pointer place-items-center rounded text-(--color-muted-foreground) hover:bg-(--color-surface) hover:text-(--color-foreground) lg:grid lg:pl-1"
|
||||
>
|
||||
{desktopTreeOpen ? (
|
||||
<PanelLeftClose className="size-4" aria-hidden />
|
||||
|
||||
+3
-70
@@ -1,34 +1,17 @@
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import {
|
||||
Outlet,
|
||||
RouterProvider,
|
||||
createRootRouteWithContext,
|
||||
createRoute,
|
||||
createRouter,
|
||||
notFound,
|
||||
} from "@tanstack/react-router";
|
||||
import { Outlet, RouterProvider, createRootRouteWithContext, createRoute, createRouter } from "@tanstack/react-router";
|
||||
|
||||
import { Footer } from "@/components/Footer";
|
||||
import { Navbar } from "@/components/Navbar";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { webContext } from "@/lib/context";
|
||||
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 { Landing } from "@/pages/Landing";
|
||||
import { NotFound } from "@/pages/NotFound";
|
||||
import { ServerError } from "@/pages/ServerError";
|
||||
import { RepoCommit, type RepoCommitPage } from "@/pages/repo/Commit";
|
||||
import { validateRepoCommitSearch } from "@/pages/repo/Commit.search";
|
||||
import { createRepoRoutes } from "@/routes/repo";
|
||||
import { createUserRoutes } from "@/routes/user";
|
||||
|
||||
// Match the legacy server-side route constraint (see `web.go` near the
|
||||
// `/commit/:sha([a-f0-9]{7,40})$` declaration). The server enforces the same
|
||||
// shape for SEO and to skip the SPA shell for malformed paths; this client
|
||||
// check short-circuits the loader so we render 404 without a wasted fetch.
|
||||
const SHA_RE = /^[a-f0-9]{7,40}$/;
|
||||
|
||||
interface RouterContext {
|
||||
user: UserInfo | null;
|
||||
queryClient: QueryClient;
|
||||
@@ -55,57 +38,7 @@ const landingRoute = createRoute({
|
||||
component: Landing,
|
||||
});
|
||||
|
||||
const repoCommitRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/$owner/$repo/commit/$sha",
|
||||
validateSearch: validateRepoCommitSearch,
|
||||
// Reject malformed SHA at parse time so the route doesn't match for paths
|
||||
// like `/owner/repo/commit/garbage`. The thrown `notFound()` bubbles to the
|
||||
// root route's NotFound component.
|
||||
params: {
|
||||
parse: (raw: { owner: string; repo: string; sha: string }) => {
|
||||
if (!SHA_RE.test(raw.sha)) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error -- `notFound()` is the documented TanStack Router signal for 404, not an Error subclass.
|
||||
throw notFound();
|
||||
}
|
||||
return raw;
|
||||
},
|
||||
stringify: (params: { owner: string; repo: string; sha: string }) => params,
|
||||
},
|
||||
loaderDeps: ({ search }) => ({ whitespace: search.whitespace }),
|
||||
loader: async ({ params, deps, context }): Promise<RepoCommitPage> => {
|
||||
const metaURL = subUrl(`/api/web/${params.owner}/${params.repo}/commit/${params.sha}`);
|
||||
const rawBase = subUrl(`/${params.owner}/${params.repo}/commit/${params.sha}.diff`);
|
||||
const rawURL = deps.whitespace ? `${rawBase}?whitespace=${encodeURIComponent(deps.whitespace)}` : rawBase;
|
||||
// Three requests in parallel: repo header (via Query cache for cross-page
|
||||
// reuse), commit metadata JSON, raw patch text. Splitting the patch out
|
||||
// skips JSON-string escaping and lets the browser cache the (often large)
|
||||
// patch separately from the metadata.
|
||||
try {
|
||||
const [, meta, patch] = await Promise.all([
|
||||
context.queryClient.ensureQueryData(repoHeaderQuery(params.owner, params.repo)),
|
||||
fetch(metaURL, { credentials: "same-origin" }).then(async (res) => {
|
||||
if (!res.ok) throw await loaderResponseError(res);
|
||||
return (await res.json()) as Omit<RepoCommitPage, "patch">;
|
||||
}),
|
||||
fetch(rawURL, { credentials: "same-origin" }).then(async (res) => {
|
||||
if (!res.ok) throw await loaderResponseError(res);
|
||||
return res.text();
|
||||
}),
|
||||
]);
|
||||
return { ...meta, patch };
|
||||
} catch (err) {
|
||||
if (err instanceof LoaderResponseError && err.status === 404) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error -- `notFound()` is the documented TanStack Router signal for 404, not an Error subclass.
|
||||
throw notFound();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
component: RepoCommit,
|
||||
});
|
||||
|
||||
const routeTree = rootRoute.addChildren([landingRoute, ...createUserRoutes(rootRoute), repoCommitRoute]);
|
||||
const routeTree = rootRoute.addChildren([landingRoute, ...createUserRoutes(rootRoute), ...createRepoRoutes(rootRoute)]);
|
||||
|
||||
function makeRouter(context: RouterContext) {
|
||||
return createRouter({
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { QueryClient } from "@tanstack/react-query";
|
||||
import { type AnyRoute, createRoute, notFound } from "@tanstack/react-router";
|
||||
|
||||
import { LoaderResponseError, loaderResponseError } from "@/lib/loader-error";
|
||||
import { repoHeaderQuery } from "@/lib/queries/repo";
|
||||
import { subUrl } from "@/lib/url";
|
||||
import { RepoCommit, type RepoCommitPage } from "@/pages/repo/Commit";
|
||||
import { type RepoCommitSearch, validateRepoCommitSearch } from "@/pages/repo/Commit.search";
|
||||
|
||||
// Match the legacy server-side route constraint (see `web.go` near the
|
||||
// `/commit/:sha([a-f0-9]{7,40})$` declaration). The server enforces the same
|
||||
// shape for SEO and to skip the SPA shell for malformed paths; this client
|
||||
// check short-circuits the loader so we render 404 without a wasted fetch.
|
||||
const SHA_RE = /^[a-f0-9]{7,40}$/;
|
||||
|
||||
interface RouterContext {
|
||||
queryClient: QueryClient;
|
||||
}
|
||||
|
||||
export function createRepoRoutes(rootRoute: AnyRoute) {
|
||||
const repoCommitRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/$owner/$repo/commit/$sha",
|
||||
validateSearch: validateRepoCommitSearch,
|
||||
// Reject malformed SHA at parse time so the route doesn't match for paths
|
||||
// like `/owner/repo/commit/garbage`. The thrown `notFound()` bubbles to the
|
||||
// root route's NotFound component.
|
||||
params: {
|
||||
parse: (raw: { owner: string; repo: string; sha: string }) => {
|
||||
if (!SHA_RE.test(raw.sha)) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error -- `notFound()` is the documented TanStack Router signal for 404, not an Error subclass.
|
||||
throw notFound();
|
||||
}
|
||||
return raw;
|
||||
},
|
||||
stringify: (params: { owner: string; repo: string; sha: string }) => params,
|
||||
},
|
||||
loaderDeps: ({ search }: { search: RepoCommitSearch }) => ({ whitespace: search.whitespace }),
|
||||
loader: async ({ params, deps, context }): Promise<RepoCommitPage> => {
|
||||
const metaURL = subUrl(`/api/web/${params.owner}/${params.repo}/commit/${params.sha}`);
|
||||
const rawBase = subUrl(`/${params.owner}/${params.repo}/commit/${params.sha}.diff`);
|
||||
const rawURL = deps.whitespace ? `${rawBase}?whitespace=${encodeURIComponent(deps.whitespace)}` : rawBase;
|
||||
const routerContext = context as RouterContext;
|
||||
// Three requests in parallel: repo header (via Query cache for cross-page
|
||||
// reuse), commit metadata JSON, raw patch text. Splitting the patch out
|
||||
// skips JSON-string escaping and lets the browser cache the (often large)
|
||||
// patch separately from the metadata.
|
||||
try {
|
||||
const [, meta, patch] = await Promise.all([
|
||||
routerContext.queryClient.ensureQueryData(repoHeaderQuery(params.owner, params.repo)),
|
||||
fetch(metaURL, { credentials: "same-origin" }).then(async (res) => {
|
||||
if (!res.ok) throw await loaderResponseError(res);
|
||||
return (await res.json()) as Omit<RepoCommitPage, "patch">;
|
||||
}),
|
||||
fetch(rawURL, { credentials: "same-origin" }).then(async (res) => {
|
||||
if (!res.ok) throw await loaderResponseError(res);
|
||||
return res.text();
|
||||
}),
|
||||
]);
|
||||
return { ...meta, patch };
|
||||
} catch (err) {
|
||||
if (err instanceof LoaderResponseError && err.status === 404) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error -- `notFound()` is the documented TanStack Router signal for 404, not an Error subclass.
|
||||
throw notFound();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
component: RepoCommit,
|
||||
});
|
||||
|
||||
return [repoCommitRoute];
|
||||
}
|
||||
+4
-4
@@ -13,10 +13,10 @@ export default defineConfig({
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
// The dev page is served by the gogs Go server (e.g. https://gogs.localhost)
|
||||
// which reverse-proxies HTTP to this Vite dev server. That proxy is HTTP-only,
|
||||
// so the HMR client's WebSocket can't tunnel through it. Point HMR's WS
|
||||
// directly at the Vite dev port instead, bypassing gogs entirely.
|
||||
// The dev page is served by the Go server (e.g., https://gogs.localhost)
|
||||
// which reverse-proxies HTTP to this Vite dev server. That proxy is
|
||||
// HTTP-only, so the HMR client's WebSocket can't tunnel through it. Point
|
||||
// HMR's WS directly at the Vite dev port instead, bypassing gogs entirely.
|
||||
hmr: {
|
||||
protocol: "ws",
|
||||
host: "localhost",
|
||||
|
||||
Reference in New Issue
Block a user