Add selection support for addresses
This commit is contained in:
parent
fb7d1f48df
commit
05719eb4ae
|
@ -15,6 +15,7 @@ import { SearchController } from "./search/search";
|
|||
import { RuntimeContext } from "./useRuntime";
|
||||
import { useENSCache } from "./useReverseCache";
|
||||
import { useFeeToggler } from "./search/useFeeToggler";
|
||||
import { SelectionContext, useSelection } from "./useSelection";
|
||||
|
||||
type BlockParams = {
|
||||
addressOrName: string;
|
||||
|
@ -153,6 +154,8 @@ const AddressTransactions: React.FC = () => {
|
|||
|
||||
const [feeDisplay, feeDisplayToggler] = useFeeToggler();
|
||||
|
||||
const selection = useSelection();
|
||||
|
||||
return (
|
||||
<StandardFrame>
|
||||
{error ? (
|
||||
|
@ -204,7 +207,7 @@ const AddressTransactions: React.FC = () => {
|
|||
feeDisplayToggler={feeDisplayToggler}
|
||||
/>
|
||||
{controller ? (
|
||||
<>
|
||||
<SelectionContext.Provider value={selection}>
|
||||
{controller.getPage().map((tx) => (
|
||||
<TransactionItem
|
||||
key={tx.hash}
|
||||
|
@ -228,7 +231,7 @@ const AddressTransactions: React.FC = () => {
|
|||
nextHash={page ? page[page.length - 1].hash : ""}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</SelectionContext.Provider>
|
||||
) : (
|
||||
<PendingResults />
|
||||
)}
|
||||
|
|
|
@ -15,6 +15,7 @@ import { PAGE_SIZE } from "./params";
|
|||
import { useFeeToggler } from "./search/useFeeToggler";
|
||||
import { RuntimeContext } from "./useRuntime";
|
||||
import { useENSCache } from "./useReverseCache";
|
||||
import { SelectionContext, useSelection } from "./useSelection";
|
||||
|
||||
type BlockParams = {
|
||||
blockNumber: string;
|
||||
|
@ -116,6 +117,8 @@ const BlockTransactions: React.FC = () => {
|
|||
|
||||
const [feeDisplay, feeDisplayToggler] = useFeeToggler();
|
||||
|
||||
const selection = useSelection();
|
||||
|
||||
return (
|
||||
<StandardFrame>
|
||||
<StandardSubtitle>Transactions</StandardSubtitle>
|
||||
|
@ -142,7 +145,7 @@ const BlockTransactions: React.FC = () => {
|
|||
feeDisplayToggler={feeDisplayToggler}
|
||||
/>
|
||||
{page ? (
|
||||
<>
|
||||
<SelectionContext.Provider value={selection}>
|
||||
{page.map((tx) => (
|
||||
<TransactionItem
|
||||
key={tx.hash}
|
||||
|
@ -161,7 +164,7 @@ const BlockTransactions: React.FC = () => {
|
|||
total={total}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</SelectionContext.Provider>
|
||||
) : (
|
||||
<PendingResults />
|
||||
)}
|
||||
|
|
|
@ -14,6 +14,7 @@ import TransactionValue from "../components/TransactionValue";
|
|||
import { ENSReverseCache, ProcessedTransaction } from "../types";
|
||||
import { FeeDisplay } from "./useFeeToggler";
|
||||
import { formatValue } from "../components/formatter";
|
||||
import { useSelectionContext } from "../useSelection";
|
||||
|
||||
type TransactionItemProps = {
|
||||
tx: ProcessedTransaction;
|
||||
|
@ -45,6 +46,14 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
|
|||
const ensTo = ensCache && tx.to && ensCache[tx.to];
|
||||
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 (
|
||||
<div
|
||||
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="truncate" title={tx.from}>
|
||||
{tx.from && (
|
||||
<div
|
||||
className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 ${
|
||||
selection !== null &&
|
||||
selection.type === "address" &&
|
||||
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>
|
||||
|
@ -86,12 +107,24 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
|
|||
</span>
|
||||
<span className="col-span-2 truncate" title={tx.to}>
|
||||
{tx.to && (
|
||||
<div
|
||||
className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 ${
|
||||
selection !== null &&
|
||||
selection.type === "address" &&
|
||||
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 className="col-span-2 truncate">
|
||||
|
|
|
@ -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;
|
||||
};
|
Loading…
Reference in New Issue