diff --git a/dapp/src/assets/icons/Pause.tsx b/dapp/src/assets/icons/Pause.tsx new file mode 100644 index 000000000..5bdd71bc0 --- /dev/null +++ b/dapp/src/assets/icons/Pause.tsx @@ -0,0 +1,16 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const PauseIcon = createIcon({ + displayName: "PauseIcon", + viewBox: "0 0 18 20", + path: ( + + ), +}) diff --git a/dapp/src/assets/icons/index.ts b/dapp/src/assets/icons/index.ts index fef11b54a..582477ae8 100644 --- a/dapp/src/assets/icons/index.ts +++ b/dapp/src/assets/icons/index.ts @@ -9,3 +9,4 @@ export * from "./ConnectBTCAccount" export * from "./ConnectETHAccount" export * from "./AlertInfo" export * from "./ShieldPlus" +export * from "./Pause" diff --git a/dapp/src/components/Modals/Staking/DepositBTC.tsx b/dapp/src/components/Modals/Staking/DepositBTC.tsx index 924a0ee24..a7d6a520b 100644 --- a/dapp/src/components/Modals/Staking/DepositBTC.tsx +++ b/dapp/src/components/Modals/Staking/DepositBTC.tsx @@ -1,12 +1,18 @@ -import React from "react" +import React, { useCallback } from "react" import { useDepositBTCTransaction, useModalFlowContext } from "#/hooks" import Alert from "#/components/shared/Alert" import { TextMd } from "#/components/shared/Typography" import StakingSteps from "./components/StakingSteps" export default function DepositBTC() { - const { goNext } = useModalFlowContext() - const { depositBTC } = useDepositBTCTransaction(goNext) + const { goNext, endTransactionProcess } = useModalFlowContext() + + const onDepositSuccess = useCallback(() => { + endTransactionProcess() + goNext() + }, [endTransactionProcess, goNext]) + + const { depositBTC } = useDepositBTCTransaction(onDepositSuccess) return ( diff --git a/dapp/src/components/Modals/Staking/SignMessage.tsx b/dapp/src/components/Modals/Staking/SignMessage.tsx index d653ba781..a369da5cc 100644 --- a/dapp/src/components/Modals/Staking/SignMessage.tsx +++ b/dapp/src/components/Modals/Staking/SignMessage.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { useEffect } from "react" import { Highlight } from "@chakra-ui/react" import { useModalFlowContext, useSignMessage } from "#/hooks" import Alert from "#/components/shared/Alert" @@ -7,9 +7,13 @@ import { asyncWrapper } from "#/utils" import StakingSteps from "./components/StakingSteps" export default function SignMessage() { - const { goNext } = useModalFlowContext() + const { goNext, startTransactionProcess } = useModalFlowContext() const { signMessage } = useSignMessage(goNext) + useEffect(() => { + startTransactionProcess() + }, [startTransactionProcess]) + const handleClick = () => { asyncWrapper(signMessage()) } diff --git a/dapp/src/components/Modals/Support/ResumeModal.tsx b/dapp/src/components/Modals/Support/ResumeModal.tsx new file mode 100644 index 000000000..fb633e7eb --- /dev/null +++ b/dapp/src/components/Modals/Support/ResumeModal.tsx @@ -0,0 +1,42 @@ +import React from "react" +import { + ModalHeader, + ModalBody, + ModalFooter, + Button, + HStack, +} from "@chakra-ui/react" + +import Spinner from "#/components/shared/Spinner" +import { PauseIcon } from "#/assets/icons" +import { TextMd } from "#/components/shared/Typography" + +export default function ResumeModal({ + onResume, + onClose, +}: { + onResume: () => void + onClose: () => void +}) { + return ( + <> + Paused + + + + + + + Are your sure you want to cancel? + + + + + + + ) +} diff --git a/dapp/src/components/Modals/Support/index.tsx b/dapp/src/components/Modals/Support/index.tsx index 47689622a..1d13bf1e0 100644 --- a/dapp/src/components/Modals/Support/index.tsx +++ b/dapp/src/components/Modals/Support/index.tsx @@ -1,11 +1,13 @@ import React from "react" import { + useModalFlowContext, useRequestBitcoinAccount, useRequestEthereumAccount, useWalletContext, } from "#/hooks" import { ConnectBTCAccount, ConnectETHAccount } from "#/assets/icons" import MissingAccount from "./MissingAccount" +import ResumeModal from "./ResumeModal" export default function SupportWrapper({ children, @@ -15,6 +17,7 @@ export default function SupportWrapper({ const { btcAccount, ethAccount } = useWalletContext() const { requestAccount: requestBitcoinAccount } = useRequestBitcoinAccount() const { requestAccount: requestEthereumAccount } = useRequestEthereumAccount() + const { isPaused, onClose, onResume } = useModalFlowContext() if (!btcAccount) return ( @@ -34,5 +37,9 @@ export default function SupportWrapper({ /> ) + if (isPaused) { + return + } + return children } diff --git a/dapp/src/components/TransactionModal/index.tsx b/dapp/src/components/TransactionModal/index.tsx index e656f7642..84b032594 100644 --- a/dapp/src/components/TransactionModal/index.tsx +++ b/dapp/src/components/TransactionModal/index.tsx @@ -24,17 +24,37 @@ export default function TransactionModal({ const { onOpen: openSideBar, onClose: closeSidebar } = useSidebar() const [activeStep, setActiveStep] = useState(defaultStep) + const [isPaused, setIsPaused] = useState(false) + const [isPendingTransaction, setIsPendingTransaction] = useState(false) + + const handleResume = useCallback(() => { + setIsPaused(false) + }, []) const handleGoNext = useCallback(() => { setActiveStep((prevStep) => prevStep + 1) }, []) const handleClose = useCallback(() => { - onClose() - }, [onClose]) + if (!isPaused && isPendingTransaction) { + setIsPaused(true) + } else { + onClose() + } + }, [isPaused, isPendingTransaction, onClose]) + + const handleStartTransactionProcess = useCallback(() => { + setIsPendingTransaction(true) + }, [setIsPendingTransaction]) + + const handleStopTransactionProcess = useCallback(() => { + setIsPendingTransaction(false) + }, [setIsPendingTransaction]) const resetState = useCallback(() => { setActiveStep(defaultStep) + setIsPaused(false) + setIsPendingTransaction(false) }, [defaultStep]) useEffect(() => { @@ -58,14 +78,26 @@ export default function TransactionModal({ const contextValue: ModalFlowContextValue = useMemo( () => ({ activeStep, + isPaused, onClose: handleClose, + onResume: handleResume, goNext: handleGoNext, + startTransactionProcess: handleStartTransactionProcess, + endTransactionProcess: handleStopTransactionProcess, }), - [activeStep, handleGoNext, handleClose], + [ + activeStep, + isPaused, + handleGoNext, + handleClose, + handleResume, + handleStartTransactionProcess, + handleStopTransactionProcess, + ], ) return ( - + {children} diff --git a/dapp/src/contexts/ModalFlowContext.tsx b/dapp/src/contexts/ModalFlowContext.tsx index 287d134e1..5f314ba6f 100644 --- a/dapp/src/contexts/ModalFlowContext.tsx +++ b/dapp/src/contexts/ModalFlowContext.tsx @@ -6,12 +6,20 @@ export type ModalStep = { export type ModalFlowContextValue = { activeStep?: number + isPaused?: boolean onClose: () => void + onResume: () => void goNext: () => void + startTransactionProcess: () => void + endTransactionProcess: () => void } export const ModalFlowContext = createContext({ activeStep: undefined, - goNext: () => {}, + isPaused: false, onClose: () => {}, + onResume: () => {}, + goNext: () => {}, + startTransactionProcess: () => {}, + endTransactionProcess: () => {}, }) diff --git a/dapp/src/theme/Spinner.ts b/dapp/src/theme/Spinner.ts index 74b0f3ff8..678482d13 100644 --- a/dapp/src/theme/Spinner.ts +++ b/dapp/src/theme/Spinner.ts @@ -8,4 +8,13 @@ const baseStyle = defineStyle({ borderLeftColor: "gold.400", }) -export const spinnerTheme = defineStyleConfig({ baseStyle }) +const sizeXl = defineStyle({ + width: 16, + height: 16, +}) + +const sizes = { + xl: sizeXl, +} + +export const spinnerTheme = defineStyleConfig({ baseStyle, sizes })