diff --git a/web/src/App.tsx b/web/src/App.tsx index b52261c..58dace1 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -16,6 +16,7 @@ import { BlockTicker } from './components/BlockTicker' import { ChainSwitcher } from './components/ChainSwitcher' import { Leaderboard } from './components/Leaderboard' import { MinerPanel } from './components/MinerPanel' +import { RuntimePanel } from './components/RuntimePanel' import { StatBar } from './components/StatBar' import { seconds, windowSpan } from './lib/format' import { href, parse, WINDOWS } from './lib/routes' @@ -67,12 +68,6 @@ export default function App() { [chain, navigate], ) - /** Back to the standings, keeping the window the panel was opened from. */ - const closePanel = useCallback( - () => navigate(href({ chain, window: route.window })), - [chain, route.window, navigate], - ) - 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]! @@ -143,7 +138,6 @@ export default function App() { block={route.block} targetSeconds={info?.target_block_time_seconds ?? 6} onResolved={blockResolved} - onClose={closePanel} /> )} @@ -163,13 +157,14 @@ export default function App() { )} - {/* A miner and an account are pages, not things opened over the board. - Each is somebody's own record and the whole subject of the URL that - reached it; leaving eleven other miners' rows underneath is the site - failing to notice which page it is on. A block keeps the board, - because a block is read *against* it — who won this one, and where do - they sit — and the ticker below is the row you clicked to get here. */} - {!route.account && !route.miner && ( + {/* Every one of these is a page, not something opened over the board. A + URL that names one thing has that thing as its whole subject, and + leaving eleven unrelated mining rows underneath is the site failing to + notice which page it is on. The board is what `/:chain/:window` is + for. */} + {route.runtime !== null && chain && } + + {!route.account && !route.miner && !route.block && route.runtime === null && (
@@ -215,6 +210,22 @@ export default function App() { is the only identity the chain itself asserts. An elsewhere tag means the name was earned by the same reward preimage on another chain, not observed on this one. + {state.summary?.spec_version !== null && state.summary?.spec_version !== undefined && ( + + {/* "Decoded how?" has an answer, and it is a page. Every event and + reward on this site was read against this runtime's own type + registry rather than against anything written here, so the + runtime is a load-bearing part of the explanation and not a + footnote. */} + Rewards and transfers are decoded against the chain's own metadata — the type registry + the node produces by running the runtime WASM in each block's state, not a schema + written here. This chain is on{' '} + + {state.summary.spec_name ?? 'runtime'} v{state.summary.spec_version} + + . + + )} {/* Its own line rather than a fourth item in the `space-between` flow: the three above are caveats about the numbers, this is diff --git a/web/src/components/BlockPanel.tsx b/web/src/components/BlockPanel.tsx index 8a8c556..ad7f8da 100644 --- a/web/src/components/BlockPanel.tsx +++ b/web/src/components/BlockPanel.tsx @@ -56,7 +56,6 @@ export function BlockPanel({ block, targetSeconds, onResolved, - onClose, }: { chain: string /** Height or hash, as it appeared in the URL. */ @@ -65,7 +64,6 @@ export function BlockPanel({ targetSeconds: number /** Called with the canonical hash once a height has resolved to one. */ onResolved: (hash: string) => void - onClose: () => void }) { const [detail, setDetail] = useState(null) const [error, setError] = useState(null) @@ -122,21 +120,9 @@ export function BlockPanel({ {detail?.hash ?? ''}
- + {/* No close button: this is a URL somebody navigated to, not a dialog + that opened over something they were reading. The back button and + the chain chip both already do what it would. */} {error &&

{error}

}