fix: set language using url param in language dropdown (#2063)

* set language using url param in language dropdown

* refactor common code into a hook

* add hook

* address pr feedback
This commit is contained in:
Justin Domingue 2021-07-16 10:56:33 -07:00 committed by GitHub
parent 6004c4be3e
commit 1d82a4c71e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 54 deletions

@ -21,10 +21,12 @@ import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { Trans } from '@lingui/macro'
import { ExternalLink } from '../../theme'
import { ButtonPrimary } from '../Button'
import { useDarkModeManager, useUserLocaleManager } from 'state/user/hooks'
import { useDarkModeManager } from 'state/user/hooks'
import { L2_CHAIN_IDS, CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { LOCALE_LABEL, SUPPORTED_LOCALES } from 'constants/locales'
import { LOCALE_LABEL, SupportedLocale, SUPPORTED_LOCALES } from 'constants/locales'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
import { useActiveLocale } from 'hooks/useActiveLocale'
export enum FlyoutAlignment {
LEFT = 'LEFT',
@ -140,6 +142,20 @@ const InternalMenuItem = styled(Link)`
}
`
const InternalLinkMenuItem = styled(InternalMenuItem)`
display: flex;
flex-direction: row;
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: space-between;
text-decoration: none;
:hover {
color: ${({ theme }) => theme.text1};
cursor: pointer;
text-decoration: none;
}
`
const ToggleMenuItem = styled.button`
background-color: transparent;
margin: 0;
@ -163,6 +179,34 @@ const ToggleMenuItem = styled.button`
const CODE_LINK = 'https://github.com/Uniswap/uniswap-interface'
function LanguageMenuItem({ locale, active, key }: { locale: SupportedLocale; active: boolean; key: string }) {
const { to, onClick } = useLocationLinkProps(locale)
if (!to) return null
return (
<InternalLinkMenuItem onClick={onClick} key={key} to={to}>
<div>{LOCALE_LABEL[locale]}</div>
{active && <Check opacity={0.6} size={16} />}
</InternalLinkMenuItem>
)
}
function LanguageMenu({ close }: { close: () => void }) {
const activeLocale = useActiveLocale()
return (
<MenuFlyout>
<ToggleMenuItem onClick={close}>
<ChevronLeft size={16} />
</ToggleMenuItem>
{SUPPORTED_LOCALES.map((locale) => (
<LanguageMenuItem locale={locale} active={activeLocale === locale} key={locale} />
))}
</MenuFlyout>
)
}
export default function Menu() {
const { account, chainId } = useActiveWeb3React()
@ -175,7 +219,6 @@ export default function Menu() {
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
const [darkMode, toggleDarkMode] = useDarkModeManager()
const [currentLocale, setLocale] = useUserLocaleManager()
const [menu, setMenu] = useState<'main' | 'lang'>('main')
@ -194,19 +237,7 @@ export default function Menu() {
(() => {
switch (menu) {
case 'lang':
return (
<MenuFlyout>
<ToggleMenuItem onClick={() => setMenu('main')}>
<ChevronLeft size={16} />
</ToggleMenuItem>
{SUPPORTED_LOCALES.map((locale) => (
<ToggleMenuItem onClick={() => setLocale(locale)} key={locale}>
<div>{LOCALE_LABEL[locale]}</div>
{currentLocale === locale && <Check opacity={0.6} size={16} />}
</ToggleMenuItem>
))}
</MenuFlyout>
)
return <LanguageMenu close={() => setMenu('main')} />
case 'main':
default:
return (

@ -1,13 +1,10 @@
import { Trans } from '@lingui/macro'
import { useMemo } from 'react'
import ReactGA from 'react-ga'
import { useLocation } from 'react-router'
import styled from 'styled-components/macro'
import { DEFAULT_LOCALE, LOCALE_LABEL, SupportedLocale } from '../../constants/locales'
import { navigatorLocale, useActiveLocale } from '../../hooks/useActiveLocale'
import useParsedQueryString from '../../hooks/useParsedQueryString'
import { StyledInternalLink, TYPE } from '../../theme'
import { stringify } from 'qs'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
const Container = styled(TYPE.small)`
opacity: 0.6;
@ -17,46 +14,35 @@ const Container = styled(TYPE.small)`
margin-top: 1rem !important;
`
export function SwitchLocaleLink() {
const activeLocale = useActiveLocale()
const useTargetLocale = (activeLocale: SupportedLocale) => {
const browserLocale = useMemo(() => navigatorLocale(), [])
const location = useLocation()
const qs = useParsedQueryString()
if (browserLocale && (browserLocale !== DEFAULT_LOCALE || activeLocale !== DEFAULT_LOCALE)) {
let targetLocale: SupportedLocale
if (activeLocale === browserLocale) {
targetLocale = DEFAULT_LOCALE
return DEFAULT_LOCALE
} else {
targetLocale = browserLocale
return browserLocale
}
}
return null
}
const target = {
...location,
search: stringify({ ...qs, lng: targetLocale }),
}
export function SwitchLocaleLink() {
const activeLocale = useActiveLocale()
const targetLocale = useTargetLocale(activeLocale)
const { to, onClick } = useLocationLinkProps(targetLocale)
if (!targetLocale || !to) return null
return (
<Container>
<Trans>
Uniswap available in:{' '}
{
<StyledInternalLink
onClick={() => {
ReactGA.event({
category: 'Localization',
action: 'Switch Locale',
label: `${activeLocale} -> ${targetLocale}`,
})
}}
to={target}
>
<StyledInternalLink onClick={onClick} to={to}>
{LOCALE_LABEL[targetLocale]}
</StyledInternalLink>
}
</Trans>
</Container>
)
}
return null
}

@ -0,0 +1,37 @@
import ReactGA from 'react-ga'
import { stringify } from 'qs'
import useParsedQueryString from 'hooks/useParsedQueryString'
import { useLocation } from 'react-router-dom'
import { LocationDescriptor } from 'history'
import { SupportedLocale } from 'constants/locales'
import { useActiveLocale } from './useActiveLocale'
import { useMemo } from 'react'
export function useLocationLinkProps(locale: SupportedLocale | null): {
to?: LocationDescriptor
onClick?: () => void
} {
const location = useLocation()
const qs = useParsedQueryString()
const activeLocale = useActiveLocale()
return useMemo(
() =>
!locale
? {}
: {
to: {
...location,
search: stringify({ ...qs, lng: locale }),
},
onClick: () => {
ReactGA.event({
category: 'Localization',
action: 'Switch Locale',
label: `${activeLocale} -> ${locale}`,
})
},
},
[location, qs, activeLocale, locale]
)
}