diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 58e7ac0..9a96a52 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -91,6 +91,11 @@ jobs: # already on PATH from `npm i -g pnpm` (gitea-runners.md §4). cd web pnpm install --frozen-lockfile + # The web half's counterpart to `cargo fmt --check` above. It skips + # src/api/generated (.prettierignore) — ts-rs owns those files and + # regenerates them in its own style, so formatting them here would be + # undone on the next `cargo test` and fail the drift gate above. + pnpm format:check pnpm lint pnpm build diff --git a/web/.prettierignore b/web/.prettierignore new file mode 100644 index 0000000..b462b3f --- /dev/null +++ b/web/.prettierignore @@ -0,0 +1,7 @@ +# Written by ts-rs from the Rust entities crate when `cargo test -p +# blackbeard-entities` runs, and checked for drift in CI. Formatting them here +# would be undone by the next regeneration, and the "generated types are +# current" gate would then fail on every build. +src/api/generated/ + +dist/ diff --git a/web/package.json b/web/package.json index 225f9ef..eb0cd8c 100644 --- a/web/package.json +++ b/web/package.json @@ -10,6 +10,7 @@ "preview": "vite preview", "lint": "eslint .", "format": "prettier --write src", + "format:check": "prettier --check src", "typecheck": "tsc -b --noEmit" }, "dependencies": { diff --git a/web/src/App.tsx b/web/src/App.tsx index a3d7e89..c5343fc 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -56,7 +56,10 @@ export default function App() { // Default to the busiest chain we can actually track — the list is ordered // by node count, and an untracked chain has nothing behind it. const chain = route.chain ?? state.chains.find((c) => c.tracking === 'full')?.id ?? null - const info = useMemo(() => state.chains.find((c) => c.id === chain) ?? null, [state.chains, chain]) + const info = useMemo( + () => state.chains.find((c) => c.id === chain) ?? null, + [state.chains, chain], + ) useWatch(chain, route.window) @@ -67,16 +70,14 @@ export default function App() { : `/${merged.chain ?? ''}/${merged.window}` }, []) - const selectMiner = useCallback( - (miner: string) => { - // Keep the chain and window; the miner panel opens above the board rather - // than replacing the page, so the standings stay visible behind it. - setRoute((r) => ({ ...r, miner })) - }, - [], - ) + const selectMiner = useCallback((miner: string) => { + // Keep the chain and window; the miner panel opens above the board rather + // than replacing the page, so the standings stay visible behind it. + setRoute((r) => ({ ...r, miner })) + }, []) - const interval = state.summary?.block_interval_seconds ?? state.summary?.target_block_time_seconds ?? 6 + const interval = + state.summary?.block_interval_seconds ?? state.summary?.target_block_time_seconds ?? 6 const activeWindow = WINDOWS.find((w) => w.id === route.window) ?? WINDOWS[1]! return ( @@ -199,7 +200,10 @@ function Sigil() { stroke="var(--data)" strokeWidth="1.6" /> - + diff --git a/web/src/components/BlockTicker.tsx b/web/src/components/BlockTicker.tsx index 953b601..4bac369 100644 --- a/web/src/components/BlockTicker.tsx +++ b/web/src/components/BlockTicker.tsx @@ -50,11 +50,7 @@ export function BlockTicker({ return (
@@ -77,7 +73,9 @@ export function BlockTicker({ {block.display} - {block.gap_seconds !== null ? `+${seconds(block.gap_seconds)}` : ago(block.observed_at)} + {block.gap_seconds !== null + ? `+${seconds(block.gap_seconds)}` + : ago(block.observed_at)}
) diff --git a/web/src/components/ChainSwitcher.tsx b/web/src/components/ChainSwitcher.tsx index dffa255..290ada3 100644 --- a/web/src/components/ChainSwitcher.tsx +++ b/web/src/components/ChainSwitcher.tsx @@ -52,11 +52,7 @@ export function ChainSwitcher({