otterscan/src/special/london/Blocks.tsx

164 lines
4.9 KiB
TypeScript
Raw Normal View History

2021-07-30 07:55:21 +00:00
import React, {
useState,
useEffect,
useContext,
useMemo,
useCallback,
} from "react";
import { ethers } from "ethers";
2021-07-30 06:26:24 +00:00
import { Line } from "react-chartjs-2";
2021-07-29 18:53:52 +00:00
import { Transition } from "@headlessui/react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2021-07-30 02:05:23 +00:00
import {
faBurn,
faCoins,
faCube,
faGasPump,
2021-07-30 08:18:28 +00:00
faHistory,
2021-07-30 02:05:23 +00:00
} from "@fortawesome/free-solid-svg-icons";
2021-07-30 07:42:39 +00:00
import BlockRow from "./BlockRow";
2021-07-30 07:41:29 +00:00
import { ExtendedBlock, readBlock } from "../../useErigonHooks";
import { RuntimeContext } from "../../useRuntime";
2021-08-04 01:49:42 +00:00
import { options, toChartData } from "./chart";
2021-07-29 18:53:52 +00:00
const MAX_BLOCK_HISTORY = 20;
2021-07-30 08:05:31 +00:00
const PREV_BLOCK_COUNT = 15;
type BlocksProps = {
latestBlock: ethers.providers.Block;
2021-07-30 07:55:21 +00:00
targetBlockNumber: number;
};
2021-07-30 07:55:21 +00:00
const Blocks: React.FC<BlocksProps> = ({ latestBlock, targetBlockNumber }) => {
const { provider } = useContext(RuntimeContext);
2021-08-02 04:53:08 +00:00
const [blocks, setBlocks] = useState<ExtendedBlock[]>([]);
2021-07-30 02:46:59 +00:00
const [now, setNow] = useState<number>(Date.now());
2021-07-30 07:55:21 +00:00
const addBlock = useCallback(
async (blockNumber: number) => {
if (!provider) {
return;
}
2021-07-30 08:05:31 +00:00
// Skip blocks before the hard fork during the transition
if (blockNumber < targetBlockNumber) {
return;
}
2021-07-30 07:55:21 +00:00
const extBlock = await readBlock(provider, blockNumber.toString());
2021-07-30 02:46:59 +00:00
setNow(Date.now());
2021-08-02 04:53:08 +00:00
setBlocks((_blocks) => {
2021-07-30 07:55:21 +00:00
if (_blocks.length > 0 && blockNumber === _blocks[0].number) {
return _blocks;
}
2021-07-30 07:46:39 +00:00
// Leave the last block because of transition animation
const newBlocks = [extBlock, ..._blocks].slice(
0,
MAX_BLOCK_HISTORY + 1
);
// Little hack to fix out of order block notifications
2021-07-30 07:55:21 +00:00
newBlocks.sort((a, b) => b.number - a.number);
2021-07-30 07:46:39 +00:00
return newBlocks;
});
2021-07-30 07:55:21 +00:00
},
2021-07-30 08:05:31 +00:00
[provider, targetBlockNumber]
2021-07-30 07:55:21 +00:00
);
useEffect(() => {
addBlock(latestBlock.number);
}, [addBlock, latestBlock]);
2021-08-04 01:49:42 +00:00
const data = useMemo(() => toChartData(blocks), [blocks]);
2021-07-30 06:26:24 +00:00
2021-07-30 08:05:31 +00:00
// On page reload, pre-populate the last N blocks
useEffect(
() => {
const addPreviousBlocks = async () => {
for (
let i = latestBlock.number - PREV_BLOCK_COUNT;
i < latestBlock.number;
i++
) {
await addBlock(i);
}
};
addPreviousBlocks();
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
return (
2021-07-30 01:56:06 +00:00
<div className="w-full mb-auto">
2021-07-30 02:38:58 +00:00
<div className="px-9 pt-3 pb-12 divide-y-2">
2021-07-30 08:33:02 +00:00
<div className="flex justify-center items-baseline space-x-2 px-3 pb-2 text-lg text-orange-500 ">
<span>
<FontAwesomeIcon icon={faBurn} />
</span>
2021-07-30 21:02:11 +00:00
<span>EIP-1559 is activated. Watch the fees burn.</span>
2021-07-30 08:33:02 +00:00
<span>
<FontAwesomeIcon icon={faBurn} />
</span>
</div>
2021-07-30 06:26:24 +00:00
<div>
<Line data={data} height={100} options={options} />
</div>
<div className="mt-5 grid grid-cols-8 px-3 py-2">
2021-07-30 02:05:23 +00:00
<div className="flex space-x-1 items-baseline">
<span className="text-gray-500">
<FontAwesomeIcon icon={faCube} />
</span>
<span>Block</span>
</div>
<div className="text-right flex space-x-1 justify-end items-baseline">
<span className="text-gray-500">
<FontAwesomeIcon icon={faGasPump} />
</span>
<span>Gas used</span>
</div>
2021-07-30 02:05:23 +00:00
<div className="text-right">Gas target</div>
<div className="text-right">Base fee</div>
<div className="text-right col-span-2 flex space-x-1 justify-end items-baseline">
<span className="text-yellow-400">
<FontAwesomeIcon icon={faCoins} />
</span>
<span>Rewards</span>
</div>
<div className="text-right flex space-x-1 justify-end items-baseline">
<span className="text-orange-500">
<FontAwesomeIcon icon={faBurn} />
</span>
<span>Burnt fees</span>
</div>
2021-07-30 08:18:28 +00:00
<div className="text-right flex space-x-1 justify-end items-baseline">
<span className="text-gray-500">
<FontAwesomeIcon icon={faHistory} />
</span>
<span>Age</span>
</div>
</div>
2021-07-29 18:53:52 +00:00
{blocks.map((b, i) => (
<Transition
key={b.hash}
show={i < MAX_BLOCK_HISTORY}
appear
enter="transition transform ease-out duration-500"
enterFrom="opacity-0 -translate-y-10"
enterTo="opacity-100 translate-y-0"
leave="transition transform ease-out duration-1000"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-10"
>
2021-07-30 07:42:39 +00:00
<BlockRow now={now} block={b} />
2021-07-29 18:53:52 +00:00
</Transition>
))}
</div>
</div>
);
};
export default React.memo(Blocks);