diff --git a/cypress/e2e/wallet-dropdown.test.ts b/cypress/e2e/wallet-dropdown.test.ts index e0db6845fa..0df0645895 100644 --- a/cypress/e2e/wallet-dropdown.test.ts +++ b/cypress/e2e/wallet-dropdown.test.ts @@ -1,3 +1,5 @@ +import { FeatureFlag } from 'featureFlags' + import { getTestSelector } from '../utils' describe('Wallet Dropdown', () => { @@ -21,10 +23,14 @@ describe('Wallet Dropdown', () => { }) } - function itChangesLocale() { + function itChangesLocale({ featureFlag = false }: { featureFlag?: boolean } = {}) { it('should change locale', () => { cy.contains('Uniswap available in: English').should('not.exist') + if (featureFlag) { + cy.get(getTestSelector('language-settings-button')).click() + } + cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true }) cy.location('search').should('match', /\?lng=af-ZA$/) cy.contains('Uniswap available in: English') @@ -45,6 +51,15 @@ describe('Wallet Dropdown', () => { itChangesLocale() }) + describe('should change locale with feature flag', () => { + beforeEach(() => { + cy.visit('/', { featureFlags: [FeatureFlag.currencyConversion] }) + cy.get(getTestSelector('web3-status-connected')).click() + cy.get(getTestSelector('wallet-settings')).click() + }) + itChangesLocale({ featureFlag: true }) + }) + describe('testnet toggle', () => { beforeEach(() => { cy.visit('/swap') diff --git a/src/components/AccountDrawer/DefaultMenu.tsx b/src/components/AccountDrawer/DefaultMenu.tsx index 1f2a6c2f90..ed7615f693 100644 --- a/src/components/AccountDrawer/DefaultMenu.tsx +++ b/src/components/AccountDrawer/DefaultMenu.tsx @@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from 'react' import styled from 'styled-components' import AuthenticatedHeader from './AuthenticatedHeader' +import LanguageMenu from './LanguageMenu' import SettingsMenu from './SettingsMenu' const DefaultMenuWrap = styled(Column)` @@ -15,6 +16,7 @@ const DefaultMenuWrap = styled(Column)` enum MenuState { DEFAULT, SETTINGS, + LANGUAGE_SETTINGS, } function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) { @@ -24,9 +26,10 @@ function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) { const [menu, setMenu] = useState(MenuState.DEFAULT) const openSettings = useCallback(() => setMenu(MenuState.SETTINGS), []) const closeSettings = useCallback(() => setMenu(MenuState.DEFAULT), []) + const openLanguageSettings = useCallback(() => setMenu(MenuState.LANGUAGE_SETTINGS), []) useEffect(() => { - if (!drawerOpen && menu === MenuState.SETTINGS) { + if (!drawerOpen && menu !== MenuState.DEFAULT) { // wait for the drawer to close before resetting the menu const timer = setTimeout(() => { closeSettings() @@ -44,7 +47,10 @@ function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) { ) : ( ))} - {menu === MenuState.SETTINGS && } + {menu === MenuState.SETTINGS && ( + + )} + {menu === MenuState.LANGUAGE_SETTINGS && } ) } diff --git a/src/components/AccountDrawer/LanguageMenu.tsx b/src/components/AccountDrawer/LanguageMenu.tsx new file mode 100644 index 0000000000..593324cbfa --- /dev/null +++ b/src/components/AccountDrawer/LanguageMenu.tsx @@ -0,0 +1,56 @@ +import { Trans } from '@lingui/macro' +import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales' +import { useActiveLocale } from 'hooks/useActiveLocale' +import { useLocationLinkProps } from 'hooks/useLocationLinkProps' +import { Check } from 'react-feather' +import { Link } from 'react-router-dom' +import styled, { useTheme } from 'styled-components' +import { ClickableStyle, ThemedText } from 'theme' + +import { SlideOutMenu } from './SlideOutMenu' + +const InternalLinkMenuItem = styled(Link)` + ${ClickableStyle} + flex: 1; + display: flex; + flex-direction: row; + align-items: center; + padding: 12px 0; + justify-content: space-between; + text-decoration: none; + color: ${({ theme }) => theme.textPrimary}; +` + +function LanguageMenuItem({ locale, isActive }: { locale: SupportedLocale; isActive: boolean }) { + const { to, onClick } = useLocationLinkProps(locale) + const theme = useTheme() + + if (!to) return null + + return ( + + {LOCALE_LABEL[locale]} + {isActive && } + + ) +} + +export function LanguageMenuItems() { + const activeLocale = useActiveLocale() + + return ( + <> + {SUPPORTED_LOCALES.map((locale) => ( + + ))} + + ) +} + +export default function LanguageMenu({ onClose }: { onClose: () => void }) { + return ( + Language} onClose={onClose}> + + + ) +} diff --git a/src/components/AccountDrawer/SettingsMenu.tsx b/src/components/AccountDrawer/SettingsMenu.tsx index e819739230..35fb5ea161 100644 --- a/src/components/AccountDrawer/SettingsMenu.tsx +++ b/src/components/AccountDrawer/SettingsMenu.tsx @@ -1,46 +1,27 @@ import { Trans } from '@lingui/macro' -import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales' +import Column from 'components/Column' +import Row from 'components/Row' +import { LOCALE_LABEL } from 'constants/locales' +import { useCurrencyConversionFlagEnabled } from 'featureFlags/flags/currencyConversion' import { useActiveLocale } from 'hooks/useActiveLocale' -import { useLocationLinkProps } from 'hooks/useLocationLinkProps' -import { Check } from 'react-feather' -import { Link } from 'react-router-dom' -import styled, { useTheme } from 'styled-components' +import { ReactNode } from 'react' +import { ChevronRight } from 'react-feather' +import styled from 'styled-components' import { ClickableStyle, ThemedText } from 'theme' import ThemeToggle from 'theme/components/ThemeToggle' import { AnalyticsToggle } from './AnalyticsToggle' import { GitVersionRow } from './GitVersionRow' +import { LanguageMenuItems } from './LanguageMenu' import { SlideOutMenu } from './SlideOutMenu' import { SmallBalanceToggle } from './SmallBalanceToggle' import { TestnetsToggle } from './TestnetsToggle' -const InternalLinkMenuItem = styled(Link)` - ${ClickableStyle} - flex: 1; - color: ${({ theme }) => theme.textTertiary}; - display: flex; - flex-direction: row; - align-items: center; - padding: 12px 0; +const Container = styled(Column)` + height: 100%; justify-content: space-between; - text-decoration: none; - color: ${({ theme }) => theme.textPrimary}; ` -function LanguageMenuItem({ locale, isActive }: { locale: SupportedLocale; isActive: boolean }) { - const { to, onClick } = useLocationLinkProps(locale) - const theme = useTheme() - - if (!to) return null - - return ( - - {LOCALE_LABEL[locale]} - {isActive && } - - ) -} - const SectionTitle = styled(ThemedText.SubHeader)` color: ${({ theme }) => theme.textSecondary}; padding-bottom: 24px; @@ -53,28 +34,81 @@ const ToggleWrapper = styled.div` margin-bottom: 24px; ` -export default function SettingsMenu({ onClose }: { onClose: () => void }) { +const SettingsButtonWrapper = styled(Row)` + ${ClickableStyle} +` + +const StyledChevron = styled(ChevronRight)` + color: ${({ theme }) => theme.textSecondary}; +` + +const LanguageLabel = styled(Row)` + white-space: nowrap; +` + +const SettingsButton = ({ + title, + currentState, + onClick, + testId, +}: { + title: ReactNode + currentState: ReactNode + onClick: () => void + testId?: string +}) => ( + + {title} + + {currentState} + + + +) + +export default function SettingsMenu({ + onClose, + openLanguageSettings, +}: { + onClose: () => void + openLanguageSettings: () => void +}) { + const currencyConversionEnabled = useCurrencyConversionFlagEnabled() const activeLocale = useActiveLocale() return ( Settings} onClose={onClose}> - - Preferences - - - - - - - + +
+ + Preferences + + + + + + + + {!currencyConversionEnabled && ( + <> + + Language + + + + )} - - Language - - {SUPPORTED_LOCALES.map((locale) => ( - - ))} - + {currencyConversionEnabled && ( + Language} + currentState={LOCALE_LABEL[activeLocale]} + onClick={openLanguageSettings} + testId="language-settings-button" + /> + )} +
+ +
) } diff --git a/src/components/AccountDrawer/SlideOutMenu.tsx b/src/components/AccountDrawer/SlideOutMenu.tsx index 9f8701f33f..3118e700f8 100644 --- a/src/components/AccountDrawer/SlideOutMenu.tsx +++ b/src/components/AccountDrawer/SlideOutMenu.tsx @@ -1,9 +1,10 @@ +import Column from 'components/Column' import { ScrollBarStyles } from 'components/Common' import { ArrowLeft } from 'react-feather' import styled from 'styled-components' import { ClickableStyle, ThemedText } from 'theme' -const Menu = styled.div` +const Menu = styled(Column)` width: 100%; overflow: auto; margin-top: 4px; diff --git a/src/featureFlags/flags/currencyConversion.ts b/src/featureFlags/flags/currencyConversion.ts index d65902d495..71888a67ed 100644 --- a/src/featureFlags/flags/currencyConversion.ts +++ b/src/featureFlags/flags/currencyConversion.ts @@ -3,3 +3,7 @@ import { BaseVariant, FeatureFlag, useBaseFlag } from '../index' export function useCurrencyConversionFlag(): BaseVariant { return useBaseFlag(FeatureFlag.currencyConversion) } + +export function useCurrencyConversionFlagEnabled(): boolean { + return useCurrencyConversionFlag() === BaseVariant.Enabled +} diff --git a/src/theme/components/text.tsx b/src/theme/components/text.tsx index d18b3ce3b9..fd8bd76031 100644 --- a/src/theme/components/text.tsx +++ b/src/theme/components/text.tsx @@ -43,6 +43,9 @@ export const ThemedText = { Hero(props: TextProps) { return }, + LabelMedium(props: TextProps) { + return + }, LabelSmall(props: TextProps) { return },