Commit 2e8ef480 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat(testnets): add toggle for testnets (#6786)

* feat(testnets): add toggle for testnets

* e2e test

* update toggle syntax and fix a bug

* simplify list calculation per eddie's input

* add all testnets

* clean up the styles

* Update src/components/NavBar/ChainSelector.tsx

* fix lint
parent f27bba9f
...@@ -41,6 +41,23 @@ describe('Wallet Dropdown', () => { ...@@ -41,6 +41,23 @@ describe('Wallet Dropdown', () => {
itShouldChangeTheLanguage() itShouldChangeTheLanguage()
}) })
describe('testnet toggle', () => {
beforeEach(() => {
cy.visit('/swap')
})
it('should toggle testnet visibility', () => {
cy.get(getTestSelector('chain-selector')).last().click()
cy.get(getTestSelector('chain-selector-options')).should('not.contain.text', 'Sepolia')
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('wallet-settings')).click()
cy.get('#testnets-toggle').click()
cy.get(getTestSelector('close-account-drawer')).click()
cy.get(getTestSelector('chain-selector')).last().click()
cy.get(getTestSelector('chain-selector-options')).should('contain.text', 'Sepolia')
})
})
describe('disconnected', () => { describe('disconnected', () => {
beforeEach(() => { beforeEach(() => {
cy.visit('/') cy.visit('/')
......
...@@ -11,6 +11,7 @@ import ThemeToggle from 'theme/components/ThemeToggle' ...@@ -11,6 +11,7 @@ import ThemeToggle from 'theme/components/ThemeToggle'
import { GitVersionRow } from './GitVersionRow' import { GitVersionRow } from './GitVersionRow'
import { SlideOutMenu } from './SlideOutMenu' import { SlideOutMenu } from './SlideOutMenu'
import { SmallBalanceToggle } from './SmallBalanceToggle' import { SmallBalanceToggle } from './SmallBalanceToggle'
import { TestnetsToggle } from './TestnetsToggle'
const InternalLinkMenuItem = styled(Link)` const InternalLinkMenuItem = styled(Link)`
${ClickableStyle} ${ClickableStyle}
...@@ -44,13 +45,11 @@ const SectionTitle = styled(ThemedText.SubHeader)` ...@@ -44,13 +45,11 @@ const SectionTitle = styled(ThemedText.SubHeader)`
padding-bottom: 24px; padding-bottom: 24px;
` `
const ThemeToggleContainer = styled.div` const ToggleWrapper = styled.div`
margin: 0 0 6px; display: flex;
` flex-direction: column;
gap: 16px;
const BalanceToggleContainer = styled.div` margin-bottom: 24px;
padding: 16px 0;
margin-bottom: 26px;
` `
export default function SettingsMenu({ onClose }: { onClose: () => void }) { export default function SettingsMenu({ onClose }: { onClose: () => void }) {
...@@ -61,12 +60,11 @@ export default function SettingsMenu({ onClose }: { onClose: () => void }) { ...@@ -61,12 +60,11 @@ export default function SettingsMenu({ onClose }: { onClose: () => void }) {
<SectionTitle> <SectionTitle>
<Trans>Preferences</Trans> <Trans>Preferences</Trans>
</SectionTitle> </SectionTitle>
<ThemeToggleContainer> <ToggleWrapper>
<ThemeToggle /> <ThemeToggle />
</ThemeToggleContainer>
<BalanceToggleContainer>
<SmallBalanceToggle /> <SmallBalanceToggle />
</BalanceToggleContainer> <TestnetsToggle />
</ToggleWrapper>
<SectionTitle data-testid="wallet-header"> <SectionTitle data-testid="wallet-header">
<Trans>Language</Trans> <Trans>Language</Trans>
......
import { Trans } from '@lingui/macro'
import Row from 'components/Row'
import Toggle from 'components/Toggle'
import { useAtom } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
import { ThemedText } from 'theme'
export const showTestnetsAtom = atomWithStorage<boolean>('showTestnets', false)
export function TestnetsToggle() {
const [showTestnets, updateShowTestnets] = useAtom(showTestnetsAtom)
return (
<Row align="center">
<Row width="50%">
<ThemedText.SubHeaderSmall color="primary">
<Trans>Show testnets</Trans>
</ThemedText.SubHeaderSmall>
</Row>
<Row width="50%" justify="flex-end">
<Toggle
id="testnets-toggle"
isActive={showTestnets}
toggle={() => {
updateShowTestnets(!showTestnets)
}}
/>
</Row>
</Row>
)
}
import { t } from '@lingui/macro' import { t } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { WalletConnect } from '@web3-react/walletconnect-v2' import { WalletConnect } from '@web3-react/walletconnect-v2'
import { showTestnetsAtom } from 'components/AccountDrawer/TestnetsToggle'
import { MouseoverTooltip } from 'components/Tooltip' import { MouseoverTooltip } from 'components/Tooltip'
import { getConnection } from 'connection' import { getConnection } from 'connection'
import { ConnectionType } from 'connection/types' import { ConnectionType } from 'connection/types'
import { getChainInfo } from 'constants/chainInfo' import { getChainInfo } from 'constants/chainInfo'
import { SupportedChainId, UniWalletSupportedChains } from 'constants/chains' import { L1_CHAIN_IDS, L2_CHAIN_IDS, SupportedChainId, TESTNET_SET, UniWalletSupportedChains } from 'constants/chains'
import { useOnClickOutside } from 'hooks/useOnClickOutside' import { useOnClickOutside } from 'hooks/useOnClickOutside'
import useSelectChain from 'hooks/useSelectChain' import useSelectChain from 'hooks/useSelectChain'
import useSyncChainQuery from 'hooks/useSyncChainQuery' import useSyncChainQuery from 'hooks/useSyncChainQuery'
import { useAtomValue } from 'jotai/utils'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Portal } from 'nft/components/common/Portal' import { Portal } from 'nft/components/common/Portal'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
...@@ -16,24 +18,12 @@ import { useIsMobile } from 'nft/hooks' ...@@ -16,24 +18,12 @@ import { useIsMobile } from 'nft/hooks'
import { useCallback, useRef, useState } from 'react' import { useCallback, useRef, useState } from 'react'
import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather' import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather'
import { useTheme } from 'styled-components/macro' import { useTheme } from 'styled-components/macro'
import { isProductionEnv } from 'utils/env'
import * as styles from './ChainSelector.css' import * as styles from './ChainSelector.css'
import ChainSelectorRow from './ChainSelectorRow' import ChainSelectorRow from './ChainSelectorRow'
import { NavDropdown } from './NavDropdown' import { NavDropdown } from './NavDropdown'
const NETWORK_SELECTOR_CHAINS = [ const NETWORK_SELECTOR_CHAINS = [...L1_CHAIN_IDS, ...L2_CHAIN_IDS]
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
SupportedChainId.BNB,
]
if (!isProductionEnv()) {
NETWORK_SELECTOR_CHAINS.push(SupportedChainId.SEPOLIA)
}
interface ChainSelectorProps { interface ChainSelectorProps {
leftAlign?: boolean leftAlign?: boolean
...@@ -72,6 +62,11 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => { ...@@ -72,6 +62,11 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => {
const theme = useTheme() const theme = useTheme()
const showTestnets = useAtomValue(showTestnetsAtom)
const chains = showTestnets
? NETWORK_SELECTOR_CHAINS
: NETWORK_SELECTOR_CHAINS.filter((chain) => !TESTNET_SET.has(chain))
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const modalRef = useRef<HTMLDivElement>(null) const modalRef = useRef<HTMLDivElement>(null)
useOnClickOutside(ref, () => setIsOpen(false), [modalRef]) useOnClickOutside(ref, () => setIsOpen(false), [modalRef])
...@@ -103,8 +98,8 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => { ...@@ -103,8 +98,8 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => {
const dropdown = ( const dropdown = (
<NavDropdown top="56" left={leftAlign ? '0' : 'auto'} right={leftAlign ? 'auto' : '0'} ref={modalRef}> <NavDropdown top="56" left={leftAlign ? '0' : 'auto'} right={leftAlign ? 'auto' : '0'} ref={modalRef}>
<Column paddingX="8"> <Column paddingX="8" data-testid="chain-selector-options">
{NETWORK_SELECTOR_CHAINS.map((selectorChain: SupportedChainId) => ( {chains.map((selectorChain: SupportedChainId) => (
<ChainSelectorRow <ChainSelectorRow
disabled={!walletSupportsChain.includes(selectorChain)} disabled={!walletSupportsChain.includes(selectorChain)}
onSelectChain={onSelectChain} onSelectChain={onSelectChain}
...@@ -127,6 +122,7 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => { ...@@ -127,6 +122,7 @@ export const ChainSelector = ({ leftAlign }: ChainSelectorProps) => {
<Box position="relative" ref={ref}> <Box position="relative" ref={ref}>
<MouseoverTooltip text={t`Your wallet's current network is unsupported.`} disabled={isSupported}> <MouseoverTooltip text={t`Your wallet's current network is unsupported.`} disabled={isSupported}>
<Row <Row
data-testid="chain-selector"
as="button" as="button"
gap="8" gap="8"
className={styles.ChainSelector} className={styles.ChainSelector}
......
...@@ -87,6 +87,16 @@ export const TESTNET_CHAIN_IDS = [ ...@@ -87,6 +87,16 @@ export const TESTNET_CHAIN_IDS = [
SupportedChainId.OPTIMISM_GOERLI, SupportedChainId.OPTIMISM_GOERLI,
] as const ] as const
export const TESTNET_SET = new Set([
SupportedChainId.GOERLI,
SupportedChainId.SEPOLIA,
SupportedChainId.ARBITRUM_GOERLI,
SupportedChainId.OPTIMISM_GOERLI,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.CELO_ALFAJORES,
])
export type SupportedTestnetChainId = typeof TESTNET_CHAIN_IDS[number] export type SupportedTestnetChainId = typeof TESTNET_CHAIN_IDS[number]
/** /**
......
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