diff --git a/src/components/speedtest/speedtest-rpc-client.tsx b/src/components/speedtest/speedtest-rpc-client.tsx index 28cff19e..0b16f132 100644 --- a/src/components/speedtest/speedtest-rpc-client.tsx +++ b/src/components/speedtest/speedtest-rpc-client.tsx @@ -165,14 +165,16 @@ function Gauge({ ms, label, sub, + className = "mx-auto w-[280px] sm:w-[340px]", }: { ms: number | null; label: string; sub: string; + className?: string; }) { const angle = ms == null ? GAUGE_START : msToAngle(ms); return ( -
+
{/* Track */}
{ms == null ? "—" : Math.round(ms)} - ms + ms
-

{label}

-

{sub}

+

{label}

+

{sub}

); @@ -340,7 +342,7 @@ export function SpeedtestRpcClient() { patch(ep.id, { status: "cors_blocked", error: - "Endpoint rejected the browser request (CORS or network). Test it from a terminal instead — see the curl below.", + "This endpoint does not answer browser requests (no CORS headers on preflight) — dapps cannot call it from a browser either. It may still be fast server-side: measure it from a terminal with the curl below.", }); } } @@ -425,7 +427,6 @@ export function SpeedtestRpcClient() { useEffect(() => () => { abortRef.current.stop = true; }, []); - const active = endpoints.find((e) => e.id === activeId) ?? null; const ranked = useMemo(() => { const done = endpoints.filter((e) => e.samples.length > 0); return done @@ -552,11 +553,66 @@ export function SpeedtestRpcClient() {
- + {/* One speedometer per endpoint, all live at once. The + active one (currently being probed) lifts and gets an + ink border; the others keep their last reading. */} +
+ {endpoints.map((ep) => { + const s = stats(ep); + const isActive = ep.id === activeId; + const blocked = ep.status === "cors_blocked"; + return ( +
+ {blocked ? ( +
+

{ep.host}

+

no CORS · browser-blocked

+
+ ) : ( + <> + +
+ p50 {Number.isNaN(s.p50) ? "—" : `${Math.round(s.p50)}ms`} + {s.n} probes + {s.successPct}% ok + {ep.staleRounds > 0 && ( + stale ×{ep.staleRounds} + )} +
+ + )} +
+ ); + })} +
{/* Progress */}
@@ -569,41 +625,6 @@ export function SpeedtestRpcClient() { {elapsed.toFixed(0)}s / {durationSec}s

- - {/* Live per-endpoint cards */} -
- {endpoints.map((ep) => { - const s = stats(ep); - const isActive = ep.id === activeId; - return ( -
-
-

{ep.host}

- {ep.status === "cors_blocked" ? ( - browser-blocked - ) : ( - - {ep.lastMs != null ? `${Math.round(ep.lastMs)} ms` : "…"} - - )} -
-
- p50 {Number.isNaN(s.p50) ? "—" : `${Math.round(s.p50)}ms`} - {s.n} probes - {s.successPct}% ok - {ep.staleRounds > 0 && stale ×{ep.staleRounds}} -
-
- ); - })} -
)}