Add selection support for addresses

This commit is contained in:
Willian Mitsuda 2021-07-14 03:52:31 -03:00
parent fb7d1f48df
commit 05719eb4ae
4 changed files with 78 additions and 16 deletions

View File

@ -15,6 +15,7 @@ import { SearchController } from "./search/search";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
import { useENSCache } from "./useReverseCache"; import { useENSCache } from "./useReverseCache";
import { useFeeToggler } from "./search/useFeeToggler"; import { useFeeToggler } from "./search/useFeeToggler";
import { SelectionContext, useSelection } from "./useSelection";
type BlockParams = { type BlockParams = {
addressOrName: string; addressOrName: string;
@ -153,6 +154,8 @@ const AddressTransactions: React.FC = () => {
const [feeDisplay, feeDisplayToggler] = useFeeToggler(); const [feeDisplay, feeDisplayToggler] = useFeeToggler();
const selection = useSelection();
return ( return (
<StandardFrame> <StandardFrame>
{error ? ( {error ? (
@ -204,7 +207,7 @@ const AddressTransactions: React.FC = () => {
feeDisplayToggler={feeDisplayToggler} feeDisplayToggler={feeDisplayToggler}
/> />
{controller ? ( {controller ? (
<> <SelectionContext.Provider value={selection}>
{controller.getPage().map((tx) => ( {controller.getPage().map((tx) => (
<TransactionItem <TransactionItem
key={tx.hash} key={tx.hash}
@ -228,7 +231,7 @@ const AddressTransactions: React.FC = () => {
nextHash={page ? page[page.length - 1].hash : ""} nextHash={page ? page[page.length - 1].hash : ""}
/> />
</div> </div>
</> </SelectionContext.Provider>
) : ( ) : (
<PendingResults /> <PendingResults />
)} )}

View File

@ -15,6 +15,7 @@ import { PAGE_SIZE } from "./params";
import { useFeeToggler } from "./search/useFeeToggler"; import { useFeeToggler } from "./search/useFeeToggler";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
import { useENSCache } from "./useReverseCache"; import { useENSCache } from "./useReverseCache";
import { SelectionContext, useSelection } from "./useSelection";
type BlockParams = { type BlockParams = {
blockNumber: string; blockNumber: string;
@ -116,6 +117,8 @@ const BlockTransactions: React.FC = () => {
const [feeDisplay, feeDisplayToggler] = useFeeToggler(); const [feeDisplay, feeDisplayToggler] = useFeeToggler();
const selection = useSelection();
return ( return (
<StandardFrame> <StandardFrame>
<StandardSubtitle>Transactions</StandardSubtitle> <StandardSubtitle>Transactions</StandardSubtitle>
@ -142,7 +145,7 @@ const BlockTransactions: React.FC = () => {
feeDisplayToggler={feeDisplayToggler} feeDisplayToggler={feeDisplayToggler}
/> />
{page ? ( {page ? (
<> <SelectionContext.Provider value={selection}>
{page.map((tx) => ( {page.map((tx) => (
<TransactionItem <TransactionItem
key={tx.hash} key={tx.hash}
@ -161,7 +164,7 @@ const BlockTransactions: React.FC = () => {
total={total} total={total}
/> />
</div> </div>
</> </SelectionContext.Provider>
) : ( ) : (
<PendingResults /> <PendingResults />
)} )}

View File

@ -14,6 +14,7 @@ import TransactionValue from "../components/TransactionValue";
import { ENSReverseCache, ProcessedTransaction } from "../types"; import { ENSReverseCache, ProcessedTransaction } from "../types";
import { FeeDisplay } from "./useFeeToggler"; import { FeeDisplay } from "./useFeeToggler";
import { formatValue } from "../components/formatter"; import { formatValue } from "../components/formatter";
import { useSelectionContext } from "../useSelection";
type TransactionItemProps = { type TransactionItemProps = {
tx: ProcessedTransaction; tx: ProcessedTransaction;
@ -45,6 +46,14 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
const ensTo = ensCache && tx.to && ensCache[tx.to]; const ensTo = ensCache && tx.to && ensCache[tx.to];
const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction; const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction;
const [selection, setSelection] = useSelectionContext();
const select = (address: string) => {
setSelection({ type: "address", content: address });
};
const deselect = () => {
setSelection(null);
};
return ( return (
<div <div
className={`grid grid-cols-12 gap-x-1 items-baseline text-sm border-t border-gray-200 ${ className={`grid grid-cols-12 gap-x-1 items-baseline text-sm border-t border-gray-200 ${
@ -69,12 +78,24 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
<span className="col-span-2 flex justify-between items-baseline space-x-2 pr-2"> <span className="col-span-2 flex justify-between items-baseline space-x-2 pr-2">
<span className="truncate" title={tx.from}> <span className="truncate" title={tx.from}>
{tx.from && ( {tx.from && (
<AddressOrENSName <div
address={tx.from} className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 ${
ensName={ensFrom} selection !== null &&
selectedAddress={selectedAddress} selection.type === "address" &&
minerAddress={tx.miner} selection.content === tx.from
/> ? "border-orange-400 bg-yellow-100"
: "border-transparent"
}`}
onMouseEnter={() => select(tx.from!)}
onMouseLeave={deselect}
>
<AddressOrENSName
address={tx.from}
ensName={ensFrom}
selectedAddress={selectedAddress}
minerAddress={tx.miner}
/>
</div>
)} )}
</span> </span>
<span> <span>
@ -86,12 +107,24 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
</span> </span>
<span className="col-span-2 truncate" title={tx.to}> <span className="col-span-2 truncate" title={tx.to}>
{tx.to && ( {tx.to && (
<AddressOrENSName <div
address={tx.to} className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 ${
ensName={ensTo} selection !== null &&
selectedAddress={selectedAddress} selection.type === "address" &&
minerAddress={tx.miner} selection.content === tx.to
/> ? "border-orange-400 bg-yellow-100"
: "border-transparent"
}`}
onMouseEnter={() => select(tx.to!)}
onMouseLeave={deselect}
>
<AddressOrENSName
address={tx.to}
ensName={ensTo}
selectedAddress={selectedAddress}
minerAddress={tx.miner}
/>
</div>
)} )}
</span> </span>
<span className="col-span-2 truncate"> <span className="col-span-2 truncate">

23
src/useSelection.ts Normal file
View File

@ -0,0 +1,23 @@
import React, { useState, useContext } from "react";
export type Selection = {
type: string;
content: string;
};
export const useSelection = (): [
Selection | null,
React.Dispatch<React.SetStateAction<Selection | null>>
] => {
const [selection, setSelection] = useState<Selection | null>(null);
return [selection, setSelection];
};
export const SelectionContext = React.createContext<
ReturnType<typeof useSelection>
>(null!);
export const useSelectionContext = () => {
const ctx = useContext(SelectionContext);
return ctx;
};