From e5642a788d158900a4c91039a586c957525ffbb2 Mon Sep 17 00:00:00 2001 From: Evan Gray Date: Fri, 15 Oct 2021 15:33:59 -0400 Subject: [PATCH] bridge_ui: transfer confirmation dialog Change-Id: I232f60354388b0b88ba3ab43d9bbd9cb5ceb255e --- bridge_ui/src/components/Transfer/Send.tsx | 35 +++++-- .../Transfer/SendConfirmationDialog.tsx | 93 +++++++++++++++++++ .../src/components/Transfer/SourcePreview.tsx | 10 +- bridge_ui/src/components/Transfer/Target.tsx | 40 ++++++-- .../src/components/Transfer/TargetPreview.tsx | 34 ++++--- 5 files changed, 183 insertions(+), 29 deletions(-) create mode 100644 bridge_ui/src/components/Transfer/SendConfirmationDialog.tsx diff --git a/bridge_ui/src/components/Transfer/Send.tsx b/bridge_ui/src/components/Transfer/Send.tsx index 21ea6b1f..e7f961b3 100644 --- a/bridge_ui/src/components/Transfer/Send.tsx +++ b/bridge_ui/src/components/Transfer/Send.tsx @@ -24,10 +24,22 @@ import KeyAndBalance from "../KeyAndBalance"; import ShowTx from "../ShowTx"; import StepDescription from "../StepDescription"; import TransactionProgress from "../TransactionProgress"; +import SendConfirmationDialog from "./SendConfirmationDialog"; import WaitingForWalletMessage from "./WaitingForWalletMessage"; function Send() { const { handleClick, disabled, showLoader } = useHandleTransfer(); + const [isConfirmOpen, setIsConfirmOpen] = useState(false); + const handleTransferClick = useCallback(() => { + setIsConfirmOpen(true); + }, []); + const handleConfirmClick = useCallback(() => { + handleClick(); + setIsConfirmOpen(false); + }, [handleClick]); + const handleConfirmClose = useCallback(() => { + setIsConfirmOpen(false); + }, []); const sourceChain = useSelector(selectTransferSourceChain); const sourceAsset = useSelector(selectTransferSourceAsset); @@ -143,14 +155,21 @@ function Send() { ) : ( - - Transfer - + <> + + Transfer + + + )} {transferTx ? : null} diff --git a/bridge_ui/src/components/Transfer/SendConfirmationDialog.tsx b/bridge_ui/src/components/Transfer/SendConfirmationDialog.tsx new file mode 100644 index 00000000..a8870e0d --- /dev/null +++ b/bridge_ui/src/components/Transfer/SendConfirmationDialog.tsx @@ -0,0 +1,93 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Typography, +} from "@material-ui/core"; +import { ArrowDownward } from "@material-ui/icons"; +import { Alert } from "@material-ui/lab"; +import { useSelector } from "react-redux"; +import { + selectTransferSourceChain, + selectTransferSourceParsedTokenAccount, +} from "../../store/selectors"; +import { CHAINS_BY_ID } from "../../utils/consts"; +import SmartAddress from "../SmartAddress"; +import { useTargetInfo } from "./Target"; + +function SendConfirmationContent() { + const sourceChain = useSelector(selectTransferSourceChain); + const sourceParsedTokenAccount = useSelector( + selectTransferSourceParsedTokenAccount + ); + const { targetChain, targetAsset, symbol, tokenName, logo } = useTargetInfo(); + return ( + <> + {targetAsset ? ( +
+ +
+ + {CHAINS_BY_ID[sourceChain].name} + +
+
+ +
+ +
+ + {CHAINS_BY_ID[targetChain].name} + +
+
+ ) : null} + + Once the transfer transaction is submitted, the transfer must be + completed by redeeming the tokens on the target chain. Please ensure + that the token listed above is the desired token and confirm that + markets exist on the target chain. + + + ); +} + +export default function SendConfirmationDialog({ + open, + onClick, + onClose, +}: { + open: boolean; + onClick: () => void; + onClose: () => void; +}) { + return ( + + Are you sure? + + + + + + + + + ); +} diff --git a/bridge_ui/src/components/Transfer/SourcePreview.tsx b/bridge_ui/src/components/Transfer/SourcePreview.tsx index f8d4f35e..88df64dc 100644 --- a/bridge_ui/src/components/Transfer/SourcePreview.tsx +++ b/bridge_ui/src/components/Transfer/SourcePreview.tsx @@ -1,6 +1,7 @@ import { makeStyles, Typography } from "@material-ui/core"; import { useSelector } from "react-redux"; import { + selectSourceWalletAddress, selectTransferAmount, selectTransferSourceChain, selectTransferSourceParsedTokenAccount, @@ -21,6 +22,7 @@ export default function SourcePreview() { const sourceParsedTokenAccount = useSelector( selectTransferSourceParsedTokenAccount ); + const sourceWalletAddress = useSelector(selectSourceWalletAddress); const sourceAmount = useSelector(selectTransferAmount); const explainerContent = @@ -31,7 +33,13 @@ export default function SourcePreview() { chainId={sourceChain} parsedTokenAccount={sourceParsedTokenAccount} /> - from {CHAINS_BY_ID[sourceChain].name} + {sourceWalletAddress ? ( + <> + from + + + ) : null} + on {CHAINS_BY_ID[sourceChain].name} ) : ( "" diff --git a/bridge_ui/src/components/Transfer/Target.tsx b/bridge_ui/src/components/Transfer/Target.tsx index 504ec715..b1013095 100644 --- a/bridge_ui/src/components/Transfer/Target.tsx +++ b/bridge_ui/src/components/Transfer/Target.tsx @@ -43,15 +43,7 @@ const useStyles = makeStyles((theme) => ({ }, })); -function Target() { - const classes = useStyles(); - const dispatch = useDispatch(); - const isBeta = useBetaContext(); - const sourceChain = useSelector(selectTransferSourceChain); - const chains = useMemo( - () => CHAINS.filter((c) => c.id !== sourceChain), - [sourceChain] - ); +export const useTargetInfo = () => { const targetChain = useSelector(selectTransferTargetChain); const targetAddressHex = useSelector(selectTransferTargetAddressHex); const targetAsset = useSelector(selectTransferTargetAsset); @@ -68,6 +60,36 @@ function Target() { (targetAsset && metadata.data?.get(targetAsset)?.logo) || undefined; const readableTargetAddress = hexToNativeString(targetAddressHex, targetChain) || ""; + return useMemo( + () => ({ + targetChain, + targetAsset, + tokenName, + symbol, + logo, + readableTargetAddress, + }), + [targetChain, targetAsset, tokenName, symbol, logo, readableTargetAddress] + ); +}; + +function Target() { + const classes = useStyles(); + const dispatch = useDispatch(); + const isBeta = useBetaContext(); + const sourceChain = useSelector(selectTransferSourceChain); + const chains = useMemo( + () => CHAINS.filter((c) => c.id !== sourceChain), + [sourceChain] + ); + const { + targetChain, + targetAsset, + tokenName, + symbol, + logo, + readableTargetAddress, + } = useTargetInfo(); const uiAmountString = useSelector(selectTransferTargetBalanceString); const transferAmount = useSelector(selectTransferAmount); const error = useSelector(selectTransferTargetError); diff --git a/bridge_ui/src/components/Transfer/TargetPreview.tsx b/bridge_ui/src/components/Transfer/TargetPreview.tsx index 63b826a4..4a35f97b 100644 --- a/bridge_ui/src/components/Transfer/TargetPreview.tsx +++ b/bridge_ui/src/components/Transfer/TargetPreview.tsx @@ -1,12 +1,7 @@ -import { hexToNativeString } from "@certusone/wormhole-sdk"; import { makeStyles, Typography } from "@material-ui/core"; -import { useSelector } from "react-redux"; -import { - selectTransferTargetAddressHex, - selectTransferTargetChain, -} from "../../store/selectors"; import { CHAINS_BY_ID } from "../../utils/consts"; import SmartAddress from "../SmartAddress"; +import { useTargetInfo } from "./Target"; const useStyles = makeStyles((theme) => ({ description: { @@ -16,15 +11,32 @@ const useStyles = makeStyles((theme) => ({ export default function TargetPreview() { const classes = useStyles(); - const targetChain = useSelector(selectTransferTargetChain); - const targetAddress = useSelector(selectTransferTargetAddressHex); - const targetAddressNative = hexToNativeString(targetAddress, targetChain); + const { + targetChain, + readableTargetAddress, + targetAsset, + symbol, + tokenName, + logo, + } = useTargetInfo(); const explainerContent = - targetChain && targetAddressNative ? ( + targetChain && readableTargetAddress ? ( <> + {targetAsset ? ( + <> + and receive + + + ) : null} to - + on {CHAINS_BY_ID[targetChain].name} ) : (