Extract and apply block navigation to block txs page

This commit is contained in:
Willian Mitsuda 2021-07-23 19:46:21 -03:00
parent e6083e5cd5
commit 6c763b4817
7 changed files with 101 additions and 46 deletions

View File

@ -1,15 +1,10 @@
import React, { useEffect, useState, useMemo, useContext } from "react"; import React, { useEffect, useState, useMemo, useContext } from "react";
import { useParams, NavLink } from "react-router-dom"; import { useParams, NavLink } from "react-router-dom";
import { ethers, BigNumber } from "ethers"; import { ethers, BigNumber } from "ethers";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faChevronLeft,
faChevronRight,
} from "@fortawesome/free-solid-svg-icons";
import StandardFrame from "./StandardFrame"; import StandardFrame from "./StandardFrame";
import StandardSubtitle from "./StandardSubtitle"; import StandardSubtitle from "./StandardSubtitle";
import NavBlock from "./block/NavBlock";
import ContentFrame from "./ContentFrame"; import ContentFrame from "./ContentFrame";
import NavButton from "./components/NavButton";
import Timestamp from "./components/Timestamp"; import Timestamp from "./components/Timestamp";
import GasValue from "./components/GasValue"; import GasValue from "./components/GasValue";
import BlockLink from "./components/BlockLink"; import BlockLink from "./components/BlockLink";
@ -18,6 +13,7 @@ import TransactionValue from "./components/TransactionValue";
import HexValue from "./components/HexValue"; import HexValue from "./components/HexValue";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
import { useLatestBlockNumber } from "./useLatestBlock"; import { useLatestBlockNumber } from "./useLatestBlock";
import { blockTxsURL } from "./url";
type BlockParams = { type BlockParams = {
blockNumberOrHash: string; blockNumberOrHash: string;
@ -113,33 +109,10 @@ const Block: React.FC = () => {
#{params.blockNumberOrHash} #{params.blockNumberOrHash}
</span> </span>
{block && ( {block && (
<div className="pl-2 self-center flex space-x-1"> <NavBlock
<NavButton blockNumber={block.number}
blockNum={block.number - 1} latestBlockNumber={latestBlockNumber}
disabled={block.number === 0} />
>
<FontAwesomeIcon icon={faChevronLeft} />
</NavButton>
<NavButton
blockNum={block.number + 1}
disabled={
latestBlockNumber === undefined ||
block.number >= latestBlockNumber
}
>
<FontAwesomeIcon icon={faChevronRight} />
</NavButton>
<NavButton
blockNum={latestBlockNumber!}
disabled={
latestBlockNumber === undefined ||
block.number >= latestBlockNumber
}
>
<FontAwesomeIcon icon={faChevronRight} />
<FontAwesomeIcon icon={faChevronRight} />
</NavButton>
</div>
)} )}
</div> </div>
</StandardSubtitle> </StandardSubtitle>
@ -156,7 +129,7 @@ const Block: React.FC = () => {
<InfoRow title="Transactions"> <InfoRow title="Transactions">
<NavLink <NavLink
className="bg-link-blue bg-opacity-10 text-link-blue hover:bg-opacity-100 hover:text-white rounded-lg px-2 py-1 text-xs" className="bg-link-blue bg-opacity-10 text-link-blue hover:bg-opacity-100 hover:text-white rounded-lg px-2 py-1 text-xs"
to={`/block/${block.number}/txs`} to={blockTxsURL(block.number)}
> >
{block.transactions.length} transactions {block.transactions.length} transactions
</NavLink>{" "} </NavLink>{" "}

View File

@ -1,7 +1,11 @@
import React from "react"; import React, { useContext } from "react";
import { ethers } from "ethers"; import { ethers } from "ethers";
import StandardSubtitle from "./StandardSubtitle"; import StandardSubtitle from "./StandardSubtitle";
import BlockLink from "./components/BlockLink"; import BlockLink from "./components/BlockLink";
import NavBlock from "./block/NavBlock";
import { RuntimeContext } from "./useRuntime";
import { useLatestBlockNumber } from "./useLatestBlock";
import { blockTxsURL } from "./url";
type BlockTransactionHeaderProps = { type BlockTransactionHeaderProps = {
blockTag: ethers.providers.BlockTag; blockTag: ethers.providers.BlockTag;
@ -9,13 +13,26 @@ type BlockTransactionHeaderProps = {
const BlockTransactionHeader: React.FC<BlockTransactionHeaderProps> = ({ const BlockTransactionHeader: React.FC<BlockTransactionHeaderProps> = ({
blockTag, blockTag,
}) => ( }) => {
<> const { provider } = useContext(RuntimeContext);
<StandardSubtitle>Transactions</StandardSubtitle> const latestBlockNumber = useLatestBlockNumber(provider);
<div className="pb-2 text-sm text-gray-500">
For Block <BlockLink blockTag={blockTag} /> return (
<StandardSubtitle>
<div className="flex space-x-1 items-baseline">
<span>Transactions</span>
<div className="flex space-x-1 text-sm text-gray-500">
<span>For Block</span>
<BlockLink blockTag={blockTag} />
<NavBlock
blockNumber={blockTag as number}
latestBlockNumber={latestBlockNumber}
urlBuilder={blockTxsURL}
/>
</div> </div>
</> </div>
); </StandardSubtitle>
);
};
export default React.memo(BlockTransactionHeader); export default React.memo(BlockTransactionHeader);

View File

@ -5,6 +5,7 @@ import Logo from "./Logo";
import Timestamp from "./components/Timestamp"; import Timestamp from "./components/Timestamp";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
import { useLatestBlock } from "./useLatestBlock"; import { useLatestBlock } from "./useLatestBlock";
import { blockURL } from "./url";
const Home: React.FC = () => { const Home: React.FC = () => {
const { provider } = useContext(RuntimeContext); const { provider } = useContext(RuntimeContext);
@ -56,7 +57,7 @@ const Home: React.FC = () => {
{latestBlock && ( {latestBlock && (
<NavLink <NavLink
className="mx-auto flex flex-col items-center space-y-1 mt-5 text-sm text-gray-500 hover:text-link-blue" className="mx-auto flex flex-col items-center space-y-1 mt-5 text-sm text-gray-500 hover:text-link-blue"
to={`/block/${latestBlock.number}`} to={blockURL(latestBlock.number)}
> >
<div>Latest block: {ethers.utils.commify(latestBlock.number)}</div> <div>Latest block: {ethers.utils.commify(latestBlock.number)}</div>
<Timestamp value={latestBlock.timestamp} /> <Timestamp value={latestBlock.timestamp} />

51
src/block/NavBlock.tsx Normal file
View File

@ -0,0 +1,51 @@
import React from "react";
import { ethers } from "ethers";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faChevronLeft,
faChevronRight,
} from "@fortawesome/free-solid-svg-icons";
import NavButton from "./NavButton";
type NavBlockProps = {
blockNumber: number;
latestBlockNumber: number | undefined;
urlBuilder?: (blockNumber: ethers.providers.BlockTag) => string;
};
const NavBlock: React.FC<NavBlockProps> = ({
blockNumber,
latestBlockNumber,
urlBuilder,
}) => (
<div className="pl-2 self-center flex space-x-1">
<NavButton
blockNum={blockNumber - 1}
disabled={blockNumber === 0}
urlBuilder={urlBuilder}
>
<FontAwesomeIcon icon={faChevronLeft} />
</NavButton>
<NavButton
blockNum={blockNumber + 1}
disabled={
latestBlockNumber === undefined || blockNumber >= latestBlockNumber
}
urlBuilder={urlBuilder}
>
<FontAwesomeIcon icon={faChevronRight} />
</NavButton>
<NavButton
blockNum={latestBlockNumber!}
disabled={
latestBlockNumber === undefined || blockNumber >= latestBlockNumber
}
urlBuilder={urlBuilder}
>
<FontAwesomeIcon icon={faChevronRight} />
<FontAwesomeIcon icon={faChevronRight} />
</NavButton>
</div>
);
export default React.memo(NavBlock);

View File

@ -1,13 +1,17 @@
import { ethers } from "ethers";
import { NavLink } from "react-router-dom"; import { NavLink } from "react-router-dom";
import { blockURL } from "../url";
type NavButtonProps = { type NavButtonProps = {
blockNum: number; blockNum: number;
disabled?: boolean; disabled?: boolean;
urlBuilder?: (blockNumber: ethers.providers.BlockTag) => string;
}; };
const NavButton: React.FC<NavButtonProps> = ({ const NavButton: React.FC<NavButtonProps> = ({
blockNum, blockNum,
disabled, disabled,
urlBuilder,
children, children,
}) => { }) => {
if (disabled) { if (disabled) {
@ -21,7 +25,7 @@ const NavButton: React.FC<NavButtonProps> = ({
return ( return (
<NavLink <NavLink
className="transition-colors bg-link-blue bg-opacity-10 text-link-blue hover:bg-opacity-100 hover:text-white disabled:bg-link-blue disabled:text-gray-400 disabled:cursor-default rounded px-2 py-1 text-xs" className="transition-colors bg-link-blue bg-opacity-10 text-link-blue hover:bg-opacity-100 hover:text-white disabled:bg-link-blue disabled:text-gray-400 disabled:cursor-default rounded px-2 py-1 text-xs"
to={`/block/${blockNum}`} to={urlBuilder ? urlBuilder(blockNum) : blockURL(blockNum)}
> >
{children} {children}
</NavLink> </NavLink>

View File

@ -1,6 +1,7 @@
import React from "react"; import React from "react";
import { NavLink } from "react-router-dom"; import { NavLink } from "react-router-dom";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { blockURL } from "../url";
type BlockLinkProps = { type BlockLinkProps = {
blockTag: ethers.providers.BlockTag; blockTag: ethers.providers.BlockTag;
@ -18,7 +19,7 @@ const BlockLink: React.FC<BlockLinkProps> = ({ blockTag }) => {
className={`text-link-blue hover:text-link-blue-hover ${ className={`text-link-blue hover:text-link-blue-hover ${
isNum ? "font-blocknum" : "font-hash" isNum ? "font-blocknum" : "font-hash"
}`} }`}
to={`/block/${blockTag}`} to={blockURL(blockTag)}
> >
{text} {text}
</NavLink> </NavLink>

View File

@ -1,3 +1,5 @@
import { ethers } from "ethers";
export const fourBytesURL = ( export const fourBytesURL = (
assetsURLPrefix: string, assetsURLPrefix: string,
fourBytes: string fourBytes: string
@ -7,3 +9,9 @@ export const tokenLogoURL = (
assetsURLPrefix: string, assetsURLPrefix: string,
address: string address: string
): string => `${assetsURLPrefix}/assets/${address}/logo.png`; ): string => `${assetsURLPrefix}/assets/${address}/logo.png`;
export const blockURL = (blockNum: ethers.providers.BlockTag) =>
`/block/${blockNum}`;
export const blockTxsURL = (blockNum: ethers.providers.BlockTag) =>
`/block/${blockNum}/txs`;