import React, { useMemo } from "https://esm.sh/react@17.0.2"; import styled from "https://esm.sh/styled-components"; import config from "../back/config/config.ts"; import { Container } from "../components/Container.ts"; import { Content } from "../components/Content.ts"; import SiteTitle from "../components/SiteTitle.tsx"; import { useStoreState } from "../state/index.ts"; import SiteMenu from "../components/SiteMenu.tsx"; import { Donation } from "../components/Donation.tsx"; const Table = styled.table` width: 100%; max-width: 1000px; box-shadow: #000 3px 3px 14px; border-radius: 6px; margin: 0 auto 30px; border: 0; border-collapse: collapse; border-radius: 8px; overflow: hidden; `; const TableHead = styled.thead` background-color: #383838; `; const TableBody = styled.tbody` text-align: center; background-color: #434343; tr:hover { background-color: #505050; } `; const TableRow = styled.tr` border-bottom: 2px solid #393939; &:last-child { border-bottom: 0; } `; const TableHeader = styled.th` color: #efefef; padding: 9px; `; const Cell = styled.td` color: #f0f0f0; > a { color: #f0f0f0; } padding: 17px; `; const SignallingCell = styled.td` padding: 16px; text-align: center; `; interface IMinerData { [key: string]: { name: string; signals: boolean; website: string | undefined; numBlocks: number; }; } export default function Miners() { const blocks = useStoreState((store) => store.blocks); const forkName = config.fork.name; const currentNumberOfBlocks = blocks.reduce((prev, currentBlock) => prev + +(currentBlock.signals !== undefined), 0); const miners = useMemo(() => { // We have to reverse the array as we have to check // for the latest block by a miner to decide whether they // are signalling or not. const blocksReversed = blocks.slice(0); blocksReversed.reverse(); const miners = blocksReversed.reduce((prev, currBlock) => { if (currBlock.signals === undefined) { return prev; } const key = currBlock.miner ?? (currBlock.signals ? "unknown_signalling" : "unknown_nonsignalling"); if (!prev[key]) { prev[key] = { name: currBlock.miner ?? "Unrecognized miners", signals: currBlock.signals ?? false, website: currBlock.minerWebsite, numBlocks: 1, }; return prev; } prev[key].numBlocks++; return prev; }, {} as IMinerData); // Sort the miners by share return Object.entries(miners).sort(([_, a], [_2, b]) => { return b.numBlocks - a.numBlocks; }); }, [blocks]); return ( {forkName} activation - Miners Miner name Share Signals {miners.map(([_, miner]) => { return ( {miner.website && ( {miner.name} )} {!miner.website && miner.name} {((miner.numBlocks / currentNumberOfBlocks) * 100).toFixed(1)}% {miner.signals && <>✅} {!miner.signals && <>🚫} ); })}
{config.donation && }
); }