feat: add about page with versions, changelog, and how-to-play

- New GET /about API endpoint caches Gitea releases for 5 minutes
- AboutPanel displays client version (via Vite define), API version, collapsible changelog, and How to Play guide
- GiteaRelease and AboutResponse types added to shared package
This commit is contained in:
2026-03-06 23:16:50 -08:00
committed by Naomi Carrigan
parent dc1353a15c
commit 3ff17bda84
14 changed files with 353 additions and 5 deletions
+2
View File
@@ -2,6 +2,7 @@ import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
import { aboutRouter } from "./routes/about.js";
import { authRouter } from "./routes/auth.js";
import { bossRouter } from "./routes/boss.js";
import { gameRouter } from "./routes/game.js";
@@ -20,6 +21,7 @@ app.use(
}),
);
app.route("/about", aboutRouter);
app.route("/auth", authRouter);
app.route("/game", gameRouter);
app.route("/boss", bossRouter);
+46
View File
@@ -0,0 +1,46 @@
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { Hono } from "hono";
import type { AboutResponse, GiteaRelease } from "@elysium/types";
const __dirname = dirname(fileURLToPath(import.meta.url));
const { version: API_VERSION } = JSON.parse(
readFileSync(join(__dirname, "../../package.json"), "utf-8"),
) as { version: string };
const GITEA_RELEASES_URL =
"https://git.nhcarrigan.com/api/v1/repos/nhcarrigan-ideation/elysium/releases";
const CACHE_TTL_MS = 5 * 60 * 1000;
let releasesCache: GiteaRelease[] = [];
let cacheTimestamp = 0;
const fetchReleases = async (): Promise<GiteaRelease[]> => {
const now = Date.now();
if (releasesCache.length > 0 && now - cacheTimestamp < CACHE_TTL_MS) {
return releasesCache;
}
try {
const response = await fetch(GITEA_RELEASES_URL);
if (!response.ok) {
return releasesCache;
}
releasesCache = (await response.json()) as GiteaRelease[];
cacheTimestamp = now;
return releasesCache;
} catch {
return releasesCache;
}
};
export const aboutRouter = new Hono();
aboutRouter.get("/", async (context) => {
const releases = await fetchReleases();
const body: AboutResponse = {
apiVersion: API_VERSION,
releases,
};
return context.json(body);
});