Merge branch 'feature/improve-block-navigation' into develop

This commit is contained in:
Willian Mitsuda 2021-07-23 19:50:38 -03:00
commit fd96c4e854
10 changed files with 137 additions and 78 deletions

View File

@ -1,15 +1,10 @@
import React, { useEffect, useState, useMemo, useContext } from "react";
import { useParams, NavLink } from "react-router-dom";
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 StandardSubtitle from "./StandardSubtitle";
import NavBlock from "./block/NavBlock";
import ContentFrame from "./ContentFrame";
import NavButton from "./components/NavButton";
import Timestamp from "./components/Timestamp";
import GasValue from "./components/GasValue";
import BlockLink from "./components/BlockLink";
@ -18,6 +13,7 @@ import TransactionValue from "./components/TransactionValue";
import HexValue from "./components/HexValue";
import { RuntimeContext } from "./useRuntime";
import { useLatestBlockNumber } from "./useLatestBlock";
import { blockTxsURL } from "./url";
type BlockParams = {
blockNumberOrHash: string;
@ -107,44 +103,25 @@ const Block: React.FC = () => {
return (
<StandardFrame>
<StandardSubtitle>
Block{" "}
<div className="flex space-x-1 items-baseline">
<span>Block</span>
<span className="text-base text-gray-500">
#{params.blockNumberOrHash}
</span>
{block && (
<NavBlock
blockNumber={block.number}
latestBlockNumber={latestBlockNumber}
/>
)}
</div>
</StandardSubtitle>
{block && (
<ContentFrame>
<InfoRow title="Block Height">
<div className="flex space-x-1 items-baseline">
<span className="font-bold mr-1">
<span className="font-bold">
{ethers.utils.commify(block.number)}
</span>
<NavButton
blockNum={block.number - 1}
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>
</InfoRow>
<InfoRow title="Timestamp">
<Timestamp value={block.timestamp} />
@ -152,7 +129,7 @@ const Block: React.FC = () => {
<InfoRow title="Transactions">
<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"
to={`/block/${block.number}/txs`}
to={blockTxsURL(block.number)}
>
{block.transactions.length} transactions
</NavLink>{" "}

View File

@ -1,21 +0,0 @@
import React from "react";
import { ethers } from "ethers";
import StandardSubtitle from "./StandardSubtitle";
import BlockLink from "./components/BlockLink";
type BlockTransactionHeaderProps = {
blockTag: ethers.providers.BlockTag;
};
const BlockTransactionHeader: React.FC<BlockTransactionHeaderProps> = ({
blockTag,
}) => (
<>
<StandardSubtitle>Transactions</StandardSubtitle>
<div className="pb-2 text-sm text-gray-500">
For Block <BlockLink blockTag={blockTag} />
</div>
</>
);
export default React.memo(BlockTransactionHeader);

View File

@ -3,8 +3,8 @@ import { useParams, useLocation } from "react-router";
import { ethers } from "ethers";
import queryString from "query-string";
import StandardFrame from "./StandardFrame";
import BlockTransactionHeader from "./BlockTransactionHeader";
import BlockTransactionResults from "./BlockTransactionResults";
import BlockTransactionHeader from "./block/BlockTransactionHeader";
import BlockTransactionResults from "./block/BlockTransactionResults";
import {
InternalOperation,
OperationType,

View File

@ -5,6 +5,7 @@ import Logo from "./Logo";
import Timestamp from "./components/Timestamp";
import { RuntimeContext } from "./useRuntime";
import { useLatestBlock } from "./useLatestBlock";
import { blockURL } from "./url";
const Home: React.FC = () => {
const { provider } = useContext(RuntimeContext);
@ -56,7 +57,7 @@ const Home: React.FC = () => {
{latestBlock && (
<NavLink
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>
<Timestamp value={latestBlock.timestamp} />

View File

@ -0,0 +1,38 @@
import React, { useContext } from "react";
import { ethers } from "ethers";
import StandardSubtitle from "../StandardSubtitle";
import BlockLink from "../components/BlockLink";
import NavBlock from "./NavBlock";
import { RuntimeContext } from "../useRuntime";
import { useLatestBlockNumber } from "../useLatestBlock";
import { blockTxsURL } from "../url";
type BlockTransactionHeaderProps = {
blockTag: ethers.providers.BlockTag;
};
const BlockTransactionHeader: React.FC<BlockTransactionHeaderProps> = ({
blockTag,
}) => {
const { provider } = useContext(RuntimeContext);
const latestBlockNumber = useLatestBlockNumber(provider);
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>
</StandardSubtitle>
);
};
export default React.memo(BlockTransactionHeader);

View File

@ -1,15 +1,15 @@
import React, { useContext } from "react";
import ContentFrame from "./ContentFrame";
import PageControl from "./search/PageControl";
import ResultHeader from "./search/ResultHeader";
import PendingResults from "./search/PendingResults";
import TransactionItem from "./search/TransactionItem";
import { useFeeToggler } from "./search/useFeeToggler";
import { RuntimeContext } from "./useRuntime";
import { SelectionContext, useSelection } from "./useSelection";
import { useENSCache } from "./useReverseCache";
import { ProcessedTransaction } from "./types";
import { PAGE_SIZE } from "./params";
import ContentFrame from "../ContentFrame";
import PageControl from "../search/PageControl";
import ResultHeader from "../search/ResultHeader";
import PendingResults from "../search/PendingResults";
import TransactionItem from "../search/TransactionItem";
import { useFeeToggler } from "../search/useFeeToggler";
import { RuntimeContext } from "../useRuntime";
import { SelectionContext, useSelection } from "../useSelection";
import { useENSCache } from "../useReverseCache";
import { ProcessedTransaction } from "../types";
import { PAGE_SIZE } from "../params";
type BlockTransactionResultsProps = {
page?: ProcessedTransaction[];

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 { blockURL } from "../url";
type NavButtonProps = {
blockNum: number;
disabled?: boolean;
urlBuilder?: (blockNumber: ethers.providers.BlockTag) => string;
};
const NavButton: React.FC<NavButtonProps> = ({
blockNum,
disabled,
urlBuilder,
children,
}) => {
if (disabled) {
@ -21,7 +25,7 @@ const NavButton: React.FC<NavButtonProps> = ({
return (
<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"
to={`/block/${blockNum}`}
to={urlBuilder ? urlBuilder(blockNum) : blockURL(blockNum)}
>
{children}
</NavLink>

View File

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

View File

@ -1,3 +1,5 @@
import { ethers } from "ethers";
export const fourBytesURL = (
assetsURLPrefix: string,
fourBytes: string
@ -7,3 +9,9 @@ export const tokenLogoURL = (
assetsURLPrefix: string,
address: string
): 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`;