bridge_ui: max button for number inputs
Change-Id: I4fdbb2b3191a012cbdf02df4ad6292c78eed5bb7
This commit is contained in:
parent
5ecdde62e1
commit
cff4d928b6
|
@ -1,10 +1,5 @@
|
|||
import { ChainId } from "@certusone/wormhole-sdk";
|
||||
import {
|
||||
CircularProgress,
|
||||
makeStyles,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@material-ui/core";
|
||||
import { CircularProgress, makeStyles, Typography } from "@material-ui/core";
|
||||
import { Alert } from "@material-ui/lab";
|
||||
import { parseUnits } from "ethers/lib/utils";
|
||||
import { useSnackbar } from "notistack";
|
||||
|
@ -14,6 +9,7 @@ import useEthereumMigratorInformation from "../../hooks/useEthereumMigratorInfor
|
|||
import useIsWalletReady from "../../hooks/useIsWalletReady";
|
||||
import ButtonWithLoader from "../ButtonWithLoader";
|
||||
import EthereumSignerKey from "../EthereumSignerKey";
|
||||
import NumberTextField from "../NumberTextField";
|
||||
import ShowTx from "../ShowTx";
|
||||
import SmartAddress from "../SmartAddress";
|
||||
|
||||
|
@ -49,6 +45,7 @@ export default function EvmWorkflow({
|
|||
signerAddress,
|
||||
toggleRefresh
|
||||
);
|
||||
const fromWalletBalance = poolInfo.data?.fromWalletBalance;
|
||||
|
||||
const [migrationAmount, setMigrationAmount] = useState("");
|
||||
const [migrationIsProcessing, setMigrationIsProcessing] = useState(false);
|
||||
|
@ -69,9 +66,9 @@ export default function EvmWorkflow({
|
|||
const hasRequisiteData = poolInfo.data;
|
||||
const amountGreaterThanZero = fromParse(migrationAmount) > BigInt(0);
|
||||
const sufficientFromTokens =
|
||||
poolInfo.data?.fromWalletBalance &&
|
||||
fromWalletBalance &&
|
||||
migrationAmount &&
|
||||
fromParse(migrationAmount) <= fromParse(poolInfo.data.fromWalletBalance);
|
||||
fromParse(migrationAmount) <= fromParse(fromWalletBalance);
|
||||
const sufficientPoolBalance =
|
||||
poolInfo.data?.toPoolBalance &&
|
||||
migrationAmount &&
|
||||
|
@ -106,6 +103,11 @@ export default function EvmWorkflow({
|
|||
(event) => setMigrationAmount(event.target.value),
|
||||
[setMigrationAmount]
|
||||
);
|
||||
const handleMaxClick = useCallback(() => {
|
||||
if (fromWalletBalance) {
|
||||
setMigrationAmount(fromWalletBalance);
|
||||
}
|
||||
}, [fromWalletBalance]);
|
||||
|
||||
const migrateTokens = useCallback(async () => {
|
||||
if (!poolInfo.data) {
|
||||
|
@ -170,8 +172,7 @@ export default function EvmWorkflow({
|
|||
<div>
|
||||
<Typography>This action will convert</Typography>
|
||||
<Typography variant="h6">
|
||||
{fromTokenPretty}{" "}
|
||||
{`(Balance: ${poolInfo.data?.fromWalletBalance || ""})`}
|
||||
{fromTokenPretty} {`(Balance: ${fromWalletBalance || ""})`}
|
||||
</Typography>
|
||||
<div className={classes.spacer} />
|
||||
<Typography>to</Typography>
|
||||
|
@ -190,14 +191,14 @@ export default function EvmWorkflow({
|
|||
<>
|
||||
{explainerContent}
|
||||
<div className={classes.spacer} />
|
||||
<TextField
|
||||
<NumberTextField
|
||||
variant="outlined"
|
||||
value={migrationAmount}
|
||||
type="number"
|
||||
onChange={handleAmountChange}
|
||||
label={"Amount"}
|
||||
disabled={!!migrationIsProcessing || !!transaction}
|
||||
></TextField>
|
||||
onMaxClick={fromWalletBalance ? handleMaxClick : undefined}
|
||||
/>
|
||||
|
||||
{!transaction && (
|
||||
<ButtonWithLoader
|
||||
|
|
|
@ -2,7 +2,7 @@ import { CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
|||
import migrateTokensTx from "@certusone/wormhole-sdk/lib/migration/migrateTokens";
|
||||
import getPoolAddress from "@certusone/wormhole-sdk/lib/migration/poolAddress";
|
||||
import getToCustodyAddress from "@certusone/wormhole-sdk/lib/migration/toCustodyAddress";
|
||||
import { makeStyles, TextField, Typography } from "@material-ui/core";
|
||||
import { makeStyles, Typography } from "@material-ui/core";
|
||||
import {
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
Token,
|
||||
|
@ -19,6 +19,7 @@ import { COLORS } from "../../muiTheme";
|
|||
import { MIGRATION_PROGRAM_ADDRESS, SOLANA_HOST } from "../../utils/consts";
|
||||
import { getMultipleAccounts, signSendAndConfirm } from "../../utils/solana";
|
||||
import ButtonWithLoader from "../ButtonWithLoader";
|
||||
import NumberTextField from "../NumberTextField";
|
||||
import ShowTx from "../ShowTx";
|
||||
import SmartAddress from "../SmartAddress";
|
||||
import SolanaCreateAssociatedAddress, {
|
||||
|
@ -358,6 +359,11 @@ export default function Workflow({
|
|||
(event) => setMigrationAmount(event.target.value),
|
||||
[setMigrationAmount]
|
||||
);
|
||||
const handleMaxClick = useCallback(() => {
|
||||
if (fromTokenAccountBalance) {
|
||||
setMigrationAmount(fromTokenAccountBalance);
|
||||
}
|
||||
}, [fromTokenAccountBalance]);
|
||||
|
||||
const getMetadata = (address: string) => {
|
||||
const tokenMapItem = solanaTokenMap.data?.find(
|
||||
|
@ -459,14 +465,14 @@ export default function Workflow({
|
|||
</>
|
||||
) : null}
|
||||
<div className={classes.spacer} />
|
||||
<TextField
|
||||
<NumberTextField
|
||||
variant="outlined"
|
||||
value={migrationAmount}
|
||||
type="number"
|
||||
onChange={handleAmountChange}
|
||||
label={"Amount"}
|
||||
disabled={!!migrationIsProcessing || !!transaction}
|
||||
></TextField>
|
||||
onMaxClick={fromTokenAccountBalance ? handleMaxClick : undefined}
|
||||
/>
|
||||
|
||||
{!transaction && (
|
||||
<ButtonWithLoader
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import {
|
||||
Button,
|
||||
InputAdornment,
|
||||
TextField,
|
||||
TextFieldProps,
|
||||
} from "@material-ui/core";
|
||||
|
||||
export default function NumberTextField(
|
||||
props: TextFieldProps & { onMaxClick?: () => void }
|
||||
) {
|
||||
return (
|
||||
<TextField
|
||||
type="number"
|
||||
{...props}
|
||||
InputProps={{
|
||||
endAdornment: props.onMaxClick ? (
|
||||
<InputAdornment position="end">
|
||||
<Button
|
||||
onClick={props.onMaxClick}
|
||||
disabled={props.disabled}
|
||||
variant="outlined"
|
||||
>
|
||||
Max
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
) : undefined,
|
||||
...(props?.InputProps || {}),
|
||||
}}
|
||||
></TextField>
|
||||
);
|
||||
}
|
|
@ -4,7 +4,7 @@ import {
|
|||
CHAIN_ID_SOLANA,
|
||||
} from "@certusone/wormhole-sdk";
|
||||
import { getAddress } from "@ethersproject/address";
|
||||
import { Button, makeStyles, TextField } from "@material-ui/core";
|
||||
import { Button, makeStyles } from "@material-ui/core";
|
||||
import { useCallback } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useHistory } from "react-router";
|
||||
|
@ -33,6 +33,7 @@ import ButtonWithLoader from "../ButtonWithLoader";
|
|||
import ChainSelect from "../ChainSelect";
|
||||
import KeyAndBalance from "../KeyAndBalance";
|
||||
import LowBalanceWarning from "../LowBalanceWarning";
|
||||
import NumberTextField from "../NumberTextField";
|
||||
import StepDescription from "../StepDescription";
|
||||
import { TokenSelector } from "../TokenSelectors/SourceTokenSelector";
|
||||
import TokenWarning from "./TokenWarning";
|
||||
|
@ -95,6 +96,11 @@ function Source() {
|
|||
},
|
||||
[dispatch]
|
||||
);
|
||||
const handleMaxClick = useCallback(() => {
|
||||
if (uiAmountString) {
|
||||
dispatch(setAmount(uiAmountString));
|
||||
}
|
||||
}, [dispatch, uiAmountString]);
|
||||
const handleNextClick = useCallback(() => {
|
||||
dispatch(incrementStep());
|
||||
}, [dispatch]);
|
||||
|
@ -136,15 +142,15 @@ function Source() {
|
|||
/>
|
||||
<LowBalanceWarning chainId={sourceChain} />
|
||||
{hasParsedTokenAccount ? (
|
||||
<TextField
|
||||
<NumberTextField
|
||||
variant="outlined"
|
||||
label="Amount"
|
||||
type="number"
|
||||
fullWidth
|
||||
className={classes.transferField}
|
||||
value={amount}
|
||||
onChange={handleAmountChange}
|
||||
disabled={shouldLockFields}
|
||||
onMaxClick={uiAmountString ? handleMaxClick : undefined}
|
||||
/>
|
||||
) : null}
|
||||
<ButtonWithLoader
|
||||
|
|
Loading…
Reference in New Issue