/ is now the swarm's name over the digital-rain backdrop the hive dashboard's home has, and the swarm name in the header links to it. The hive directory moves to /hives, where the nav's hives tab points. The swarm name is read once per page load by a shared hook, the header and the start page both use it. Closes #5252
36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
// useSwarmName — the swarm's configured display name from `GET /api/swarm`,
|
|
// or `null` until it arrives, when none is configured, or when the fetch
|
|
// fails. The label is cosmetic, so a failure is swallowed rather than shown:
|
|
// callers fall back to their own default, as an operator who never set a
|
|
// name sees. One request per page load, shared by every caller, because the
|
|
// header and the start page both ask for it and the name does not change
|
|
// within a visit.
|
|
import { useEffect, useState } from "preact/hooks";
|
|
|
|
let pending: Promise<string | null> | null = null;
|
|
|
|
function fetchSwarmName(): Promise<string | null> {
|
|
if (pending === null) {
|
|
pending = (async () => {
|
|
const r = await fetch("/api/swarm");
|
|
if (!r.ok) return null;
|
|
const data = (await r.json()) as { name: string | null };
|
|
return data.name || null;
|
|
})().catch(() => null);
|
|
}
|
|
return pending;
|
|
}
|
|
|
|
export function useSwarmName(): string | null {
|
|
const [name, setName] = useState<string | null>(null);
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
void fetchSwarmName().then((n) => {
|
|
if (!cancelled && n !== null) setName(n);
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
return name;
|
|
}
|