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 { 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 />
|
||||||
)}
|
)}
|
||||||
|
@ -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 />
|
||||||
)}
|
)}
|
||||||
|
@ -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
23
src/useSelection.ts
Normal 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;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user