Retrofit the AddressHighlighter into the new generic SelectionHighlighter
This commit is contained in:
parent
ad94813476
commit
09e89c5f41
|
@ -1,5 +1,5 @@
|
||||||
import React, { useMemo } from "react";
|
import React from "react";
|
||||||
import { useSelectionContext } from "../useSelection";
|
import SelectionHighlighter, { addressSelector } from "./SelectionHighlighter";
|
||||||
|
|
||||||
type AddressHighlighterProps = React.PropsWithChildren<{
|
type AddressHighlighterProps = React.PropsWithChildren<{
|
||||||
address: string;
|
address: string;
|
||||||
|
@ -8,50 +8,14 @@ type AddressHighlighterProps = React.PropsWithChildren<{
|
||||||
const AddressHighlighter: React.FC<AddressHighlighterProps> = ({
|
const AddressHighlighter: React.FC<AddressHighlighterProps> = ({
|
||||||
address,
|
address,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => (
|
||||||
const [selection, setSelection] = useSelectionContext();
|
<SelectionHighlighter
|
||||||
const [select, deselect] = useMemo(() => {
|
myType="address"
|
||||||
const _select = () => {
|
myContent={address}
|
||||||
setSelection({ type: "address", content: address });
|
selector={addressSelector}
|
||||||
};
|
|
||||||
const _deselect = () => {
|
|
||||||
setSelection(null);
|
|
||||||
};
|
|
||||||
return [_select, _deselect];
|
|
||||||
}, [setSelection, address]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AddressHighlighterImpl
|
|
||||||
selected={
|
|
||||||
selection !== null &&
|
|
||||||
selection.type === "address" &&
|
|
||||||
selection.content === address
|
|
||||||
}
|
|
||||||
select={select}
|
|
||||||
deselect={deselect}
|
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AddressHighlighterImpl>
|
</SelectionHighlighter>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
type _AddressHighlighterImplProps = {
|
|
||||||
selected: boolean;
|
|
||||||
select: () => void;
|
|
||||||
deselect: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AddressHighlighterImpl: React.FC<_AddressHighlighterImplProps> =
|
|
||||||
React.memo(({ selected, select, deselect, children }) => (
|
|
||||||
<div
|
|
||||||
className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 truncate ${
|
|
||||||
selected ? "border-orange-400 bg-yellow-100" : "border-transparent"
|
|
||||||
}`}
|
|
||||||
onMouseEnter={select}
|
|
||||||
onMouseLeave={deselect}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
|
|
||||||
export default AddressHighlighter;
|
export default AddressHighlighter;
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
import React, { useMemo } from "react";
|
||||||
|
import {
|
||||||
|
useSelectionContext,
|
||||||
|
OptionalSelection,
|
||||||
|
SelectionType,
|
||||||
|
} from "../useSelection";
|
||||||
|
|
||||||
|
export type ContentSelector = (
|
||||||
|
selection: OptionalSelection,
|
||||||
|
content: string
|
||||||
|
) => boolean;
|
||||||
|
|
||||||
|
export const genericSelector =
|
||||||
|
(type: SelectionType) =>
|
||||||
|
(selection: OptionalSelection, content: string): boolean =>
|
||||||
|
selection !== null &&
|
||||||
|
selection.type === type &&
|
||||||
|
selection.content === content;
|
||||||
|
|
||||||
|
export const addressSelector: ContentSelector = genericSelector("address");
|
||||||
|
|
||||||
|
type SelectionHighlighterProps = React.PropsWithChildren<{
|
||||||
|
myType: SelectionType;
|
||||||
|
myContent: string;
|
||||||
|
selector: ContentSelector;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
const SelectionHighlighter: React.FC<SelectionHighlighterProps> = ({
|
||||||
|
myType,
|
||||||
|
myContent,
|
||||||
|
selector,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [selection, setSelection] = useSelectionContext();
|
||||||
|
const [select, deselect] = useMemo(() => {
|
||||||
|
const _select = () => {
|
||||||
|
setSelection({ type: myType, content: myContent });
|
||||||
|
};
|
||||||
|
const _deselect = () => {
|
||||||
|
setSelection(null);
|
||||||
|
};
|
||||||
|
return [_select, _deselect];
|
||||||
|
}, [setSelection, myType, myContent]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HighlighterBox
|
||||||
|
selected={selector(selection, myContent)}
|
||||||
|
select={select}
|
||||||
|
deselect={deselect}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</HighlighterBox>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type HighlighterBoxProps = {
|
||||||
|
selected: boolean;
|
||||||
|
select: () => void;
|
||||||
|
deselect: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HighlighterBox: React.FC<HighlighterBoxProps> = React.memo(
|
||||||
|
({ selected, select, deselect, children }) => (
|
||||||
|
<div
|
||||||
|
className={`border border-dashed rounded hover:bg-transparent hover:border-transparent px-1 truncate ${
|
||||||
|
selected ? "border-orange-400 bg-yellow-100" : "border-transparent"
|
||||||
|
}`}
|
||||||
|
onMouseEnter={select}
|
||||||
|
onMouseLeave={deselect}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
export default SelectionHighlighter;
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type FunctionSignatureProps = {
|
||||||
|
callType: string;
|
||||||
|
sig: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FunctionSignature: React.FC<FunctionSignatureProps> = ({
|
||||||
|
callType,
|
||||||
|
sig,
|
||||||
|
}) => (
|
||||||
|
<span
|
||||||
|
className={`font-bold ${
|
||||||
|
callType === "STATICCALL"
|
||||||
|
? "text-red-700"
|
||||||
|
: callType === "DELEGATECALL" || callType === "CALLCODE"
|
||||||
|
? "text-gray-400"
|
||||||
|
: "text-blue-900"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{sig}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default FunctionSignature;
|
|
@ -2,6 +2,7 @@ import React from "react";
|
||||||
import AddressHighlighter from "../components/AddressHighlighter";
|
import AddressHighlighter from "../components/AddressHighlighter";
|
||||||
import DecoratedAddressLink from "../components/DecoratedAddressLink";
|
import DecoratedAddressLink from "../components/DecoratedAddressLink";
|
||||||
import FormattedBalance from "../components/FormattedBalance";
|
import FormattedBalance from "../components/FormattedBalance";
|
||||||
|
import FunctionSignature from "./FunctionSignature";
|
||||||
import { TransactionData } from "../types";
|
import { TransactionData } from "../types";
|
||||||
import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes";
|
import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes";
|
||||||
import { TraceGroup } from "../useErigonHooks";
|
import { TraceGroup } from "../useErigonHooks";
|
||||||
|
@ -38,17 +39,10 @@ const TraceItem: React.FC<TraceItemProps> = ({ t, txData, last }) => {
|
||||||
</AddressHighlighter>
|
</AddressHighlighter>
|
||||||
</span>
|
</span>
|
||||||
<span>.</span>
|
<span>.</span>
|
||||||
<span
|
<FunctionSignature
|
||||||
className={`font-bold ${
|
callType={t.type}
|
||||||
t.type === "STATICCALL"
|
sig={fourBytesEntry ? fourBytesEntry.name : raw4Bytes}
|
||||||
? "text-red-700"
|
/>
|
||||||
: t.type === "DELEGATECALL" || t.type === "CALLCODE"
|
|
||||||
? "text-gray-400"
|
|
||||||
: "text-blue-900"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{fourBytesEntry ? fourBytesEntry.name : raw4Bytes}
|
|
||||||
</span>
|
|
||||||
{t.value && !t.value.isZero() && (
|
{t.value && !t.value.isZero() && (
|
||||||
<span className="text-red-700 whitespace-nowrap">
|
<span className="text-red-700 whitespace-nowrap">
|
||||||
{"{"}value: <FormattedBalance value={t.value} /> ETH{"}"}
|
{"{"}value: <FormattedBalance value={t.value} /> ETH{"}"}
|
||||||
|
|
|
@ -6,12 +6,14 @@ import {
|
||||||
useContext,
|
useContext,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
|
||||||
|
export type SelectionType = "address" | "value" | "functionSig";
|
||||||
|
|
||||||
export type Selection = {
|
export type Selection = {
|
||||||
type: "address" | "value";
|
type: SelectionType;
|
||||||
content: string;
|
content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OptionalSelection = Selection | null;
|
export type OptionalSelection = Selection | null;
|
||||||
|
|
||||||
export const useSelection = (): [
|
export const useSelection = (): [
|
||||||
OptionalSelection,
|
OptionalSelection,
|
||||||
|
|
Loading…
Reference in New Issue