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:
parent
6004c4be3e
commit
1d82a4c71e
@ -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
|
||||
}
|
||||
|
37
src/hooks/useLocationLinkProps.ts
Normal file
37
src/hooks/useLocationLinkProps.ts
Normal file
@ -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]
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user