Commit 3686803c authored by Mike Grabowski's avatar Mike Grabowski Committed by GitHub

refactor: improve metamask error modal (#5818)

* refactor: improve metamask error modal

* chore: rename and use translations

* chore: fix lint

* chore: Fix test
parent 6f147c1f
......@@ -8,7 +8,7 @@ import { Text } from 'rebass'
import styled from 'styled-components/macro'
import { CloseIcon, ThemedText } from 'theme'
import { useModalIsOpen, useToggleMetamaskConnectionErrorModal } from '../../state/application/hooks'
import { useModalIsOpen, useToggleMetaMaskConnectionErrorModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
const Wrapper = styled.div`
......@@ -61,12 +61,9 @@ const WarningIcon = styled(AlertTriangle)`
const onReconnect = () => window.location.reload()
const header = 'Wallet disconnected'
const description = 'A Metamask error caused your wallet to disconnect. Reload the page to reconnect.'
export default function MetamaskConnectionError() {
export default function MetaMaskConnectionErrorModal() {
const modalOpen = useModalIsOpen(ApplicationModal.METAMASK_CONNECTION_ERROR)
const toggleModal = useToggleMetamaskConnectionErrorModal()
const toggleModal = useToggleMetaMaskConnectionErrorModal()
return (
<Modal isOpen={modalOpen} onDismiss={toggleModal} minHeight={false} maxHeight={90}>
......@@ -83,8 +80,12 @@ export default function MetamaskConnectionError() {
</AutoColumn>
<ShortColumn>
<InfoText>
<ThemedText.HeadlineSmall marginBottom="8px">{header}</ThemedText.HeadlineSmall>
<ThemedText.BodySmall>{description}</ThemedText.BodySmall>
<ThemedText.HeadlineSmall marginBottom="8px">
<Trans>Wallet disconnected</Trans>
</ThemedText.HeadlineSmall>
<ThemedText.BodySmall>
<Trans>A MetaMask error caused your wallet to disconnect. Reload the page to reconnect.</Trans>
</ThemedText.BodySmall>
</InfoText>
</ShortColumn>
<StyledButton onClick={onReconnect}>
......
......@@ -12,6 +12,7 @@ import { ApplicationModal } from 'state/application/reducer'
const Bag = lazy(() => import('nft/components/bag/Bag'))
const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal'))
const AirdropModal = lazy(() => import('components/AirdropModal'))
const MetaMaskConnectionErrorModal = lazy(() => import('components/MetaMaskConnectionErrorModal'))
export default function TopLevelModals() {
const addressClaimOpen = useModalIsOpen(ApplicationModal.ADDRESS_CLAIM)
......@@ -29,6 +30,7 @@ export default function TopLevelModals() {
<Bag />
<TransactionCompleteModal />
<AirdropModal />
<MetaMaskConnectionErrorModal />
{fiatOnrampFlagEnabled && <FiatOnrampModal />}
</>
)
......
......@@ -22,6 +22,9 @@ jest.mock('.../../state/application/hooks', () => {
useToggleWalletModal: () => {
return
},
useToggleMetaMaskConnectionErrorModal: () => {
return
},
}
})
......
import { useWeb3React, Web3ReactHooks, Web3ReactProvider } from '@web3-react/core'
import { Connector } from '@web3-react/types'
import { Connection } from 'connection'
import { ConnectionType, setMetMaskErrorHandler } from 'connection'
import { setMetMaskErrorHandler } from 'connection'
import { getConnectionName } from 'connection/utils'
import { isSupportedChain } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
......@@ -9,18 +9,18 @@ import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/tra
import useEagerlyConnect from 'hooks/useEagerlyConnect'
import useOrderedConnections from 'hooks/useOrderedConnections'
import { ReactNode, useEffect, useMemo } from 'react'
import { updateConnectionError } from 'state/connection/reducer'
import { useAppDispatch } from 'state/hooks'
import { useToggleMetaMaskConnectionErrorModal } from 'state/application/hooks'
export default function Web3Provider({ children }: { children: ReactNode }) {
const dispatch = useAppDispatch()
// Set metamask error handler for metamask disconnection warning modal.
// https://github.com/MetaMask/metamask-extension/issues/13375
const toggleMetaMaskConnectionErrorModal = useToggleMetaMaskConnectionErrorModal()
useEffect(() => {
setMetMaskErrorHandler((error: Error) =>
dispatch(updateConnectionError({ connectionType: ConnectionType.INJECTED, error: error.message }))
)
}, [dispatch])
setMetMaskErrorHandler((error) => {
if (error.code === 1013) {
toggleMetaMaskConnectionErrorModal()
}
})
}, [toggleMetaMaskConnectionErrorModal])
useEagerlyConnect()
const connections = useOrderedConnections()
......
......@@ -5,12 +5,12 @@ import { useWeb3React } from '@web3-react/core'
import { FiatOnrampAnnouncement } from 'components/FiatOnrampAnnouncement'
import { IconWrapper } from 'components/Identicon/StatusIcon'
import WalletDropdown from 'components/WalletDropdown'
import { getConnection, getIsMetaMask } from 'connection/utils'
import { getConnection } from 'connection/utils'
import { Portal } from 'nft/components/common/Portal'
import { useIsNftClaimAvailable } from 'nft/hooks/useIsNftClaimAvailable'
import { getIsValidSwapQuote } from 'pages/Swap'
import { darken } from 'polished'
import { useCallback, useEffect, useMemo, useRef } from 'react'
import { useCallback, useMemo, useRef } from 'react'
import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather'
import { useAppSelector } from 'state/hooks'
import { useDerivedSwapInfo } from 'state/swap/hooks'
......@@ -22,7 +22,6 @@ import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import {
useCloseModal,
useModalIsOpen,
useOpenMetamaskConnectionErrorModal,
useToggleWalletDropdown,
useToggleWalletModal,
} from '../../state/application/hooks'
......@@ -35,7 +34,6 @@ import StatusIcon from '../Identicon/StatusIcon'
import Loader from '../Loader'
import { RowBetween } from '../Row'
import WalletModal from '../WalletModal'
import MetamaskConnectionError from './MetamaskConnectionError'
// https://stackoverflow.com/a/31617326
const FULL_BORDER_RADIUS = 9999
......@@ -213,16 +211,10 @@ function Web3StatusInner() {
toggleWalletDropdown()
}, [toggleWalletDropdown])
const toggleWalletModal = useToggleWalletModal()
const openMetamaskConnectionErrorModal = useOpenMetamaskConnectionErrorModal()
const walletIsOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
const isClaimAvailable = useIsNftClaimAvailable((state) => state.isClaimAvailable)
const error = useAppSelector((state) => state.connection.errorByConnectionType[connectionType])
useEffect(() => {
if (getIsMetaMask(connectionType) && error) {
openMetamaskConnectionErrorModal()
}
}, [error, connectionType, openMetamaskConnectionErrorModal])
const allTransactions = useAllTransactions()
......@@ -326,7 +318,6 @@ export default function Web3Status() {
<Web3StatusInner />
<FiatOnrampAnnouncement />
<WalletModal ENSName={ENSName ?? undefined} pendingTransactions={pending} confirmedTransactions={confirmed} />
<MetamaskConnectionError />
<Portal>
<span ref={walletRef}>
<WalletDropdown />
......
......@@ -25,9 +25,10 @@ export interface Connection {
type: ConnectionType
}
let metaMaskErrorHandler: (error: Error) => void | undefined
type MetaMaskError = Error & { code: number }
export function setMetMaskErrorHandler(errorHandler: (error: Error) => void) {
let metaMaskErrorHandler: (error: MetaMaskError) => void | undefined
export function setMetMaskErrorHandler(errorHandler: typeof metaMaskErrorHandler) {
metaMaskErrorHandler = errorHandler
}
......@@ -35,9 +36,9 @@ function onError(error: Error) {
console.debug(`web3-react error: ${error}`)
}
function onMetamaskError(error: Error) {
function onMetaMaskError(error: Error) {
onError(error)
metaMaskErrorHandler?.(error)
metaMaskErrorHandler?.(error as MetaMaskError)
}
const [web3Network, web3NetworkHooks] = initializeConnector<Network>(
......@@ -50,7 +51,7 @@ export const networkConnection: Connection = {
}
const [web3Injected, web3InjectedHooks] = initializeConnector<MetaMask>(
(actions) => new MetaMask({ actions, onError: onMetamaskError })
(actions) => new MetaMask({ actions, onError: onMetaMaskError })
)
export const injectedConnection: Connection = {
connector: web3Injected,
......
......@@ -93,14 +93,10 @@ export function useCloseModal(): () => void {
return useCallback(() => dispatch(setOpenModal(null)), [dispatch])
}
export function useToggleMetamaskConnectionErrorModal(): () => void {
export function useToggleMetaMaskConnectionErrorModal(): () => void {
return useToggleModal(ApplicationModal.METAMASK_CONNECTION_ERROR)
}
export function useOpenMetamaskConnectionErrorModal(): () => void {
return useOpenModal(ApplicationModal.METAMASK_CONNECTION_ERROR)
}
export function useOpenModal(modal: ApplicationModal): () => void {
const dispatch = useAppDispatch()
return useCallback(() => dispatch(setOpenModal(modal)), [dispatch, modal])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment