78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import type { VersionInfo } from "@/lib/versionInfo";
|
|
|
|
const EMPTY: VersionInfo = {
|
|
version: null,
|
|
tag: null,
|
|
gitDescribe: null,
|
|
commitHash: null,
|
|
commitDate: null,
|
|
commitSubject: null,
|
|
buildTime: null,
|
|
};
|
|
|
|
function resolveVersionLabel(info: VersionInfo): string {
|
|
return info.gitDescribe ?? info.tag ?? info.version ?? "unknown version";
|
|
}
|
|
|
|
function formatCommitDate(iso: string | null): string | null {
|
|
if (!iso) return null;
|
|
const date = new Date(iso);
|
|
if (Number.isNaN(date.getTime())) return null;
|
|
return date.toLocaleString("en-US", {
|
|
year: "numeric",
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
});
|
|
}
|
|
|
|
const VersionOverlay = ({ canSeeCommit }: { canSeeCommit: boolean }) => {
|
|
const [info, setInfo] = useState<VersionInfo | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
void fetch("/api/version", { cache: "no-store" })
|
|
.then((res) => res.json() as Promise<VersionInfo>)
|
|
.then((data) => {
|
|
if (!cancelled) setInfo(data);
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) setInfo(EMPTY);
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
const resolved = info ?? EMPTY;
|
|
const versionLabel = resolveVersionLabel(resolved);
|
|
const lastUpdated = formatCommitDate(resolved.commitDate);
|
|
const commitInfo =
|
|
resolved.commitHash && resolved.commitSubject
|
|
? `${resolved.commitHash} · ${resolved.commitSubject}`
|
|
: (resolved.commitHash ?? resolved.commitSubject ?? null);
|
|
const showSecondary = lastUpdated !== null || commitInfo !== null;
|
|
|
|
return (
|
|
<div className="fixed top-0 z-9999 w-full flex justify-center">
|
|
<div className="text-white flex flex-col items-center justify-center bg-accent w-fit px-2 rounded-b group overflow-hidden opacity-33 hover:opacity-100">
|
|
<span className="text-center text-xs pointer-events-none text-amber-500">
|
|
version {versionLabel}
|
|
</span>
|
|
{showSecondary && (
|
|
<span className="text-center text-[10px] gap-0 leading-3.5 h-0 group-hover:h-full pointer-events-none transition-all duration-100 ease-in-out">
|
|
{lastUpdated && <>last updated {lastUpdated}</>}
|
|
{lastUpdated && commitInfo && <br />}
|
|
{canSeeCommit && commitInfo && <span className="opacity-50">{commitInfo}</span>}
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default VersionOverlay;
|