diff --git a/src/custom/components/Header/NetworkSelector/NetworkSelectorMod.tsx b/src/custom/components/Header/NetworkSelector/NetworkSelectorMod.tsx index 4a8b386959..5f93d878e0 100644 --- a/src/custom/components/Header/NetworkSelector/NetworkSelectorMod.tsx +++ b/src/custom/components/Header/NetworkSelector/NetworkSelectorMod.tsx @@ -11,7 +11,7 @@ import { ChevronDown } from 'react-feather' // import { useHistory } from 'react-router-dom' // import { useModalOpen, useToggleModal } from 'state/application/hooks' // import { addPopup, ApplicationModal } from 'state/application/reducer' -import styled from 'styled-components/macro' +import styled, { css } from 'styled-components/macro' import { ExternalLink, MEDIA_WIDTHS } from 'theme' // import { replaceURLParam } from 'utils/routes' // import { useAppDispatch } from 'state/hooks' @@ -25,6 +25,10 @@ import { } from '@src/components/Header/NetworkSelector' import useChangeNetworks, { ChainSwitchCallbackOptions } from 'hooks/useChangeNetworks' import { transparentize } from 'polished' +// mod +import { UnsupportedChainIdError, useWeb3React } from 'web3-react-core' +import { useAddPopup, useRemovePopup } from 'state/application/hooks' +import { useEffect } from 'react' import { getExplorerBaseUrl } from 'utils/explorer' /* const ActiveRowLinkList = styled.div` @@ -288,6 +292,42 @@ export default function NetworkSelector() { // mod: refactored inner logic into useChangeNetworks hook const { node, open, toggle, info, handleChainSwitch } = useChangeNetworks({ account, chainId, library }) + // mod: add error and isUnsupportedNetwork const and useEffect + const { error } = useWeb3React() + const isUnsupportedNetwork = error instanceof UnsupportedChainIdError + const addPopup = useAddPopup() + const removePopup = useRemovePopup() + + useEffect(() => { + const POPUP_KEY = chainId?.toString() + + if (POPUP_KEY && isUnsupportedNetwork) { + addPopup( + { + failedSwitchNetwork: chainId as SupportedChainId, + unsupportedNetwork: true, + styles: css` + background: ${({ theme }) => theme.yellow3}; + &&& { + margin-top: 20px; + ${({ theme }) => theme.mediaWidth.upToSmall` + margin-top: 40px; + `} + } + `, + }, + // ID + POPUP_KEY, + // null to disable auto hide + null + ) + } + + return () => { + POPUP_KEY && removePopup(POPUP_KEY) + } + }, [addPopup, chainId, isUnsupportedNetwork, removePopup]) + /* const parsedQs = useParsedQueryString() const { urlChain, urlChainId } = getParsedChainId(parsedQs) const prevChainId = usePrevious(chainId) @@ -352,7 +392,7 @@ export default function NetworkSelector() { } }, [chainId, history, urlChainId, urlChain]) */ - if (!chainId || !info || !library) { + if (!chainId || !info || !library || isUnsupportedNetwork) { return null } diff --git a/src/custom/components/Popups/FailedNetworkSwitchPopupMod.tsx b/src/custom/components/Popups/FailedNetworkSwitchPopupMod.tsx index e620e0b91e..94eb645b18 100644 --- a/src/custom/components/Popups/FailedNetworkSwitchPopupMod.tsx +++ b/src/custom/components/Popups/FailedNetworkSwitchPopupMod.tsx @@ -13,20 +13,27 @@ const RowNoFlex = styled(AutoRow)` flex-wrap: nowrap; ` -export default function FailedNetworkSwitchPopup({ chainId }: { chainId: SupportedChainId }) { +export default function FailedNetworkSwitchPopup({ + chainId, + isUnsupportedNetwork = false, +}: { + chainId: SupportedChainId + isUnsupportedNetwork?: boolean +}) { const chainInfo = CHAIN_INFO[chainId] const theme = useContext(ThemeContext) return (
- +
- + - Failed to switch networks from the CowSwap Interface. In order to use CowSwap on {chainInfo.label}, you must - change the network in your wallet. + {isUnsupportedNetwork + ? `Please connect your wallet to one of the supported networks: Ethereum Mainnet or Gnosis Chain.` + : `Failed to switch networks from the CowSwap Interface. In order to use CowSwap on ${chainInfo.label}, you must change the network in your wallet.`} diff --git a/src/custom/components/Popups/PopupItem.tsx b/src/custom/components/Popups/PopupItem.tsx index d7720e0410..6516388e69 100644 --- a/src/custom/components/Popups/PopupItem.tsx +++ b/src/custom/components/Popups/PopupItem.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components/macro' import { PopupContent } from 'state/application/reducer' -import { default as PopupItemUni, Popup, Fader, StyledClose } from './PopupItemMod' +import { default as PopupItemUni, Popup, Fader } from './PopupItemMod' const Wrapper = styled.div` ${Popup} { @@ -15,10 +15,6 @@ const Wrapper = styled.div` height: 4px; } - ${StyledClose} { - stroke: ${({ theme }) => theme.text1}; - } - a { text-decoration: underline; color: ${({ theme }) => theme.textLink}; diff --git a/src/custom/components/Popups/PopupItemMod.tsx b/src/custom/components/Popups/PopupItemMod.tsx index 4e763361de..552aa04c29 100644 --- a/src/custom/components/Popups/PopupItemMod.tsx +++ b/src/custom/components/Popups/PopupItemMod.tsx @@ -2,7 +2,7 @@ import { useCallback, useContext, useEffect } from 'react' import { X } from 'react-feather' import { animated } from 'react-spring' import { useSpring } from 'react-spring/web' -import styled, { ThemeContext } from 'styled-components/macro' +import styled, { FlattenInterpolation, ThemeContext, ThemeProps, DefaultTheme } from 'styled-components/macro' import { useRemovePopup } from 'state/application/hooks' import { PopupContent } from 'state/application/reducer' @@ -21,7 +21,7 @@ export const StyledClose = styled(X)` cursor: pointer; } ` -export const Popup = styled.div` +export const Popup = styled.div<{ css?: FlattenInterpolation> }>` display: inline-block; width: 100%; //padding: 1em; @@ -38,6 +38,8 @@ export const Popup = styled.div` margin-right: 20px; } `} + + ${({ css }) => css && css} ` export const Fader = styled.div` position: absolute; @@ -77,22 +79,30 @@ export default function PopupItem({ const theme = useContext(ThemeContext) + // mod + const isTxn = 'txn' in content + const isListUpdate = 'listUpdate' in content + const isUnsupportedNetwork = 'unsupportedNetwork' in content + const isMetaTxn = 'metatxn' in content + let popupContent - if ('txn' in content) { + if (isTxn) { const { txn: { hash, success, summary }, } = content popupContent = - } else if ('listUpdate' in content) { + } else if (isListUpdate) { const { listUpdate: { listUrl, oldList, newList, auto }, } = content popupContent = - } else if ('metatxn' in content) { + } else if (isMetaTxn) { const { metatxn: { id, success, summary }, } = content popupContent = + } else if (isUnsupportedNetwork) { + popupContent = } else if ('failedSwitchNetwork' in content) { popupContent = } @@ -104,8 +114,8 @@ export default function PopupItem({ }) return ( - - + + {popupContent} {removeAfterMs !== null ? : null} diff --git a/src/custom/components/WalletModal/WalletModalMod.tsx b/src/custom/components/WalletModal/WalletModalMod.tsx index f63288d945..f6ce1ce980 100644 --- a/src/custom/components/WalletModal/WalletModalMod.tsx +++ b/src/custom/components/WalletModal/WalletModalMod.tsx @@ -349,7 +349,10 @@ export default function WalletModal({ {error instanceof UnsupportedChainIdError ? (
- Please connect to a supported network in the dropdown menu or in your wallet. + + App/wallet network mismatch. Please connect to a supported network in your wallet: Ethereum Mainnet or + Gnosis Chain. +
) : ( Error connecting. Try refreshing the page. diff --git a/src/custom/state/application/hooks.ts b/src/custom/state/application/hooks.ts index 2bb60aae3d..936eee9395 100644 --- a/src/custom/state/application/hooks.ts +++ b/src/custom/state/application/hooks.ts @@ -1,7 +1,8 @@ import { createAction } from '@reduxjs/toolkit' +import { DEFAULT_TXN_DISMISS_MS } from '@src/constants/misc' import { useToggleModal } from '@src/state/application/hooks' import { useCallback } from 'react' -import { ApplicationModal } from 'state/application/reducer' +import { addPopup, ApplicationModal, PopupContent } from 'state/application/reducer' import { useAppDispatch } from 'state/hooks' export * from '@src/state/application/hooks' @@ -22,3 +23,22 @@ export function useCloseModals(): () => void { const dispatch = useAppDispatch() return useCallback(() => dispatch(setOpenModal(null)), [dispatch]) } + +// mod: add removeAfterMs change +// returns a function that allows adding a popup +export function useAddPopup(): (content: PopupContent, key?: string, removeAfterMs?: number | null) => void { + const dispatch = useAppDispatch() + + return useCallback( + (content: PopupContent, key?: string, removeAfterMs?: number | null) => { + dispatch( + addPopup({ + content, + key, + removeAfterMs: removeAfterMs === null ? null : removeAfterMs ?? DEFAULT_TXN_DISMISS_MS, + }) + ) + }, + [dispatch] + ) +} diff --git a/src/state/application/reducer.ts b/src/state/application/reducer.ts index 491cb7c1e8..5d91a9af13 100644 --- a/src/state/application/reducer.ts +++ b/src/state/application/reducer.ts @@ -2,6 +2,7 @@ import { createSlice, nanoid } from '@reduxjs/toolkit' import { DEFAULT_TXN_DISMISS_MS } from 'constants/misc' import { SupportedChainId } from 'constants/chains' +import { FlattenInterpolation, ThemeProps, DefaultTheme } from 'styled-components/macro' // mod type BasePopupContent = // | { @@ -12,10 +13,15 @@ type BasePopupContent = // | { { failedSwitchNetwork: SupportedChainId + // mod: unsupported network + unsupportedNetwork?: boolean } // MOD: Modified PopupContent. The mod happened directly in the src file, to avoid redefining the state/hoos/etc -export type PopupContent = TxPopupContent | MetaTxPopupContent | BasePopupContent +export type PopupContent = (TxPopupContent | MetaTxPopupContent | BasePopupContent) & { + // mod: custom styles + styles?: FlattenInterpolation> +} export type TxPopupContent = { txn: {