feat(i18n): improve i18n (#1692)

* replaced i18next with lingui

* integrate lingui in i18n and update dev setup

* updated components to @lingui

* fix compile error after rebase

* detect locale

* add all previous languages to linguirc

* address pr feedback

* remove it for now

* ignore generate *js files, various fixes

* added more translations

* fixed yarn build command

* wrapped more hardcoded english around <Trans>

* finished second round of translations

* added support for pseudo-en locale

* improvements

* moved copy.tsx to different branch

* moved extra files to different branch

* regenerated po

* clean up

* more fixes

* regenerate po

* remove messages.js

* clean up

* addressed pr feedback

* regenerated po
This commit is contained in:
Justin Domingue 2021-05-26 13:34:52 -07:00 committed by GitHub
parent dbbffd17a6
commit c4846c8832
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 5097 additions and 2880 deletions

1
.gitignore vendored

@ -3,6 +3,7 @@
# generated contract types
/src/types/v3
/src/abis/types
/src/locales/**/*.js
# dependencies
/node_modules

20
lingui.config.js Normal file

@ -0,0 +1,20 @@
module.exports = {
catalogs: [
{
path: '<rootDir>/src/locales/{locale}/messages',
include: ['<rootDir>'],
exclude: ['**/node_modules/**', '**/build/**'],
},
],
compileNamespace: 'cjs',
fallbackLocales: {
'pseudo-en': 'en',
},
format: 'po',
locales: ['en', 'pseudo-en'],
orderBy: 'messageId',
pseudoLocale: 'pseudo-en',
rootDir: '.',
runtimeConfigModule: ['@lingui/core', 'i18n'],
sourceLocale: 'en',
}

@ -6,6 +6,11 @@
"devDependencies": {
"@emotion/core": "^11.0.0",
"@ethersproject/experimental": "^5.2.0",
"@lingui/cli": "^3.9.0",
"@lingui/detect-locale": "^3.9.0",
"@lingui/loader": "^3.9.0",
"@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0",
"@metamask/jazzicon": "^2.0.0",
"@popperjs/core": "^2.4.4",
"@reach/dialog": "^0.10.3",
@ -24,6 +29,9 @@
"@styled-system/css": "^5.1.5",
"@typechain/ethers-v5": "^7.0.0",
"@types/jest": "^25.2.1",
"@types/lingui__core": "^2.7.1",
"@types/lingui__macro": "^2.7.4",
"@types/lingui__react": "^2.8.3",
"@types/lodash.flatmap": "^4.5.6",
"@types/luxon": "^1.24.4",
"@types/multicodec": "^1.0.0",
@ -70,9 +78,6 @@
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^4.0.0",
"ethers": "^5.2.0",
"i18next": "^15.0.9",
"i18next-browser-languagedetector": "^3.0.1",
"i18next-xhr-backend": "^2.0.1",
"inter-ui": "^3.13.1",
"lightweight-charts": "^3.3.0",
"lodash.flatmap": "^4.5.0",
@ -89,7 +94,6 @@
"react-dom": "^17.0.1",
"react-feather": "^2.0.8",
"react-ga": "^2.5.7",
"react-i18next": "^10.7.0",
"react-markdown": "^4.3.1",
"react-popper": "^2.2.3",
"react-redux": "^7.2.2",
@ -123,10 +127,12 @@
"compile-contract-types": "yarn compile-external-abi-types && yarn compile-v3-contract-types",
"compile-external-abi-types": "typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'",
"compile-v3-contract-types": "typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'",
"build": "yarn compile-contract-types && react-scripts build",
"build": "yarn compile-contract-types yarn i18n:extract && yarn i18n:compile && react-scripts build",
"i18n:extract": "lingui extract",
"i18n:compile": "lingui compile",
"integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run'",
"postinstall": "yarn compile-contract-types",
"start": "yarn compile-contract-types && react-scripts start",
"start": "yarn compile-contract-types && yarn i18n:extract && yarn i18n:compile && react-scripts start",
"storybook": "start-storybook -p 6006",
"test": "react-scripts test --env=jsdom"
},

@ -4,7 +4,7 @@ import Badge, { BadgeVariant } from 'components/Badge'
import styled from 'styled-components/macro'
import { MouseoverTooltip } from '../../components/Tooltip'
import { useTranslation } from 'react-i18next'
import { Trans, t } from '@lingui/macro'
import { AlertCircle } from 'react-feather'
const BadgeWrapper = styled.div`
@ -40,35 +40,51 @@ export default function RangeBadge({
removed: boolean | undefined
inRange: boolean | undefined
}) {
const { t } = useTranslation()
return (
<BadgeWrapper>
{removed ? (
<MouseoverTooltip text={`Your position has 0 liquidity, and is not earning fees.`}>
<MouseoverTooltip
text={t({
id: 'pools.labels.inactiveTooltip',
message: 'Your position has 0 liquidity, and is not earning fees.',
})}
>
<Badge variant={BadgeVariant.DEFAULT}>
<AlertCircle width={14} height={14} />
&nbsp;
<BadgeText>{t('Inactive')}</BadgeText>
<BadgeText>
<Trans id="pools.labels.inactive">Inactive</Trans>
</BadgeText>
</Badge>
</MouseoverTooltip>
) : inRange ? (
<MouseoverTooltip
text={`The price of this pool is within your selected range. Your position is currently earning fees.`}
text={t({
id: 'pools.labels.inRangeTooltip',
message: 'The price of this pool is within your selected range. Your position is currently earning fees.',
})}
>
<Badge variant={BadgeVariant.DEFAULT}>
<ActiveDot /> &nbsp;
<BadgeText>{t('In range')}</BadgeText>
<BadgeText>
<Trans id="pools.labels.inRange">In range</Trans>
</BadgeText>
</Badge>
</MouseoverTooltip>
) : (
<MouseoverTooltip
text={`The price of this pool is outside of your selected range. Your position is not currently earning fees.`}
text={t({
id: 'pools.labels.outOfRangeTooltip',
message:
'The price of this pool is outside of your selected range. Your position is not currently earning fees.',
})}
>
<Badge variant={BadgeVariant.WARNING}>
<AlertCircle width={14} height={14} />
&nbsp;
<BadgeText>{t('Out of range')}</BadgeText>
<BadgeText>
<Trans id="pools.labels.outOfRange">Out of range</Trans>
</BadgeText>
</Badge>
</MouseoverTooltip>
)}

@ -13,7 +13,7 @@ import { TYPE } from '../../theme'
import { Input as NumericalInput } from '../NumericalInput'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTranslation } from 'react-i18next'
import { Trans, t } from '@lingui/macro'
import useTheme from '../../hooks/useTheme'
import { Lock } from 'react-feather'
import { AutoColumn } from 'components/Column'
@ -183,8 +183,6 @@ export default function CurrencyInputPanel({
locked = false,
...rest
}: CurrencyInputPanelProps) {
const { t } = useTranslation()
const [modalOpen, setModalOpen] = useState(false)
const { account } = useActiveWeb3React()
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
@ -201,7 +199,9 @@ export default function CurrencyInputPanel({
<AutoColumn gap="sm" justify="center">
<Lock />
<TYPE.label fontSize="12px" textAlign="center">
The market price is outside your specified price range. Single-asset deposit only.
<Trans id="currencies.input.priceOutsideWarning">
The market price is outside your specified price range. Single-asset deposit only.
</Trans>
</TYPE.label>
</AutoColumn>
</FixedContainer>
@ -237,7 +237,7 @@ export default function CurrencyInputPanel({
? currency.symbol.slice(0, 4) +
'...' +
currency.symbol.slice(currency.symbol.length - 5, currency.symbol.length)
: currency?.symbol) || t('selectToken')}
: currency?.symbol) || t({ id: 'currencies.search.selectToken', message: 'Select a token' })}
</StyledTokenName>
)}
</RowFixed>
@ -276,7 +276,9 @@ export default function CurrencyInputPanel({
: ''}
</TYPE.body>
{showMaxButton && selectedCurrencyBalance ? (
<StyledBalanceMax onClick={onMax}>(Max)</StyledBalanceMax>
<StyledBalanceMax onClick={onMax}>
<Trans id="currencies.input.max">(Max)</Trans>
</StyledBalanceMax>
) : null}
</RowFixed>
) : (

@ -1,6 +1,6 @@
import React from 'react'
import { FeeAmount } from '@uniswap/v3-sdk'
import { useTranslation } from 'react-i18next'
import { t } from '@lingui/macro'
import { AutoColumn } from 'components/Column'
import { DynamicSection } from 'pages/AddLiquidity/styled'
import { TYPE } from 'theme'
@ -23,14 +23,15 @@ export default function FeeSelector({
feeAmount?: FeeAmount
handleFeePoolSelect: (feeAmount: FeeAmount) => void
}) {
const { t } = useTranslation()
return (
<AutoColumn gap="16px">
<DynamicSection gap="md" disabled={disabled}>
<TYPE.label>{t('selectPool')}</TYPE.label>
<TYPE.label>{t({ id: 'pools.feeSelector.title', message: 'Select Pool' })}</TYPE.label>
<TYPE.main fontSize={14} fontWeight={400} style={{ marginBottom: '.5rem', lineHeight: '125%' }}>
Select a pool type based on your preferred liquidity provider fee.
{t({
id: 'pools.feeSelector.subtitle',
message: 'Select a pool type based on your preferred liquidity provider fee.',
})}
</TYPE.main>
<RowBetween>
<ButtonRadioChecked
@ -39,9 +40,9 @@ export default function FeeSelector({
onClick={() => handleFeePoolSelect(FeeAmount.LOW)}
>
<AutoColumn gap="sm" justify="flex-start">
<ResponsiveText>0.05% {t('fee')}</ResponsiveText>
<ResponsiveText>{t({ id: 'pools.feeSelector.lowFee', message: `0.05% fee` })}</ResponsiveText>
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
Best for stable pairs.
{t({ id: 'pools.feeSelector.lowFeeHint', message: 'Best for stable pairs.' })}
</TYPE.main>
</AutoColumn>
</ButtonRadioChecked>
@ -51,9 +52,9 @@ export default function FeeSelector({
onClick={() => handleFeePoolSelect(FeeAmount.MEDIUM)}
>
<AutoColumn gap="sm" justify="flex-start">
<ResponsiveText>0.3% {t('fee')}</ResponsiveText>
<ResponsiveText>{t({ id: 'pools.feeSelector.mediumFee', message: `0.3% fee` })}</ResponsiveText>
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
Best for most pairs.
{t({ id: 'pools.feeSelector.mediumFeeHint', message: 'Best for most pairs.' })}
</TYPE.main>
</AutoColumn>
</ButtonRadioChecked>
@ -63,9 +64,9 @@ export default function FeeSelector({
onClick={() => handleFeePoolSelect(FeeAmount.HIGH)}
>
<AutoColumn gap="sm" justify="flex-start">
<ResponsiveText>1% {t('fee')}</ResponsiveText>
<ResponsiveText>{t({ id: 'pools.feeSelector.highFee', message: '1% fee' })}</ResponsiveText>
<TYPE.main fontWeight={400} fontSize="12px" textAlign="left">
Best for exotic pairs.
{t({ id: 'pools.feeSelector.highFeeHint', message: 'Best for exotic pairs.' })}
</TYPE.main>
</AutoColumn>
</ButtonRadioChecked>

@ -3,7 +3,7 @@ import React, { useState } from 'react'
import { Text } from 'rebass'
import { NavLink } from 'react-router-dom'
import { darken } from 'polished'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { Moon, Sun } from 'react-feather'
import styled from 'styled-components/macro'
@ -309,7 +309,6 @@ const NETWORK_LABELS: { [chainId: number]: string } = {
export default function Header() {
const { account, chainId } = useActiveWeb3React()
const { t } = useTranslation()
const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? '']
// const [isDark] = useDarkModeManager()
@ -341,7 +340,7 @@ export default function Header() {
</HeaderRow>
<HeaderLinks>
<StyledNavLink id={`swap-nav-link`} to={'/swap'}>
{t('swap')}
<Trans id="nav.swap">Swap</Trans>
</StyledNavLink>
<StyledNavLink
id={`pool-nav-link`}
@ -354,13 +353,15 @@ export default function Header() {
pathname.startsWith('/find')
}
>
{t('pool')}
<Trans id="nav.pool">Pool</Trans>
</StyledNavLink>
<StyledNavLink id={`stake-nav-link`} to={'/vote'}>
Vote
<Trans id="nav.vote">Vote</Trans>
</StyledNavLink>
<StyledExternalLink id={`stake-nav-link`} href={'https://info.uniswap.org'}>
Charts <span style={{ fontSize: '11px', textDecoration: 'none !important' }}></span>
<Trans id="nav.charts">
Charts <span style={{ fontSize: '11px', textDecoration: 'none !important' }}></span>
</Trans>
</StyledExternalLink>
</HeaderLinks>
<HeaderControls>
@ -374,7 +375,13 @@ export default function Header() {
<UNIWrapper onClick={toggleClaimModal}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
<TYPE.white padding="0 2px">
{claimTxn && !claimTxn?.receipt ? <Dots>Claiming UNI</Dots> : 'Claim UNI'}
{claimTxn && !claimTxn?.receipt ? (
<Dots>
<Trans id="claim.buttons.claimingUNI">Claiming UNI</Trans>
</Dots>
) : (
<Trans id="claim.buttons.claimUNI">Claim UNI</Trans>
)}
</TYPE.white>
</UNIAmount>
<CardNoise />
@ -383,7 +390,7 @@ export default function Header() {
<AccountElement active={!!account} style={{ pointerEvents: 'auto' }}>
{account && userEthBalance ? (
<BalanceText style={{ flexShrink: 0 }} pl="0.75rem" pr="0.5rem" fontWeight={500}>
{userEthBalance?.toSignificant(4)} ETH
<Trans id="wallet.ethBalance">{userEthBalance?.toSignificant(4)} ETH</Trans>
</BalanceText>
) : null}
<Web3Status />

@ -1,7 +1,7 @@
import React from 'react'
import styled from 'styled-components/macro'
import { darken } from 'polished'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { NavLink, Link as HistoryLink } from 'react-router-dom'
import { Percent } from '@uniswap/sdk-core'
@ -60,14 +60,13 @@ const StyledArrowLeft = styled(ArrowLeft)`
`
export function SwapPoolTabs({ active }: { active: 'swap' | 'pool' }) {
const { t } = useTranslation()
return (
<Tabs style={{ marginBottom: '20px', display: 'none', padding: '1rem 1rem 0 1rem' }}>
<StyledNavLink id={`swap-nav-link`} to={'/swap'} isActive={() => active === 'swap'}>
{t('swap')}
<Trans id="nav.swap">Swap</Trans>
</StyledNavLink>
<StyledNavLink id={`pool-nav-link`} to={'/pool'} isActive={() => active === 'pool'}>
{t('pool')}
<Trans id="nav.pool">Pool</Trans>
</StyledNavLink>
</Tabs>
)
@ -80,7 +79,9 @@ export function FindPoolTabs({ origin }: { origin: string }) {
<HistoryLink to={origin}>
<StyledArrowLeft />
</HistoryLink>
<ActiveText>Import Pool</ActiveText>
<ActiveText>
<Trans id="nav.importPool">Import Pool</Trans>
</ActiveText>
</RowBetween>
</Tabs>
)
@ -118,7 +119,13 @@ export function AddRemoveTabs({
<StyledArrowLeft stroke={theme.text2} />
</HistoryLink>
<TYPE.mediumHeader fontWeight={500} fontSize={20}>
{creating ? 'Create a pair' : adding ? 'Add Liquidity' : 'Remove Liquidity'}
{creating ? (
<Trans id="pools.buttons.createPair">Create a pair</Trans>
) : adding ? (
<Trans id="pools.buttons.addLiquidity">Add Liquidity</Trans>
) : (
<Trans id="pools.buttons.removeLiquidity">Remove Liquidity</Trans>
)}
</TYPE.mediumHeader>
<SettingsTab placeholderSlippage={defaultSlippage} />
</RowBetween>

@ -1,6 +1,6 @@
import PositionListItem from 'components/PositionListItem'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import styled from 'styled-components/macro'
import { MEDIA_WIDTHS } from 'theme'
import { PositionDetails } from 'types/position'
@ -39,18 +39,20 @@ export type PositionListProps = React.PropsWithChildren<{
}>
export default function PositionList({ positions }: PositionListProps) {
const { t } = useTranslation()
return (
<>
<DesktopHeader>
<div>
{t('Your positions')}
<Trans id="pool.yourPositions">Your positions</Trans>
{positions && ' (' + positions.length + ')'}
</div>
<div>{t('Price range')}</div>
<div>
<Trans id="pool.priceRange">Price range</Trans>
</div>
</DesktopHeader>
<MobileHeader>Your positions</MobileHeader>
<MobileHeader>
<Trans id="pool.yourPositions">Your positions</Trans>
</MobileHeader>
{positions.map((p) => {
return <PositionListItem key={p.tokenId.toString()} positionDetails={p} />
})}

@ -7,7 +7,7 @@ import { RowBetween, RowFixed } from 'components/Row'
import CurrencyLogo from 'components/CurrencyLogo'
import { unwrappedToken } from 'utils/unwrappedToken'
import { Break } from 'components/earn/styled'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import RateToggle from 'components/RateToggle'
import DoubleCurrencyLogo from 'components/DoubleLogo'
@ -26,8 +26,6 @@ export const PositionPreview = ({
inRange: boolean
baseCurrencyDefault?: Currency | undefined
}) => {
const { t } = useTranslation()
const theme = useContext(ThemeContext)
const currency0 = unwrappedToken(position.pool.token0)
@ -97,8 +95,12 @@ export const PositionPreview = ({
</RowBetween>
<Break />
<RowBetween>
<TYPE.label>{t('feeTier')}</TYPE.label>
<TYPE.label>{position?.pool?.fee / 10000}%</TYPE.label>
<TYPE.label>
<Trans id="pools.labels.feeTier">Fee Tier</Trans>
</TYPE.label>
<TYPE.label>
<Trans id="pools.labels.feeTierValue">{position?.pool?.fee / 10000}%</Trans>
</TYPE.label>
</RowBetween>
</AutoColumn>
</LightCard>
@ -116,40 +118,53 @@ export const PositionPreview = ({
<RowBetween>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">Min Price</TYPE.main>
<TYPE.main fontSize="12px">
<Trans id="pools.minPriceLabel">Min Price</Trans>
</TYPE.main>
<TYPE.mediumHeader textAlign="center">{`${priceLower.toSignificant(5)}`}</TYPE.mediumHeader>
<TYPE.main
textAlign="center"
fontSize="12px"
>{` ${quoteCurrency.symbol}/${baseCurrency.symbol}`}</TYPE.main>
<TYPE.main textAlign="center" fontSize="12px">
<Trans id="currencies.denominated">
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
Your position will be 100% composed of {baseCurrency?.symbol} at this price
<Trans id="pools.minMaxPriceHint">
Your position will be 100% composed of {baseCurrency?.symbol} at this price
</Trans>
</TYPE.small>
</AutoColumn>
</LightCard>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">Max Price</TYPE.main>
<TYPE.main fontSize="12px">
<Trans id="pools.maxPrice">Max Price</Trans>
</TYPE.main>
<TYPE.mediumHeader textAlign="center">{`${priceUpper.toSignificant(5)}`}</TYPE.mediumHeader>
<TYPE.main
textAlign="center"
fontSize="12px"
>{` ${quoteCurrency.symbol} per ${baseCurrency.symbol}`}</TYPE.main>
<TYPE.main textAlign="center" fontSize="12px">
<Trans id="currencies.denominated">
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
<TYPE.small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
Your position will be 100% composed of {quoteCurrency?.symbol} at this price
<Trans id="pools.minMaxPriceHint">
Your position will be 100% composed of {quoteCurrency?.symbol} at this price
</Trans>
</TYPE.small>
</AutoColumn>
</LightCard>
</RowBetween>
<LightCard padding="12px ">
<AutoColumn gap="4px" justify="center">
<TYPE.main fontSize="12px">Current price</TYPE.main>
<TYPE.main fontSize="12px">
<Trans id="pools.currentPrice">Current price</Trans>
</TYPE.main>
<TYPE.mediumHeader>{`${price.toSignificant(5)} `}</TYPE.mediumHeader>
<TYPE.main
textAlign="center"
fontSize="12px"
>{` ${quoteCurrency.symbol} per ${baseCurrency.symbol}`}</TYPE.main>
<TYPE.main textAlign="center" fontSize="12px">
<Trans id="currencies.denominated">
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
</AutoColumn>
</LightCard>
</AutoColumn>

@ -1,7 +1,7 @@
import { Currency, Ether, Token } from '@uniswap/sdk-core'
import React, { KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import ReactGA from 'react-ga'
import { useTranslation } from 'react-i18next'
import { t, Trans } from '@lingui/macro'
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
import { useActiveWeb3React } from '../../hooks/web3'
@ -63,7 +63,6 @@ export function CurrencySearch({
showImportView,
setImportToken,
}: CurrencySearchProps) {
const { t } = useTranslation()
const { chainId } = useActiveWeb3React()
const theme = useTheme()
@ -172,7 +171,7 @@ export function CurrencySearch({
<PaddedColumn gap="16px">
<RowBetween>
<Text fontWeight={500} fontSize={16}>
Select a token
<Trans id="currencies.search.selectToken">Select a token</Trans>
</Text>
<CloseIcon onClick={onDismiss} />
</RowBetween>
@ -180,7 +179,7 @@ export function CurrencySearch({
<SearchInput
type="text"
id="token-search-input"
placeholder={t('tokenSearchPlaceholder')}
placeholder={t({ id: 'currencies.search.placeholder', message: 'Search name or paste address' })}
autoComplete="off"
value={searchQuery}
ref={inputRef as RefObject<HTMLInputElement>}
@ -218,7 +217,7 @@ export function CurrencySearch({
) : (
<Column style={{ padding: '20px', height: '100%' }}>
<TYPE.main color={theme.text3} textAlign="center" mb="20px">
No results found.
<Trans id="currencies.search.noResults">No results found.</Trans>
</TYPE.main>
</Column>
)}
@ -229,7 +228,9 @@ export function CurrencySearch({
<IconWrapper size="16px" marginRight="6px">
<Edit />
</IconWrapper>
<TYPE.main color={theme.blue1}>Manage Token Lists</TYPE.main>
<TYPE.main color={theme.blue1}>
<Trans id="tokenLists.manage">Manage Token Lists</Trans>
</TYPE.main>
</RowFixed>
</ButtonText>
</Row>

@ -20,6 +20,7 @@ import { useFetchListCallback } from 'hooks/useFetchListCallback'
import { removeList, enableList } from 'state/lists/actions'
import { CurrencyModalView } from './CurrencySearchModal'
import { useAllLists } from 'state/lists/hooks'
import { Trans } from '@lingui/macro'
const Wrapper = styled.div`
position: relative;
@ -80,7 +81,9 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<PaddedColumn gap="14px" style={{ width: '100%', flex: '1 1' }}>
<RowBetween>
<ArrowLeft style={{ cursor: 'pointer' }} onClick={() => setModalView(CurrencyModalView.manage)} />
<TYPE.mediumHeader>Import List</TYPE.mediumHeader>
<TYPE.mediumHeader>
<Trans id="tokenLists.importList">Import List</Trans>
</TYPE.mediumHeader>
<CloseIcon onClick={onDismiss} />
</RowBetween>
</PaddedColumn>
@ -98,7 +101,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
</TYPE.body>
<TextDot />
<TYPE.main fontSize={'16px'} ml="6px">
{list.tokens.length} tokens
<Trans id="tokensLists.numberOfTokens">{list.tokens.length} tokens</Trans>
</TYPE.main>
</RowFixed>
<ExternalLink href={`https://tokenlists.org/token-list?url=${listURL}`}>
@ -114,18 +117,22 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<AutoColumn justify="center" style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<AlertTriangle stroke={theme.red1} size={32} />
<TYPE.body fontWeight={500} fontSize={20} color={theme.red1}>
Import at your own risk{' '}
<Trans id="tokenLists.importWarning">Import at your own risk</Trans>
</TYPE.body>
</AutoColumn>
<AutoColumn style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<TYPE.body fontWeight={500} color={theme.red1}>
By adding this list you are implicitly trusting that the data is correct. Anyone can create a list,
including creating fake versions of existing lists and lists that claim to represent projects that do
not have one.
<Trans id="tokenLists.importHint1">
By adding this list you are implicitly trusting that the data is correct. Anyone can create a list,
including creating fake versions of existing lists and lists that claim to represent projects that do
not have one.
</Trans>
</TYPE.body>
<TYPE.body fontWeight={600} color={theme.red1}>
If you purchase a token from this list, you may not be able to sell it back.
<Trans id="tokenLists.importHint2">
If you purchase a token from this list, you may not be able to sell it back.
</Trans>
</TYPE.body>
</AutoColumn>
<AutoRow justify="center" style={{ cursor: 'pointer' }} onClick={() => setConfirmed(!confirmed)}>
@ -136,7 +143,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
onChange={() => setConfirmed(!confirmed)}
/>
<TYPE.body ml="10px" fontSize="16px" color={theme.red1} fontWeight={500}>
I understand
<Trans id="common.IUnderstand">I understand</Trans>
</TYPE.body>
</AutoRow>
</Card>
@ -148,7 +155,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
padding="10px 1rem"
onClick={handleAddList}
>
Import
<Trans id="tokenLists.buttons.import">Import</Trans>
</ButtonPrimary>
{addError ? (
<TYPE.error title={addError} style={{ textOverflow: 'ellipsis', overflow: 'hidden' }} error>

@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'
import { useWeb3React } from '@web3-react/core'
import styled from 'styled-components/macro'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { network } from '../../connectors'
import { useEagerConnect, useInactiveListener } from '../../hooks/web3'
@ -20,7 +20,6 @@ const Message = styled.h2`
`
export default function Web3ReactManager({ children }: { children: JSX.Element }) {
const { t } = useTranslation()
const { active } = useWeb3React()
const { active: networkActive, error: networkError, activate: activateNetwork } = useWeb3React(NetworkContextName)
@ -58,7 +57,11 @@ export default function Web3ReactManager({ children }: { children: JSX.Element }
if (!active && networkError) {
return (
<MessageWrapper>
<Message>{t('unknownError')}</Message>
<Message>
<Trans id="errors.unknown">
Oops! An unknown error occurred. Please refresh the page, or visit from another browser or device.
</Trans>
</Message>
</MessageWrapper>
)
}

@ -3,7 +3,7 @@ import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { darken, lighten } from 'polished'
import React, { useMemo } from 'react'
import { Activity } from 'react-feather'
import { useTranslation } from 'react-i18next'
import { t, Trans } from '@lingui/macro'
import styled, { css } from 'styled-components'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
@ -136,25 +136,25 @@ function StatusIcon({ connector }: { connector: AbstractConnector }) {
} else if (connector === walletconnect) {
return (
<IconWrapper size={16}>
<img src={WalletConnectIcon} alt={''} />
<img src={WalletConnectIcon} alt={'WalletConnect'} />
</IconWrapper>
)
} else if (connector === walletlink) {
return (
<IconWrapper size={16}>
<img src={CoinbaseWalletIcon} alt={''} />
<img src={CoinbaseWalletIcon} alt={'CoinbaseWallet'} />
</IconWrapper>
)
} else if (connector === fortmatic) {
return (
<IconWrapper size={16}>
<img src={FortmaticIcon} alt={''} />
<img src={FortmaticIcon} alt={'Fortmatic'} />
</IconWrapper>
)
} else if (connector === portis) {
return (
<IconWrapper size={16}>
<img src={PortisIcon} alt={''} />
<img src={PortisIcon} alt={'Portis'} />
</IconWrapper>
)
}
@ -162,7 +162,6 @@ function StatusIcon({ connector }: { connector: AbstractConnector }) {
}
function Web3StatusInner() {
const { t } = useTranslation()
const { account, connector, error } = useWeb3React()
const { ENSName } = useENSName(account ?? undefined)
@ -185,7 +184,10 @@ function Web3StatusInner() {
<Web3StatusConnected id="web3-status-connected" onClick={toggleWalletModal} pending={hasPendingTransactions}>
{hasPendingTransactions ? (
<RowBetween>
<Text>{pending?.length} Pending</Text> <Loader stroke="white" />
<Text>
<Trans id="transactions.pending">{pending?.length} Pending</Trans>
</Text>{' '}
<Loader stroke="white" />
</RowBetween>
) : (
<>
@ -200,13 +202,19 @@ function Web3StatusInner() {
return (
<Web3StatusError onClick={toggleWalletModal}>
<NetworkIcon />
<Text>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error'}</Text>
<Text>
{error instanceof UnsupportedChainIdError
? t({ id: 'error.wrongNetwork', message: 'Wrong Network' })
: t({ id: 'error.generic', message: 'Error' })}
</Text>
</Web3StatusError>
)
} else {
return (
<Web3StatusConnect id="connect-wallet" onClick={toggleWalletModal} faded={!account}>
<Text>{t('Connect to a wallet')}</Text>
<Text>
<Trans id="wallet.connectLongForm">Connect to a wallet</Trans>
</Text>
</Web3StatusConnect>
)
}

@ -1,23 +0,0 @@
import i18next from 'i18next'
import { initReactI18next } from 'react-i18next'
import XHR from 'i18next-xhr-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
i18next
.use(XHR)
.use(LanguageDetector)
.use(initReactI18next)
.init({
backend: {
loadPath: `./locales/{{lng}}.json`,
},
react: {
useSuspense: true,
},
fallbackLng: 'en',
preload: ['en'],
keySeparator: false,
interpolation: { escapeValue: false },
})
export default i18next

34
src/i18n.tsx Normal file

@ -0,0 +1,34 @@
import React from 'react'
import { i18n } from '@lingui/core'
import { I18nProvider } from '@lingui/react'
import { detect, fromUrl } from '@lingui/detect-locale'
import { ReactNode, useEffect } from 'react'
export const locales = ['en', 'pseudo-en']
export const defaultLocale = 'en'
// load locale data for each supported language
locales.forEach((locale) => i18n.loadLocaleData(locale, { plurals: () => null }))
const getDetectedLocale = () => {
const detected =
detect(
fromUrl('lang'), // helps local development
defaultLocale
) ?? defaultLocale
return locales.includes(detected) ? detected : defaultLocale
}
export async function dynamicActivate(locale: string) {
const { messages } = await import(`@lingui/loader!./locales/${locale}/messages.po`)
i18n.load(locale, messages)
i18n.activate(locale)
}
export function LanguageProvider({ children }: { children: ReactNode }) {
useEffect(() => {
dynamicActivate(getDetectedLocale())
}, [])
return <I18nProvider i18n={i18n}>{children}</I18nProvider>
}

@ -8,7 +8,7 @@ import { Provider } from 'react-redux'
import { HashRouter } from 'react-router-dom'
import Blocklist from './components/Blocklist'
import { NetworkContextName } from './constants/misc'
import './i18n'
import { LanguageProvider } from './i18n'
import App from './pages/App'
import store from './state'
import * as serviceWorkerRegistration from './serviceWorkerRegistration'
@ -60,22 +60,24 @@ function Updaters() {
ReactDOM.render(
<StrictMode>
<FixedGlobalStyle />
<Web3ReactProvider getLibrary={getLibrary}>
<Web3ProviderNetwork getLibrary={getLibrary}>
<Blocklist>
<Provider store={store}>
<Updaters />
<ThemeProvider>
<ThemedGlobalStyle />
<HashRouter>
<App />
</HashRouter>
</ThemeProvider>
</Provider>
</Blocklist>
</Web3ProviderNetwork>
</Web3ReactProvider>
<LanguageProvider>
<FixedGlobalStyle />
<Web3ReactProvider getLibrary={getLibrary}>
<Web3ProviderNetwork getLibrary={getLibrary}>
<Blocklist>
<Provider store={store}>
<Updaters />
<ThemeProvider>
<ThemedGlobalStyle />
<HashRouter>
<App />
</HashRouter>
</ThemeProvider>
</Provider>
</Blocklist>
</Web3ProviderNetwork>
</Web3ReactProvider>
</LanguageProvider>
</StrictMode>,
document.getElementById('root')
)

769
src/locales/en/messages.po Normal file

@ -0,0 +1,769 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2021-05-26 13:04-0700\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: en\n"
#: src/pages/AddLiquidity/index.tsx:528
msgid "addLiquidity.labels.currentPrice"
msgstr "Current {0} Price:"
#: src/pages/AddLiquidity/index.tsx:574
msgid "addLiquidity.labels.selectLiquidityRange"
msgstr "Set Price Range"
#: src/pages/AddLiquidity/index.tsx:439
msgid "addLiquidity.labels.selectPair"
msgstr "Select pair"
#: src/pages/AddLiquidity/index.tsx:500
msgid "addLiquidity.labels.selectStartingPrice"
msgstr "Set Starting Price"
#: src/pages/AddLiquidity/index.tsx:484
msgid "addLiquidity.labels.selectedRange"
msgstr "Selected Range"
#: src/pages/RemoveLiquidity/index.tsx:368
msgid "buttons.confirm"
msgstr "Confirm"
#: src/pages/RemoveLiquidity/V3.tsx:257
msgid "buttons.remove"
msgstr "Remove"
#: src/components/Header/index.tsx:383
msgid "claim.buttons.claimUNI"
msgstr "Claim UNI"
#: src/components/Header/index.tsx:380
msgid "claim.buttons.claimingUNI"
msgstr "Claiming UNI"
#: src/components/SearchModal/ImportList.tsx:146
msgid "common.IUnderstand"
msgstr "I understand"
#: src/pages/AddLiquidity/index.tsx:443
msgid "common.clearAll"
msgstr "Clear All"
#: src/pages/RemoveLiquidity/index.tsx:475
msgid "common.detailed"
msgstr "Detailed"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:758
#: src/pages/PoolFinder/index.tsx:207
#: src/pages/Swap/index.tsx:535
msgid "common.loading"
msgstr "Loading"
#: src/pages/RemoveLiquidity/index.tsx:473
msgid "common.simple"
msgstr "Simple"
#: src/pages/Pool/CTACards.tsx:140
msgid "cta.topPools"
msgstr "Top pools"
#: src/pages/Pool/CTACards.tsx:143
msgid "cta.v3.explore"
msgstr "Explore popular pools on Uniswap Analytics."
#: src/pages/Pool/CTACards.tsx:126
msgid "cta.v3.launchAnnouncement"
msgstr "Uniswap V3 is here!"
#: src/pages/Pool/CTACards.tsx:129
msgid "cta.v3.walkthroughAndMigration"
msgstr "Check out our v3 LP walkthrough and migration guides."
#: src/components/PositionPreview/index.tsx:126
#: src/components/PositionPreview/index.tsx:145
#: src/components/PositionPreview/index.tsx:164
#: src/pages/Pool/PositionPage.tsx:173
#: src/pages/Pool/PositionPage.tsx:807
msgid "currencies.denominated"
msgstr "{0} per {1}"
#: src/components/CurrencyInputPanel/index.tsx:280
msgid "currencies.input.max"
msgstr "(Max)"
#: src/components/CurrencyInputPanel/index.tsx:202
msgid "currencies.input.priceOutsideWarning"
msgstr "The market price is outside your specified price range. Single-asset deposit only."
#: src/components/SearchModal/CurrencySearch.tsx:220
msgid "currencies.search.noResults"
msgstr "No results found."
#: src/components/SearchModal/CurrencySearch.tsx:182
msgid "currencies.search.placeholder"
msgstr "Search name or paste address"
#: src/components/CurrencyInputPanel/index.tsx:240
#: src/components/SearchModal/CurrencySearch.tsx:174
#: src/pages/PoolFinder/index.tsx:122
#: src/pages/PoolFinder/index.tsx:146
msgid "currencies.search.selectToken"
msgstr "Select a token"
#: src/components/Web3Status/index.tsx:208
msgid "error.generic"
msgstr "Error"
#: src/pages/AddLiquidity/index.tsx:654
msgid "error.invalidRangeWarning"
msgstr "Invalid range selected. The min price must be lower than the max price."
#: src/pages/AddLiquidity/index.tsx:708
msgid "error.unsupportedAsset"
msgstr "Unsupported Asset"
#: src/pages/Swap/index.tsx:514
msgid "error.unsupportedAssets"
msgstr "Unsupported Asset"
#: src/components/Web3Status/index.tsx:207
msgid "error.wrongNetwork"
msgstr "Wrong Network"
#: src/components/Web3ReactManager/index.tsx:61
msgid "errors.unknown"
msgstr "Oops! An unknown error occurred. Please refresh the page, or visit from another browser or device."
#: src/pages/AddLiquidity/index.tsx:640
msgid "inactiveRangeWarning"
msgstr "Your position will not earn fees or be used in trades until the market price moves into your range."
#: src/pages/RemoveLiquidity/V3.tsx:307
msgid "labels.amount"
msgstr "Amount"
#: src/pages/RemoveLiquidity/V3.tsx:413
msgid "labels.inactive"
msgstr "Inactive"
#: src/pages/RemoveLiquidity/V3.tsx:324
msgid "labels.max"
msgstr "Max"
#: src/pages/RemoveLiquidity/V3.tsx:415
msgid "labels.remove"
msgstr "Remove"
#: src/pages/AddLiquidity/index.tsx:672
msgid "liquidity.depositAmounts"
msgstr "Deposit Amounts"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:659
msgid "migrate.buttons.migrate"
msgstr "Migrate"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:656
msgid "migrate.buttons.migrating"
msgstr "Migrating"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:586
msgid "migrate.errors.invalidRangeWarning"
msgstr "Invalid range selected. The min price must be lower than the max price."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:458
msgid "migrate.hint.firstV3LPGasCost"
msgstr "Your transaction cost will be much higher as it includes the gas to create the pool."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:451
msgid "migrate.hint.firstV3LiquidityProvider"
msgstr "You are the first liquidity provider for this Uniswap V3 pool. Your liquidity will migrate at the current {0} price."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:404
msgid "migrate.hint.migrationContract"
msgstr "Uniswap migration contract↗"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:519
msgid "migrate.hint.priceHint"
msgstr "You should only deposit liquidity into Uniswap V3 at a price you believe is correct. <0/>If the price seems incorrect, you can either make a swap to move the price or wait for someone else to do so."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:397
msgid "migrate.hint.toolInformation"
msgstr "This tool will safely migrate your {0} liquidity to V3. The process is completely trustless thanks to the"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:573
msgid "migrate.hints.inactiveRangeWarning"
msgstr "Your position will not earn fees or be used in trades until the market price moves into your range."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:600
msgid "migrate.hints.priceRangeRefund"
msgstr "At least {0} {1} and {2} {3} will be refunded to your wallet due to selected price range."
#: src/pages/MigrateV2/MigrateV2Pair.tsx:438
msgid "migrate.label.lpNFTToken"
msgstr "{0}/{1} LP NFT"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:417
msgid "migrate.label.lpToken"
msgstr "{0}/{1} LP Tokens"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:738
msgid "migrate.labels.migrateV2Liquidity"
msgstr "Migrate V2 Liquidity"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:467
#: src/pages/MigrateV2/MigrateV2Pair.tsx:485
msgid "migrate.labels.price"
msgstr "{0} {1} Price:"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:511
msgid "migrate.labels.priceDifference"
msgstr "Price Difference:"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:541
msgid "migrate.labels.selectLiquidityRange"
msgstr "Set Price Range"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:498
#: src/pages/MigrateV2/MigrateV2Pair.tsx:529
msgid "migrate.labels.v3Price"
msgstr "V3 {0} Price:"
#: src/pages/Pool/PositionPage.tsx:814
msgid "minMaxPriceHint"
msgstr "Your position will be 100% {0} at this price."
#: src/components/Header/index.tsx:362
msgid "nav.charts"
msgstr "Charts <0>↗</0>"
#: src/components/NavigationTabs/index.tsx:83
msgid "nav.importPool"
msgstr "Import Pool"
#: src/components/Header/index.tsx:356
#: src/components/NavigationTabs/index.tsx:69
msgid "nav.pool"
msgstr "Pool"
#: src/components/Header/index.tsx:343
#: src/components/NavigationTabs/index.tsx:66
msgid "nav.swap"
msgstr "Swap"
#: src/components/Header/index.tsx:359
msgid "nav.vote"
msgstr "Vote"
#: src/pages/RemoveLiquidity/V3.tsx:315
msgid "number.25Percent"
msgstr "25%"
#: src/pages/RemoveLiquidity/V3.tsx:318
msgid "number.50Percent"
msgstr "50%"
#: src/pages/RemoveLiquidity/V3.tsx:321
msgid "number.75Percent"
msgstr "75%"
#: src/pages/Pool/PositionPage.tsx:666
msgid "numbers.emptyFiatValue"
msgstr "$-"
#: src/pages/Pool/PositionPage.tsx:612
msgid "numbers.emptyValueInFiat"
msgstr "$-"
#: src/pages/Pool/PositionPage.tsx:662
msgid "numbers.fiatValue"
msgstr "${0}"
#: src/pages/Pool/PositionPage.tsx:606
msgid "numbers.valueInFiat"
msgstr "${0}"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:514
#: src/pages/Pool/PositionPage.tsx:528
#: src/pages/Pool/PositionPage.tsx:627
#: src/pages/Pool/PositionPage.tsx:642
msgid "numbers.valueWithPercent"
msgstr "{0}%"
#: src/pages/Pool/PositionPage.tsx:506
msgid "pool.label.claimFees"
msgstr "Claim fees"
#: src/pages/Pool/PositionPage.tsx:511
msgid "pool.label.collectingFees"
msgstr "Collecting fees"
#: src/pages/RemoveLiquidity/V3.tsx:205
#: src/pages/RemoveLiquidity/V3.tsx:216
#: src/pages/RemoveLiquidity/V3.tsx:335
#: src/pages/RemoveLiquidity/V3.tsx:346
msgid "pool.pooledCurrency"
msgstr "Pooled {0}:"
#: src/components/PositionList/index.tsx:50
#: src/pages/Pool/PositionPage.tsx:759
msgid "pool.priceRange"
msgstr "Price range"
#: src/components/PositionList/index.tsx:46
#: src/components/PositionList/index.tsx:54
msgid "pool.yourPositions"
msgstr "Your positions"
#: src/pages/Pool/PositionPage.tsx:517
msgid "pools.button.backToPoolsOverview"
msgstr "← Back to Pools Overview"
#: src/components/NavigationTabs/index.tsx:125
msgid "pools.buttons.addLiquidity"
msgstr "Add Liquidity"
#: src/pages/PoolFinder/index.tsx:178
msgid "pools.buttons.addLiquidityPoolFinder"
msgstr "Add liquidity."
#: src/pages/Pool/PositionPage.tsx:476
msgid "pools.buttons.collect"
msgstr "Collect"
#: src/components/NavigationTabs/index.tsx:123
msgid "pools.buttons.createPair"
msgstr "Create a pair"
#: src/pages/PoolFinder/index.tsx:191
msgid "pools.buttons.createPool"
msgstr "Create pool."
#: src/pages/Pool/PositionPage.tsx:544
msgid "pools.buttons.increaseLiquidity"
msgstr "Increase Liquidity"
#: src/pages/PoolFinder/index.tsx:160
msgid "pools.buttons.manage"
msgstr "Manage this pool."
#: src/pages/Pool/index.tsx:291
msgid "pools.buttons.migrateLiquidity"
msgstr "Migrate Liquidity"
#: src/pages/Pool/index.tsx:252
msgid "pools.buttons.migrateV2Liquidity"
msgstr "Migrate V2 liquidity"
#: src/pages/Pool/index.tsx:196
msgid "pools.buttons.newPosition"
msgstr "New Position"
#: src/pages/Pool/PositionPage.tsx:581
msgid "pools.buttons.owner"
msgstr "Owner"
#: src/components/NavigationTabs/index.tsx:127
#: src/pages/Pool/PositionPage.tsx:555
msgid "pools.buttons.removeLiquidity"
msgstr "Remove Liquidity"
#: src/pages/Pool/index.tsx:274
msgid "pools.buttons.viewV2Liquidity"
msgstr "View V2 Liquidity"
#: src/components/PositionPreview/index.tsx:160
#: src/pages/Pool/PositionPage.tsx:167
msgid "pools.currentPrice"
msgstr "Current price"
#: src/pages/Pool/index.tsx:238
msgid "pools.emptyStateHint"
msgstr "Your V3 liquidity positions will appear here."
#: src/pages/PoolFinder/index.tsx:188
msgid "pools.error.noPoolFound"
msgstr "No pool found."
#: src/pages/PoolFinder/index.tsx:199
msgid "pools.errors.invalidPair"
msgstr "Invalid pair."
#: src/components/FeeSelector/index.tsx:67
msgid "pools.feeSelector.highFee"
msgstr "1% fee"
#: src/components/FeeSelector/index.tsx:69
msgid "pools.feeSelector.highFeeHint"
msgstr "Best for exotic pairs."
#: src/components/FeeSelector/index.tsx:43
msgid "pools.feeSelector.lowFee"
msgstr "0.05% fee"
#: src/components/FeeSelector/index.tsx:45
msgid "pools.feeSelector.lowFeeHint"
msgstr "Best for stable pairs."
#: src/components/FeeSelector/index.tsx:55
msgid "pools.feeSelector.mediumFee"
msgstr "0.3% fee"
#: src/components/FeeSelector/index.tsx:57
msgid "pools.feeSelector.mediumFeeHint"
msgstr "Best for most pairs."
#: src/components/FeeSelector/index.tsx:31
msgid "pools.feeSelector.subtitle"
msgstr "Select a pool type based on your preferred liquidity provider fee."
#: src/components/FeeSelector/index.tsx:29
msgid "pools.feeSelector.title"
msgstr "Select Pool"
#: src/pages/Pool/index.tsx:179
msgid "pools.heading.poolsOverview"
msgstr "Pools Overview"
#: src/pages/Pool/PositionPage.tsx:473
msgid "pools.hint.collectingFees"
msgstr "Collecting fees will withdraw currently available fees for you."
#: src/pages/PoolFinder/index.tsx:101
msgid "pools.hint.toolHelperText"
msgstr "<0>Tip:</0> Use this tool to find pairs that don't automatically appear in the interface."
#: src/pages/PoolFinder/index.tsx:86
msgid "pools.label.connectWalletToFindPools"
msgstr "Connect to a wallet to find pools"
#: src/pages/PoolFinder/index.tsx:174
msgid "pools.label.noLiquidityInPoolYet"
msgstr "You dont have liquidity in this pool yet."
#: src/pages/Pool/PositionPage.tsx:693
msgid "pools.labels.collectFees"
msgstr "Collect fees"
#: src/pages/Pool/PositionPage.tsx:740
#: src/pages/RemoveLiquidity/V3.tsx:395
msgid "pools.labels.collectFeesAsWETH"
msgstr "Collect as WETH"
#: src/pages/Pool/PositionPage.tsx:681
msgid "pools.labels.collectedFees"
msgstr "Collected"
#: src/pages/Pool/PositionPage.tsx:687
msgid "pools.labels.collectingFees"
msgstr "Collecting"
#: src/components/PositionPreview/index.tsx:99
msgid "pools.labels.feeTier"
msgstr "Fee Tier"
#: src/components/PositionPreview/index.tsx:102
msgid "pools.labels.feeTierValue"
msgstr "{0}%"
#: src/components/Badge/RangeBadge.tsx:70
msgid "pools.labels.inRange"
msgstr "In range"
#: src/components/Badge/RangeBadge.tsx:62
msgid "pools.labels.inRangeTooltip"
msgstr "The price of this pool is within your selected range. Your position is currently earning fees."
#: src/components/Badge/RangeBadge.tsx:56
msgid "pools.labels.inactive"
msgstr "Inactive"
#: src/components/Badge/RangeBadge.tsx:47
msgid "pools.labels.inactiveTooltip"
msgstr "Your position has 0 liquidity, and is not earning fees."
#: src/pages/Pool/PositionPage.tsx:602
msgid "pools.labels.liquidity"
msgstr "Liquidity"
#: src/components/Badge/RangeBadge.tsx:86
msgid "pools.labels.outOfRange"
msgstr "Out of range"
#: src/components/Badge/RangeBadge.tsx:76
msgid "pools.labels.outOfRangeTooltip"
msgstr "The price of this pool is outside of your selected range. Your position is not currently earning fees."
#: src/pages/PoolFinder/index.tsx:156
msgid "pools.labels.poolFound"
msgstr "Pool Found!"
#: src/pages/PoolFinder/index.tsx:88
msgid "pools.labels.selectTokenToFindLiquidity"
msgstr "Select a token to find your liquidity."
#: src/pages/Pool/PositionPage.tsx:658
msgid "pools.labels.unclaimedFees"
msgstr "Unclaimed fees"
#: src/components/PositionPreview/index.tsx:141
msgid "pools.maxPrice"
msgstr "Max Price"
#: src/pages/Pool/PositionPage.tsx:802
msgid "pools.maxPriceLabel"
msgstr "Max price"
#: src/pages/Pool/index.tsx:132
msgid "pools.menu.create"
msgstr "Create a pool"
#: src/pages/Pool/index.tsx:162
msgid "pools.menu.learn"
msgstr "Learn"
#: src/pages/Pool/index.tsx:142
msgid "pools.menu.migrate"
msgstr "Migrate"
#: src/pages/Pool/index.tsx:189
msgid "pools.menu.more"
msgstr "More"
#: src/pages/Pool/index.tsx:152
msgid "pools.menu.v2Liquidity"
msgstr "V2 liquidity"
#: src/components/PositionPreview/index.tsx:131
#: src/components/PositionPreview/index.tsx:150
#: src/pages/Pool/PositionPage.tsx:790
msgid "pools.minMaxPriceHint"
msgstr "Your position will be 100% {0} at this price."
#: src/components/PositionPreview/index.tsx:122
#: src/pages/Pool/PositionPage.tsx:783
msgid "pools.minPriceLabel"
msgstr "Min price"
#: src/pages/Pool/index.tsx:206
msgid "pools.toggle.hideClosedPositions"
msgstr "Hide closed positions"
#: src/pages/RemoveLiquidity/index.tsx:464
msgid "removeLiquidity.buttons.RemoveAmount"
msgstr "Remove Amount"
#: src/pages/RemoveLiquidity/index.tsx:652
msgid "removeLiquidity.buttons.remove"
msgstr "Remove"
#: src/pages/RemoveLiquidity/V3.tsx:193
#: src/pages/RemoveLiquidity/index.tsx:375
msgid "removeLiquidity.confirming.pending"
msgstr "Removing {0} {1} and {2} {3}"
#: src/pages/RemoveLiquidity/index.tsx:323
msgid "removeLiquidity.hint.outputEstimated"
msgstr "Output is estimated. If the price changes by more than {0}% your transaction will revert."
#: src/pages/RemoveLiquidity/V3.tsx:228
msgid "removeLiquidity.hints.collectFeesEarn"
msgstr "You will also collect fees earned from this position."
#: src/pages/RemoveLiquidity/index.tsx:453
msgid "removeLiquidity.hints.removingPoolTokensConvertsPosition"
msgstr "<0>Tip:</0> Removing pool tokens converts your position back into underlying tokens at the current rate, proportional to your share of the pool. Accrued fees are included in the amounts you receive."
#: src/pages/RemoveLiquidity/V3.tsx:234
#: src/pages/RemoveLiquidity/V3.tsx:245
#: src/pages/RemoveLiquidity/V3.tsx:360
msgid "removeLiquidity.label.feesEarned"
msgstr "{0} Fees Earned:"
#: src/pages/RemoveLiquidity/index.tsx:337
msgid "removeLiquidity.labels.UNIBurned"
msgstr "UNI {0}/{1} Burned"
#: src/pages/RemoveLiquidity/index.tsx:441
msgid "removeLiquidity.labels.confirmationTitle"
msgstr "You will receive"
#: src/pages/RemoveLiquidity/index.tsx:352
msgid "removeLiquidity.labels.modalPrice"
msgstr "Price"
#: src/pages/RemoveLiquidity/V3.tsx:311
msgid "removeLiquidity.labels.percentForSlider"
msgstr "{percentForSlider}%"
#: src/pages/RemoveLiquidity/index.tsx:606
msgid "removeLiquidity.labels.price"
msgstr "Price:"
#: src/pages/RemoveLiquidity/V3.tsx:272
msgid "removeLiquidity.labels.removeLiquidity"
msgstr "Remove Liquidity"
#: src/pages/Swap/index.tsx:575
msgid "swap.buttons.allowUniswapToUseCurrency"
msgstr "Allow the Uniswap Protocol to use your {0}"
#: src/pages/Swap/index.tsx:467
msgid "swap.buttons.backToV3"
msgstr "<0>Back to</0>V3"
#: src/pages/Swap/index.tsx:624
msgid "swap.buttons.highPriceImpact"
msgstr "High Price Impact"
#: src/pages/Swap/index.tsx:657
msgid "swap.buttons.priceImpactTooHigh"
msgstr "Price Impact Too High"
#: src/pages/Swap/index.tsx:628
#: src/pages/Swap/index.tsx:661
msgid "swap.buttons.swap"
msgstr "Swap"
#: src/pages/Swap/index.tsx:626
#: src/pages/Swap/index.tsx:659
msgid "swap.buttons.swapAnyway"
msgstr "Swap Anyway"
#: src/pages/Swap/index.tsx:571
msgid "swap.buttons.tradeCurrency"
msgstr "You can now trade {0}"
#: src/pages/Swap/index.tsx:527
msgid "swap.buttons.unwrap"
msgstr "Unwrap"
#: src/pages/Swap/index.tsx:525
msgid "swap.buttons.wrap"
msgstr "Wrap"
#: src/pages/Swap/index.tsx:587
msgid "swap.hints.permission"
msgstr "You must give the Uniswap smart contracts permission to use your {0}. You only have to do this once per token."
#: src/pages/Swap/index.tsx:383
msgid "swap.labels.from"
msgstr "From"
#: src/pages/Swap/index.tsx:382
msgid "swap.labels.fromAtMost"
msgstr "From (at most)"
#: src/pages/Swap/index.tsx:542
msgid "swap.labels.insufficientLiquidity"
msgstr "Insufficient liquidity for this trade."
#: src/pages/Swap/index.tsx:538
msgid "swap.labels.insufficientLiquiditySingleHopOnly"
msgstr "Insufficient liquidity for this trade. Try enabling multi-hop trades."
#: src/pages/Swap/index.tsx:433
msgid "swap.labels.removeSend"
msgstr "- Remove send"
#: src/pages/Swap/index.tsx:412
msgid "swap.labels.to"
msgstr "To"
#: src/pages/Swap/index.tsx:411
msgid "swap.labels.toAtLeast"
msgstr "To (at least)"
#: src/components/SearchModal/ImportList.tsx:158
msgid "tokenLists.buttons.import"
msgstr "Import"
#: src/components/SearchModal/ImportList.tsx:126
msgid "tokenLists.importHint1"
msgstr "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
#: src/components/SearchModal/ImportList.tsx:133
msgid "tokenLists.importHint2"
msgstr "If you purchase a token from this list, you may not be able to sell it back."
#: src/components/SearchModal/ImportList.tsx:85
msgid "tokenLists.importList"
msgstr "Import List"
#: src/components/SearchModal/ImportList.tsx:120
msgid "tokenLists.importWarning"
msgstr "Import at your own risk"
#: src/components/SearchModal/CurrencySearch.tsx:232
msgid "tokenLists.manage"
msgstr "Manage Token Lists"
#: src/components/SearchModal/ImportList.tsx:104
msgid "tokensLists.numberOfTokens"
msgstr "{0} tokens"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:633
msgid "transactions.allowLPTokenMigration"
msgstr "Allow LP token migration"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:631
msgid "transactions.allower"
msgstr "Allowed"
#: src/pages/RemoveLiquidity/index.tsx:641
msgid "transactions.approve"
msgstr "Approve"
#: src/pages/RemoveLiquidity/index.tsx:639
msgid "transactions.approved"
msgstr "Approved"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:628
#: src/pages/RemoveLiquidity/index.tsx:636
msgid "transactions.approving"
msgstr "Approving"
#: src/pages/AddLiquidity/index.tsx:417
msgid "transactions.confirmation.button"
msgstr "Add"
#: src/components/Web3Status/index.tsx:188
msgid "transactions.pending"
msgstr "{0} Pending"
#: src/pages/AddLiquidity/index.tsx:266
msgid "transactions.summary.addLiquidity"
msgstr "Add {0}/{1} V3 liquidity"
#: src/pages/AddLiquidity/index.tsx:262
msgid "transactions.summary.createPoolAndAddLiquidity"
msgstr "Create pool and add {0}/{1} V3 liquidity"
#: src/pages/RemoveLiquidity/index.tsx:269
#: src/pages/RemoveLiquidity/index.tsx:269
msgid "transactions.summary.removeLiquidity"
msgstr "Remove {0} {1} and {2} {3}"
#: src/pages/RemoveLiquidity/V3.tsx:155
msgid "transactions.summary.removeLiquidityV3"
msgstr "Remove {0}/{1} V3 liquidity"
#: src/pages/AddLiquidity/index.tsx:713
#: src/pages/Pool/index.tsx:243
#: src/pages/RemoveLiquidity/index.tsx:622
#: src/pages/Swap/index.tsx:519
msgid "wallet.connect"
msgstr "Connect Wallet"
#: src/components/Web3Status/index.tsx:216
msgid "wallet.connectLongForm"
msgstr "Connect to a wallet"
#: src/components/Header/index.tsx:393
msgid "wallet.ethBalance"
msgstr "{0} ETH"
#: src/pages/MigrateV2/MigrateV2Pair.tsx:745
msgid "wallet.mustConnectAccount"
msgstr "You must connect an account."

@ -0,0 +1,769 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2021-05-26 13:04-0700\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: pseudo-en\n"
#: src/pages/AddLiquidity/index.tsx:528
msgid "addLiquidity.labels.currentPrice"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:574
msgid "addLiquidity.labels.selectLiquidityRange"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:439
msgid "addLiquidity.labels.selectPair"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:500
msgid "addLiquidity.labels.selectStartingPrice"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:484
msgid "addLiquidity.labels.selectedRange"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:368
msgid "buttons.confirm"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:257
msgid "buttons.remove"
msgstr ""
#: src/components/Header/index.tsx:383
msgid "claim.buttons.claimUNI"
msgstr ""
#: src/components/Header/index.tsx:380
msgid "claim.buttons.claimingUNI"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:146
msgid "common.IUnderstand"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:443
msgid "common.clearAll"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:475
msgid "common.detailed"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:758
#: src/pages/PoolFinder/index.tsx:207
#: src/pages/Swap/index.tsx:535
msgid "common.loading"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:473
msgid "common.simple"
msgstr ""
#: src/pages/Pool/CTACards.tsx:140
msgid "cta.topPools"
msgstr ""
#: src/pages/Pool/CTACards.tsx:143
msgid "cta.v3.explore"
msgstr ""
#: src/pages/Pool/CTACards.tsx:126
msgid "cta.v3.launchAnnouncement"
msgstr ""
#: src/pages/Pool/CTACards.tsx:129
msgid "cta.v3.walkthroughAndMigration"
msgstr ""
#: src/components/PositionPreview/index.tsx:126
#: src/components/PositionPreview/index.tsx:145
#: src/components/PositionPreview/index.tsx:164
#: src/pages/Pool/PositionPage.tsx:173
#: src/pages/Pool/PositionPage.tsx:807
msgid "currencies.denominated"
msgstr ""
#: src/components/CurrencyInputPanel/index.tsx:280
msgid "currencies.input.max"
msgstr ""
#: src/components/CurrencyInputPanel/index.tsx:202
msgid "currencies.input.priceOutsideWarning"
msgstr ""
#: src/components/SearchModal/CurrencySearch.tsx:220
msgid "currencies.search.noResults"
msgstr ""
#: src/components/SearchModal/CurrencySearch.tsx:182
msgid "currencies.search.placeholder"
msgstr ""
#: src/components/CurrencyInputPanel/index.tsx:240
#: src/components/SearchModal/CurrencySearch.tsx:174
#: src/pages/PoolFinder/index.tsx:122
#: src/pages/PoolFinder/index.tsx:146
msgid "currencies.search.selectToken"
msgstr ""
#: src/components/Web3Status/index.tsx:208
msgid "error.generic"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:654
msgid "error.invalidRangeWarning"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:708
msgid "error.unsupportedAsset"
msgstr ""
#: src/pages/Swap/index.tsx:514
msgid "error.unsupportedAssets"
msgstr ""
#: src/components/Web3Status/index.tsx:207
msgid "error.wrongNetwork"
msgstr ""
#: src/components/Web3ReactManager/index.tsx:61
msgid "errors.unknown"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:640
msgid "inactiveRangeWarning"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:307
msgid "labels.amount"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:413
msgid "labels.inactive"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:324
msgid "labels.max"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:415
msgid "labels.remove"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:672
msgid "liquidity.depositAmounts"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:659
msgid "migrate.buttons.migrate"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:656
msgid "migrate.buttons.migrating"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:586
msgid "migrate.errors.invalidRangeWarning"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:458
msgid "migrate.hint.firstV3LPGasCost"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:451
msgid "migrate.hint.firstV3LiquidityProvider"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:404
msgid "migrate.hint.migrationContract"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:519
msgid "migrate.hint.priceHint"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:397
msgid "migrate.hint.toolInformation"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:573
msgid "migrate.hints.inactiveRangeWarning"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:600
msgid "migrate.hints.priceRangeRefund"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:438
msgid "migrate.label.lpNFTToken"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:417
msgid "migrate.label.lpToken"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:738
msgid "migrate.labels.migrateV2Liquidity"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:467
#: src/pages/MigrateV2/MigrateV2Pair.tsx:485
msgid "migrate.labels.price"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:511
msgid "migrate.labels.priceDifference"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:541
msgid "migrate.labels.selectLiquidityRange"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:498
#: src/pages/MigrateV2/MigrateV2Pair.tsx:529
msgid "migrate.labels.v3Price"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:814
msgid "minMaxPriceHint"
msgstr ""
#: src/components/Header/index.tsx:362
msgid "nav.charts"
msgstr ""
#: src/components/NavigationTabs/index.tsx:83
msgid "nav.importPool"
msgstr ""
#: src/components/Header/index.tsx:356
#: src/components/NavigationTabs/index.tsx:69
msgid "nav.pool"
msgstr ""
#: src/components/Header/index.tsx:343
#: src/components/NavigationTabs/index.tsx:66
msgid "nav.swap"
msgstr ""
#: src/components/Header/index.tsx:359
msgid "nav.vote"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:315
msgid "number.25Percent"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:318
msgid "number.50Percent"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:321
msgid "number.75Percent"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:666
msgid "numbers.emptyFiatValue"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:612
msgid "numbers.emptyValueInFiat"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:662
msgid "numbers.fiatValue"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:606
msgid "numbers.valueInFiat"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:514
#: src/pages/Pool/PositionPage.tsx:528
#: src/pages/Pool/PositionPage.tsx:627
#: src/pages/Pool/PositionPage.tsx:642
msgid "numbers.valueWithPercent"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:506
msgid "pool.label.claimFees"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:511
msgid "pool.label.collectingFees"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:205
#: src/pages/RemoveLiquidity/V3.tsx:216
#: src/pages/RemoveLiquidity/V3.tsx:335
#: src/pages/RemoveLiquidity/V3.tsx:346
msgid "pool.pooledCurrency"
msgstr ""
#: src/components/PositionList/index.tsx:50
#: src/pages/Pool/PositionPage.tsx:759
msgid "pool.priceRange"
msgstr ""
#: src/components/PositionList/index.tsx:46
#: src/components/PositionList/index.tsx:54
msgid "pool.yourPositions"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:517
msgid "pools.button.backToPoolsOverview"
msgstr ""
#: src/components/NavigationTabs/index.tsx:125
msgid "pools.buttons.addLiquidity"
msgstr ""
#: src/pages/PoolFinder/index.tsx:178
msgid "pools.buttons.addLiquidityPoolFinder"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:476
msgid "pools.buttons.collect"
msgstr ""
#: src/components/NavigationTabs/index.tsx:123
msgid "pools.buttons.createPair"
msgstr ""
#: src/pages/PoolFinder/index.tsx:191
msgid "pools.buttons.createPool"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:544
msgid "pools.buttons.increaseLiquidity"
msgstr ""
#: src/pages/PoolFinder/index.tsx:160
msgid "pools.buttons.manage"
msgstr ""
#: src/pages/Pool/index.tsx:291
msgid "pools.buttons.migrateLiquidity"
msgstr ""
#: src/pages/Pool/index.tsx:252
msgid "pools.buttons.migrateV2Liquidity"
msgstr ""
#: src/pages/Pool/index.tsx:196
msgid "pools.buttons.newPosition"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:581
msgid "pools.buttons.owner"
msgstr ""
#: src/components/NavigationTabs/index.tsx:127
#: src/pages/Pool/PositionPage.tsx:555
msgid "pools.buttons.removeLiquidity"
msgstr ""
#: src/pages/Pool/index.tsx:274
msgid "pools.buttons.viewV2Liquidity"
msgstr ""
#: src/components/PositionPreview/index.tsx:160
#: src/pages/Pool/PositionPage.tsx:167
msgid "pools.currentPrice"
msgstr ""
#: src/pages/Pool/index.tsx:238
msgid "pools.emptyStateHint"
msgstr ""
#: src/pages/PoolFinder/index.tsx:188
msgid "pools.error.noPoolFound"
msgstr ""
#: src/pages/PoolFinder/index.tsx:199
msgid "pools.errors.invalidPair"
msgstr ""
#: src/components/FeeSelector/index.tsx:67
msgid "pools.feeSelector.highFee"
msgstr ""
#: src/components/FeeSelector/index.tsx:69
msgid "pools.feeSelector.highFeeHint"
msgstr ""
#: src/components/FeeSelector/index.tsx:43
msgid "pools.feeSelector.lowFee"
msgstr ""
#: src/components/FeeSelector/index.tsx:45
msgid "pools.feeSelector.lowFeeHint"
msgstr ""
#: src/components/FeeSelector/index.tsx:55
msgid "pools.feeSelector.mediumFee"
msgstr ""
#: src/components/FeeSelector/index.tsx:57
msgid "pools.feeSelector.mediumFeeHint"
msgstr ""
#: src/components/FeeSelector/index.tsx:31
msgid "pools.feeSelector.subtitle"
msgstr ""
#: src/components/FeeSelector/index.tsx:29
msgid "pools.feeSelector.title"
msgstr ""
#: src/pages/Pool/index.tsx:179
msgid "pools.heading.poolsOverview"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:473
msgid "pools.hint.collectingFees"
msgstr ""
#: src/pages/PoolFinder/index.tsx:101
msgid "pools.hint.toolHelperText"
msgstr ""
#: src/pages/PoolFinder/index.tsx:86
msgid "pools.label.connectWalletToFindPools"
msgstr ""
#: src/pages/PoolFinder/index.tsx:174
msgid "pools.label.noLiquidityInPoolYet"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:693
msgid "pools.labels.collectFees"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:740
#: src/pages/RemoveLiquidity/V3.tsx:395
msgid "pools.labels.collectFeesAsWETH"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:681
msgid "pools.labels.collectedFees"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:687
msgid "pools.labels.collectingFees"
msgstr ""
#: src/components/PositionPreview/index.tsx:99
msgid "pools.labels.feeTier"
msgstr ""
#: src/components/PositionPreview/index.tsx:102
msgid "pools.labels.feeTierValue"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:70
msgid "pools.labels.inRange"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:62
msgid "pools.labels.inRangeTooltip"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:56
msgid "pools.labels.inactive"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:47
msgid "pools.labels.inactiveTooltip"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:602
msgid "pools.labels.liquidity"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:86
msgid "pools.labels.outOfRange"
msgstr ""
#: src/components/Badge/RangeBadge.tsx:76
msgid "pools.labels.outOfRangeTooltip"
msgstr ""
#: src/pages/PoolFinder/index.tsx:156
msgid "pools.labels.poolFound"
msgstr ""
#: src/pages/PoolFinder/index.tsx:88
msgid "pools.labels.selectTokenToFindLiquidity"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:658
msgid "pools.labels.unclaimedFees"
msgstr ""
#: src/components/PositionPreview/index.tsx:141
msgid "pools.maxPrice"
msgstr ""
#: src/pages/Pool/PositionPage.tsx:802
msgid "pools.maxPriceLabel"
msgstr ""
#: src/pages/Pool/index.tsx:132
msgid "pools.menu.create"
msgstr ""
#: src/pages/Pool/index.tsx:162
msgid "pools.menu.learn"
msgstr ""
#: src/pages/Pool/index.tsx:142
msgid "pools.menu.migrate"
msgstr ""
#: src/pages/Pool/index.tsx:189
msgid "pools.menu.more"
msgstr ""
#: src/pages/Pool/index.tsx:152
msgid "pools.menu.v2Liquidity"
msgstr ""
#: src/components/PositionPreview/index.tsx:131
#: src/components/PositionPreview/index.tsx:150
#: src/pages/Pool/PositionPage.tsx:790
msgid "pools.minMaxPriceHint"
msgstr ""
#: src/components/PositionPreview/index.tsx:122
#: src/pages/Pool/PositionPage.tsx:783
msgid "pools.minPriceLabel"
msgstr ""
#: src/pages/Pool/index.tsx:206
msgid "pools.toggle.hideClosedPositions"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:464
msgid "removeLiquidity.buttons.RemoveAmount"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:652
msgid "removeLiquidity.buttons.remove"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:193
#: src/pages/RemoveLiquidity/index.tsx:375
msgid "removeLiquidity.confirming.pending"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:323
msgid "removeLiquidity.hint.outputEstimated"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:228
msgid "removeLiquidity.hints.collectFeesEarn"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:453
msgid "removeLiquidity.hints.removingPoolTokensConvertsPosition"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:234
#: src/pages/RemoveLiquidity/V3.tsx:245
#: src/pages/RemoveLiquidity/V3.tsx:360
msgid "removeLiquidity.label.feesEarned"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:337
msgid "removeLiquidity.labels.UNIBurned"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:441
msgid "removeLiquidity.labels.confirmationTitle"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:352
msgid "removeLiquidity.labels.modalPrice"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:311
msgid "removeLiquidity.labels.percentForSlider"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:606
msgid "removeLiquidity.labels.price"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:272
msgid "removeLiquidity.labels.removeLiquidity"
msgstr ""
#: src/pages/Swap/index.tsx:575
msgid "swap.buttons.allowUniswapToUseCurrency"
msgstr ""
#: src/pages/Swap/index.tsx:467
msgid "swap.buttons.backToV3"
msgstr ""
#: src/pages/Swap/index.tsx:624
msgid "swap.buttons.highPriceImpact"
msgstr ""
#: src/pages/Swap/index.tsx:657
msgid "swap.buttons.priceImpactTooHigh"
msgstr ""
#: src/pages/Swap/index.tsx:628
#: src/pages/Swap/index.tsx:661
msgid "swap.buttons.swap"
msgstr ""
#: src/pages/Swap/index.tsx:626
#: src/pages/Swap/index.tsx:659
msgid "swap.buttons.swapAnyway"
msgstr ""
#: src/pages/Swap/index.tsx:571
msgid "swap.buttons.tradeCurrency"
msgstr ""
#: src/pages/Swap/index.tsx:527
msgid "swap.buttons.unwrap"
msgstr ""
#: src/pages/Swap/index.tsx:525
msgid "swap.buttons.wrap"
msgstr ""
#: src/pages/Swap/index.tsx:587
msgid "swap.hints.permission"
msgstr ""
#: src/pages/Swap/index.tsx:383
msgid "swap.labels.from"
msgstr ""
#: src/pages/Swap/index.tsx:382
msgid "swap.labels.fromAtMost"
msgstr ""
#: src/pages/Swap/index.tsx:542
msgid "swap.labels.insufficientLiquidity"
msgstr ""
#: src/pages/Swap/index.tsx:538
msgid "swap.labels.insufficientLiquiditySingleHopOnly"
msgstr ""
#: src/pages/Swap/index.tsx:433
msgid "swap.labels.removeSend"
msgstr ""
#: src/pages/Swap/index.tsx:412
msgid "swap.labels.to"
msgstr ""
#: src/pages/Swap/index.tsx:411
msgid "swap.labels.toAtLeast"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:158
msgid "tokenLists.buttons.import"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:126
msgid "tokenLists.importHint1"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:133
msgid "tokenLists.importHint2"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:85
msgid "tokenLists.importList"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:120
msgid "tokenLists.importWarning"
msgstr ""
#: src/components/SearchModal/CurrencySearch.tsx:232
msgid "tokenLists.manage"
msgstr ""
#: src/components/SearchModal/ImportList.tsx:104
msgid "tokensLists.numberOfTokens"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:633
msgid "transactions.allowLPTokenMigration"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:631
msgid "transactions.allower"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:641
msgid "transactions.approve"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:639
msgid "transactions.approved"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:628
#: src/pages/RemoveLiquidity/index.tsx:636
msgid "transactions.approving"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:417
msgid "transactions.confirmation.button"
msgstr ""
#: src/components/Web3Status/index.tsx:188
msgid "transactions.pending"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:266
msgid "transactions.summary.addLiquidity"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:262
msgid "transactions.summary.createPoolAndAddLiquidity"
msgstr ""
#: src/pages/RemoveLiquidity/index.tsx:269
#: src/pages/RemoveLiquidity/index.tsx:269
msgid "transactions.summary.removeLiquidity"
msgstr ""
#: src/pages/RemoveLiquidity/V3.tsx:155
msgid "transactions.summary.removeLiquidityV3"
msgstr ""
#: src/pages/AddLiquidity/index.tsx:713
#: src/pages/Pool/index.tsx:243
#: src/pages/RemoveLiquidity/index.tsx:622
#: src/pages/Swap/index.tsx:519
msgid "wallet.connect"
msgstr ""
#: src/components/Web3Status/index.tsx:216
msgid "wallet.connectLongForm"
msgstr ""
#: src/components/Header/index.tsx:393
msgid "wallet.ethBalance"
msgstr ""
#: src/pages/MigrateV2/MigrateV2Pair.tsx:745
msgid "wallet.mustConnectAccount"
msgstr ""

@ -38,7 +38,7 @@ import { Dots } from '../Pool/styleds'
import { currencyId } from '../../utils/currencyId'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import { DynamicSection, CurrencyDropdown, StyledInput, Wrapper, ScrollablePage } from './styled'
import { useTranslation } from 'react-i18next'
import { Trans, t } from '@lingui/macro'
import {
useV3MintState,
useV3MintActionHandlers,
@ -64,8 +64,6 @@ export default function AddLiquidity({
},
history,
}: RouteComponentProps<{ currencyIdA?: string; currencyIdB?: string; feeAmount?: string; tokenId?: string }>) {
const { t } = useTranslation()
const { account, chainId, library } = useActiveWeb3React()
const theme = useContext(ThemeContext)
const toggleWalletModal = useWalletModalToggle() // toggle wallet when disconnected
@ -261,8 +259,14 @@ export default function AddLiquidity({
setAttemptingTxn(false)
addTransaction(response, {
summary: noLiquidity
? `Create pool and add ${currencyA?.symbol}/${currencyB?.symbol} V3 liquidity`
: `Add ${currencyA?.symbol}/${currencyB?.symbol} V3 liquidity`,
? t({
id: 'transactions.summary.createPoolAndAddLiquidity',
message: `Create pool and add ${currencyA?.symbol}/${currencyB?.symbol} V3 liquidity`,
})
: t({
id: 'transactions.summary.addLiquidity',
message: `Add ${currencyA?.symbol}/${currencyB?.symbol} V3 liquidity`,
}),
})
setTxHash(response.hash)
ReactGA.event({
@ -410,7 +414,7 @@ export default function AddLiquidity({
bottomContent={() => (
<ButtonPrimary style={{ marginTop: '1rem' }} onClick={onAdd}>
<Text fontWeight={500} fontSize={20}>
Add
<Trans id="transactions.confirmation.button">Add</Trans>
</Text>
</ButtonPrimary>
)}
@ -431,9 +435,13 @@ export default function AddLiquidity({
<>
<AutoColumn gap="md">
<RowBetween paddingBottom="20px">
<TYPE.label>Select pair</TYPE.label>
<TYPE.label>
<Trans id="addLiquidity.labels.selectPair">Select pair</Trans>
</TYPE.label>
<ButtonText onClick={clearAll}>
<TYPE.blue fontSize="12px">Clear All</TYPE.blue>
<TYPE.blue fontSize="12px">
<Trans id="common.clearAll">Clear All</Trans>
</TYPE.blue>
</ButtonText>
</RowBetween>
<RowBetween>
@ -471,7 +479,11 @@ export default function AddLiquidity({
)}
{hasExistingPosition && existingPosition ? (
<PositionPreview position={existingPosition} title={'Selected Range'} inRange={!outOfRange} />
<PositionPreview
position={existingPosition}
title={t({ id: 'addLiquidity.labels.selectedRange', message: 'Selected Range' })}
inRange={!outOfRange}
/>
) : (
<>
<FeeSelector
@ -484,7 +496,9 @@ export default function AddLiquidity({
<DynamicSection disabled={!currencyA || !currencyB}>
<AutoColumn gap="md">
<RowBetween>
<TYPE.label>{t('selectStartingPrice')}</TYPE.label>
<TYPE.label>
<Trans id="addLiquidity.labels.selectStartingPrice">Set Starting Price</Trans>
</TYPE.label>
{baseCurrency && quoteCurrency ? (
<RateToggle
currencyA={baseCurrency}
@ -510,7 +524,9 @@ export default function AddLiquidity({
/>
</OutlineCard>
<RowBetween style={{ backgroundColor: theme.bg1, padding: '12px', borderRadius: '12px' }}>
<TYPE.main>Current {baseCurrency?.symbol} Price:</TYPE.main>
<TYPE.main>
<Trans id="addLiquidity.labels.currentPrice">Current {baseCurrency?.symbol} Price:</Trans>
</TYPE.main>
<TYPE.main>
{price ? (
<TYPE.main>
@ -554,7 +570,9 @@ export default function AddLiquidity({
<DynamicSection gap="md" disabled={!feeAmount || invalidPool || (noLiquidity && !startPriceTypedValue)}>
<RowBetween>
<TYPE.label>{t('selectLiquidityRange')}</TYPE.label>
<TYPE.label>
<Trans id="addLiquidity.labels.selectLiquidityRange">Set Price Range</Trans>
</TYPE.label>
{baseCurrency && quoteCurrency ? (
<RateToggle
@ -619,7 +637,10 @@ export default function AddLiquidity({
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
{t('inactiveRangeWarning')}
<Trans id="inactiveRangeWarning">
Your position will not earn fees or be used in trades until the market price moves into your
range.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
@ -630,7 +651,9 @@ export default function AddLiquidity({
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
{t('invalidRangeWarning')}
<Trans id="error.invalidRangeWarning">
Invalid range selected. The min price must be lower than the max price.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
@ -643,7 +666,11 @@ export default function AddLiquidity({
disabled={tickLower === undefined || tickUpper === undefined || invalidPool || invalidRange}
>
<AutoColumn gap="md">
<TYPE.label>{hasExistingPosition ? 'Add more liquidity' : t('depositAmounts')}</TYPE.label>
<TYPE.label>
{hasExistingPosition
? 'Add more liquidity'
: t({ id: 'liquidity.depositAmounts', message: 'Deposit Amounts' })}
</TYPE.label>
<CurrencyInputPanel
value={formattedAmounts[Field.CURRENCY_A]}
@ -677,11 +704,13 @@ export default function AddLiquidity({
<div>
{addIsUnsupported ? (
<ButtonPrimary disabled={true} borderRadius="12px" padding={'12px'}>
<TYPE.main mb="4px">{t('unsupportedAsset')}</TYPE.main>
<TYPE.main mb="4px">
<Trans id="error.unsupportedAsset">Unsupported Asset</Trans>
</TYPE.main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal} borderRadius="12px" padding={'12px'}>
{t('connectWallet')}
<Trans id="wallet.connect">Connect wallet</Trans>
</ButtonLight>
) : (
<AutoColumn gap={'md'}>

@ -34,7 +34,7 @@ import { TransactionResponse } from '@ethersproject/providers'
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
import { useV3DerivedMintInfo, useRangeHopCallbacks, useV3MintActionHandlers } from 'state/mint/v3/hooks'
import { Bound, resetMintState } from 'state/mint/v3/actions'
import { useTranslation } from 'react-i18next'
import { t, Trans } from '@lingui/macro'
import { AlertCircle, AlertTriangle, ArrowDown } from 'react-feather'
import FeeSelector from 'components/FeeSelector'
import RangeSelector from 'components/RangeSelector'
@ -121,7 +121,6 @@ function V2PairMigration({
token0: Token
token1: Token
}) {
const { t } = useTranslation()
const { chainId, account } = useActiveWeb3React()
const theme = useTheme()
@ -395,11 +394,15 @@ function V2PairMigration({
return (
<AutoColumn gap="20px">
<TYPE.body my={9} style={{ fontWeight: 400 }}>
This tool will safely migrate your {isNotUniswap ? 'SushiSwap' : 'V2'} liquidity to V3. The process is
completely trustless thanks to the{' '}
<Trans id="migrate.hint.toolInformation">
This tool will safely migrate your {isNotUniswap ? 'SushiSwap' : 'V2'} liquidity to V3. The process is
completely trustless thanks to the{' '}
</Trans>
{chainId && migrator && (
<ExternalLink href={getExplorerLink(chainId, migrator.address, ExplorerDataType.ADDRESS)}>
<TYPE.blue display="inline">Uniswap migration contract</TYPE.blue>
<TYPE.blue display="inline">
<Trans id="migrate.hint.migrationContract">Uniswap migration contract</Trans>
</TYPE.blue>
</ExternalLink>
)}
.
@ -411,7 +414,9 @@ function V2PairMigration({
<RowFixed style={{ marginLeft: '8px' }}>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={false} size={20} />
<TYPE.mediumHeader style={{ marginLeft: '8px' }}>
{currency0.symbol}/{currency1.symbol} LP Tokens
<Trans id="migrate.label.lpToken">
{currency0.symbol}/{currency1.symbol} LP Tokens
</Trans>
</TYPE.mediumHeader>
</RowFixed>
<Badge variant={BadgeVariant.WARNING}>{isNotUniswap ? 'Sushi' : 'V2'}</Badge>
@ -430,7 +435,9 @@ function V2PairMigration({
<RowFixed style={{ marginLeft: '8px' }}>
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={false} size={20} />
<TYPE.mediumHeader style={{ marginLeft: '8px' }}>
{currency0.symbol}/{currency1.symbol} LP NFT
<Trans id="migrate.label.lpNFTToken">
{currency0.symbol}/{currency1.symbol} LP NFT
</Trans>
</TYPE.mediumHeader>
</RowFixed>
<Badge variant={BadgeVariant.PRIMARY}>V3</Badge>
@ -441,19 +448,25 @@ function V2PairMigration({
<BlueCard style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<AlertCircle color={theme.text1} style={{ marginBottom: '12px', opacity: 0.8 }} />
<TYPE.body fontSize={14} style={{ marginBottom: 8, fontWeight: 500, opacity: 0.8 }} textAlign="center">
You are the first liquidity provider for this Uniswap V3 pool. Your liquidity will migrate at the
current {isNotUniswap ? 'SushiSwap' : 'V2'} price.
<Trans id="migrate.hint.firstV3LiquidityProvider">
You are the first liquidity provider for this Uniswap V3 pool. Your liquidity will migrate at the
current {isNotUniswap ? 'SushiSwap' : 'V2'} price.
</Trans>
</TYPE.body>
<TYPE.body fontWeight={500} textAlign="center" fontSize={14} style={{ marginTop: '8px', opacity: 0.8 }}>
Your transaction cost will be much higher as it includes the gas to create the pool.
<Trans id="migrate.hint.firstV3LPGasCost">
Your transaction cost will be much higher as it includes the gas to create the pool.
</Trans>
</TYPE.body>
{v2SpotPrice && (
<AutoColumn gap="8px" style={{ marginTop: '12px' }}>
<RowBetween>
<TYPE.body fontWeight={500} fontSize={14}>
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:{' '}
<Trans id="migrate.labels.price">
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:
</Trans>{' '}
{invertPrice
? `${v2SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
: `${v2SpotPrice?.toSignificant(6)} ${currency1.symbol}`}
@ -469,7 +482,9 @@ function V2PairMigration({
<AutoColumn gap="8px">
<RowBetween>
<TYPE.body fontSize={14}>
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:
<Trans id="migrate.labels.price">
{isNotUniswap ? 'SushiSwap' : 'V2'} {invertPrice ? currency1.symbol : currency0.symbol} Price:
</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
{invertPrice
@ -479,7 +494,11 @@ function V2PairMigration({
</RowBetween>
<RowBetween>
<TYPE.body fontSize={14}>V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:</TYPE.body>
<TYPE.body fontSize={14}>
<Trans id="migrate.labels.v3Price">
V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:
</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
{invertPrice
? `${v3SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
@ -489,22 +508,26 @@ function V2PairMigration({
<RowBetween>
<TYPE.body fontSize={14} color="inherit">
Price Difference:
<Trans id="migrate.labels.priceDifference">Price Difference:</Trans>
</TYPE.body>
<TYPE.black fontSize={14} color="inherit">
{priceDifferenceFraction?.toSignificant(4)}%
<Trans id="numbers.valueWithPercent">{priceDifferenceFraction?.toSignificant(4)}%</Trans>
</TYPE.black>
</RowBetween>
</AutoColumn>
<TYPE.body fontSize={14} style={{ marginTop: 8, fontWeight: 400 }}>
You should only deposit liquidity into Uniswap V3 at a price you believe is correct. <br />
If the price seems incorrect, you can either make a swap to move the price or wait for someone else to
do so.
<Trans id="migrate.hint.priceHint">
You should only deposit liquidity into Uniswap V3 at a price you believe is correct. <br />
If the price seems incorrect, you can either make a swap to move the price or wait for someone else to
do so.
</Trans>
</TYPE.body>
</YellowCard>
) : !noLiquidity && v3SpotPrice ? (
<RowBetween>
<TYPE.body fontSize={14}>V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:</TYPE.body>
<TYPE.body fontSize={14}>
<Trans id="migrate.labels.v3Price">V3 {invertPrice ? currency1.symbol : currency0.symbol} Price:</Trans>
</TYPE.body>
<TYPE.black fontSize={14}>
{invertPrice
? `${v3SpotPrice?.invert()?.toSignificant(6)} ${currency0.symbol}`
@ -514,7 +537,9 @@ function V2PairMigration({
) : null}
<RowBetween>
<TYPE.label>{t('selectLiquidityRange')}</TYPE.label>
<TYPE.label>
<Trans id="migrate.labels.selectLiquidityRange">Set Price Range</Trans>
</TYPE.label>
<RateToggle
currencyA={invertPrice ? currency1 : currency0}
currencyB={invertPrice ? currency0 : currency1}
@ -545,7 +570,9 @@ function V2PairMigration({
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
{t('inactiveRangeWarning')}
<Trans id="migrate.hints.inactiveRangeWarning">
Your position will not earn fees or be used in trades until the market price moves into your range.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
@ -556,7 +583,9 @@ function V2PairMigration({
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
{t('invalidRangeWarning')}
<Trans id="migrate.errors.invalidRangeWarning">
Invalid range selected. The min price must be lower than the max price.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
@ -568,9 +597,11 @@ function V2PairMigration({
<LiquidityInfo token0Amount={position.amount0} token1Amount={position.amount1} />
{chainId && refund0 && refund1 ? (
<TYPE.black fontSize={12}>
At least {formatTokenAmount(refund0, 4)} {token0.equals(WETH9[chainId]) ? 'ETH' : token0.symbol} and{' '}
{formatTokenAmount(refund1, 4)} {token1.equals(WETH9[chainId]) ? 'ETH' : token1.symbol} will be
refunded to your wallet due to selected price range.
<Trans id="migrate.hints.priceRangeRefund">
At least {formatTokenAmount(refund0, 4)} {token0.equals(WETH9[chainId]) ? 'ETH' : token0.symbol}{' '}
and {formatTokenAmount(refund1, 4)} {token1.equals(WETH9[chainId]) ? 'ETH' : token1.symbol} will
be refunded to your wallet due to selected price range.
</Trans>
</TYPE.black>
) : null}
</AutoColumn>
@ -593,11 +624,13 @@ function V2PairMigration({
onClick={approve}
>
{approval === ApprovalState.PENDING ? (
<Dots>Approving</Dots>
<Dots>
<Trans id="transactions.approving">Approving</Trans>
</Dots>
) : approval === ApprovalState.APPROVED || signatureData !== null ? (
'Allowed'
<Trans id="transactions.allower">Allowed</Trans>
) : (
'Allow LP token migration'
<Trans id="transactions.allowLPTokenMigration">Allow LP token migration</Trans>
)}
</ButtonConfirmed>
</AutoColumn>
@ -616,7 +649,15 @@ function V2PairMigration({
}
onClick={migrate}
>
{isSuccessfullyMigrated ? 'Success!' : isMigrationPending ? <Dots>Migrating</Dots> : 'Migrate'}
{isSuccessfullyMigrated ? (
'Success!'
) : isMigrationPending ? (
<Dots>
<Trans id="migrate.buttons.migrating">Migrating</Trans>
</Dots>
) : (
<Trans id="migrate.buttons.migrate">Migrate</Trans>
)}
</ButtonConfirmed>
</AutoColumn>
</AutoColumn>
@ -693,12 +734,16 @@ export default function MigrateV2Pair({
<AutoColumn gap="16px">
<AutoRow style={{ alignItems: 'center', justifyContent: 'space-between' }} gap="8px">
<BackArrow to="/migrate/v2" />
<TYPE.mediumHeader>Migrate V2 Liquidity</TYPE.mediumHeader>
<TYPE.mediumHeader>
<Trans id="migrate.labels.migrateV2Liquidity">Migrate V2 Liquidity</Trans>
</TYPE.mediumHeader>
<SettingsTab placeholderSlippage={DEFAULT_MIGRATE_SLIPPAGE_TOLERANCE} />
</AutoRow>
{!account ? (
<TYPE.largeHeader>You must connect an account.</TYPE.largeHeader>
<TYPE.largeHeader>
<Trans id="wallet.mustConnectAccount">You must connect an account.</Trans>
</TYPE.largeHeader>
) : pairBalance && totalSupply && reserve0 && reserve1 && token0 && token1 ? (
<V2PairMigration
pair={pair}
@ -710,7 +755,7 @@ export default function MigrateV2Pair({
token1={token1}
/>
) : (
<EmptyState message="Loading..." />
<EmptyState message={t({ id: 'common.loading', message: 'Loading' })} />
)}
</AutoColumn>
</BodyWrapper>

@ -1,7 +1,7 @@
import React from 'react'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { ExternalLink } from '../../theme'
import { AutoColumn } from 'components/Column'
import Squiggle from '../../assets/images/squiggle.png'
@ -118,29 +118,31 @@ const StyledImage = styled.img`
`
export default function CTACards() {
const { t } = useTranslation()
return (
<CTASection>
<CTA1 href={'https://docs.uniswap.org/concepts/introduction/liquidity-user-guide'}>
<ResponsiveColumn>
<HeaderText>{t('Uniswap V3 is here!')}</HeaderText>
<HeaderText>
<Trans id="cta.v3.launchAnnouncement">Uniswap V3 is here!</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignItems: 'center', display: 'flex', maxWidth: '80%' }}>
{t('Check out our v3 LP walkthrough and migration guides.')}
<Trans id="cta.v3.walkthroughAndMigration">Check out our v3 LP walkthrough and migration guides.</Trans>
</TYPE.body>
<RowBetween align="flex-end">
<HeaderText>{t('↗')}</HeaderText>
<HeaderText></HeaderText>
<StyledImage src={Squiggle} />
</RowBetween>
</ResponsiveColumn>
</CTA1>
<CTA2 href={'https://info.uniswap.org/#/pools'}>
<ResponsiveColumn>
<HeaderText style={{ alignSelf: 'flex-start' }}>{t('Top pools')}</HeaderText>
<HeaderText style={{ alignSelf: 'flex-start' }}>
<Trans id="cta.topPools">Top pools</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignSelf: 'flex-start' }}>
{t('Explore popular pools on Uniswap Analytics.')}
<Trans id="cta.v3.explore">Explore popular pools on Uniswap Analytics.</Trans>
</TYPE.body>
<HeaderText style={{ alignSelf: 'flex-end' }}>{t('↗')}</HeaderText>
<HeaderText style={{ alignSelf: 'flex-end' }}></HeaderText>
</ResponsiveColumn>
</CTA2>
</CTASection>

@ -19,7 +19,7 @@ import Badge from 'components/Badge'
import { ButtonConfirmed, ButtonPrimary, ButtonGray } from 'components/Button'
import { DarkCard, LightCard } from 'components/Card'
import CurrencyLogo from 'components/CurrencyLogo'
import { useTranslation } from 'react-i18next'
import { t, Trans } from '@lingui/macro'
import { currencyId } from 'utils/currencyId'
import { formatTokenAmount } from 'utils/formatTokenAmount'
import { useV3PositionFees } from 'hooks/useV3PositionFees'
@ -156,7 +156,6 @@ function CurrentPriceCard({
currencyQuote?: Currency
currencyBase?: Currency
}) {
const { t } = useTranslation()
if (!pool || !currencyQuote || !currencyBase) {
return null
}
@ -164,11 +163,17 @@ function CurrentPriceCard({
return (
<LightCard padding="12px ">
<AutoColumn gap="8px" justify="center">
<ExtentsText>{t('Current price')}</ExtentsText>
<ExtentsText>
<Trans id="pools.currentPrice">Current price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">
{(inverted ? pool.token1Price : pool.token0Price).toSignificant(6)}{' '}
</TYPE.mediumHeader>
<ExtentsText>{currencyQuote?.symbol + ' per ' + currencyBase?.symbol}</ExtentsText>
<ExtentsText>
<Trans id="currencies.denominated">
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
</AutoColumn>
</LightCard>
)
@ -288,7 +293,6 @@ export function PositionPage({
params: { tokenId: tokenIdFromUrl },
},
}: RouteComponentProps<{ tokenId?: string }>) {
const { t } = useTranslation()
const { chainId, account, library } = useActiveWeb3React()
const theme = useTheme()
@ -465,8 +469,12 @@ export function PositionPage({
</RowBetween>
</AutoColumn>
</LightCard>
<TYPE.italic>Collecting fees will withdraw currently available fees for you.</TYPE.italic>
<ButtonPrimary onClick={collect}>Collect</ButtonPrimary>
<TYPE.italic>
<Trans id="pools.hint.collectingFees">Collecting fees will withdraw currently available fees for you.</Trans>
</TYPE.italic>
<ButtonPrimary onClick={collect}>
<Trans id="pools.buttons.collect">Collect</Trans>
</ButtonPrimary>
</AutoColumn>
)
}
@ -495,17 +503,19 @@ export function PositionPage({
hash={collectMigrationHash ?? ''}
content={() => (
<ConfirmationModalContent
title={'Claim fees'}
title={t({ id: 'pool.label.claimFees', message: 'Claim fees' })}
onDismiss={() => setShowConfirm(false)}
topContent={modalHeader}
/>
)}
pendingText={'Collecting fees'}
pendingText={t({ id: 'pool.label.collectingFees', message: 'Collecting fees' })}
/>
<AutoColumn gap="md">
<AutoColumn gap="sm">
<Link style={{ textDecoration: 'none', width: 'fit-content', marginBottom: '0.5rem' }} to="/pool">
<HoverText>{'← Back to Pools Overview'}</HoverText>
<HoverText>
<Trans id="pools.button.backToPoolsOverview"> Back to Pools Overview</Trans>
</HoverText>
</Link>
<ResponsiveRow>
<RowFixed>
@ -514,7 +524,9 @@ export function PositionPage({
&nbsp;{currencyQuote?.symbol}&nbsp;/&nbsp;{currencyBase?.symbol}
</TYPE.label>
<Badge style={{ marginRight: '8px' }}>
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
<BadgeText>
<Trans id="numbers.valueWithPercent">{new Percent(feeAmount, 1_000_000).toSignificant()}%</Trans>
</BadgeText>
</Badge>
<RangeBadge removed={removed} inRange={inRange} />
</RowFixed>
@ -529,7 +541,7 @@ export function PositionPage({
borderRadius="12px"
style={{ marginRight: '8px' }}
>
{t('Increase Liquidity')}
<Trans id="pools.buttons.increaseLiquidity">Increase Liquidity</Trans>
</ButtonGray>
) : null}
{tokenId && !removed ? (
@ -540,7 +552,7 @@ export function PositionPage({
padding="6px 8px"
borderRadius="12px"
>
{t('Remove Liquidity')}
<Trans id="pools.buttons.removeLiquidity">Remove Liquidity</Trans>
</ResponsiveButtonPrimary>
) : null}
</RowFixed>
@ -565,7 +577,9 @@ export function PositionPage({
<NFT image={metadata.result.image} height={400} />
</div>
{typeof chainId === 'number' && owner && !ownsNFT ? (
<ExternalLink href={getExplorerLink(chainId, owner, ExplorerDataType.ADDRESS)}>Owner</ExternalLink>
<ExternalLink href={getExplorerLink(chainId, owner, ExplorerDataType.ADDRESS)}>
<Trans id="pools.buttons.owner">Owner</Trans>
</ExternalLink>
) : null}
</DarkCard>
) : (
@ -584,14 +598,18 @@ export function PositionPage({
<DarkCard>
<AutoColumn gap="md" style={{ width: '100%' }}>
<AutoColumn gap="md">
<Label>Liquidity</Label>
<Label>
<Trans id="pools.labels.liquidity">Liquidity</Trans>
</Label>
{fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader fontSize="36px" fontWeight={500}>
${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}
<Trans id="numbers.valueInFiat">
${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}
</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
$-
<Trans id="numbers.emptyValueInFiat">$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
@ -605,7 +623,9 @@ export function PositionPage({
</TYPE.main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main fontSize={11}>{inverted ? ratio : 100 - ratio}%</TYPE.main>
<TYPE.main fontSize={11}>
<Trans id="numbers.valueWithPercent">{inverted ? ratio : 100 - ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
</RowFixed>
@ -619,7 +639,7 @@ export function PositionPage({
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main color={theme.text2} fontSize={11}>
{inverted ? 100 - ratio : ratio}%
<Trans id="numbers.valueWithPercent">{inverted ? 100 - ratio : ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
@ -634,14 +654,16 @@ export function PositionPage({
<AutoColumn gap="md">
<RowBetween style={{ alignItems: 'flex-start' }}>
<AutoColumn gap="md">
<Label>Unclaimed fees</Label>
<Label>
<Trans id="pools.labels.unclaimedFees">Unclaimed fees</Trans>
</Label>
{fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}
<Trans id="numbers.fiatValue">${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
$-
<Trans id="numbers.emptyFiatValue">$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
@ -655,15 +677,21 @@ export function PositionPage({
onClick={() => setShowConfirm(true)}
>
{!!collectMigrationHash && !isCollectPending ? (
<TYPE.main color={theme.text1}> Collected</TYPE.main>
<TYPE.main color={theme.text1}>
<Trans id="pools.labels.collectedFees"> Collected</Trans>
</TYPE.main>
) : isCollectPending || collecting ? (
<TYPE.main color={theme.text1}>
{' '}
<Dots>Collecting</Dots>
<Dots>
<Trans id="pools.labels.collectingFees">Collecting</Trans>
</Dots>
</TYPE.main>
) : (
<>
<TYPE.main color={theme.white}>Collect fees</TYPE.main>
<TYPE.main color={theme.white}>
<Trans id="pools.labels.collectFees">Collect fees</Trans>
</TYPE.main>
</>
)}
</ButtonConfirmed>
@ -708,7 +736,9 @@ export function PositionPage({
!collectMigrationHash ? (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<TYPE.main>
<Trans id="pools.labels.collectFeesAsWETH">Collect as WETH</Trans>
</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
@ -726,7 +756,7 @@ export function PositionPage({
<RowBetween>
<RowFixed>
<Label display="flex" style={{ marginRight: '12px' }}>
Price range
<Trans id="pool.priceRange">Price range</Trans>
</Label>
<HideExtraSmall>
<>
@ -749,13 +779,17 @@ export function PositionPage({
<RowBetween>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>Min price</ExtentsText>
<ExtentsText>
<Trans id="pools.minPriceLabel">Min price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceLower?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText> {currencyQuote?.symbol + ' per ' + currencyBase?.symbol}</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
Your position will be 100% {currencyBase?.symbol} at this price.
<Trans id="pools.minMaxPriceHint">
Your position will be 100% {currencyBase?.symbol} at this price.
</Trans>
</TYPE.small>
)}
</AutoColumn>
@ -764,13 +798,22 @@ export function PositionPage({
<DoubleArrow></DoubleArrow>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>Max price</ExtentsText>
<ExtentsText>
<Trans id="pools.maxPriceLabel">Max price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceUpper?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText> {currencyQuote?.symbol + ' per ' + currencyBase?.symbol}</ExtentsText>
<ExtentsText>
{' '}
<Trans id="currencies.denominated">
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
Your position will be 100% {currencyQuote?.symbol} at this price.
<Trans id="minMaxPriceHint">
Your position will be 100% {currencyQuote?.symbol} at this price.
</Trans>
</TYPE.small>
)}
</AutoColumn>

@ -8,7 +8,7 @@ import { RowBetween, RowFixed } from 'components/Row'
import { useActiveWeb3React } from 'hooks/web3'
import { useV3Positions } from 'hooks/useV3Positions'
import { BookOpen, ChevronDown, Download, Inbox, PlusCircle, ChevronsRight, Layers } from 'react-feather'
import { useTranslation } from 'react-i18next'
import { Trans } from '@lingui/macro'
import { Link } from 'react-router-dom'
import { useWalletModalToggle } from 'state/application/hooks'
import styled, { ThemeContext } from 'styled-components'
@ -108,7 +108,7 @@ const ShowInactiveToggle = styled.div`
export default function Pool() {
const { account } = useActiveWeb3React()
const toggleWalletModal = useWalletModalToggle()
const { t } = useTranslation()
const theme = useContext(ThemeContext)
const [userHideClosedPositions, setUserHideClosedPositions] = useUserHideClosedPositions()
@ -129,7 +129,7 @@ export default function Pool() {
content: (
<MenuItem>
<PlusCircle size={16} style={{ marginRight: '12px' }} />
{t('Create a pool')}
<Trans id="pools.menu.create">Create a pool</Trans>
</MenuItem>
),
link: '/add/ETH',
@ -139,7 +139,7 @@ export default function Pool() {
content: (
<MenuItem>
<ChevronsRight size={16} style={{ marginRight: '12px' }} />
{t('Migrate')}
<Trans id="pools.menu.migrate">Migrate</Trans>
</MenuItem>
),
link: '/migrate/v2',
@ -149,7 +149,7 @@ export default function Pool() {
content: (
<MenuItem>
<Layers size={16} style={{ marginRight: '12px' }} />
{t('V2 liquidity')}
<Trans id="pools.menu.v2Liquidity">V2 liquidity</Trans>
</MenuItem>
),
link: '/pool/v2',
@ -159,7 +159,7 @@ export default function Pool() {
content: (
<MenuItem>
<BookOpen size={16} style={{ marginRight: '12px' }} />
{t('Learn')}
<Trans id="pools.menu.learn">Learn</Trans>
</MenuItem>
),
link: 'https://docs.uniswap.org/',
@ -175,7 +175,9 @@ export default function Pool() {
<AutoColumn gap="lg" style={{ width: '100%' }}>
<TitleRow style={{ marginTop: '1rem' }} padding={'0'}>
<HideSmall>
<TYPE.mediumHeader>{t('Pools Overview')}</TYPE.mediumHeader>
<TYPE.mediumHeader>
<Trans id="pools.heading.poolsOverview">Pools Overview</Trans>
</TYPE.mediumHeader>
</HideSmall>
<ButtonRow>
<Menu
@ -184,14 +186,14 @@ export default function Pool() {
ToggleUI={(props: any) => (
<MoreOptionsButton {...props}>
<TYPE.body style={{ alignItems: 'center', display: 'flex' }}>
{t('More')}
<Trans id="pools.menu.more">More</Trans>
<ChevronDown size={15} />
</TYPE.body>
</MoreOptionsButton>
)}
/>
<ResponsiveButtonPrimary id="join-pool-button" as={Link} to="/add/ETH">
+ {t('New Position')}
+ <Trans id="pools.buttons.newPosition">New Position</Trans>
</ResponsiveButtonPrimary>
</ButtonRow>
</TitleRow>
@ -200,7 +202,9 @@ export default function Pool() {
{closedPositions.length > 0 ? (
<ShowInactiveToggle>
<TYPE.darkGray>{t('Hide closed positions')}</TYPE.darkGray>
<TYPE.darkGray>
<Trans id="pools.toggle.hideClosedPositions">Hide closed positions</Trans>
</TYPE.darkGray>
<Toggle
isActive={userHideClosedPositions}
toggle={() => setUserHideClosedPositions(!userHideClosedPositions)}
@ -230,11 +234,13 @@ export default function Pool() {
<NoLiquidity>
<TYPE.mediumHeader color={theme.text3} textAlign="center">
<Inbox size={48} strokeWidth={1} style={{ marginBottom: '.5rem' }} />
<div>{t('Your V3 liquidity positions will appear here.')}</div>
<div>
<Trans id="pools.emptyStateHint">Your V3 liquidity positions will appear here.</Trans>
</div>
</TYPE.mediumHeader>
{!account ? (
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}>
{t('Connect a wallet')}
<Trans id="wallet.connect">Connect a wallet</Trans>
</ButtonPrimary>
) : (
<ButtonGray
@ -243,7 +249,7 @@ export default function Pool() {
id="import-pool-link"
style={{ marginTop: '2em', padding: '8px 16px', borderRadius: '12px', width: 'fit-content' }}
>
{t('Migrate V2 liquidity')}?&nbsp;&nbsp;
<Trans id="pools.buttons.migrateV2Liquidity">Migrate V2 liquidity</Trans>?&nbsp;&nbsp;
<Download size={16} />
</ButtonGray>
)}
@ -265,7 +271,7 @@ export default function Pool() {
>
<Layers size={14} style={{ marginRight: '8px' }} />
{t('View V2 Liquidity')}
<Trans id="pools.buttons.viewV2Liquidity">View V2 Liquidity</Trans>
</ButtonOutlined>
{positions && positions.length > 0 && (
<ButtonOutlined
@ -282,7 +288,7 @@ export default function Pool() {
>
<ChevronsRight size={16} style={{ marginRight: '8px' }} />
{t('Migrate Liquidity')}
<Trans id="pools.buttons.migrateLiquidity">Migrate Liquidity</Trans>
</ButtonOutlined>
)}
</RowFixed>

@ -22,6 +22,7 @@ import { Dots } from '../Pool/styleds'
import { BlueCard } from '../../components/Card'
import { TYPE } from '../../theme'
import { useLocation } from 'react-router'
import { Trans } from '@lingui/macro'
enum Fields {
TOKEN0 = 0,
@ -81,7 +82,11 @@ export default function PoolFinder() {
const prerequisiteMessage = (
<LightCard padding="45px 10px">
<Text textAlign="center">
{!account ? 'Connect to a wallet to find pools' : 'Select a token to find your liquidity.'}
{!account ? (
<Trans id="pools.label.connectWalletToFindPools">Connect to a wallet to find pools</Trans>
) : (
<Trans id="pools.labels.selectTokenToFindLiquidity">Select a token to find your liquidity.</Trans>
)}
</Text>
</LightCard>
)
@ -93,7 +98,9 @@ export default function PoolFinder() {
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<b>Tip:</b> Use this tool to find pairs that don&apos;t automatically appear in the interface.
<Trans id="pools.hint.toolHelperText">
<b>Tip:</b> Use this tool to find pairs that don&apos;t automatically appear in the interface.
</Trans>
</TYPE.link>
</AutoColumn>
</BlueCard>
@ -112,7 +119,7 @@ export default function PoolFinder() {
</Row>
) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
Select a Token
<Trans id="currencies.search.selectToken">Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
@ -136,7 +143,7 @@ export default function PoolFinder() {
</Row>
) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
Select a Token
<Trans id="currencies.search.selectToken">Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
@ -146,10 +153,12 @@ export default function PoolFinder() {
style={{ justifyItems: 'center', backgroundColor: '', padding: '12px 0px', borderRadius: '12px' }}
>
<Text textAlign="center" fontWeight={500}>
Pool Found!
<Trans id="pools.labels.poolFound">Pool Found!</Trans>
</Text>
<StyledInternalLink to={`/pool`}>
<Text textAlign="center">Manage this pool.</Text>
<Text textAlign="center">
<Trans id="pools.buttons.manage">Manage this pool.</Trans>
</Text>
</StyledInternalLink>
</ColumnCenter>
)}
@ -161,9 +170,13 @@ export default function PoolFinder() {
) : (
<LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center">
<Text textAlign="center">You dont have liquidity in this pool yet.</Text>
<Text textAlign="center">
<Trans id="pools.label.noLiquidityInPoolYet">You dont have liquidity in this pool yet.</Trans>
</Text>
<StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}>
<Text textAlign="center">Add liquidity.</Text>
<Text textAlign="center">
<Trans id="pools.buttons.addLiquidityPoolFinder">Add liquidity.</Trans>
</Text>
</StyledInternalLink>
</AutoColumn>
</LightCard>
@ -171,9 +184,11 @@ export default function PoolFinder() {
) : validPairNoLiquidity ? (
<LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center">
<Text textAlign="center">No pool found.</Text>
<Text textAlign="center">
<Trans id="pools.error.noPoolFound">No pool found.</Trans>
</Text>
<StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}>
Create pool.
<Trans id="pools.buttons.createPool">Create pool.</Trans>
</StyledInternalLink>
</AutoColumn>
</LightCard>
@ -181,7 +196,7 @@ export default function PoolFinder() {
<LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center">
<Text textAlign="center" fontWeight={500}>
Invalid pair.
<Trans id="pools.errors.invalidPair">Invalid pair.</Trans>
</Text>
</AutoColumn>
</LightCard>
@ -189,7 +204,7 @@ export default function PoolFinder() {
<LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center">
<Text textAlign="center">
Loading
<Trans id="common.loading">Loading</Trans>
<Dots />
</Text>
</AutoColumn>

@ -33,6 +33,7 @@ import useTheme from 'hooks/useTheme'
import { AddRemoveTabs } from 'components/NavigationTabs'
import RangeBadge from 'components/Badge/RangeBadge'
import Toggle from 'components/Toggle'
import { t, Trans } from '@lingui/macro'
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
@ -151,7 +152,10 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
setTxnHash(response.hash)
setAttemptingTxn(false)
addTransaction(response, {
summary: `Remove ${liquidityValue0.currency.symbol}/${liquidityValue1.currency.symbol} V3 liquidity`,
summary: t({
id: 'transactions.summary.removeLiquidityV3',
message: `Remove ${liquidityValue0.currency.symbol}/${liquidityValue1.currency.symbol} V3 liquidity`,
}),
})
})
})
@ -186,16 +190,19 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
setTxnHash('')
}, [onPercentSelectForSlider, txnHash])
const pendingText = `Removing ${liquidityValue0?.toSignificant(6)} ${
liquidityValue0?.currency?.symbol
} and ${liquidityValue1?.toSignificant(6)} ${liquidityValue1?.currency?.symbol}`
const pendingText = t({
id: 'removeLiquidity.confirming.pending',
message: `Removing ${liquidityValue0?.toSignificant(6)} ${
liquidityValue0?.currency?.symbol
} and ${liquidityValue1?.toSignificant(6)} ${liquidityValue1?.currency?.symbol}`,
})
function modalHeader() {
return (
<AutoColumn gap={'sm'} style={{ padding: '16px' }}>
<RowBetween align="flex-end">
<Text fontSize={16} fontWeight={500}>
Pooled {liquidityValue0?.currency?.symbol}:
<Trans id="pool.pooledCurrency">Pooled {liquidityValue0?.currency?.symbol}:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -206,7 +213,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</RowBetween>
<RowBetween align="flex-end">
<Text fontSize={16} fontWeight={500}>
Pooled {liquidityValue1?.currency?.symbol}:
<Trans id="pool.pooledCurrency">Pooled {liquidityValue1?.currency?.symbol}:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -218,11 +225,13 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
<>
<TYPE.italic fontSize={12} color={theme.text2} textAlign="left" padding={'8px 0 0 0'}>
{`You will also collect fees earned from this position.`}
<Trans id="removeLiquidity.hints.collectFeesEarn">
You will also collect fees earned from this position.
</Trans>
</TYPE.italic>
<RowBetween>
<Text fontSize={16} fontWeight={500}>
{feeValue0?.currency?.symbol} Fees Earned:
<Trans id="removeLiquidity.label.feesEarned">{feeValue0?.currency?.symbol} Fees Earned:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -233,7 +242,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</RowBetween>
<RowBetween>
<Text fontSize={16} fontWeight={500}>
{feeValue1?.currency?.symbol} Fees Earned:
<Trans id="removeLiquidity.label.feesEarned">{feeValue1?.currency?.symbol} Fees Earned:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -245,7 +254,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</>
) : null}
<ButtonPrimary mt="16px" onClick={burn}>
Remove
<Trans id="buttons.remove">Remove</Trans>
</ButtonPrimary>
</AutoColumn>
)
@ -260,7 +269,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
hash={txnHash ?? ''}
content={() => (
<ConfirmationModalContent
title={'Remove Liquidity'}
title={t({ id: 'removeLiquidity.labels.removeLiquidity', message: 'Remove Liquidity' })}
onDismiss={handleDismissConfirmation}
topContent={modalHeader}
/>
@ -294,21 +303,25 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</RowBetween>
<LightCard>
<AutoColumn gap="md">
<TYPE.main fontWeight={400}>Amount</TYPE.main>
<TYPE.main fontWeight={400}>
<Trans id="labels.amount">Amount</Trans>
</TYPE.main>
<RowBetween>
<ResponsiveHeaderText>{percentForSlider}%</ResponsiveHeaderText>
<ResponsiveHeaderText>
<Trans id="removeLiquidity.labels.percentForSlider">{percentForSlider}%</Trans>
</ResponsiveHeaderText>
<AutoRow gap="4px" justify="flex-end">
<SmallMaxButton onClick={() => onPercentSelect(25)} width="20%">
25%
<Trans id="number.25Percent">25%</Trans>
</SmallMaxButton>
<SmallMaxButton onClick={() => onPercentSelect(50)} width="20%">
50%
<Trans id="number.50Percent">50%</Trans>
</SmallMaxButton>
<SmallMaxButton onClick={() => onPercentSelect(75)} width="20%">
75%
<Trans id="number.75Percent">75%</Trans>
</SmallMaxButton>
<SmallMaxButton onClick={() => onPercentSelect(100)} width="20%">
Max
<Trans id="labels.max">Max</Trans>
</SmallMaxButton>
</AutoRow>
</RowBetween>
@ -319,7 +332,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<AutoColumn gap="md">
<RowBetween>
<Text fontSize={16} fontWeight={500}>
Pooled {liquidityValue0?.currency?.symbol}:
<Trans id="pool.pooledCurrency">Pooled {liquidityValue0?.currency?.symbol}:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -330,7 +343,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</RowBetween>
<RowBetween>
<Text fontSize={16} fontWeight={500}>
Pooled {liquidityValue1?.currency?.symbol}:
<Trans id="pool.pooledCurrency">Pooled {liquidityValue1?.currency?.symbol}:</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -344,7 +357,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<Break />
<RowBetween>
<Text fontSize={16} fontWeight={500}>
{feeValue0?.currency?.symbol} Fees Earned:
<Trans id="removeLiquidity.label.feesEarned">
{feeValue0?.currency?.symbol} Fees Earned:
</Trans>
</Text>
<RowFixed>
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
@ -376,7 +391,9 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
liquidityValue0.currency.wrapped.equals(WETH9[liquidityValue0.currency.chainId]) ||
liquidityValue1.currency.wrapped.equals(WETH9[liquidityValue1.currency.chainId])) ? (
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<TYPE.main>
<Trans id="pools.labels.collectFeesAsWETH">Collect as WETH</Trans>
</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
@ -392,7 +409,11 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
disabled={removed || percent === 0 || !liquidityValue0}
onClick={() => setShowConfirm(true)}
>
{removed ? 'Inactive' : error ?? 'Remove'}
{removed ? (
<Trans id="labels.inactive">Inactive</Trans>
) : (
error ?? <Trans id="labels.remove">Remove</Trans>
)}
</ButtonConfirmed>
</AutoColumn>
</div>

@ -41,6 +41,7 @@ import { Field } from '../../state/burn/actions'
import { useWalletModalToggle } from '../../state/application/hooks'
import { useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { BigNumber } from '@ethersproject/bignumber'
import { t, Trans } from '@lingui/macro'
const DEFAULT_REMOVE_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(5, 100)
@ -265,15 +266,12 @@ export default function RemoveLiquidity({
setAttemptingTxn(false)
addTransaction(response, {
summary:
'Remove ' +
parsedAmounts[Field.CURRENCY_A]?.toSignificant(3) +
' ' +
currencyA?.symbol +
' and ' +
parsedAmounts[Field.CURRENCY_B]?.toSignificant(3) +
' ' +
currencyB?.symbol,
summary: t({
id: 'transactions.summary.removeLiquidity',
message: `Remove ${parsedAmounts[Field.CURRENCY_A]?.toSignificant(3)} ${
currencyA?.symbol
} and ${parsedAmounts[Field.CURRENCY_B]?.toSignificant(3)} ${currencyB?.symbol}`,
}),
})
setTxHash(response.hash)
@ -322,9 +320,10 @@ export default function RemoveLiquidity({
</RowBetween>
<TYPE.italic fontSize={12} color={theme.text2} textAlign="left" padding={'12px 0 0 0'}>
{`Output is estimated. If the price changes by more than ${allowedSlippage.toSignificant(
4
)}% your transaction will revert.`}
<Trans id="removeLiquidity.hint.outputEstimated">
Output is estimated. If the price changes by more than {allowedSlippage.toSignificant(4)}% your transaction
will revert.
</Trans>
</TYPE.italic>
</AutoColumn>
)
@ -335,7 +334,9 @@ export default function RemoveLiquidity({
<>
<RowBetween>
<Text color={theme.text2} fontWeight={500} fontSize={16}>
{'UNI ' + currencyA?.symbol + '/' + currencyB?.symbol} Burned
<Trans id="removeLiquidity.labels.UNIBurned">
UNI {currencyA?.symbol}/{currencyB?.symbol} Burned
</Trans>
</Text>
<RowFixed>
<DoubleCurrencyLogo currency0={currencyA} currency1={currencyB} margin={true} />
@ -348,7 +349,7 @@ export default function RemoveLiquidity({
<>
<RowBetween>
<Text color={theme.text2} fontWeight={500} fontSize={16}>
Price
<Trans id="removeLiquidity.labels.modalPrice">Price</Trans>
</Text>
<Text fontWeight={500} fontSize={16} color={theme.text1}>
1 {currencyA?.symbol} = {tokenA ? pair.priceOf(tokenA).toSignificant(6) : '-'} {currencyB?.symbol}
@ -364,16 +365,19 @@ export default function RemoveLiquidity({
)}
<ButtonPrimary disabled={!(approval === ApprovalState.APPROVED || signatureData !== null)} onClick={onRemove}>
<Text fontWeight={500} fontSize={20}>
Confirm
<Trans id="buttons.confirm">Confirm</Trans>
</Text>
</ButtonPrimary>
</>
)
}
const pendingText = `Removing ${parsedAmounts[Field.CURRENCY_A]?.toSignificant(6)} ${
currencyA?.symbol
} and ${parsedAmounts[Field.CURRENCY_B]?.toSignificant(6)} ${currencyB?.symbol}`
const pendingText = t({
id: 'removeLiquidity.confirming.pending',
message: `Removing ${parsedAmounts[Field.CURRENCY_A]?.toSignificant(6)} ${currencyA?.symbol} and ${parsedAmounts[
Field.CURRENCY_B
]?.toSignificant(6)} ${currencyB?.symbol}`,
})
const liquidityPercentChangeCallback = useCallback(
(value: number) => {
@ -434,7 +438,7 @@ export default function RemoveLiquidity({
hash={txHash ? txHash : ''}
content={() => (
<ConfirmationModalContent
title={'You will receive'}
title={t({ id: 'removeLiquidity.labels.confirmationTitle', message: 'You will receive' })}
onDismiss={handleDismissConfirmation}
topContent={modalHeader}
bottomContent={modalBottom}
@ -446,22 +450,30 @@ export default function RemoveLiquidity({
<BlueCard>
<AutoColumn gap="10px">
<TYPE.link fontWeight={400} color={'primaryText1'}>
<b>Tip:</b> Removing pool tokens converts your position back into underlying tokens at the current
rate, proportional to your share of the pool. Accrued fees are included in the amounts you receive.
<Trans id="removeLiquidity.hints.removingPoolTokensConvertsPosition">
<b>Tip:</b> Removing pool tokens converts your position back into underlying tokens at the current
rate, proportional to your share of the pool. Accrued fees are included in the amounts you receive.
</Trans>
</TYPE.link>
</AutoColumn>
</BlueCard>
<LightCard>
<AutoColumn gap="20px">
<RowBetween>
<Text fontWeight={500}>Remove Amount</Text>
<Text fontWeight={500}>
<Trans id="removeLiquidity.buttons.RemoveAmount">Remove Amount</Trans>
</Text>
<ClickableText
fontWeight={500}
onClick={() => {
setShowDetailed(!showDetailed)
}}
>
{showDetailed ? 'Simple' : 'Detailed'}
{showDetailed ? (
<Trans id="common.simple">Simple</Trans>
) : (
<Trans id="common.detailed">Detailed</Trans>
)}
</ClickableText>
</RowBetween>
<Row style={{ alignItems: 'flex-end' }}>
@ -591,7 +603,7 @@ export default function RemoveLiquidity({
{pair && (
<div style={{ padding: '10px 20px' }}>
<RowBetween>
Price:
<Trans id="removeLiquidity.labels.price">Price:</Trans>
<div>
1 {currencyA?.symbol} = {tokenA ? pair.priceOf(tokenA).toSignificant(6) : '-'} {currencyB?.symbol}
</div>
@ -606,7 +618,9 @@ export default function RemoveLiquidity({
)}
<div style={{ position: 'relative' }}>
{!account ? (
<ButtonLight onClick={toggleWalletModal}>Connect Wallet</ButtonLight>
<ButtonLight onClick={toggleWalletModal}>
<Trans id="wallet.connect">Connect Wallet</Trans>
</ButtonLight>
) : (
<RowBetween>
<ButtonConfirmed
@ -618,11 +632,13 @@ export default function RemoveLiquidity({
fontSize={16}
>
{approval === ApprovalState.PENDING ? (
<Dots>Approving</Dots>
<Dots>
<Trans id="transactions.approving">Approving</Trans>
</Dots>
) : approval === ApprovalState.APPROVED || signatureData !== null ? (
'Approved'
<Trans id="transactions.approved">Approved</Trans>
) : (
'Approve'
<Trans id="transactions.approve">Approve</Trans>
)}
</ButtonConfirmed>
<ButtonError
@ -633,7 +649,7 @@ export default function RemoveLiquidity({
error={!isValid && !!parsedAmounts[Field.CURRENCY_A] && !!parsedAmounts[Field.CURRENCY_B]}
>
<Text fontSize={16} fontWeight={500}>
{error || 'Remove'}
{error || <Trans id="removeLiquidity.buttons.remove">Remove</Trans>}
</Text>
</ButtonError>
</RowBetween>

@ -55,6 +55,7 @@ import { isTradeBetter } from '../../utils/isTradeBetter'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody'
import { t, Trans } from '@lingui/macro'
const StyledInfo = styled(Info)`
opacity: 0.4;
@ -376,7 +377,11 @@ export default function Swap({ history }: RouteComponentProps) {
<AutoColumn gap={'md'}>
<div style={{ display: 'relative' }}>
<CurrencyInputPanel
label={independentField === Field.OUTPUT && !showWrap ? 'From (at most)' : 'From'}
label={
independentField === Field.OUTPUT && !showWrap
? t({ id: 'swap.labels.fromAtMost', message: 'From (at most)' })
: t({ id: 'swap.labels.from', message: 'From' })
}
value={formattedAmounts[Field.INPUT]}
showMaxButton={showMaxButton}
currency={currencies[Field.INPUT]}
@ -401,7 +406,11 @@ export default function Swap({ history }: RouteComponentProps) {
<CurrencyInputPanel
value={formattedAmounts[Field.OUTPUT]}
onUserInput={handleTypeOutput}
label={independentField === Field.INPUT && !showWrap ? 'To (at least)' : 'To'}
label={
independentField === Field.INPUT && !showWrap
? t({ id: 'swap.labels.toAtLeast', message: 'To (at least)' })
: t({ id: 'swap.labels.to', message: 'To' })
}
showMaxButton={false}
hideBalance={false}
fiatValue={fiatValueOutput ?? undefined}
@ -421,7 +430,7 @@ export default function Swap({ history }: RouteComponentProps) {
<ArrowDown size="16" color={theme.text2} />
</ArrowWrapper>
<LinkStyledButton id="remove-recipient-button" onClick={() => onChangeRecipient(null)}>
- Remove send
<Trans id="swap.labels.removeSend">- Remove send</Trans>
</LinkStyledButton>
</AutoRow>
<AddressInputPanel id="recipient" value={recipient} onChange={onChangeRecipient} />
@ -455,7 +464,10 @@ export default function Swap({ history }: RouteComponentProps) {
>
<ArrowLeft color={theme.text3} size={12} /> &nbsp;
<TYPE.main style={{ lineHeight: '120%' }} fontSize={12}>
<HideSmall>Back to </HideSmall>V3
<Trans id="swap.buttons.backToV3">
<HideSmall>Back to</HideSmall>
V3
</Trans>
</TYPE.main>
</ButtonGray>
)
@ -498,22 +510,36 @@ export default function Swap({ history }: RouteComponentProps) {
<BottomGrouping>
{swapIsUnsupported ? (
<ButtonPrimary disabled={true}>
<TYPE.main mb="4px">Unsupported Asset</TYPE.main>
<TYPE.main mb="4px">
<Trans id="error.unsupportedAssets">Unsupported Asset</Trans>
</TYPE.main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal}>Connect Wallet</ButtonLight>
<ButtonLight onClick={toggleWalletModal}>
<Trans id="wallet.connect">Connect Wallet</Trans>
</ButtonLight>
) : showWrap ? (
<ButtonPrimary disabled={Boolean(wrapInputError)} onClick={onWrap}>
{wrapInputError ??
(wrapType === WrapType.WRAP ? 'Wrap' : wrapType === WrapType.UNWRAP ? 'Unwrap' : null)}
(wrapType === WrapType.WRAP ? (
<Trans id="swap.buttons.wrap">Wrap</Trans>
) : wrapType === WrapType.UNWRAP ? (
<Trans id="swap.buttons.unwrap">Unwrap</Trans>
) : null)}
</ButtonPrimary>
) : routeNotFound && userHasSpecifiedInputOutput ? (
<GreyCard style={{ textAlign: 'center' }}>
<TYPE.main mb="4px">
{isLoadingRoute ? (
<Dots>Loading</Dots>
<Dots>
<Trans id="common.loading">Loading</Trans>
</Dots>
) : singleHopOnly ? (
<Trans id="swap.labels.insufficientLiquiditySingleHopOnly">
Insufficient liquidity for this trade. Try enabling multi-hop trades.
</Trans>
) : (
`Insufficient liquidity for this trade.${singleHopOnly ? ' Try enabling multi-hop trades.' : ''}`
<Trans id="swap.labels.insufficientLiquidity">Insufficient liquidity for this trade.</Trans>
)}
</TYPE.main>
</GreyCard>
@ -541,9 +567,15 @@ export default function Swap({ history }: RouteComponentProps) {
style={{ marginRight: '8px', flexShrink: 0 }}
/>
{/* we need to shorten this string on mobile */}
{approvalState === ApprovalState.APPROVED || signatureState === UseERC20PermitState.SIGNED
? 'You can now trade ' + currencies[Field.INPUT]?.symbol
: 'Allow the Uniswap Protocol to use your ' + currencies[Field.INPUT]?.symbol}
{approvalState === ApprovalState.APPROVED || signatureState === UseERC20PermitState.SIGNED ? (
<Trans id="swap.buttons.tradeCurrency">
You can now trade {currencies[Field.INPUT]?.symbol}
</Trans>
) : (
<Trans id="swap.buttons.allowUniswapToUseCurrency">
Allow the Uniswap Protocol to use your {currencies[Field.INPUT]?.symbol}
</Trans>
)}
</span>
{approvalState === ApprovalState.PENDING ? (
<Loader stroke="white" />
@ -552,11 +584,12 @@ export default function Swap({ history }: RouteComponentProps) {
<CheckCircle size="20" color={theme.green1} />
) : (
<MouseoverTooltip
text={
'You must give the Uniswap smart contracts permission to use your ' +
currencies[Field.INPUT]?.symbol +
'. You only have to do this once per token.'
}
text={t({
id: 'swap.hints.permission',
message: `You must give the Uniswap smart contracts permission to use your ${
currencies[Field.INPUT]?.symbol
}. You only have to do this once per token.`,
})}
>
<HelpCircle size="20" color={'white'} style={{ marginLeft: '8px' }} />
</MouseoverTooltip>
@ -587,7 +620,13 @@ export default function Swap({ history }: RouteComponentProps) {
error={isValid && priceImpactSeverity > 2}
>
<Text fontSize={16} fontWeight={500}>
{priceImpactTooHigh ? `High Price Impact` : `Swap${priceImpactSeverity > 2 ? ' Anyway' : ''}`}
{priceImpactTooHigh ? (
<Trans id="swap.buttons.highPriceImpact">High Price Impact</Trans>
) : priceImpactSeverity > 2 ? (
<Trans id="swap.buttons.swapAnyway">Swap Anyway</Trans>
) : (
<Trans id="swap.buttons.swap">Swap</Trans>
)}
</Text>
</ButtonError>
</AutoColumn>
@ -612,11 +651,15 @@ export default function Swap({ history }: RouteComponentProps) {
error={isValid && priceImpactSeverity > 2 && !swapCallbackError}
>
<Text fontSize={20} fontWeight={500}>
{swapInputError
? swapInputError
: priceImpactTooHigh
? `Price Impact Too High`
: `Swap${priceImpactSeverity > 2 ? ' Anyway' : ''}`}
{swapInputError ? (
swapInputError
) : priceImpactTooHigh ? (
<Trans id="swap.buttons.priceImpactTooHigh">Price Impact Too High</Trans>
) : priceImpactSeverity > 2 ? (
<Trans id="swap.buttons.swapAnyway">Swap Anyway</Trans>
) : (
<Trans id="swap.buttons.swap">Swap</Trans>
)}
</Text>
</ButtonError>
)}

5446
yarn.lock

File diff suppressed because it is too large Load Diff