Skip to content

Commit

Permalink
refactor: colocate error message element with tx input (#1807)
Browse files Browse the repository at this point in the history
  • Loading branch information
fionnachan authored Jul 26, 2024
1 parent e502a9b commit f0ea7be
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ import { defaultErc20Decimals } from '../../defaults'
import { TransferReadinessRichErrorMessage } from './useTransferReadinessUtils'
import { useNetworks } from '../../hooks/useNetworks'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
import {
TransferDisabledDialog,
useTransferDisabledDialogStore
} from './TransferDisabledDialog'
import { TransferDisabledDialog } from './TransferDisabledDialog'
import { getBridgeUiConfigForChain } from '../../util/bridgeUiConfig'
import { useGasSummary } from '../../hooks/TransferPanel/useGasSummary'
import { useUpdateUSDCTokenData } from './TransferPanelMain/hooks'
Expand Down Expand Up @@ -359,8 +356,6 @@ export function TransferPanelMain({
}, [nativeCurrency, ethParentBalance, ethChildBalance, erc20ParentBalances])

const [loadingMaxAmount, setLoadingMaxAmount] = useState(false)
const { openDialog: openTransferDisabledDialog } =
useTransferDisabledDialogStore()
const [oneNovaTransferDialogProps, openOneNovaTransferDialog] = useDialog()
const [
oneNovaTransferDestinationNetworkId,
Expand Down Expand Up @@ -467,50 +462,9 @@ export function TransferPanelMain({
}
}, [selectedToken, setDestinationAddress])

const errorMessageElement = useMemo(() => {
if (typeof errorMessage === 'undefined') {
return undefined
}

if (typeof errorMessage === 'string') {
return errorMessage
}

switch (errorMessage) {
case TransferReadinessRichErrorMessage.GAS_ESTIMATION_FAILURE:
return (
<span>
Gas estimation failed, join our{' '}
<ExternalLink
href="https://discord.com/invite/ZpZuw7p"
className="underline"
>
Discord
</ExternalLink>{' '}
and reach out in #support for assistance.
</span>
)

case TransferReadinessRichErrorMessage.TOKEN_WITHDRAW_ONLY:
case TransferReadinessRichErrorMessage.TOKEN_TRANSFER_DISABLED:
return (
<>
<span>This token can&apos;t be bridged over.</span>{' '}
<button
className="arb-hover underline"
onClick={openTransferDisabledDialog}
>
Learn more.
</button>
</>
)
}
}, [errorMessage, openTransferDisabledDialog])

useUpdateUSDCTokenData()

type NetworkListboxesProps = {
from: Pick<NetworkListboxProps, 'onChange'>
to: Omit<NetworkListboxProps, 'label'>
}

Expand Down Expand Up @@ -547,26 +501,6 @@ export function TransferPanelMain({
const destinationChains = getDestinationChains()

return {
from: {
onChange: async network => {
if (networks.destinationChain.id === network.id) {
setNetworks({
sourceChainId: networks.destinationChain.id,
destinationChainId: networks.sourceChain.id
})
return
}

// if changing sourceChainId, let the destinationId be the same, and let the `setNetworks` func decide whether it's a valid or invalid chain pair
// this way, the destination doesn't reset to the default chain if the source chain is changed, and if both are valid
setNetworks({
sourceChainId: network.id,
destinationChainId: networks.destinationChain.id
})

actions.app.setSelectedToken(null)
}
},
to: {
disabled:
isSmartContractWallet ||
Expand Down Expand Up @@ -604,10 +538,9 @@ export function TransferPanelMain({
amount={amount}
loadingMaxAmount={loadingMaxAmount}
setMaxAmount={setMaxAmount}
errorMessageElement={errorMessageElement}
errorMessage={errorMessage}
customFeeTokenBalances={customFeeTokenBalances}
showUsdcSpecificInfo={showUSDCSpecificInfo}
sourceNetworkListboxProps={networkListboxProps.from}
/>

<SwitchNetworksButton />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { twMerge } from 'tailwind-merge'
import { Chain } from 'wagmi'
import { useCallback } from 'react'

import { getNetworkName } from '../../../util/networks'
import { NetworkSelectionContainer } from '../../common/NetworkSelectionContainer'
Expand All @@ -10,7 +12,7 @@ import {
} from '../TransferPanelMain'
import { TokenBalance } from './TokenBalance'
import { NetworkType } from './utils'
import { useAppState } from '../../../state'
import { useActions, useAppState } from '../../../state'
import { useNetworks } from '../../../hooks/useNetworks'
import { useNativeCurrency } from '../../../hooks/useNativeCurrency'
import { useNetworksRelationship } from '../../../hooks/useNetworksRelationship'
Expand All @@ -26,28 +28,27 @@ import {
import { ExternalLink } from '../../common/ExternalLink'
import { EstimatedGas } from '../EstimatedGas'
import { TransferPanelMainInput } from '../TransferPanelMainInput'
import { NetworkListboxProps } from '../NetworkListbox'
import { getBridgeUiConfigForChain } from '../../../util/bridgeUiConfig'
import { AmountQueryParamEnum } from '../../../hooks/useArbQueryParams'
import { TransferReadinessRichErrorMessage } from '../useTransferReadinessUtils'

export function SourceNetworkBox({
amount,
loadingMaxAmount,
setMaxAmount,
errorMessageElement,
errorMessage,
customFeeTokenBalances,
showUsdcSpecificInfo,
sourceNetworkListboxProps
showUsdcSpecificInfo
}: {
amount: string
loadingMaxAmount: boolean
setMaxAmount: () => Promise<void>
errorMessageElement: string | React.JSX.Element | undefined
errorMessage: string | TransferReadinessRichErrorMessage | undefined
customFeeTokenBalances: Balances
showUsdcSpecificInfo: boolean
sourceNetworkListboxProps: Pick<NetworkListboxProps, 'onChange'>
}) {
const [networks] = useNetworks()
const actions = useActions()
const [networks, setNetworks] = useNetworks()
const { childChain, childChainProvider, isDepositMode } =
useNetworksRelationship(networks)
const {
Expand All @@ -63,6 +64,33 @@ export function SourceNetworkBox({
backgroundColor: getBridgeUiConfigForChain(networks.sourceChain.id).color
}

const onChange = useCallback(
async (network: Chain) => {
if (networks.destinationChain.id === network.id) {
setNetworks({
sourceChainId: networks.destinationChain.id,
destinationChainId: networks.sourceChain.id
})
return
}

// if changing sourceChainId, let the destinationId be the same, and let the `setNetworks` func decide whether it's a valid or invalid chain pair
// this way, the destination doesn't reset to the default chain if the source chain is changed, and if both are valid
setNetworks({
sourceChainId: network.id,
destinationChainId: networks.destinationChain.id
})

actions.app.setSelectedToken(null)
},
[
actions.app,
networks.destinationChain.id,
networks.sourceChain.id,
setNetworks
]
)

return (
<NetworkContainer bgLogoHeight={138} network={networks.sourceChain}>
<NetworkListboxPlusBalancesContainer>
Expand All @@ -71,7 +99,7 @@ export function SourceNetworkBox({
buttonClassName={twMerge(
'arb-hover flex w-max items-center gap-1 md:gap-2 rounded px-3 py-2 text-sm text-white outline-none md:text-2xl'
)}
onChange={sourceNetworkListboxProps.onChange}
onChange={onChange}
>
<span className="max-w-[220px] truncate text-sm leading-[1.1] md:max-w-[250px] md:text-xl">
From: {getNetworkName(networks.sourceChain.id)}
Expand Down Expand Up @@ -124,7 +152,7 @@ export function SourceNetworkBox({
loading: isMaxAmount || loadingMaxAmount,
onClick: setMaxAmount
}}
errorMessage={errorMessageElement}
errorMessage={errorMessage}
value={isMaxAmount ? '' : amount}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount'
import { countDecimals } from '../../util/NumberUtils'
import { useSelectedTokenDecimals } from '../../hooks/TransferPanel/useSelectedTokenDecimals'
import { useBalances } from '../../hooks/useBalances'
import { TransferReadinessRichErrorMessage } from './useTransferReadinessUtils'
import { ExternalLink } from '../common/ExternalLink'
import { useTransferDisabledDialogStore } from './TransferDisabledDialog'

type MaxButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
loading: boolean
Expand Down Expand Up @@ -112,9 +115,58 @@ function TransferPanelInputField(
)
}

function ErrorMessage({
errorMessage
}: {
errorMessage: string | TransferReadinessRichErrorMessage | undefined
}) {
const { openDialog: openTransferDisabledDialog } =
useTransferDisabledDialogStore()

if (typeof errorMessage === 'undefined') {
return null
}

if (typeof errorMessage === 'string') {
return <span className="text-sm text-brick">{errorMessage}</span>
}

switch (errorMessage) {
case TransferReadinessRichErrorMessage.GAS_ESTIMATION_FAILURE:
return (
<span className="text-sm text-brick">
Gas estimation failed, join our{' '}
<ExternalLink
href="https://discord.com/invite/ZpZuw7p"
className="underline"
>
Discord
</ExternalLink>{' '}
and reach out in #support for assistance.
</span>
)

case TransferReadinessRichErrorMessage.TOKEN_WITHDRAW_ONLY:
case TransferReadinessRichErrorMessage.TOKEN_TRANSFER_DISABLED:
return (
<>
<span className="text-sm text-brick">
This token can&apos;t be bridged over.
</span>{' '}
<button
className="arb-hover underline"
onClick={openTransferDisabledDialog}
>
Learn more.
</button>
</>
)
}
}

export type TransferPanelMainInputProps =
React.InputHTMLAttributes<HTMLInputElement> & {
errorMessage?: string | React.ReactNode
errorMessage?: string | TransferReadinessRichErrorMessage | undefined
maxButtonProps: MaxButtonProps
value: string
}
Expand Down Expand Up @@ -144,9 +196,7 @@ export function TransferPanelMainInput(props: TransferPanelMainInputProps) {
</div>
</div>

{typeof errorMessage !== 'undefined' && (
<span className="text-sm text-brick">{errorMessage}</span>
)}
<ErrorMessage errorMessage={errorMessage} />
</>
)
}

0 comments on commit f0ea7be

Please sign in to comment.