Use eslint/prettier for typescript files (#737)
* Use eslint/prettier for typescript files * Fix more linting errors * Turn linting errors off so CI passes
This commit is contained in:
commit
e023a02037
32
.eslintrc.json
Normal file
32
.eslintrc.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"sourceType": "module",
|
||||||
|
"ecmaFeatures": {
|
||||||
|
// Allows for the parsing of JSX
|
||||||
|
"jsx": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ignorePatterns": [
|
||||||
|
"node_modules/**/*"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"react": {
|
||||||
|
"version": "detect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:react/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"prettier/@typescript-eslint",
|
||||||
|
"plugin:prettier/recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
"react/prop-types": "off",
|
||||||
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
|
"react/display-name": "off"
|
||||||
|
}
|
||||||
|
}
|
13
.github/workflows/tests.yaml
vendored
13
.github/workflows/tests.yaml
vendored
@ -31,4 +31,15 @@ jobs:
|
|||||||
- run: yarn
|
- run: yarn
|
||||||
- run: yarn test
|
- run: yarn test
|
||||||
|
|
||||||
# todo: add job for typescript linting
|
lint:
|
||||||
|
name: Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '12'
|
||||||
|
- run: yarn
|
||||||
|
- run: yarn lint
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
/**
|
/**
|
||||||
* @type {Cypress.PluginConfig}
|
* @type {Cypress.PluginConfig}
|
||||||
*/
|
*/
|
||||||
module.exports = (on, config) => {
|
module.exports = () => {
|
||||||
// `on` is used to hook into various events Cypress emits
|
// `on` is used to hook into various events Cypress emits
|
||||||
// `config` is the resolved Cypress config
|
// `config` is the resolved Cypress config
|
||||||
}
|
}
|
||||||
|
16
package.json
16
package.json
@ -57,7 +57,13 @@
|
|||||||
"@types/react-dom": "^16.9.7",
|
"@types/react-dom": "^16.9.7",
|
||||||
"@types/react-router-dom": "^5.0.0",
|
"@types/react-router-dom": "^5.0.0",
|
||||||
"@types/styled-components": "^4.2.0",
|
"@types/styled-components": "^4.2.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^2.31.0",
|
||||||
|
"@typescript-eslint/parser": "^2.31.0",
|
||||||
"cypress": "^4.5.0",
|
"cypress": "^4.5.0",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-config-prettier": "^6.11.0",
|
||||||
|
"eslint-plugin-prettier": "^3.1.3",
|
||||||
|
"eslint-plugin-react": "^7.19.0",
|
||||||
"prettier": "^1.17.0",
|
"prettier": "^1.17.0",
|
||||||
"serve": "^11.3.0",
|
"serve": "^11.3.0",
|
||||||
"start-server-and-test": "^1.11.0",
|
"start-server-and-test": "^1.11.0",
|
||||||
@ -68,14 +74,8 @@
|
|||||||
"build": "cross-env REACT_APP_GIT_COMMIT_HASH=$(git show -s --format=%H) react-scripts build",
|
"build": "cross-env REACT_APP_GIT_COMMIT_HASH=$(git show -s --format=%H) react-scripts build",
|
||||||
"test": "react-scripts test --env=jsdom",
|
"test": "react-scripts test --env=jsdom",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"lint:base": "yarn eslint './src/**/*.{js,jsx}'",
|
"lint": "eslint '**/*.{js,jsx,ts,tsx}'",
|
||||||
"format:base": "yarn prettier './src/**/*.{js,jsx,scss}'",
|
"lint:fix": "eslint '**/*.{js,jsx,ts,tsx}' --fix",
|
||||||
"fix:lint": "yarn lint:base --fix",
|
|
||||||
"fix:format": "yarn format:base --write",
|
|
||||||
"fix:all": "yarn fix:lint && yarn fix:format",
|
|
||||||
"check:lint": "yarn lint:base",
|
|
||||||
"check:format": "yarn format:base --check",
|
|
||||||
"check:all": "yarn check:lint && yarn check:format",
|
|
||||||
"cy:run": "cypress run",
|
"cy:run": "cypress run",
|
||||||
"serve:build": "serve -s build -l 3000",
|
"serve:build": "serve -s build -l 3000",
|
||||||
"integration-test": "yarn build && start-server-and-test 'yarn run serve:build' http://localhost:3000 cy:run"
|
"integration-test": "yarn build && start-server-and-test 'yarn run serve:build' http://localhost:3000 cy:run"
|
||||||
|
@ -33,12 +33,12 @@ export default function CopyHelper(props: { toCopy: string; children?: React.Rea
|
|||||||
{props.children}
|
{props.children}
|
||||||
{isCopied ? (
|
{isCopied ? (
|
||||||
<TransactionStatusText>
|
<TransactionStatusText>
|
||||||
<CheckCircle size={'16'}/>
|
<CheckCircle size={'16'} />
|
||||||
<TransactionStatusText>Copied</TransactionStatusText>
|
<TransactionStatusText>Copied</TransactionStatusText>
|
||||||
</TransactionStatusText>
|
</TransactionStatusText>
|
||||||
) : (
|
) : (
|
||||||
<TransactionStatusText>
|
<TransactionStatusText>
|
||||||
<Copy size={'16'}/>
|
<Copy size={'16'} />
|
||||||
</TransactionStatusText>
|
</TransactionStatusText>
|
||||||
)}
|
)}
|
||||||
</CopyIcon>
|
</CopyIcon>
|
||||||
|
@ -43,7 +43,7 @@ const rotate = keyframes`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const TransactionState = styled.div<{pending?: boolean;}>`
|
const TransactionState = styled.div<{ pending?: boolean }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: ${({ pending, theme }) =>
|
background-color: ${({ pending, theme }) =>
|
||||||
pending ? transparentize(0.95, theme.blue1) : transparentize(0.95, theme.green1)};
|
pending ? transparentize(0.95, theme.blue1) : transparentize(0.95, theme.green1)};
|
||||||
@ -64,13 +64,13 @@ const TransactionState = styled.div<{pending?: boolean;}>`
|
|||||||
pending ? transparentize(0, theme.blue1) : transparentize(0, theme.green1)};
|
pending ? transparentize(0, theme.blue1) : transparentize(0, theme.green1)};
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const ButtonWrapper = styled.div<{pending: boolean}>`
|
const ButtonWrapper = styled.div<{ pending: boolean }>`
|
||||||
a {
|
a {
|
||||||
color: ${({ pending, theme }) => (pending ? theme.blue1 : theme.green1)};
|
color: ${({ pending, theme }) => (pending ? theme.blue1 : theme.green1)};
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function Transaction({ hash, pending }) {
|
export default function Transaction({ hash, pending }: { hash: string; pending: boolean }) {
|
||||||
const { chainId } = useWeb3React()
|
const { chainId } = useWeb3React()
|
||||||
const allTransactions = useAllTransactions()
|
const allTransactions = useAllTransactions()
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ const LowerSection = styled.div`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const AccountControl = styled.div<{ hasENS: boolean; isENS: boolean; }>`
|
const AccountControl = styled.div<{ hasENS: boolean; isENS: boolean }>`
|
||||||
${({ theme }) => theme.flexRowNoWrap};
|
${({ theme }) => theme.flexRowNoWrap};
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@ -156,7 +156,7 @@ const ConnectButtonRow = styled.div`
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
`
|
`
|
||||||
|
|
||||||
const StyledLink = styled(Link) <{ hasENS: boolean; isENS: boolean; }>`
|
const StyledLink = styled(Link)<{ hasENS: boolean; isENS: boolean }>`
|
||||||
color: ${({ hasENS, isENS, theme }) => (hasENS ? (isENS ? theme.blue1 : theme.text3) : theme.blue1)};
|
color: ${({ hasENS, isENS, theme }) => (hasENS ? (isENS ? theme.blue1 : theme.text3) : theme.blue1)};
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ const WalletName = styled.div`
|
|||||||
width: initial;
|
width: initial;
|
||||||
`
|
`
|
||||||
|
|
||||||
const IconWrapper = styled.div<{size?: number}>`
|
const IconWrapper = styled.div<{ size?: number }>`
|
||||||
${({ theme }) => theme.flexColumnNoWrap};
|
${({ theme }) => theme.flexColumnNoWrap};
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -217,19 +217,27 @@ function renderTransactions(transactions, pending) {
|
|||||||
return (
|
return (
|
||||||
<TransactionListWrapper>
|
<TransactionListWrapper>
|
||||||
{transactions.map((hash, i) => {
|
{transactions.map((hash, i) => {
|
||||||
return <Transaction key={i} hash={hash} pending={pending}/>
|
return <Transaction key={i} hash={hash} pending={pending} />
|
||||||
})}
|
})}
|
||||||
</TransactionListWrapper>
|
</TransactionListWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AccountDetailsProps {
|
||||||
|
toggleWalletModal: () => void
|
||||||
|
pendingTransactions: any[]
|
||||||
|
confirmedTransactions: any[]
|
||||||
|
ENSName?: string
|
||||||
|
openOptions: () => void
|
||||||
|
}
|
||||||
|
|
||||||
export default function AccountDetails({
|
export default function AccountDetails({
|
||||||
toggleWalletModal,
|
toggleWalletModal,
|
||||||
pendingTransactions,
|
pendingTransactions,
|
||||||
confirmedTransactions,
|
confirmedTransactions,
|
||||||
ENSName,
|
ENSName,
|
||||||
openOptions
|
openOptions
|
||||||
}) {
|
}: AccountDetailsProps) {
|
||||||
const { chainId, account, connector } = useWeb3React()
|
const { chainId, account, connector } = useWeb3React()
|
||||||
const theme = useContext(ThemeContext)
|
const theme = useContext(ThemeContext)
|
||||||
|
|
||||||
@ -249,32 +257,32 @@ export default function AccountDetails({
|
|||||||
if (connector === injected) {
|
if (connector === injected) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<Identicon/> {formatConnectorName()}
|
<Identicon /> {formatConnectorName()}
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === walletconnect) {
|
} else if (connector === walletconnect) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={WalletConnectIcon} alt={''}/> {formatConnectorName()}
|
<img src={WalletConnectIcon} alt={''} /> {formatConnectorName()}
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === walletlink) {
|
} else if (connector === walletlink) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={CoinbaseWalletIcon} alt={''}/> {formatConnectorName()}
|
<img src={CoinbaseWalletIcon} alt={''} /> {formatConnectorName()}
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === fortmatic) {
|
} else if (connector === fortmatic) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={FortmaticIcon} alt={''}/> {formatConnectorName()}
|
<img src={FortmaticIcon} alt={''} /> {formatConnectorName()}
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === portis) {
|
} else if (connector === portis) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={PortisIcon} alt={''}/> {formatConnectorName()}
|
<img src={PortisIcon} alt={''} /> {formatConnectorName()}
|
||||||
<MainWalletAction
|
<MainWalletAction
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
portis.portis.showPortis()
|
portis.portis.showPortis()
|
||||||
@ -292,7 +300,7 @@ export default function AccountDetails({
|
|||||||
<>
|
<>
|
||||||
<UpperSection>
|
<UpperSection>
|
||||||
<CloseIcon onClick={toggleWalletModal}>
|
<CloseIcon onClick={toggleWalletModal}>
|
||||||
<CloseColor/>
|
<CloseColor />
|
||||||
</CloseIcon>
|
</CloseIcon>
|
||||||
<HeaderRow>Account</HeaderRow>
|
<HeaderRow>Account</HeaderRow>
|
||||||
<AccountSection>
|
<AccountSection>
|
||||||
@ -304,7 +312,7 @@ export default function AccountDetails({
|
|||||||
{connector !== injected && connector !== walletlink && (
|
{connector !== injected && connector !== walletlink && (
|
||||||
<WalletAction
|
<WalletAction
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
(connector as any).close()
|
;(connector as any).close()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Disconnect
|
Disconnect
|
||||||
@ -312,7 +320,7 @@ export default function AccountDetails({
|
|||||||
)}
|
)}
|
||||||
<CircleWrapper>
|
<CircleWrapper>
|
||||||
<GreenCircle>
|
<GreenCircle>
|
||||||
<div/>
|
<div />
|
||||||
</GreenCircle>
|
</GreenCircle>
|
||||||
</CircleWrapper>
|
</CircleWrapper>
|
||||||
</div>
|
</div>
|
||||||
@ -323,14 +331,14 @@ export default function AccountDetails({
|
|||||||
<StyledLink hasENS={!!ENSName} isENS={true} href={getEtherscanLink(chainId, ENSName, 'address')}>
|
<StyledLink hasENS={!!ENSName} isENS={true} href={getEtherscanLink(chainId, ENSName, 'address')}>
|
||||||
{ENSName} ↗{' '}
|
{ENSName} ↗{' '}
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
<Copy toCopy={ENSName}/>
|
<Copy toCopy={ENSName} />
|
||||||
</AccountControl>
|
</AccountControl>
|
||||||
) : (
|
) : (
|
||||||
<AccountControl hasENS={!!ENSName} isENS={false}>
|
<AccountControl hasENS={!!ENSName} isENS={false}>
|
||||||
<StyledLink hasENS={!!ENSName} isENS={false} href={getEtherscanLink(chainId, account, 'address')}>
|
<StyledLink hasENS={!!ENSName} isENS={false} href={getEtherscanLink(chainId, account, 'address')}>
|
||||||
{account} ↗{' '}
|
{account} ↗{' '}
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
<Copy toCopy={account}/>
|
<Copy toCopy={account} />
|
||||||
</AccountControl>
|
</AccountControl>
|
||||||
)}
|
)}
|
||||||
</AccountGroupingRow>
|
</AccountGroupingRow>
|
||||||
|
@ -63,7 +63,15 @@ const Input = styled.input<{ error: boolean }>`
|
|||||||
// border-radius: 8px;
|
// border-radius: 8px;
|
||||||
// `
|
// `
|
||||||
|
|
||||||
export default function AddressInputPanel({ initialInput = '', onChange, onError }) {
|
export default function AddressInputPanel({
|
||||||
|
initialInput = '',
|
||||||
|
onChange,
|
||||||
|
onError
|
||||||
|
}: {
|
||||||
|
initialInput?: string
|
||||||
|
onChange: (val: { address: string; name?: string }) => void
|
||||||
|
onError: (error: boolean, input: string) => void
|
||||||
|
}) {
|
||||||
const { library } = useWeb3React()
|
const { library } = useWeb3React()
|
||||||
|
|
||||||
const [input, setInput] = useState(initialInput ? initialInput : '')
|
const [input, setInput] = useState(initialInput ? initialInput : '')
|
||||||
|
@ -17,7 +17,7 @@ const InputWrapper = styled(RowBetween)`
|
|||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border: ${({ active, error, theme }) =>
|
border: ${({ active, error, theme }) =>
|
||||||
error ? '1px solid ' + theme.red1 : active ? '1px solid ' + theme.blue1 : ''};
|
error ? '1px solid ' + theme.red1 : active ? '1px solid ' + theme.blue1 : ''};
|
||||||
`
|
`
|
||||||
|
|
||||||
const SLIPPAGE_INDEX = {
|
const SLIPPAGE_INDEX = {
|
||||||
@ -34,7 +34,12 @@ interface AdvancedSettingsProps {
|
|||||||
setAllowedSlippage: (number) => void
|
setAllowedSlippage: (number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippage, setAllowedSlippage }: AdvancedSettingsProps) {
|
export default function AdvancedSettings({
|
||||||
|
setIsOpen,
|
||||||
|
setDeadline,
|
||||||
|
allowedSlippage,
|
||||||
|
setAllowedSlippage
|
||||||
|
}: AdvancedSettingsProps) {
|
||||||
// text translation
|
// text translation
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@ -78,7 +83,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
|
|||||||
setActiveIndex(3)
|
setActiveIndex(3)
|
||||||
} else {
|
} else {
|
||||||
setActiveIndex(4)
|
setActiveIndex(4)
|
||||||
setSlippageInput('' + (allowedSlippage / 100))
|
setSlippageInput('' + allowedSlippage / 100)
|
||||||
parseCustomInput(allowedSlippage)
|
parseCustomInput(allowedSlippage)
|
||||||
}
|
}
|
||||||
}, [allowedSlippage, parseCustomInput])
|
}, [allowedSlippage, parseCustomInput])
|
||||||
@ -94,7 +99,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
|
|||||||
</Link>
|
</Link>
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
<TYPE.main>Front-running tolerance</TYPE.main>
|
<TYPE.main>Front-running tolerance</TYPE.main>
|
||||||
<QuestionHelper text={t('toleranceExplanation')}/>
|
<QuestionHelper text={t('toleranceExplanation')} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<Row>
|
<Row>
|
||||||
<ButtonRadio
|
<ButtonRadio
|
||||||
|
@ -10,7 +10,10 @@ export const ColumnCenter = styled(Column)`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
`
|
`
|
||||||
|
|
||||||
export const AutoColumn = styled.div<{gap?: 'sm' | 'md' | 'lg' | string; justify?: 'stretch' | 'center' | 'start' | 'end' | 'flex-start' | 'flex-end';}>`
|
export const AutoColumn = styled.div<{
|
||||||
|
gap?: 'sm' | 'md' | 'lg' | string
|
||||||
|
justify?: 'stretch' | 'center' | 'start' | 'end' | 'flex-start' | 'flex-end'
|
||||||
|
}>`
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-rows: auto;
|
grid-auto-rows: auto;
|
||||||
grid-row-gap: ${({ gap }) => (gap === 'sm' && '8px') || (gap === 'md' && '12px') || (gap === 'lg' && '24px') || gap};
|
grid-row-gap: ${({ gap }) => (gap === 'sm' && '8px') || (gap === 'md' && '12px') || (gap === 'lg' && '24px') || gap};
|
||||||
|
@ -45,17 +45,17 @@ interface ConfirmationModalProps extends RouteComponentProps<{}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ConfirmationModal({
|
function ConfirmationModal({
|
||||||
history,
|
history,
|
||||||
isOpen,
|
isOpen,
|
||||||
onDismiss,
|
onDismiss,
|
||||||
hash,
|
hash,
|
||||||
topContent,
|
topContent,
|
||||||
bottomContent,
|
bottomContent,
|
||||||
attemptingTxn,
|
attemptingTxn,
|
||||||
pendingConfirmation,
|
pendingConfirmation,
|
||||||
pendingText,
|
pendingText,
|
||||||
title = ''
|
title = ''
|
||||||
}: ConfirmationModalProps) {
|
}: ConfirmationModalProps) {
|
||||||
const { chainId } = useWeb3React()
|
const { chainId } = useWeb3React()
|
||||||
|
|
||||||
const dismissAndReturn = useCallback(() => {
|
const dismissAndReturn = useCallback(() => {
|
||||||
@ -74,7 +74,7 @@ function ConfirmationModal({
|
|||||||
<Text fontWeight={500} fontSize={20}>
|
<Text fontWeight={500} fontSize={20}>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
<CloseIcon onClick={onDismiss}/>
|
<CloseIcon onClick={onDismiss} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
{topContent()}
|
{topContent()}
|
||||||
</Section>
|
</Section>
|
||||||
@ -84,14 +84,14 @@ function ConfirmationModal({
|
|||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Section>
|
<Section>
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
<div/>
|
<div />
|
||||||
<CloseIcon onClick={onDismiss}/>
|
<CloseIcon onClick={onDismiss} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<ConfirmedIcon>
|
<ConfirmedIcon>
|
||||||
{pendingConfirmation ? (
|
{pendingConfirmation ? (
|
||||||
<Loader size="90px"/>
|
<Loader size="90px" />
|
||||||
) : (
|
) : (
|
||||||
<ArrowUpCircle strokeWidth={0.5} size={90} color="#ff007a"/>
|
<ArrowUpCircle strokeWidth={0.5} size={90} color="#ff007a" />
|
||||||
)}
|
)}
|
||||||
</ConfirmedIcon>
|
</ConfirmedIcon>
|
||||||
<AutoColumn gap="12px" justify={'center'}>
|
<AutoColumn gap="12px" justify={'center'}>
|
||||||
|
@ -139,41 +139,41 @@ interface CurrencyInputPanelProps {
|
|||||||
onUserInput: (field: number, val: string) => void
|
onUserInput: (field: number, val: string) => void
|
||||||
onMax: () => void
|
onMax: () => void
|
||||||
atMax: boolean
|
atMax: boolean
|
||||||
label?: string,
|
label?: string
|
||||||
urlAddedTokens?: Token[]
|
urlAddedTokens?: Token[]
|
||||||
onTokenSelection?: (tokenAddress: string) => void
|
onTokenSelection?: (tokenAddress: string) => void
|
||||||
token?: Token | null,
|
token?: Token | null
|
||||||
disableTokenSelect?: boolean,
|
disableTokenSelect?: boolean
|
||||||
hideBalance?: boolean,
|
hideBalance?: boolean
|
||||||
isExchange?: boolean,
|
isExchange?: boolean
|
||||||
pair?: Pair | null,
|
pair?: Pair | null
|
||||||
hideInput?: boolean,
|
hideInput?: boolean
|
||||||
showSendWithSwap?: boolean,
|
showSendWithSwap?: boolean
|
||||||
otherSelectedTokenAddress?: string | null,
|
otherSelectedTokenAddress?: string | null
|
||||||
advanced?: boolean,
|
advanced?: boolean
|
||||||
inputId: string
|
inputId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CurrencyInputPanel({
|
export default function CurrencyInputPanel({
|
||||||
value,
|
value,
|
||||||
field,
|
field,
|
||||||
onUserInput,
|
onUserInput,
|
||||||
onMax,
|
onMax,
|
||||||
atMax,
|
atMax,
|
||||||
label = 'Input',
|
label = 'Input',
|
||||||
urlAddedTokens = [], // used
|
urlAddedTokens = [], // used
|
||||||
onTokenSelection = null,
|
onTokenSelection = null,
|
||||||
token = null,
|
token = null,
|
||||||
disableTokenSelect = false,
|
disableTokenSelect = false,
|
||||||
hideBalance = false,
|
hideBalance = false,
|
||||||
isExchange = false,
|
isExchange = false,
|
||||||
pair = null, // used for double token logo
|
pair = null, // used for double token logo
|
||||||
hideInput = false,
|
hideInput = false,
|
||||||
showSendWithSwap = false,
|
showSendWithSwap = false,
|
||||||
otherSelectedTokenAddress = null,
|
otherSelectedTokenAddress = null,
|
||||||
advanced = false,
|
advanced = false,
|
||||||
inputId,
|
inputId
|
||||||
}: CurrencyInputPanelProps) {
|
}: CurrencyInputPanelProps) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const [modalOpen, setModalOpen] = useState(false)
|
const [modalOpen, setModalOpen] = useState(false)
|
||||||
@ -207,10 +207,7 @@ export default function CurrencyInputPanel({
|
|||||||
</RowBetween>
|
</RowBetween>
|
||||||
</LabelRow>
|
</LabelRow>
|
||||||
)}
|
)}
|
||||||
<InputRow
|
<InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={disableTokenSelect}>
|
||||||
style={hideInput ? { padding: '0', borderRadius: '8px' } : {}}
|
|
||||||
selected={disableTokenSelect}
|
|
||||||
>
|
|
||||||
{!hideInput && (
|
{!hideInput && (
|
||||||
<>
|
<>
|
||||||
<NumericalInput
|
<NumericalInput
|
||||||
@ -235,9 +232,9 @@ export default function CurrencyInputPanel({
|
|||||||
>
|
>
|
||||||
<Aligner>
|
<Aligner>
|
||||||
{isExchange ? (
|
{isExchange ? (
|
||||||
<DoubleLogo a0={pair?.token0.address} a1={pair?.token1.address} size={24} margin={true}/>
|
<DoubleLogo a0={pair?.token0.address} a1={pair?.token1.address} size={24} margin={true} />
|
||||||
) : token?.address ? (
|
) : token?.address ? (
|
||||||
<TokenLogo address={token?.address} size={'24px'}/>
|
<TokenLogo address={token?.address} size={'24px'} />
|
||||||
) : null}
|
) : null}
|
||||||
{isExchange ? (
|
{isExchange ? (
|
||||||
<StyledTokenName>
|
<StyledTokenName>
|
||||||
@ -248,7 +245,7 @@ export default function CurrencyInputPanel({
|
|||||||
{(token && token.symbol) || t('selectToken')}
|
{(token && token.symbol) || t('selectToken')}
|
||||||
</StyledTokenName>
|
</StyledTokenName>
|
||||||
)}
|
)}
|
||||||
{!disableTokenSelect && <StyledDropDown selected={!!token?.address}/>}
|
{!disableTokenSelect && <StyledDropDown selected={!!token?.address} />}
|
||||||
</Aligner>
|
</Aligner>
|
||||||
</CurrencySelect>
|
</CurrencySelect>
|
||||||
</InputRow>
|
</InputRow>
|
||||||
|
@ -3,11 +3,11 @@ import styled from 'styled-components'
|
|||||||
import TokenLogo from '../TokenLogo'
|
import TokenLogo from '../TokenLogo'
|
||||||
|
|
||||||
const TokenWrapper = styled.div<{ margin: boolean; sizeraw: number }>`
|
const TokenWrapper = styled.div<{ margin: boolean; sizeraw: number }>`
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin-right: ${({ sizeraw, margin }) => margin && (sizeraw / 3 + 8).toString() + 'px'};
|
margin-right: ${({ sizeraw, margin }) => margin && (sizeraw / 3 + 8).toString() + 'px'};
|
||||||
`
|
`
|
||||||
|
|
||||||
interface DoubleTokenLogoProps {
|
interface DoubleTokenLogoProps {
|
||||||
margin?: boolean
|
margin?: boolean
|
||||||
@ -17,18 +17,18 @@ interface DoubleTokenLogoProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const HigherLogo = styled(TokenLogo)`
|
const HigherLogo = styled(TokenLogo)`
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
`
|
`
|
||||||
const CoveredLogo = styled(TokenLogo)<{ sizeraw: number }>`
|
const CoveredLogo = styled(TokenLogo)<{ sizeraw: number }>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: ${({ sizeraw }) => (sizeraw / 2).toString() + 'px'};
|
left: ${({ sizeraw }) => (sizeraw / 2).toString() + 'px'};
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function DoubleTokenLogo({ a0, a1, size = 16, margin = false }: DoubleTokenLogoProps) {
|
export default function DoubleTokenLogo({ a0, a1, size = 16, margin = false }: DoubleTokenLogoProps) {
|
||||||
return (
|
return (
|
||||||
<TokenWrapper sizeraw={size} margin={margin}>
|
<TokenWrapper sizeraw={size} margin={margin}>
|
||||||
<HigherLogo address={a0} size={size.toString() + 'px'}/>
|
<HigherLogo address={a0} size={size.toString() + 'px'} />
|
||||||
<CoveredLogo address={a1} size={size.toString() + 'px'} sizeraw={size}/>
|
<CoveredLogo address={a1} size={size.toString() + 'px'} sizeraw={size} />
|
||||||
</TokenWrapper>
|
</TokenWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -178,14 +178,22 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT])
|
const pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT])
|
||||||
let bestTradeExactIn = useTradeExactIn(tradeType === TradeType.EXACT_INPUT ? parsedAmounts[independentField] : null, tokens[Field.OUTPUT])
|
const bestTradeExactIn = useTradeExactIn(
|
||||||
let bestTradeExactOut = useTradeExactOut(tokens[Field.INPUT], tradeType === TradeType.EXACT_OUTPUT ? parsedAmounts[independentField] : null)
|
tradeType === TradeType.EXACT_INPUT ? parsedAmounts[independentField] : null,
|
||||||
|
tokens[Field.OUTPUT]
|
||||||
|
)
|
||||||
|
const bestTradeExactOut = useTradeExactOut(
|
||||||
|
tokens[Field.INPUT],
|
||||||
|
tradeType === TradeType.EXACT_OUTPUT ? parsedAmounts[independentField] : null
|
||||||
|
)
|
||||||
|
|
||||||
const trade = tradeType === TradeType.EXACT_INPUT ? bestTradeExactIn : bestTradeExactOut
|
const trade = tradeType === TradeType.EXACT_INPUT ? bestTradeExactIn : bestTradeExactOut
|
||||||
const route = trade?.route
|
const route = trade?.route
|
||||||
const userHasSpecifiedInputOutput = !!parsedAmounts[independentField] &&
|
const userHasSpecifiedInputOutput =
|
||||||
|
!!parsedAmounts[independentField] &&
|
||||||
parsedAmounts[independentField].greaterThan(JSBI.BigInt(0)) &&
|
parsedAmounts[independentField].greaterThan(JSBI.BigInt(0)) &&
|
||||||
!!tokens[Field.INPUT] && !!tokens[Field.OUTPUT]
|
!!tokens[Field.INPUT] &&
|
||||||
|
!!tokens[Field.OUTPUT]
|
||||||
const noRoute = !route
|
const noRoute = !route
|
||||||
|
|
||||||
const slippageFromTrade: Percent = trade && trade.slippage
|
const slippageFromTrade: Percent = trade && trade.slippage
|
||||||
@ -213,12 +221,15 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
JSBI.multiply(slippageFromTrade.denominator, JSBI.BigInt('1000'))
|
JSBI.multiply(slippageFromTrade.denominator, JSBI.BigInt('1000'))
|
||||||
)
|
)
|
||||||
|
|
||||||
const onTokenSelection = useCallback((field: Field, address: string) => {
|
const onTokenSelection = useCallback(
|
||||||
dispatch({
|
(field: Field, address: string) => {
|
||||||
type: SwapAction.SELECT_TOKEN,
|
dispatch({
|
||||||
payload: { field, address }
|
type: SwapAction.SELECT_TOKEN,
|
||||||
})
|
payload: { field, address }
|
||||||
}, [dispatch])
|
})
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
const onSwapTokens = useCallback(() => {
|
const onSwapTokens = useCallback(() => {
|
||||||
dispatch({
|
dispatch({
|
||||||
@ -227,29 +238,38 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
})
|
})
|
||||||
}, [dispatch])
|
}, [dispatch])
|
||||||
|
|
||||||
const onUserInput = useCallback((field: Field, typedValue: string) => {
|
const onUserInput = useCallback(
|
||||||
dispatch({ type: SwapAction.TYPE, payload: { field, typedValue } })
|
(field: Field, typedValue: string) => {
|
||||||
}, [dispatch])
|
dispatch({ type: SwapAction.TYPE, payload: { field, typedValue } })
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
const onMaxInput = useCallback((typedValue: string) => {
|
const onMaxInput = useCallback(
|
||||||
dispatch({
|
(typedValue: string) => {
|
||||||
type: SwapAction.TYPE,
|
dispatch({
|
||||||
payload: {
|
type: SwapAction.TYPE,
|
||||||
field: Field.INPUT,
|
payload: {
|
||||||
typedValue
|
field: Field.INPUT,
|
||||||
}
|
typedValue
|
||||||
})
|
}
|
||||||
}, [dispatch])
|
})
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
const onMaxOutput = useCallback((typedValue: string) => {
|
const onMaxOutput = useCallback(
|
||||||
dispatch({
|
(typedValue: string) => {
|
||||||
type: SwapAction.TYPE,
|
dispatch({
|
||||||
payload: {
|
type: SwapAction.TYPE,
|
||||||
field: Field.OUTPUT,
|
payload: {
|
||||||
typedValue
|
field: Field.OUTPUT,
|
||||||
}
|
typedValue
|
||||||
})
|
}
|
||||||
}, [dispatch])
|
})
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
// reset field if sending with with swap is cancled
|
// reset field if sending with with swap is cancled
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -269,11 +289,10 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
WETH[chainId] &&
|
WETH[chainId] &&
|
||||||
JSBI.greaterThan(userBalances[Field.INPUT].raw, isWETH(tokens[Field.INPUT]) ? MIN_ETHER.raw : JSBI.BigInt(0))
|
JSBI.greaterThan(userBalances[Field.INPUT].raw, isWETH(tokens[Field.INPUT]) ? MIN_ETHER.raw : JSBI.BigInt(0))
|
||||||
? isWETH(tokens[Field.INPUT])
|
? isWETH(tokens[Field.INPUT])
|
||||||
? userBalances[Field.INPUT].subtract(MIN_ETHER)
|
? userBalances[Field.INPUT].subtract(MIN_ETHER)
|
||||||
: userBalances[Field.INPUT]
|
: userBalances[Field.INPUT]
|
||||||
: undefined
|
: undefined
|
||||||
} catch {
|
} catch {}
|
||||||
}
|
|
||||||
|
|
||||||
const atMaxAmountInput: boolean =
|
const atMaxAmountInput: boolean =
|
||||||
!!maxAmountInput && !!parsedAmounts[Field.INPUT]
|
!!maxAmountInput && !!parsedAmounts[Field.INPUT]
|
||||||
@ -323,17 +342,28 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
Field.INPUT === independentField
|
Field.INPUT === independentField
|
||||||
? parsedAmounts[Field.INPUT]
|
? parsedAmounts[Field.INPUT]
|
||||||
: calculateSlippageAmount(parsedAmounts[Field.INPUT])?.[0] &&
|
: calculateSlippageAmount(parsedAmounts[Field.INPUT])?.[0] &&
|
||||||
new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.INPUT])?.[1]),
|
new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.INPUT])?.[1]),
|
||||||
[Field.OUTPUT]:
|
[Field.OUTPUT]:
|
||||||
Field.OUTPUT === independentField
|
Field.OUTPUT === independentField
|
||||||
? parsedAmounts[Field.OUTPUT]
|
? parsedAmounts[Field.OUTPUT]
|
||||||
: calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0] &&
|
: calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0] &&
|
||||||
new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0])
|
new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
const showInputApprove: boolean =
|
const showInputApprove: boolean =
|
||||||
parsedAmounts[Field.INPUT] && inputApproval && JSBI.greaterThan(parsedAmounts[Field.INPUT].raw, inputApproval.raw)
|
parsedAmounts[Field.INPUT] && inputApproval && JSBI.greaterThan(parsedAmounts[Field.INPUT].raw, inputApproval.raw)
|
||||||
|
|
||||||
|
// reset modal state when closed
|
||||||
|
function resetModal() {
|
||||||
|
// clear input if txn submitted
|
||||||
|
if (!pendingConfirmation) {
|
||||||
|
onUserInput(Field.INPUT, '')
|
||||||
|
}
|
||||||
|
setPendingConfirmation(true)
|
||||||
|
setAttemptingTxn(false)
|
||||||
|
setShowAdvanced(false)
|
||||||
|
}
|
||||||
|
|
||||||
// function for a pure send
|
// function for a pure send
|
||||||
async function onSend() {
|
async function onSend() {
|
||||||
setAttemptingTxn(true)
|
setAttemptingTxn(true)
|
||||||
@ -349,11 +379,11 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
addTransaction(
|
addTransaction(
|
||||||
response,
|
response,
|
||||||
'Send ' +
|
'Send ' +
|
||||||
parsedAmounts[Field.INPUT]?.toSignificant(3) +
|
parsedAmounts[Field.INPUT]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.INPUT]?.symbol +
|
tokens[Field.INPUT]?.symbol +
|
||||||
' to ' +
|
' to ' +
|
||||||
recipient
|
recipient
|
||||||
)
|
)
|
||||||
setPendingConfirmation(false)
|
setPendingConfirmation(false)
|
||||||
})
|
})
|
||||||
@ -376,11 +406,11 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
addTransaction(
|
addTransaction(
|
||||||
response,
|
response,
|
||||||
'Send ' +
|
'Send ' +
|
||||||
parsedAmounts[Field.INPUT]?.toSignificant(3) +
|
parsedAmounts[Field.INPUT]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.INPUT]?.symbol +
|
tokens[Field.INPUT]?.symbol +
|
||||||
' to ' +
|
' to ' +
|
||||||
recipient
|
recipient
|
||||||
)
|
)
|
||||||
setPendingConfirmation(false)
|
setPendingConfirmation(false)
|
||||||
})
|
})
|
||||||
@ -487,13 +517,13 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
addTransaction(
|
addTransaction(
|
||||||
response,
|
response,
|
||||||
'Swap ' +
|
'Swap ' +
|
||||||
slippageAdjustedAmounts?.[Field.INPUT]?.toSignificant(3) +
|
slippageAdjustedAmounts?.[Field.INPUT]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.INPUT]?.symbol +
|
tokens[Field.INPUT]?.symbol +
|
||||||
' for ' +
|
' for ' +
|
||||||
slippageAdjustedAmounts?.[Field.OUTPUT]?.toSignificant(3) +
|
slippageAdjustedAmounts?.[Field.OUTPUT]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.OUTPUT]?.symbol
|
tokens[Field.OUTPUT]?.symbol
|
||||||
)
|
)
|
||||||
setPendingConfirmation(false)
|
setPendingConfirmation(false)
|
||||||
})
|
})
|
||||||
@ -625,17 +655,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
const warningHigh: boolean =
|
const warningHigh: boolean =
|
||||||
slippageFromTrade && parseFloat(slippageFromTrade.toFixed(4)) > ALLOWED_SLIPPAGE_HIGH / 100
|
slippageFromTrade && parseFloat(slippageFromTrade.toFixed(4)) > ALLOWED_SLIPPAGE_HIGH / 100
|
||||||
|
|
||||||
// reset modal state when closed
|
|
||||||
function resetModal() {
|
|
||||||
// clear input if txn submitted
|
|
||||||
if (!pendingConfirmation) {
|
|
||||||
onUserInput(Field.INPUT, '')
|
|
||||||
}
|
|
||||||
setPendingConfirmation(true)
|
|
||||||
setAttemptingTxn(false)
|
|
||||||
setShowAdvanced(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function modalHeader() {
|
function modalHeader() {
|
||||||
if (sending && !sendingWithSwap) {
|
if (sending && !sendingWithSwap) {
|
||||||
return (
|
return (
|
||||||
@ -644,7 +663,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<Text fontSize={36} fontWeight={500}>
|
<Text fontSize={36} fontWeight={500}>
|
||||||
{parsedAmounts[Field.INPUT]?.toSignificant(6)} {tokens[Field.INPUT]?.symbol}
|
{parsedAmounts[Field.INPUT]?.toSignificant(6)} {tokens[Field.INPUT]?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
<TokenLogo address={tokens[Field.INPUT]?.address} size={'30px'}/>
|
<TokenLogo address={tokens[Field.INPUT]?.address} size={'30px'} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<TYPE.darkGray fontSize={20}>To</TYPE.darkGray>
|
<TYPE.darkGray fontSize={20}>To</TYPE.darkGray>
|
||||||
{ENS ? (
|
{ENS ? (
|
||||||
@ -656,7 +675,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{recipient?.slice(0, 8)}...{recipient?.slice(34, 42)}↗
|
{recipient?.slice(0, 8)}...{recipient?.slice(34, 42)}↗
|
||||||
</TYPE.blue>
|
</TYPE.blue>
|
||||||
</Link>
|
</Link>
|
||||||
<Copy toCopy={recipient}/>
|
<Copy toCopy={recipient} />
|
||||||
</AutoRow>
|
</AutoRow>
|
||||||
</AutoColumn>
|
</AutoColumn>
|
||||||
) : (
|
) : (
|
||||||
@ -666,7 +685,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{recipient?.slice(0, 6)}...{recipient?.slice(36, 42)}↗
|
{recipient?.slice(0, 6)}...{recipient?.slice(36, 42)}↗
|
||||||
</TYPE.blue>
|
</TYPE.blue>
|
||||||
</Link>
|
</Link>
|
||||||
<Copy toCopy={recipient}/>
|
<Copy toCopy={recipient} />
|
||||||
</AutoRow>
|
</AutoRow>
|
||||||
)}
|
)}
|
||||||
</AutoColumn>
|
</AutoColumn>
|
||||||
@ -678,7 +697,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<AutoColumn gap="lg" style={{ marginTop: '40px' }}>
|
<AutoColumn gap="lg" style={{ marginTop: '40px' }}>
|
||||||
<AutoColumn gap="sm">
|
<AutoColumn gap="sm">
|
||||||
<AutoRow gap="10px">
|
<AutoRow gap="10px">
|
||||||
<TokenLogo address={tokens[Field.OUTPUT]?.address} size={'30px'}/>
|
<TokenLogo address={tokens[Field.OUTPUT]?.address} size={'30px'} />
|
||||||
<Text fontSize={36} fontWeight={500}>
|
<Text fontSize={36} fontWeight={500}>
|
||||||
{slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant(4)} {tokens[Field.OUTPUT]?.symbol}
|
{slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant(4)} {tokens[Field.OUTPUT]?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -706,14 +725,14 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{/* {!!slippageAdjustedAmounts[Field.INPUT] && slippageAdjustedAmounts[Field.INPUT].toSignificant(6)} */}
|
{/* {!!slippageAdjustedAmounts[Field.INPUT] && slippageAdjustedAmounts[Field.INPUT].toSignificant(6)} */}
|
||||||
</TruncatedText>
|
</TruncatedText>
|
||||||
<RowFixed gap="4px">
|
<RowFixed gap="4px">
|
||||||
<TokenLogo address={tokens[Field.INPUT]?.address} size={'24px'}/>
|
<TokenLogo address={tokens[Field.INPUT]?.address} size={'24px'} />
|
||||||
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
||||||
{tokens[Field.INPUT]?.symbol || ''}
|
{tokens[Field.INPUT]?.symbol || ''}
|
||||||
</Text>
|
</Text>
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<ArrowDown size="16" color={theme(isDark).text2}/>
|
<ArrowDown size="16" color={theme(isDark).text2} />
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<RowBetween align="flex-end">
|
<RowBetween align="flex-end">
|
||||||
<TruncatedText fontSize={24} fontWeight={500} color={warningHigh ? theme(isDark).red1 : ''}>
|
<TruncatedText fontSize={24} fontWeight={500} color={warningHigh ? theme(isDark).red1 : ''}>
|
||||||
@ -722,7 +741,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{/* {!!slippageAdjustedAmounts[Field.OUTPUT] && slippageAdjustedAmounts[Field.OUTPUT].toSignificant(6)} */}
|
{/* {!!slippageAdjustedAmounts[Field.OUTPUT] && slippageAdjustedAmounts[Field.OUTPUT].toSignificant(6)} */}
|
||||||
</TruncatedText>
|
</TruncatedText>
|
||||||
<RowFixed gap="4px">
|
<RowFixed gap="4px">
|
||||||
<TokenLogo address={tokens[Field.OUTPUT]?.address} size={'24px'}/>
|
<TokenLogo address={tokens[Field.OUTPUT]?.address} size={'24px'} />
|
||||||
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
||||||
{tokens[Field.OUTPUT]?.symbol || ''}
|
{tokens[Field.OUTPUT]?.symbol || ''}
|
||||||
</Text>
|
</Text>
|
||||||
@ -782,17 +801,17 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
>
|
>
|
||||||
{trade && showInverted
|
{trade && showInverted
|
||||||
? (trade?.executionPrice?.invert()?.toSignificant(6) ?? '') +
|
? (trade?.executionPrice?.invert()?.toSignificant(6) ?? '') +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.INPUT]?.symbol +
|
tokens[Field.INPUT]?.symbol +
|
||||||
' / ' +
|
' / ' +
|
||||||
tokens[Field.OUTPUT]?.symbol
|
tokens[Field.OUTPUT]?.symbol
|
||||||
: (trade?.executionPrice?.toSignificant(6) ?? '') +
|
: (trade?.executionPrice?.toSignificant(6) ?? '') +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.OUTPUT]?.symbol +
|
tokens[Field.OUTPUT]?.symbol +
|
||||||
' / ' +
|
' / ' +
|
||||||
tokens[Field.INPUT]?.symbol}
|
tokens[Field.INPUT]?.symbol}
|
||||||
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
|
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
|
||||||
<Repeat size={14}/>
|
<Repeat size={14} />
|
||||||
</StyledBalanceMaxMini>
|
</StyledBalanceMaxMini>
|
||||||
</Text>
|
</Text>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
@ -802,8 +821,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<TYPE.black fontSize={14} fontWeight={400}>
|
<TYPE.black fontSize={14} fontWeight={400}>
|
||||||
{independentField === Field.INPUT ? (sending ? 'Min sent' : 'Minimum received') : 'Maximum sold'}
|
{independentField === Field.INPUT ? (sending ? 'Min sent' : 'Minimum received') : 'Maximum sold'}
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper
|
<QuestionHelper text="A boundary is set so you are protected from large price movements after you submit your trade." />
|
||||||
text="A boundary is set so you are protected from large price movements after you submit your trade."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<TYPE.black fontSize={14}>
|
<TYPE.black fontSize={14}>
|
||||||
@ -814,10 +832,10 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
: slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5)
|
: slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5)
|
||||||
: '-'
|
: '-'
|
||||||
: slippageAdjustedAmounts[Field.INPUT]
|
: slippageAdjustedAmounts[Field.INPUT]
|
||||||
? slippageAdjustedAmounts[Field.INPUT]?.toFixed(5) === '0.00000'
|
? slippageAdjustedAmounts[Field.INPUT]?.toFixed(5) === '0.00000'
|
||||||
? '<0.00001'
|
? '<0.00001'
|
||||||
: slippageAdjustedAmounts[Field.INPUT]?.toFixed(5)
|
: slippageAdjustedAmounts[Field.INPUT]?.toFixed(5)
|
||||||
: '-'}
|
: '-'}
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
{parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.INPUT] && (
|
{parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.INPUT] && (
|
||||||
<TYPE.black fontSize={14} marginLeft={'4px'}>
|
<TYPE.black fontSize={14} marginLeft={'4px'}>
|
||||||
@ -833,7 +851,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<TYPE.black color={theme(isDark).text1} fontSize={14} fontWeight={400}>
|
<TYPE.black color={theme(isDark).text1} fontSize={14} fontWeight={400}>
|
||||||
Price impact
|
Price impact
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper text="The difference between the market price and your price due to trade size."/>
|
<QuestionHelper text="The difference between the market price and your price due to trade size." />
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<ErrorText
|
<ErrorText
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
@ -854,8 +872,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<TYPE.black fontSize={14} fontWeight={400}>
|
<TYPE.black fontSize={14} fontWeight={400}>
|
||||||
Liquidity Provider Fee
|
Liquidity Provider Fee
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper
|
<QuestionHelper text="A portion of each trade (0.3%) goes to liquidity providers to incentivize liquidity on the protocol." />
|
||||||
text="A portion of each trade (0.3%) goes to liquidity providers to incentivize liquidity on the protocol."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<TYPE.black fontSize={14}>
|
<TYPE.black fontSize={14}>
|
||||||
{feeTimesInputFormatted
|
{feeTimesInputFormatted
|
||||||
@ -877,7 +894,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PriceBar = function () {
|
const PriceBar = function() {
|
||||||
return (
|
return (
|
||||||
<AutoRow justify="space-between">
|
<AutoRow justify="space-between">
|
||||||
<AutoColumn justify="center">
|
<AutoColumn justify="center">
|
||||||
@ -924,7 +941,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
? `Sending ${parsedAmounts[Field.OUTPUT]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol} to ${recipient}`
|
? `Sending ${parsedAmounts[Field.OUTPUT]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol} to ${recipient}`
|
||||||
: `Sending ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${tokens[Field.INPUT]?.symbol} to ${recipient}`
|
: `Sending ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${tokens[Field.INPUT]?.symbol} to ${recipient}`
|
||||||
: ` Swapping ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${tokens[Field.INPUT]?.symbol} for ${parsedAmounts[
|
: ` Swapping ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${tokens[Field.INPUT]?.symbol} for ${parsedAmounts[
|
||||||
Field.OUTPUT
|
Field.OUTPUT
|
||||||
]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol}`
|
]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol}`
|
||||||
|
|
||||||
function _onTokenSelect(address: string) {
|
function _onTokenSelect(address: string) {
|
||||||
@ -979,7 +996,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
Max
|
Max
|
||||||
</MaxButton>
|
</MaxButton>
|
||||||
)}
|
)}
|
||||||
<StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)}/>
|
<StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)} />
|
||||||
<CurrencyInputPanel
|
<CurrencyInputPanel
|
||||||
field={Field.INPUT}
|
field={Field.INPUT}
|
||||||
value={formattedAmounts[Field.INPUT]}
|
value={formattedAmounts[Field.INPUT]}
|
||||||
@ -1025,7 +1042,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<ColumnCenter>
|
<ColumnCenter>
|
||||||
<RowBetween padding="0 12px">
|
<RowBetween padding="0 12px">
|
||||||
<ArrowWrapper onClick={onSwapTokens}>
|
<ArrowWrapper onClick={onSwapTokens}>
|
||||||
<ArrowDown size="16" color={theme(isDark).text2} onClick={onSwapTokens}/>
|
<ArrowDown size="16" color={theme(isDark).text2} onClick={onSwapTokens} />
|
||||||
</ArrowWrapper>
|
</ArrowWrapper>
|
||||||
<StyledBalanceMaxMini onClick={() => setSendingWithSwap(false)} style={{ marginRight: '0px' }}>
|
<StyledBalanceMaxMini onClick={() => setSendingWithSwap(false)} style={{ marginRight: '0px' }}>
|
||||||
<TYPE.blue>Remove Swap</TYPE.blue>
|
<TYPE.blue>Remove Swap</TYPE.blue>
|
||||||
@ -1063,7 +1080,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
/>
|
/>
|
||||||
{sendingWithSwap && (
|
{sendingWithSwap && (
|
||||||
<RowBetween padding="0 12px">
|
<RowBetween padding="0 12px">
|
||||||
<ArrowDown size="16"/>
|
<ArrowDown size="16" />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@ -1095,7 +1112,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
|
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
|
||||||
<Card padding={advanced ? '.25rem 1.25rem 0 .75rem' : '.25rem .7rem .25rem 1.25rem'} borderRadius={'20px'}>
|
<Card padding={advanced ? '.25rem 1.25rem 0 .75rem' : '.25rem .7rem .25rem 1.25rem'} borderRadius={'20px'}>
|
||||||
{advanced ? (
|
{advanced ? (
|
||||||
<PriceBar/>
|
<PriceBar />
|
||||||
) : (
|
) : (
|
||||||
<AutoColumn gap="4px">
|
<AutoColumn gap="4px">
|
||||||
{' '}
|
{' '}
|
||||||
@ -1111,17 +1128,17 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
>
|
>
|
||||||
{trade && showInverted
|
{trade && showInverted
|
||||||
? (trade?.executionPrice?.invert()?.toSignificant(6) ?? '') +
|
? (trade?.executionPrice?.invert()?.toSignificant(6) ?? '') +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.INPUT]?.symbol +
|
tokens[Field.INPUT]?.symbol +
|
||||||
' per ' +
|
' per ' +
|
||||||
tokens[Field.OUTPUT]?.symbol
|
tokens[Field.OUTPUT]?.symbol
|
||||||
: (trade?.executionPrice?.toSignificant(6) ?? '') +
|
: (trade?.executionPrice?.toSignificant(6) ?? '') +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.OUTPUT]?.symbol +
|
tokens[Field.OUTPUT]?.symbol +
|
||||||
' per ' +
|
' per ' +
|
||||||
tokens[Field.INPUT]?.symbol}
|
tokens[Field.INPUT]?.symbol}
|
||||||
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
|
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
|
||||||
<Repeat size={14}/>
|
<Repeat size={14} />
|
||||||
</StyledBalanceMaxMini>
|
</StyledBalanceMaxMini>
|
||||||
</Text>
|
</Text>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
@ -1141,8 +1158,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
: priceSlippage.toFixed(4) + '%'
|
: priceSlippage.toFixed(4) + '%'
|
||||||
: '-'}{' '}
|
: '-'}{' '}
|
||||||
</ErrorText>
|
</ErrorText>
|
||||||
<QuestionHelper
|
<QuestionHelper text="The difference between the market price and your quoted price due to trade size." />
|
||||||
text="The difference between the market price and your quoted price due to trade size."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
)}
|
)}
|
||||||
@ -1189,9 +1205,12 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<Text fontSize={20} fontWeight={500}>
|
<Text fontSize={20} fontWeight={500}>
|
||||||
{!account
|
{!account
|
||||||
? 'Connect Wallet'
|
? 'Connect Wallet'
|
||||||
: (generalError || inputError || outputError || recipientError || tradeError) ||
|
: generalError ||
|
||||||
(`${sending ? 'Send' : 'Swap'}${warningHigh ? ' Anyway' : ''}`)
|
inputError ||
|
||||||
}
|
outputError ||
|
||||||
|
recipientError ||
|
||||||
|
tradeError ||
|
||||||
|
`${sending ? 'Send' : 'Swap'}${warningHigh ? ' Anyway' : ''}`}
|
||||||
</Text>
|
</Text>
|
||||||
</ButtonError>
|
</ButtonError>
|
||||||
)}
|
)}
|
||||||
@ -1204,7 +1223,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<Text fontSize={16} fontWeight={500} style={{ userSelect: 'none' }}>
|
<Text fontSize={16} fontWeight={500} style={{ userSelect: 'none' }}>
|
||||||
Show Advanced
|
Show Advanced
|
||||||
</Text>
|
</Text>
|
||||||
<ChevronDown color={theme(isDark).text2}/>
|
<ChevronDown color={theme(isDark).text2} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</Hover>
|
</Hover>
|
||||||
)}
|
)}
|
||||||
@ -1215,10 +1234,10 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<Text fontSize={16} color={theme(isDark).text2} fontWeight={500} style={{ userSelect: 'none' }}>
|
<Text fontSize={16} color={theme(isDark).text2} fontWeight={500} style={{ userSelect: 'none' }}>
|
||||||
Hide Advanced
|
Hide Advanced
|
||||||
</Text>
|
</Text>
|
||||||
<ChevronUp color={theme(isDark).text2}/>
|
<ChevronUp color={theme(isDark).text2} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</Hover>
|
</Hover>
|
||||||
<SectionBreak/>
|
<SectionBreak />
|
||||||
<AutoColumn style={{ padding: '0 20px' }}>
|
<AutoColumn style={{ padding: '0 20px' }}>
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
@ -1233,8 +1252,8 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
text={
|
text={
|
||||||
independentField === Field.INPUT
|
independentField === Field.INPUT
|
||||||
? sending
|
? sending
|
||||||
? 'Price can change between when a transaction is submitted and when it is executed. This is the minimum amount you will send. A worse rate will cause your transaction to revert.'
|
? 'Price can change between when a transaction is submitted and when it is executed. This is the minimum amount you will send. A worse rate will cause your transaction to revert.'
|
||||||
: 'Price can change between when a transaction is submitted and when it is executed. This is the minimum amount you will receive. A worse rate will cause your transaction to revert.'
|
: 'Price can change between when a transaction is submitted and when it is executed. This is the minimum amount you will receive. A worse rate will cause your transaction to revert.'
|
||||||
: 'Price can change between when a transaction is submitted and when it is executed. This is the maximum amount you will pay. A worse rate will cause your transaction to revert.'
|
: 'Price can change between when a transaction is submitted and when it is executed. This is the maximum amount you will pay. A worse rate will cause your transaction to revert.'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -1244,18 +1263,18 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
{independentField === Field.INPUT
|
{independentField === Field.INPUT
|
||||||
? slippageAdjustedAmounts[Field.OUTPUT]
|
? slippageAdjustedAmounts[Field.OUTPUT]
|
||||||
? slippageAdjustedAmounts[Field.OUTPUT]?.lessThan(
|
? slippageAdjustedAmounts[Field.OUTPUT]?.lessThan(
|
||||||
new Fraction(JSBI.BigInt(1), JSBI.BigInt(10000))
|
new Fraction(JSBI.BigInt(1), JSBI.BigInt(10000))
|
||||||
)
|
)
|
||||||
? '<0.00001'
|
? '<0.00001'
|
||||||
: slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5)
|
: slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5)
|
||||||
: '-'
|
: '-'
|
||||||
: slippageAdjustedAmounts[Field.INPUT]
|
: slippageAdjustedAmounts[Field.INPUT]
|
||||||
? slippageAdjustedAmounts[Field.INPUT]?.lessThan(
|
? slippageAdjustedAmounts[Field.INPUT]?.lessThan(
|
||||||
new Fraction(JSBI.BigInt(1), JSBI.BigInt(10000))
|
new Fraction(JSBI.BigInt(1), JSBI.BigInt(10000))
|
||||||
)
|
)
|
||||||
? '<0.00001'
|
? '<0.00001'
|
||||||
: slippageAdjustedAmounts[Field.INPUT]?.toFixed(5)
|
: slippageAdjustedAmounts[Field.INPUT]?.toFixed(5)
|
||||||
: '-'}
|
: '-'}
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
{parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.INPUT] && (
|
{parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.INPUT] && (
|
||||||
<TYPE.black fontSize={14} marginLeft={'4px'} color={theme(isDark).text1}>
|
<TYPE.black fontSize={14} marginLeft={'4px'} color={theme(isDark).text1}>
|
||||||
@ -1271,8 +1290,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
|
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
|
||||||
Price Impact
|
Price Impact
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper
|
<QuestionHelper text="The difference between the market price and your quoted price due to trade size." />
|
||||||
text="The difference between the market price and your quoted price due to trade size."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<ErrorText
|
<ErrorText
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
@ -1293,8 +1311,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
|
<TYPE.black fontSize={14} fontWeight={400} color={theme(isDark).text1}>
|
||||||
Liquidity Provider Fee
|
Liquidity Provider Fee
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper
|
<QuestionHelper text="A portion of each trade (0.03%) goes to liquidity providers to incentivize liquidity on the protocol." />
|
||||||
text="A portion of each trade (0.03%) goes to liquidity providers to incentivize liquidity on the protocol."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<TYPE.black fontSize={14} color={theme(isDark).text1}>
|
<TYPE.black fontSize={14} color={theme(isDark).text1}>
|
||||||
{feeTimesInputFormatted
|
{feeTimesInputFormatted
|
||||||
@ -1303,13 +1320,12 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
|
|||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</AutoColumn>
|
</AutoColumn>
|
||||||
<SectionBreak/>
|
<SectionBreak />
|
||||||
<RowFixed padding={'0 20px'}>
|
<RowFixed padding={'0 20px'}>
|
||||||
<TYPE.black fontWeight={400} fontSize={14} color={theme(isDark).text1}>
|
<TYPE.black fontWeight={400} fontSize={14} color={theme(isDark).text1}>
|
||||||
Set front running resistance
|
Set front running resistance
|
||||||
</TYPE.black>
|
</TYPE.black>
|
||||||
<QuestionHelper
|
<QuestionHelper text="Your transaction will revert if the price changes more than this amount after you submit your trade." />
|
||||||
text="Your transaction will revert if the price changes more than this amount after you submit your trade."/>
|
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<SlippageTabs
|
<SlippageTabs
|
||||||
rawSlippage={allowedSlippage}
|
rawSlippage={allowedSlippage}
|
||||||
|
@ -57,7 +57,7 @@ export const BottomGrouping = styled.div`
|
|||||||
|
|
||||||
export const ErrorText = styled(Text)`
|
export const ErrorText = styled(Text)`
|
||||||
color: ${({ theme, warningLow, warningMedium, warningHigh }) =>
|
color: ${({ theme, warningLow, warningMedium, warningHigh }) =>
|
||||||
warningHigh ? theme.red1 : warningMedium ? theme.yellow2 : warningLow ? theme.green1 : theme.text1};
|
warningHigh ? theme.red1 : warningMedium ? theme.yellow2 : warningLow ? theme.green1 : theme.text1};
|
||||||
`
|
`
|
||||||
|
|
||||||
export const InputGroup = styled(AutoColumn)`
|
export const InputGroup = styled(AutoColumn)`
|
||||||
|
@ -19,7 +19,12 @@ export interface SwapState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initializeSwapState({ inputTokenAddress, outputTokenAddress, typedValue, independentField }): SwapState {
|
export function initializeSwapState({
|
||||||
|
inputTokenAddress,
|
||||||
|
outputTokenAddress,
|
||||||
|
typedValue,
|
||||||
|
independentField
|
||||||
|
}): SwapState {
|
||||||
return {
|
return {
|
||||||
independentField: independentField,
|
independentField: independentField,
|
||||||
typedValue: typedValue,
|
typedValue: typedValue,
|
||||||
@ -110,21 +115,21 @@ export function useSwapStateReducer(params: QueryParams) {
|
|||||||
typedValue:
|
typedValue:
|
||||||
params.inputTokenAddress && !params.outputTokenAddress
|
params.inputTokenAddress && !params.outputTokenAddress
|
||||||
? params.inputTokenAmount
|
? params.inputTokenAmount
|
||||||
? params.inputTokenAmount
|
? params.inputTokenAmount
|
||||||
: ''
|
: ''
|
||||||
: !params.inputTokenAddress && params.outputTokenAddress
|
: !params.inputTokenAddress && params.outputTokenAddress
|
||||||
? params.outputTokenAmount
|
? params.outputTokenAmount
|
||||||
? params.outputTokenAmount
|
? params.outputTokenAmount
|
||||||
: ''
|
: ''
|
||||||
: params.inputTokenAddress && params.outputTokenAddress
|
: params.inputTokenAddress && params.outputTokenAddress
|
||||||
|
? params.inputTokenAmount
|
||||||
? params.inputTokenAmount
|
? params.inputTokenAmount
|
||||||
? params.inputTokenAmount
|
|
||||||
: ''
|
|
||||||
: ''
|
: ''
|
||||||
? ''
|
: ''
|
||||||
: ''
|
? ''
|
||||||
? ''
|
: ''
|
||||||
: ''
|
? ''
|
||||||
|
: ''
|
||||||
},
|
},
|
||||||
initializeSwapState
|
initializeSwapState
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { withRouter } from 'react-router-dom'
|
|
||||||
|
|
||||||
import Row from '../Row'
|
import Row from '../Row'
|
||||||
import Menu from '../Menu'
|
import Menu from '../Menu'
|
||||||
@ -64,7 +63,7 @@ const TitleText = styled(Row)`
|
|||||||
`};
|
`};
|
||||||
`
|
`
|
||||||
|
|
||||||
const AccountElement = styled.div<{active: boolean;}>`
|
const AccountElement = styled.div<{ active: boolean }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -107,7 +106,7 @@ const Alpha = styled(GreyCard)`
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
`
|
`
|
||||||
|
|
||||||
const UniIcon = styled.div<{href: string}>`
|
const UniIcon = styled.div<{ href: string }>`
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
:hover {
|
:hover {
|
||||||
transform: rotate(-5deg);
|
transform: rotate(-5deg);
|
||||||
@ -133,7 +132,7 @@ const MigrateBanner = styled(AutoColumn)`
|
|||||||
`};
|
`};
|
||||||
`
|
`
|
||||||
|
|
||||||
function Header({ history }) {
|
export default function Header() {
|
||||||
const { account, chainId } = useWeb3React()
|
const { account, chainId } = useWeb3React()
|
||||||
|
|
||||||
const userEthBalance = useAddressBalance(account, WETH[chainId])
|
const userEthBalance = useAddressBalance(account, WETH[chainId])
|
||||||
@ -196,5 +195,3 @@ function Header({ history }) {
|
|||||||
</HeaderFrame>
|
</HeaderFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(Header)
|
|
||||||
|
@ -24,5 +24,5 @@ export default function Identicon() {
|
|||||||
}
|
}
|
||||||
}, [account])
|
}, [account])
|
||||||
|
|
||||||
return <StyledIdenticon ref={ref}/>
|
return <StyledIdenticon ref={ref} />
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@ const SpinnerWrapper = styled(Spinner)<{ size: string }>`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export default function Loader({ size }: { size: string }) {
|
export default function Loader({ size }: { size: string }) {
|
||||||
return <SpinnerWrapper src={Circle} alt="loader" size={size}/>
|
return <SpinnerWrapper src={Circle} alt="loader" size={size} />
|
||||||
}
|
}
|
||||||
|
@ -78,9 +78,9 @@ const MenuItem = styled(Link)`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const CODE_LINK = !!process.env.REACT_APP_GIT_COMMIT_HASH ?
|
const CODE_LINK = !!process.env.REACT_APP_GIT_COMMIT_HASH
|
||||||
`https://github.com/Uniswap/uniswap-frontend/tree/${process.env.REACT_APP_GIT_COMMIT_HASH}`:
|
? `https://github.com/Uniswap/uniswap-frontend/tree/${process.env.REACT_APP_GIT_COMMIT_HASH}`
|
||||||
'https://github.com/Uniswap/uniswap-frontend'
|
: 'https://github.com/Uniswap/uniswap-frontend'
|
||||||
|
|
||||||
export default function Menu() {
|
export default function Menu() {
|
||||||
const node = useRef<HTMLDivElement>()
|
const node = useRef<HTMLDivElement>()
|
||||||
|
@ -22,8 +22,8 @@ const StyledDialogOverlay = styled(WrappedDialogOverlay).attrs({
|
|||||||
background-color: ${({ theme }) => 'transparent'};
|
background-color: ${({ theme }) => 'transparent'};
|
||||||
|
|
||||||
${({ mobile }) =>
|
${({ mobile }) =>
|
||||||
mobile &&
|
mobile &&
|
||||||
css`
|
css`
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
`}
|
`}
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ const StyledDialogContent = styled(FilteredDialogContent)`
|
|||||||
|
|
||||||
max-width: 420px;
|
max-width: 420px;
|
||||||
${({ maxHeight }) =>
|
${({ maxHeight }) =>
|
||||||
maxHeight &&
|
maxHeight &&
|
||||||
css`
|
css`
|
||||||
max-height: ${maxHeight}vh;
|
max-height: ${maxHeight}vh;
|
||||||
`}
|
`}
|
||||||
${({ minHeight }) =>
|
${({ minHeight }) =>
|
||||||
minHeight &&
|
minHeight &&
|
||||||
css`
|
css`
|
||||||
min-height: ${minHeight}vh;
|
min-height: ${minHeight}vh;
|
||||||
`}
|
`}
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -77,7 +77,7 @@ const StyledDialogContent = styled(FilteredDialogContent)`
|
|||||||
width: 85vw;
|
width: 85vw;
|
||||||
max-height: 66vh;
|
max-height: 66vh;
|
||||||
${mobile &&
|
${mobile &&
|
||||||
css`
|
css`
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
@ -105,13 +105,13 @@ interface ModalProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Modal({
|
export default function Modal({
|
||||||
isOpen,
|
isOpen,
|
||||||
onDismiss,
|
onDismiss,
|
||||||
minHeight = false,
|
minHeight = false,
|
||||||
maxHeight = 50,
|
maxHeight = 50,
|
||||||
initialFocusRef = null,
|
initialFocusRef = null,
|
||||||
children
|
children
|
||||||
}: ModalProps) {
|
}: ModalProps) {
|
||||||
const transitions = useTransition(isOpen, null, {
|
const transitions = useTransition(isOpen, null, {
|
||||||
config: { duration: 200 },
|
config: { duration: 200 },
|
||||||
from: { opacity: 0 },
|
from: { opacity: 0 },
|
||||||
@ -163,7 +163,9 @@ export default function Modal({
|
|||||||
{props => (
|
{props => (
|
||||||
<animated.div
|
<animated.div
|
||||||
{...bind()}
|
{...bind()}
|
||||||
style={{ transform: (xy as any).interpolate((x, y) => `translate3d(${0}px,${y > 0 ? y : 0}px,0)`) }}
|
style={{
|
||||||
|
transform: (xy as any).interpolate((x, y) => `translate3d(${0}px,${y > 0 ? y : 0}px,0)`)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<StyledDialogContent
|
<StyledDialogContent
|
||||||
style={props}
|
style={props}
|
||||||
@ -172,7 +174,7 @@ export default function Modal({
|
|||||||
maxHeight={maxHeight}
|
maxHeight={maxHeight}
|
||||||
mobile={isMobile}
|
mobile={isMobile}
|
||||||
>
|
>
|
||||||
<HiddenCloseButton onClick={onDismiss}/>
|
<HiddenCloseButton onClick={onDismiss} />
|
||||||
{children}
|
{children}
|
||||||
</StyledDialogContent>
|
</StyledDialogContent>
|
||||||
</animated.div>
|
</animated.div>
|
||||||
@ -203,7 +205,7 @@ export default function Modal({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
mobile={isMobile}
|
mobile={isMobile}
|
||||||
>
|
>
|
||||||
<HiddenCloseButton onClick={onDismiss}/>
|
<HiddenCloseButton onClick={onDismiss} />
|
||||||
{children}
|
{children}
|
||||||
</StyledDialogContent>
|
</StyledDialogContent>
|
||||||
</StyledDialogOverlay>
|
</StyledDialogOverlay>
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react'
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components'
|
||||||
import { darken } from 'polished';
|
import { darken } from 'polished'
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next'
|
||||||
import { withRouter, NavLink, Link as HistoryLink, RouteComponentProps } from 'react-router-dom';
|
import { withRouter, NavLink, Link as HistoryLink, RouteComponentProps } from 'react-router-dom'
|
||||||
|
|
||||||
import { Hover } from '../../theme';
|
import { Hover } from '../../theme'
|
||||||
import { ArrowLeft } from 'react-feather';
|
import { ArrowLeft } from 'react-feather'
|
||||||
import { RowBetween } from '../Row';
|
import { RowBetween } from '../Row'
|
||||||
import QuestionHelper from '../Question';
|
import QuestionHelper from '../Question'
|
||||||
|
|
||||||
import { useBodyKeyDown } from '../../hooks';
|
import { useBodyKeyDown } from '../../hooks'
|
||||||
|
|
||||||
const tabOrder = [
|
const tabOrder = [
|
||||||
{
|
{
|
||||||
@ -27,16 +27,16 @@ const tabOrder = [
|
|||||||
textKey: 'pool',
|
textKey: 'pool',
|
||||||
regex: /\/pool/
|
regex: /\/pool/
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
|
||||||
const Tabs = styled.div`
|
const Tabs = styled.div`
|
||||||
${({ theme }) => theme.flexRowNoWrap}
|
${({ theme }) => theme.flexRowNoWrap}
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
`;
|
`
|
||||||
|
|
||||||
const activeClassName = 'ACTIVE';
|
const activeClassName = 'ACTIVE'
|
||||||
|
|
||||||
const StyledNavLink = styled(NavLink).attrs({
|
const StyledNavLink = styled(NavLink).attrs({
|
||||||
activeClassName
|
activeClassName
|
||||||
@ -65,41 +65,41 @@ const StyledNavLink = styled(NavLink).attrs({
|
|||||||
:focus {
|
:focus {
|
||||||
color: ${({ theme }) => darken(0.1, theme.text1)};
|
color: ${({ theme }) => darken(0.1, theme.text1)};
|
||||||
}
|
}
|
||||||
`;
|
`
|
||||||
|
|
||||||
const ActiveText = styled.div`
|
const ActiveText = styled.div`
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
`;
|
`
|
||||||
|
|
||||||
const ArrowLink = styled(ArrowLeft)`
|
const ArrowLink = styled(ArrowLeft)`
|
||||||
color: ${({ theme }) => theme.text1};
|
color: ${({ theme }) => theme.text1};
|
||||||
`;
|
`
|
||||||
|
|
||||||
function NavigationTabs({ location: { pathname }, history }: RouteComponentProps<{}>) {
|
function NavigationTabs({ location: { pathname }, history }: RouteComponentProps<{}>) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const navigate = useCallback(
|
const navigate = useCallback(
|
||||||
direction => {
|
direction => {
|
||||||
const tabIndex = tabOrder.findIndex(({ regex }) => pathname.match(regex));
|
const tabIndex = tabOrder.findIndex(({ regex }) => pathname.match(regex))
|
||||||
history.push(tabOrder[ (tabIndex + tabOrder.length + direction) % tabOrder.length ].path);
|
history.push(tabOrder[(tabIndex + tabOrder.length + direction) % tabOrder.length].path)
|
||||||
},
|
},
|
||||||
[pathname, history]
|
[pathname, history]
|
||||||
);
|
)
|
||||||
const navigateRight = useCallback(() => {
|
const navigateRight = useCallback(() => {
|
||||||
navigate(1);
|
navigate(1)
|
||||||
}, [navigate]);
|
}, [navigate])
|
||||||
const navigateLeft = useCallback(() => {
|
const navigateLeft = useCallback(() => {
|
||||||
navigate(-1);
|
navigate(-1)
|
||||||
}, [navigate]);
|
}, [navigate])
|
||||||
|
|
||||||
useBodyKeyDown('ArrowRight', navigateRight);
|
useBodyKeyDown('ArrowRight', navigateRight)
|
||||||
useBodyKeyDown('ArrowLeft', navigateLeft);
|
useBodyKeyDown('ArrowLeft', navigateLeft)
|
||||||
|
|
||||||
const adding = pathname.match('/add');
|
const adding = pathname.match('/add')
|
||||||
const removing = pathname.match('/remove');
|
const removing = pathname.match('/remove')
|
||||||
const finding = pathname.match('/find');
|
const finding = pathname.match('/find')
|
||||||
const creating = pathname.match('/create');
|
const creating = pathname.match('/create')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -107,7 +107,7 @@ function NavigationTabs({ location: { pathname }, history }: RouteComponentProps
|
|||||||
<Tabs>
|
<Tabs>
|
||||||
<RowBetween style={{ padding: '1rem 1rem 0 1rem' }}>
|
<RowBetween style={{ padding: '1rem 1rem 0 1rem' }}>
|
||||||
<Hover onClick={() => history.goBack()}>
|
<Hover onClick={() => history.goBack()}>
|
||||||
<ArrowLink/>
|
<ArrowLink />
|
||||||
</Hover>
|
</Hover>
|
||||||
<ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText>
|
<ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText>
|
||||||
<QuestionHelper
|
<QuestionHelper
|
||||||
@ -123,20 +123,20 @@ function NavigationTabs({ location: { pathname }, history }: RouteComponentProps
|
|||||||
<Tabs>
|
<Tabs>
|
||||||
<RowBetween style={{ padding: '1rem' }}>
|
<RowBetween style={{ padding: '1rem' }}>
|
||||||
<HistoryLink to="/pool">
|
<HistoryLink to="/pool">
|
||||||
<ArrowLink/>
|
<ArrowLink />
|
||||||
</HistoryLink>
|
</HistoryLink>
|
||||||
<ActiveText>Import Pool</ActiveText>
|
<ActiveText>Import Pool</ActiveText>
|
||||||
<QuestionHelper text={'Use this tool to find pairs that don\'t automatically appear in the interface.'}/>
|
<QuestionHelper text={"Use this tool to find pairs that don't automatically appear in the interface."} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
) : creating ? (
|
) : creating ? (
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<RowBetween style={{ padding: '1rem' }}>
|
<RowBetween style={{ padding: '1rem' }}>
|
||||||
<HistoryLink to="/pool">
|
<HistoryLink to="/pool">
|
||||||
<ArrowLink/>
|
<ArrowLink />
|
||||||
</HistoryLink>
|
</HistoryLink>
|
||||||
<ActiveText>Create Pool</ActiveText>
|
<ActiveText>Create Pool</ActiveText>
|
||||||
<QuestionHelper text={'Use this interface to create a new pool.'}/>
|
<QuestionHelper text={'Use this interface to create a new pool.'} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
) : (
|
) : (
|
||||||
@ -149,7 +149,7 @@ function NavigationTabs({ location: { pathname }, history }: RouteComponentProps
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(NavigationTabs);
|
export default withRouter(NavigationTabs)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
const StyledInput = styled.input<{error?: boolean; fontSize?: string; align?: string}>`
|
const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: string }>`
|
||||||
color: ${({ error, theme }) => error && theme.red1};
|
color: ${({ error, theme }) => error && theme.red1};
|
||||||
color: ${({ theme }) => theme.text1};
|
color: ${({ theme }) => theme.text1};
|
||||||
width: 0;
|
width: 0;
|
||||||
@ -45,8 +45,20 @@ function escapeRegExp(string: string): string {
|
|||||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Input = React.memo(({ value, onUserInput, placeHolder = null, ...rest }: any) => {
|
export const Input = React.memo(function InnerInput({
|
||||||
function enforcer(nextUserInput: string) {
|
value,
|
||||||
|
onUserInput,
|
||||||
|
placeHolder,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
value: string | number
|
||||||
|
onUserInput: (string) => void
|
||||||
|
placeHolder?: string
|
||||||
|
align?: 'right' | 'left'
|
||||||
|
id?: string
|
||||||
|
onClick?: () => void
|
||||||
|
}) {
|
||||||
|
const enforcer = (nextUserInput: string) => {
|
||||||
if (nextUserInput === '' || inputRegex.test(escapeRegExp(nextUserInput))) {
|
if (nextUserInput === '' || inputRegex.test(escapeRegExp(nextUserInput))) {
|
||||||
onUserInput(nextUserInput)
|
onUserInput(nextUserInput)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { withRouter } from 'react-router-dom'
|
import { RouteComponentProps, withRouter } from 'react-router-dom'
|
||||||
import { TokenAmount, JSBI, Token, Pair } from '@uniswap/sdk'
|
import { TokenAmount, JSBI, Token, Pair } from '@uniswap/sdk'
|
||||||
|
|
||||||
import Row from '../Row'
|
import Row from '../Row'
|
||||||
@ -21,7 +21,7 @@ import { useWeb3React } from '@web3-react/core'
|
|||||||
import { useAddressBalance } from '../../contexts/Balances'
|
import { useAddressBalance } from '../../contexts/Balances'
|
||||||
import { usePair, useAllPairs } from '../../contexts/Pairs'
|
import { usePair, useAllPairs } from '../../contexts/Pairs'
|
||||||
|
|
||||||
function PoolFinder({ history }) {
|
function PoolFinder({ history }: RouteComponentProps) {
|
||||||
const Fields = {
|
const Fields = {
|
||||||
TOKEN0: 0,
|
TOKEN0: 0,
|
||||||
TOKEN1: 1
|
TOKEN1: 1
|
||||||
@ -65,20 +65,20 @@ function PoolFinder({ history }) {
|
|||||||
function endSearch() {
|
function endSearch() {
|
||||||
history.goBack() // return to previous page
|
history.goBack() // return to previous page
|
||||||
newLiquidity &&
|
newLiquidity &&
|
||||||
addPopup(
|
addPopup(
|
||||||
<AutoColumn gap={'10px'}>
|
<AutoColumn gap={'10px'}>
|
||||||
<Text fontSize={20} fontWeight={500}>
|
<Text fontSize={20} fontWeight={500}>
|
||||||
Pool Imported
|
Pool Imported
|
||||||
</Text>
|
|
||||||
<Row>
|
|
||||||
<DoubleTokenLogo a0={token0Address || ''} a1={token1Address || ''} margin={true}/>
|
|
||||||
<Text fontSize={16} fotnWeight={500}>
|
|
||||||
UNI {token0?.symbol} / {token1?.symbol}
|
|
||||||
</Text>
|
</Text>
|
||||||
</Row>
|
<Row>
|
||||||
<Link>View on Uniswap Info.</Link>
|
<DoubleTokenLogo a0={token0Address || ''} a1={token1Address || ''} margin={true} />
|
||||||
</AutoColumn>
|
<Text fontSize={16} fotnWeight={500}>
|
||||||
)
|
UNI {token0?.symbol} / {token1?.symbol}
|
||||||
|
</Text>
|
||||||
|
</Row>
|
||||||
|
<Link>View on Uniswap Info.</Link>
|
||||||
|
</AutoColumn>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -101,7 +101,7 @@ function PoolFinder({ history }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Row>
|
<Row>
|
||||||
<TokenLogo address={token0Address}/>
|
<TokenLogo address={token0Address} />
|
||||||
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
|
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
|
||||||
{token0?.symbol}
|
{token0?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -109,7 +109,7 @@ function PoolFinder({ history }) {
|
|||||||
</ButtonDropwdownLight>
|
</ButtonDropwdownLight>
|
||||||
)}
|
)}
|
||||||
<ColumnCenter>
|
<ColumnCenter>
|
||||||
<Plus size="16" color="#888D9B"/>
|
<Plus size="16" color="#888D9B" />
|
||||||
</ColumnCenter>
|
</ColumnCenter>
|
||||||
{!token1Address ? (
|
{!token1Address ? (
|
||||||
<ButtonDropwdown
|
<ButtonDropwdown
|
||||||
@ -128,7 +128,7 @@ function PoolFinder({ history }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Row>
|
<Row>
|
||||||
<TokenLogo address={token1Address}/>
|
<TokenLogo address={token1Address} />
|
||||||
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
|
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
|
||||||
{token1?.symbol}
|
{token1?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -137,7 +137,8 @@ function PoolFinder({ history }) {
|
|||||||
)}
|
)}
|
||||||
{allowImport && (
|
{allowImport && (
|
||||||
<ColumnCenter
|
<ColumnCenter
|
||||||
style={{ justifyItems: 'center', backgroundColor: '', padding: '12px 0px', borderRadius: '12px' }}>
|
style={{ justifyItems: 'center', backgroundColor: '', padding: '12px 0px', borderRadius: '12px' }}
|
||||||
|
>
|
||||||
<Text textAlign="center" fontWeight={500} color="">
|
<Text textAlign="center" fontWeight={500} color="">
|
||||||
{newLiquidity ? 'Pool Found!' : 'Pool already imported.'}
|
{newLiquidity ? 'Pool Found!' : 'Pool already imported.'}
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -79,7 +79,7 @@ export default function App() {
|
|||||||
{activePopups.map(item => {
|
{activePopups.map(item => {
|
||||||
return (
|
return (
|
||||||
<Popup key={item.key}>
|
<Popup key={item.key}>
|
||||||
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)}/>
|
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} />
|
||||||
{React.cloneElement(item.content, { popKey: item.key })}
|
{React.cloneElement(item.content, { popKey: item.key })}
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
@ -98,7 +98,7 @@ export default function App() {
|
|||||||
.map(item => {
|
.map(item => {
|
||||||
return (
|
return (
|
||||||
<Popup key={item.key}>
|
<Popup key={item.key}>
|
||||||
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)}/>
|
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} />
|
||||||
{React.cloneElement(item.content, { popKey: item.key })}
|
{React.cloneElement(item.content, { popKey: item.key })}
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
|
@ -31,7 +31,7 @@ const HoverCard = styled(Card)`
|
|||||||
`
|
`
|
||||||
|
|
||||||
interface PositionCardProps extends RouteComponentProps<{}> {
|
interface PositionCardProps extends RouteComponentProps<{}> {
|
||||||
pairAddress: string;
|
pairAddress: string
|
||||||
token0: Token
|
token0: Token
|
||||||
token1: Token
|
token1: Token
|
||||||
minimal?: boolean
|
minimal?: boolean
|
||||||
@ -86,7 +86,7 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
</FixedHeightRow>
|
</FixedHeightRow>
|
||||||
<FixedHeightRow onClick={() => setShowMore(!showMore)}>
|
<FixedHeightRow onClick={() => setShowMore(!showMore)}>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20}/>
|
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20} />
|
||||||
<Text fontWeight={500} fontSize={20}>
|
<Text fontWeight={500} fontSize={20}>
|
||||||
{token0?.symbol}:{token1?.symbol}
|
{token0?.symbol}:{token1?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -104,7 +104,7 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
</Text>
|
</Text>
|
||||||
{token0Deposited ? (
|
{token0Deposited ? (
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
{!minimal && <TokenLogo address={token0?.address || ''}/>}
|
{!minimal && <TokenLogo address={token0?.address || ''} />}
|
||||||
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||||
{token0Deposited?.toFixed(8)}
|
{token0Deposited?.toFixed(8)}
|
||||||
</Text>
|
</Text>
|
||||||
@ -119,7 +119,7 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
</Text>
|
</Text>
|
||||||
{token1Deposited ? (
|
{token1Deposited ? (
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
{!minimal && <TokenLogo address={token1?.address || ''}/>}
|
{!minimal && <TokenLogo address={token1?.address || ''} />}
|
||||||
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||||
{token1Deposited?.toFixed(8)}
|
{token1Deposited?.toFixed(8)}
|
||||||
</Text>
|
</Text>
|
||||||
@ -140,16 +140,16 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
<AutoColumn gap="12px">
|
<AutoColumn gap="12px">
|
||||||
<FixedHeightRow onClick={() => setShowMore(!showMore)} style={{ cursor: 'pointer' }}>
|
<FixedHeightRow onClick={() => setShowMore(!showMore)} style={{ cursor: 'pointer' }}>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20}/>
|
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20} />
|
||||||
<Text fontWeight={500} fontSize={20}>
|
<Text fontWeight={500} fontSize={20}>
|
||||||
{token0?.symbol}:{token1?.symbol}
|
{token0?.symbol}:{token1?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
{showMore ? (
|
{showMore ? (
|
||||||
<ChevronUp size="20" style={{ marginLeft: '10px' }}/>
|
<ChevronUp size="20" style={{ marginLeft: '10px' }} />
|
||||||
) : (
|
) : (
|
||||||
<ChevronDown size="20" style={{ marginLeft: '10px' }}/>
|
<ChevronDown size="20" style={{ marginLeft: '10px' }} />
|
||||||
)}
|
)}
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
</FixedHeightRow>
|
</FixedHeightRow>
|
||||||
@ -167,7 +167,7 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
{token0Deposited?.toFixed(8)}
|
{token0Deposited?.toFixed(8)}
|
||||||
</Text>
|
</Text>
|
||||||
{!minimal && (
|
{!minimal && (
|
||||||
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token0?.address || ''}/>
|
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token0?.address || ''} />
|
||||||
)}
|
)}
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
) : (
|
) : (
|
||||||
@ -187,7 +187,7 @@ function PositionCard({ pairAddress, token0, token1, history, border, minimal =
|
|||||||
{token1Deposited?.toFixed(8)}
|
{token1Deposited?.toFixed(8)}
|
||||||
</Text>
|
</Text>
|
||||||
{!minimal && (
|
{!minimal && (
|
||||||
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token1?.address || ''}/>
|
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token1?.address || ''} />
|
||||||
)}
|
)}
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
) : (
|
) : (
|
||||||
|
@ -62,7 +62,7 @@ const Popup = styled.div`
|
|||||||
`}
|
`}
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function QuestionHelper({ text }) {
|
export default function QuestionHelper({ text }: { text: string }) {
|
||||||
const [showPopup, setPopup] = useState(false)
|
const [showPopup, setPopup] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -154,18 +154,18 @@ interface SearchModalProps extends RouteComponentProps<{}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function SearchModal({
|
function SearchModal({
|
||||||
history,
|
history,
|
||||||
isOpen,
|
isOpen,
|
||||||
onDismiss,
|
onDismiss,
|
||||||
onTokenSelect,
|
onTokenSelect,
|
||||||
urlAddedTokens,
|
urlAddedTokens,
|
||||||
filterType,
|
filterType,
|
||||||
hiddenToken,
|
hiddenToken,
|
||||||
showSendWithSwap,
|
showSendWithSwap,
|
||||||
otherSelectedTokenAddress,
|
otherSelectedTokenAddress,
|
||||||
otherSelectedText,
|
otherSelectedText,
|
||||||
showCommonBases = false
|
showCommonBases = false
|
||||||
}: SearchModalProps) {
|
}: SearchModalProps) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { account, chainId } = useWeb3React()
|
const { account, chainId } = useWeb3React()
|
||||||
const theme = useContext(ThemeContext)
|
const theme = useContext(ThemeContext)
|
||||||
@ -377,7 +377,7 @@ function SearchModal({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<DoubleTokenLogo a0={token0?.address || ''} a1={token1?.address || ''} size={24} margin={true}/>
|
<DoubleTokenLogo a0={token0?.address || ''} a1={token1?.address || ''} size={24} margin={true} />
|
||||||
<Text fontWeight={500} fontSize={16}>{`${token0?.symbol}/${token1?.symbol}`}</Text>
|
<Text fontWeight={500} fontSize={16}>{`${token0?.symbol}/${token1?.symbol}`}</Text>
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
{/* <Text fontWeight={500} fontSize={16}>
|
{/* <Text fontWeight={500} fontSize={16}>
|
||||||
@ -418,7 +418,7 @@ function SearchModal({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<TokenLogo address={temporaryToken.address} size={'24px'} style={{ marginRight: '14px' }}/>
|
<TokenLogo address={temporaryToken.address} size={'24px'} style={{ marginRight: '14px' }} />
|
||||||
<Column>
|
<Column>
|
||||||
<Text fontWeight={500}>{temporaryToken.symbol}</Text>
|
<Text fontWeight={500}>{temporaryToken.symbol}</Text>
|
||||||
<FadedSpan>(Found by search)</FadedSpan>
|
<FadedSpan>(Found by search)</FadedSpan>
|
||||||
@ -431,16 +431,16 @@ function SearchModal({
|
|||||||
return <TokenModalInfo>{t('noToken')}</TokenModalInfo>
|
return <TokenModalInfo>{t('noToken')}</TokenModalInfo>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO is this the right place to link to create exchange?
|
// TODO is this the right place to link to create exchange?
|
||||||
// else if (isAddress(searchQuery) && tokenAddress === ethers.constants.AddressZero) {
|
// else if (isAddress(searchQuery) && tokenAddress === ethers.constants.AddressZero) {
|
||||||
// return (
|
// return (
|
||||||
// <>
|
// <>
|
||||||
// <TokenModalInfo>{t('noToken')}</TokenModalInfo>
|
// <TokenModalInfo>{t('noToken')}</TokenModalInfo>
|
||||||
// <TokenModalInfo>
|
// <TokenModalInfo>
|
||||||
// <Link to={`/create-exchange/${searchQuery}`}>{t('createExchange')}</Link>
|
// <Link to={`/create-exchange/${searchQuery}`}>{t('createExchange')}</Link>
|
||||||
// </TokenModalInfo>
|
// </TokenModalInfo>
|
||||||
// </>
|
// </>
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
else {
|
else {
|
||||||
return filteredTokenList
|
return filteredTokenList
|
||||||
@ -453,8 +453,8 @@ function SearchModal({
|
|||||||
? -1
|
? -1
|
||||||
: 1
|
: 1
|
||||||
: sortDirection
|
: sortDirection
|
||||||
? 1
|
? 1
|
||||||
: -1
|
: -1
|
||||||
})
|
})
|
||||||
.map(({ address, symbol, balance }) => {
|
.map(({ address, symbol, balance }) => {
|
||||||
const urlAdded = urlAddedTokens && urlAddedTokens.hasOwnProperty(address)
|
const urlAdded = urlAddedTokens && urlAddedTokens.hasOwnProperty(address)
|
||||||
@ -467,13 +467,12 @@ function SearchModal({
|
|||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={address}
|
key={address}
|
||||||
onClick={() => (hiddenToken && hiddenToken === address ? () => {
|
onClick={() => (hiddenToken && hiddenToken === address ? () => {} : _onTokenSelect(address))}
|
||||||
} : _onTokenSelect(address))}
|
|
||||||
disabled={hiddenToken && hiddenToken === address}
|
disabled={hiddenToken && hiddenToken === address}
|
||||||
selected={otherSelectedTokenAddress === address}
|
selected={otherSelectedTokenAddress === address}
|
||||||
>
|
>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }}/>
|
<TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }} />
|
||||||
<Column>
|
<Column>
|
||||||
<Text fontWeight={500}>
|
<Text fontWeight={500}>
|
||||||
{symbol}
|
{symbol}
|
||||||
@ -500,9 +499,7 @@ function SearchModal({
|
|||||||
{balance ? (
|
{balance ? (
|
||||||
<Text>
|
<Text>
|
||||||
{zeroBalance && showSendWithSwap ? (
|
{zeroBalance && showSendWithSwap ? (
|
||||||
<ColumnCenter
|
<ColumnCenter style={{ backgroundColor: theme.bg2, padding: '8px', borderRadius: '12px' }}>
|
||||||
style={{ backgroundColor: theme.bg2, padding: '8px', borderRadius: '12px' }}
|
|
||||||
>
|
|
||||||
<Text textAlign="center" fontWeight={500} color={theme.blue1}>
|
<Text textAlign="center" fontWeight={500} color={theme.blue1}>
|
||||||
Send With Swap
|
Send With Swap
|
||||||
</Text>
|
</Text>
|
||||||
@ -514,7 +511,7 @@ function SearchModal({
|
|||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
) : account ? (
|
) : account ? (
|
||||||
<SpinnerWrapper src={Circle} alt="loader"/>
|
<SpinnerWrapper src={Circle} alt="loader" />
|
||||||
) : (
|
) : (
|
||||||
'-'
|
'-'
|
||||||
)}
|
)}
|
||||||
@ -569,7 +566,7 @@ function SearchModal({
|
|||||||
Import A Token
|
Import A Token
|
||||||
</Text>
|
</Text>
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<CloseIcon onClick={onDismiss}/>
|
<CloseIcon onClick={onDismiss} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<TYPE.body style={{ marginTop: '10px' }}>
|
<TYPE.body style={{ marginTop: '10px' }}>
|
||||||
To import a custom token, paste token address in the search bar.
|
To import a custom token, paste token address in the search bar.
|
||||||
@ -589,7 +586,7 @@ function SearchModal({
|
|||||||
<Text fontWeight={500} fontSize={16}>
|
<Text fontWeight={500} fontSize={16}>
|
||||||
{filterType === 'tokens' ? 'Select A Token' : 'Select A Pool'}
|
{filterType === 'tokens' ? 'Select A Token' : 'Select A Pool'}
|
||||||
</Text>
|
</Text>
|
||||||
<CloseIcon onClick={onDismiss}/>
|
<CloseIcon onClick={onDismiss} />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<Input
|
<Input
|
||||||
type={'text'}
|
type={'text'}
|
||||||
@ -604,7 +601,7 @@ function SearchModal({
|
|||||||
<Text fontWeight={500} fontSize={16}>
|
<Text fontWeight={500} fontSize={16}>
|
||||||
Common Bases
|
Common Bases
|
||||||
</Text>
|
</Text>
|
||||||
<QuestionHelper text="These tokens are commonly used in pairs."/>
|
<QuestionHelper text="These tokens are commonly used in pairs." />
|
||||||
</AutoRow>
|
</AutoRow>
|
||||||
<AutoRow gap="10px">
|
<AutoRow gap="10px">
|
||||||
{COMMON_BASES[chainId]?.map(token => {
|
{COMMON_BASES[chainId]?.map(token => {
|
||||||
@ -615,7 +612,7 @@ function SearchModal({
|
|||||||
disable={hiddenToken === token.address}
|
disable={hiddenToken === token.address}
|
||||||
key={token.address}
|
key={token.address}
|
||||||
>
|
>
|
||||||
<TokenLogo address={token.address}/>
|
<TokenLogo address={token.address} />
|
||||||
<Text fontWeight={500} fontSize={16}>
|
<Text fontWeight={500} fontSize={16}>
|
||||||
{token.symbol}
|
{token.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -637,16 +634,16 @@ function SearchModal({
|
|||||||
</RowBetween>
|
</RowBetween>
|
||||||
</PaddedColumn>
|
</PaddedColumn>
|
||||||
)}
|
)}
|
||||||
{!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: theme.bg2 }}/>}
|
{!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: theme.bg2 }} />}
|
||||||
{!showTokenImport && <TokenList>{filterType === 'tokens' ? renderTokenList() : renderPairsList()}</TokenList>}
|
{!showTokenImport && <TokenList>{filterType === 'tokens' ? renderTokenList() : renderPairsList()}</TokenList>}
|
||||||
{!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: theme.bg2 }}/>}
|
{!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: theme.bg2 }} />}
|
||||||
{!showTokenImport && (
|
{!showTokenImport && (
|
||||||
<Card>
|
<Card>
|
||||||
<AutoRow justify={'center'}>
|
<AutoRow justify={'center'}>
|
||||||
<div>
|
<div>
|
||||||
{filterType !== 'tokens' && (
|
{filterType !== 'tokens' && (
|
||||||
<Text fontWeight={500}>
|
<Text fontWeight={500}>
|
||||||
{!isMobile && 'Don\'t see a pool? '}
|
{!isMobile && "Don't see a pool? "}
|
||||||
<StyledLink
|
<StyledLink
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
history.push('/find')
|
history.push('/find')
|
||||||
@ -658,7 +655,7 @@ function SearchModal({
|
|||||||
)}
|
)}
|
||||||
{filterType === 'tokens' && (
|
{filterType === 'tokens' && (
|
||||||
<Text fontWeight={500} color={theme.text2} fontSize={14}>
|
<Text fontWeight={500} color={theme.text2} fontSize={14}>
|
||||||
{!isMobile && 'Don\'t see a token? '}
|
{!isMobile && "Don't see a token? "}
|
||||||
|
|
||||||
<StyledLink
|
<StyledLink
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -58,12 +58,15 @@ export default function InputSlider({ value, onChange, override }: InputSliderPr
|
|||||||
const [internalVal, setInternalVal] = useState<number>(value)
|
const [internalVal, setInternalVal] = useState<number>(value)
|
||||||
const debouncedInternalValue = useDebounce(internalVal, 100)
|
const debouncedInternalValue = useDebounce(internalVal, 100)
|
||||||
|
|
||||||
const handleChange = useCallback((e, val) => {
|
const handleChange = useCallback(
|
||||||
setInternalVal(val)
|
(e, val) => {
|
||||||
if (val !== debouncedInternalValue) {
|
setInternalVal(val)
|
||||||
onChange(val)
|
if (val !== debouncedInternalValue) {
|
||||||
}
|
onChange(val)
|
||||||
}, [setInternalVal, onChange, debouncedInternalValue])
|
}
|
||||||
|
},
|
||||||
|
[setInternalVal, onChange, debouncedInternalValue]
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (override) {
|
if (override) {
|
||||||
|
@ -61,21 +61,21 @@ const Input = styled.input<{ active?: boolean }>`
|
|||||||
color: ${({ theme }) => theme.text1};
|
color: ${({ theme }) => theme.text1};
|
||||||
text-align: left;
|
text-align: left;
|
||||||
${({ active }) =>
|
${({ active }) =>
|
||||||
active &&
|
active &&
|
||||||
css`
|
css`
|
||||||
color: initial;
|
color: initial;
|
||||||
cursor: initial;
|
cursor: initial;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
`}
|
`}
|
||||||
${({ placeholder }) =>
|
${({ placeholder }) =>
|
||||||
placeholder !== 'Custom' &&
|
placeholder !== 'Custom' &&
|
||||||
css`
|
css`
|
||||||
text-align: right;
|
text-align: right;
|
||||||
color: ${({ theme }) => theme.text1};
|
color: ${({ theme }) => theme.text1};
|
||||||
`}
|
`}
|
||||||
${({ color }) =>
|
${({ color }) =>
|
||||||
color === 'red' &&
|
color === 'red' &&
|
||||||
css`
|
css`
|
||||||
color: ${({ theme }) => theme.red1};
|
color: ${({ theme }) => theme.red1};
|
||||||
`}
|
`}
|
||||||
`
|
`
|
||||||
@ -84,8 +84,8 @@ const BottomError = styled(Text)`
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
${({ show }) =>
|
${({ show }) =>
|
||||||
show &&
|
show &&
|
||||||
css`
|
css`
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
`}
|
`}
|
||||||
`
|
`
|
||||||
@ -94,9 +94,10 @@ const OptionCustom = styled(FancyButton)<{ active?: boolean; warning?: boolean }
|
|||||||
height: 2rem;
|
height: 2rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 0.75rem;
|
padding: 0 0.75rem;
|
||||||
border: ${({ theme, active, warning }) => active && `1px solid ${(warning ? theme.red1 : theme.blue1)}`};
|
border: ${({ theme, active, warning }) => active && `1px solid ${warning ? theme.red1 : theme.blue1}`};
|
||||||
:hover {
|
:hover {
|
||||||
border: ${({ theme, active, warning }) => active && `1px solid ${(warning ? darken(0.1, theme.red1) : darken(0.1, theme.blue1))}`};
|
border: ${({ theme, active, warning }) =>
|
||||||
|
active && `1px solid ${warning ? darken(0.1, theme.red1) : darken(0.1, theme.blue1)}`};
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@ -116,12 +117,12 @@ const Percent = styled.div`
|
|||||||
font-size: 0, 8rem;
|
font-size: 0, 8rem;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
${({ color, theme }) =>
|
${({ color, theme }) =>
|
||||||
(color === 'faded' &&
|
(color === 'faded' &&
|
||||||
css`
|
css`
|
||||||
color: ${theme.bg1};
|
color: ${theme.bg1};
|
||||||
`) ||
|
`) ||
|
||||||
(color === 'red' &&
|
(color === 'red' &&
|
||||||
css`
|
css`
|
||||||
color: ${theme.red1};
|
color: ${theme.red1};
|
||||||
`)};
|
`)};
|
||||||
`
|
`
|
||||||
@ -133,7 +134,12 @@ interface TransactionDetailsProps {
|
|||||||
setDeadline: (deadline: number) => void
|
setDeadline: (deadline: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TransactionDetails({ setRawSlippage, rawSlippage, deadline, setDeadline }: TransactionDetailsProps) {
|
export default function TransactionDetails({
|
||||||
|
setRawSlippage,
|
||||||
|
rawSlippage,
|
||||||
|
deadline,
|
||||||
|
setDeadline
|
||||||
|
}: TransactionDetailsProps) {
|
||||||
const [activeIndex, setActiveIndex] = useState(2)
|
const [activeIndex, setActiveIndex] = useState(2)
|
||||||
|
|
||||||
const [warningType, setWarningType] = useState(WARNING_TYPE.none)
|
const [warningType, setWarningType] = useState(WARNING_TYPE.none)
|
||||||
@ -147,26 +153,10 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
|
|
||||||
const [deadlineInput, setDeadlineInput] = useState(deadline / 60)
|
const [deadlineInput, setDeadlineInput] = useState(deadline / 60)
|
||||||
|
|
||||||
function parseCustomDeadline(e) {
|
|
||||||
let val = e.target.value
|
|
||||||
const acceptableValues = [/^$/, /^\d+$/]
|
|
||||||
if (acceptableValues.some(re => re.test(val))) {
|
|
||||||
setDeadlineInput(val)
|
|
||||||
setDeadline(val * 60)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const setFromCustom = () => {
|
|
||||||
setActiveIndex(4)
|
|
||||||
inputRef.current.focus()
|
|
||||||
// if there's a value, evaluate the bounds
|
|
||||||
checkBounds(debouncedInput)
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateSlippage = useCallback(
|
const updateSlippage = useCallback(
|
||||||
newSlippage => {
|
newSlippage => {
|
||||||
// round to 2 decimals to prevent ethers error
|
// round to 2 decimals to prevent ethers error
|
||||||
let numParsed = newSlippage * 100
|
const numParsed = newSlippage * 100
|
||||||
|
|
||||||
// set both slippage values in parents
|
// set both slippage values in parents
|
||||||
setRawSlippage(numParsed)
|
setRawSlippage(numParsed)
|
||||||
@ -174,39 +164,6 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
[setRawSlippage]
|
[setRawSlippage]
|
||||||
)
|
)
|
||||||
|
|
||||||
// used for slippage presets
|
|
||||||
const setFromFixed = useCallback(
|
|
||||||
(index, slippage) => {
|
|
||||||
// update slippage in parent, reset errors and input state
|
|
||||||
updateSlippage(slippage)
|
|
||||||
setWarningType(WARNING_TYPE.none)
|
|
||||||
setActiveIndex(index)
|
|
||||||
},
|
|
||||||
[updateSlippage]
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
switch (initialSlippage) {
|
|
||||||
case 10:
|
|
||||||
setFromFixed(1, 0.1)
|
|
||||||
break
|
|
||||||
case 50:
|
|
||||||
setFromFixed(2, 0.5)
|
|
||||||
break
|
|
||||||
case 100:
|
|
||||||
setFromFixed(3, 1)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
// restrict to 2 decimal places
|
|
||||||
let acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/]
|
|
||||||
// if its within accepted decimal limit, update the input state
|
|
||||||
if (acceptableValues.some(val => val.test('' + (initialSlippage / 100)))) {
|
|
||||||
setUserInput('' + (initialSlippage / 100))
|
|
||||||
setActiveIndex(4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [initialSlippage, setFromFixed])
|
|
||||||
|
|
||||||
const checkBounds = useCallback(
|
const checkBounds = useCallback(
|
||||||
slippageValue => {
|
slippageValue => {
|
||||||
setWarningType(WARNING_TYPE.none)
|
setWarningType(WARNING_TYPE.none)
|
||||||
@ -231,12 +188,60 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
[updateSlippage]
|
[updateSlippage]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function parseCustomDeadline(e) {
|
||||||
|
const val = e.target.value
|
||||||
|
const acceptableValues = [/^$/, /^\d+$/]
|
||||||
|
if (acceptableValues.some(re => re.test(val))) {
|
||||||
|
setDeadlineInput(val)
|
||||||
|
setDeadline(val * 60)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const setFromCustom = () => {
|
||||||
|
setActiveIndex(4)
|
||||||
|
inputRef.current.focus()
|
||||||
|
// if there's a value, evaluate the bounds
|
||||||
|
checkBounds(debouncedInput)
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for slippage presets
|
||||||
|
const setFromFixed = useCallback(
|
||||||
|
(index, slippage) => {
|
||||||
|
// update slippage in parent, reset errors and input state
|
||||||
|
updateSlippage(slippage)
|
||||||
|
setWarningType(WARNING_TYPE.none)
|
||||||
|
setActiveIndex(index)
|
||||||
|
},
|
||||||
|
[updateSlippage]
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
switch (initialSlippage) {
|
||||||
|
case 10:
|
||||||
|
setFromFixed(1, 0.1)
|
||||||
|
break
|
||||||
|
case 50:
|
||||||
|
setFromFixed(2, 0.5)
|
||||||
|
break
|
||||||
|
case 100:
|
||||||
|
setFromFixed(3, 1)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
// restrict to 2 decimal places
|
||||||
|
const acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/]
|
||||||
|
// if its within accepted decimal limit, update the input state
|
||||||
|
if (acceptableValues.some(val => val.test('' + initialSlippage / 100))) {
|
||||||
|
setUserInput('' + initialSlippage / 100)
|
||||||
|
setActiveIndex(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [initialSlippage, setFromFixed])
|
||||||
|
|
||||||
// check that the theyve entered number and correct decimal
|
// check that the theyve entered number and correct decimal
|
||||||
const parseInput = e => {
|
const parseInput = e => {
|
||||||
let input = e.target.value
|
const input = e.target.value
|
||||||
|
|
||||||
// restrict to 2 decimal places
|
// restrict to 2 decimal places
|
||||||
let acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/]
|
const acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/]
|
||||||
// if its within accepted decimal limit, update the input state
|
// if its within accepted decimal limit, update the input state
|
||||||
if (acceptableValues.some(a => a.test(input))) {
|
if (acceptableValues.some(a => a.test(input))) {
|
||||||
setUserInput(input)
|
setUserInput(input)
|
||||||
@ -313,8 +318,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
placeholder={
|
placeholder={
|
||||||
activeIndex === 4
|
activeIndex === 4
|
||||||
? !!userInput
|
? !!userInput
|
||||||
? ''
|
? ''
|
||||||
: '0'
|
: '0'
|
||||||
: activeIndex !== 4 && userInput !== ''
|
: activeIndex !== 4 && userInput !== ''
|
||||||
? userInput
|
? userInput
|
||||||
: 'Custom'
|
: 'Custom'
|
||||||
@ -352,8 +357,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
: warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
|
: warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
|
||||||
? 'red'
|
? 'red'
|
||||||
: warningType === WARNING_TYPE.riskyEntryLow
|
: warningType === WARNING_TYPE.riskyEntryLow
|
||||||
? '#F3841E'
|
? '#F3841E'
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{warningType === WARNING_TYPE.emptyInput && 'Enter a slippage percentage'}
|
{warningType === WARNING_TYPE.emptyInput && 'Enter a slippage percentage'}
|
||||||
@ -366,12 +371,16 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
|
|||||||
<AutoColumn gap="sm">
|
<AutoColumn gap="sm">
|
||||||
<RowFixed padding={'0 20px'}>
|
<RowFixed padding={'0 20px'}>
|
||||||
<TYPE.body fontSize={14}>Deadline</TYPE.body>
|
<TYPE.body fontSize={14}>Deadline</TYPE.body>
|
||||||
<QuestionHelper text="Deadline in minutes. If your transaction takes longer than this it will revert."/>
|
<QuestionHelper text="Deadline in minutes. If your transaction takes longer than this it will revert." />
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<RowFixed padding={'0 20px'}>
|
<RowFixed padding={'0 20px'}>
|
||||||
<OptionCustom style={{ width: '80px' }}>
|
<OptionCustom style={{ width: '80px' }}>
|
||||||
<Input tabIndex={-1} placeholder={'' + deadlineInput} value={deadlineInput}
|
<Input
|
||||||
onChange={parseCustomDeadline}/>
|
tabIndex={-1}
|
||||||
|
placeholder={'' + deadlineInput}
|
||||||
|
value={deadlineInput}
|
||||||
|
onChange={parseCustomDeadline}
|
||||||
|
/>
|
||||||
</OptionCustom>
|
</OptionCustom>
|
||||||
<TYPE.body style={{ paddingLeft: '8px' }} fontSize={14}>
|
<TYPE.body style={{ paddingLeft: '8px' }} fontSize={14}>
|
||||||
minutes
|
minutes
|
||||||
|
@ -20,7 +20,7 @@ const Image = styled.img<{ size: string }>`
|
|||||||
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.075);
|
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.075);
|
||||||
`
|
`
|
||||||
|
|
||||||
const Emoji = styled.span<{size?:string}>`
|
const Emoji = styled.span<{ size?: string }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -30,7 +30,7 @@ const Emoji = styled.span<{size?:string}>`
|
|||||||
margin-bottom: -4px;
|
margin-bottom: -4px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const StyledEthereumLogo = styled(EthereumLogo)<{size: string}>`
|
const StyledEthereumLogo = styled(EthereumLogo)<{ size: string }>`
|
||||||
width: ${({ size }) => size};
|
width: ${({ size }) => size};
|
||||||
height: ${({ size }) => size};
|
height: ${({ size }) => size};
|
||||||
`
|
`
|
||||||
|
@ -28,7 +28,7 @@ const delay = 100
|
|||||||
|
|
||||||
export default function TxnPopup({ hash, success, summary, popKey }) {
|
export default function TxnPopup({ hash, success, summary, popKey }) {
|
||||||
const { chainId } = useWeb3React()
|
const { chainId } = useWeb3React()
|
||||||
let [count, setCount] = useState(1)
|
const [count, setCount] = useState(1)
|
||||||
|
|
||||||
const [isRunning, setIsRunning] = useState(true)
|
const [isRunning, setIsRunning] = useState(true)
|
||||||
const [, , removePopup] = usePopups()
|
const [, , removePopup] = usePopups()
|
||||||
@ -44,9 +44,9 @@ export default function TxnPopup({ hash, success, summary, popKey }) {
|
|||||||
return (
|
return (
|
||||||
<AutoRow onMouseEnter={() => setIsRunning(false)} onMouseLeave={() => setIsRunning(true)}>
|
<AutoRow onMouseEnter={() => setIsRunning(false)} onMouseLeave={() => setIsRunning(true)}>
|
||||||
{success ? (
|
{success ? (
|
||||||
<CheckCircle color={'#27AE60'} size={24} style={{ paddingRight: '24px' }}/>
|
<CheckCircle color={'#27AE60'} size={24} style={{ paddingRight: '24px' }} />
|
||||||
) : (
|
) : (
|
||||||
<AlertCircle color={'#FF6871'} size={24} style={{ paddingRight: '24px' }}/>
|
<AlertCircle color={'#FF6871'} size={24} style={{ paddingRight: '24px' }} />
|
||||||
)}
|
)}
|
||||||
<AutoColumn gap="8px">
|
<AutoColumn gap="8px">
|
||||||
<TYPE.body fontWeight={500}>
|
<TYPE.body fontWeight={500}>
|
||||||
@ -54,7 +54,7 @@ export default function TxnPopup({ hash, success, summary, popKey }) {
|
|||||||
</TYPE.body>
|
</TYPE.body>
|
||||||
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link>
|
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link>
|
||||||
</AutoColumn>
|
</AutoColumn>
|
||||||
<Fader count={count}/>
|
<Fader count={count} />
|
||||||
</AutoRow>
|
</AutoRow>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -88,16 +88,16 @@ const IconWrapper = styled.div<{ size?: number }>`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export default function Option({
|
export default function Option({
|
||||||
link = null,
|
link = null,
|
||||||
clickable = true,
|
clickable = true,
|
||||||
size = null,
|
size = null,
|
||||||
onClick = null,
|
onClick = null,
|
||||||
color,
|
color,
|
||||||
header,
|
header,
|
||||||
subheader = null,
|
subheader = null,
|
||||||
icon,
|
icon,
|
||||||
active = false
|
active = false
|
||||||
}) {
|
}) {
|
||||||
const content = (
|
const content = (
|
||||||
<OptionCardClickable onClick={onClick} clickable={clickable && !active} active={active}>
|
<OptionCardClickable onClick={onClick} clickable={clickable && !active} active={active}>
|
||||||
<OptionCardLeft>
|
<OptionCardLeft>
|
||||||
@ -106,7 +106,7 @@ export default function Option({
|
|||||||
{active ? (
|
{active ? (
|
||||||
<CircleWrapper>
|
<CircleWrapper>
|
||||||
<GreenCircle>
|
<GreenCircle>
|
||||||
<div/>
|
<div />
|
||||||
</GreenCircle>
|
</GreenCircle>
|
||||||
</CircleWrapper>
|
</CircleWrapper>
|
||||||
) : (
|
) : (
|
||||||
@ -117,7 +117,7 @@ export default function Option({
|
|||||||
{subheader && <SubHeader>{subheader}</SubHeader>}
|
{subheader && <SubHeader>{subheader}</SubHeader>}
|
||||||
</OptionCardLeft>
|
</OptionCardLeft>
|
||||||
<IconWrapper size={size}>
|
<IconWrapper size={size}>
|
||||||
<img src={icon} alt={'Icon'}/>
|
<img src={icon} alt={'Icon'} />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
</OptionCardClickable>
|
</OptionCardClickable>
|
||||||
)
|
)
|
||||||
|
@ -75,10 +75,10 @@ export default function PendingView({ uri = '', size, connector, error = false,
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PendingSection>
|
<PendingSection>
|
||||||
{!error && connector === walletconnect && <WalletConnectData size={size} uri={uri}/>}
|
{!error && connector === walletconnect && <WalletConnectData size={size} uri={uri} />}
|
||||||
<LoadingMessage error={error}>
|
<LoadingMessage error={error}>
|
||||||
<LoadingWrapper>
|
<LoadingWrapper>
|
||||||
{!error && <SpinnerWrapper src={Circle}/>}
|
{!error && <SpinnerWrapper src={Circle} />}
|
||||||
{error ? (
|
{error ? (
|
||||||
<ErrorGroup>
|
<ErrorGroup>
|
||||||
<div>Error connecting.</div>
|
<div>Error connecting.</div>
|
||||||
|
@ -21,7 +21,7 @@ export default function WalletConnectData({ uri = '', size }: WalletConnectDataP
|
|||||||
return (
|
return (
|
||||||
<QRCodeWrapper>
|
<QRCodeWrapper>
|
||||||
{uri && (
|
{uri && (
|
||||||
<QRCode size={size} value={uri} bgColor={isDark ? '#333639' : 'white'} fgColor={isDark ? 'white' : 'black'}/>
|
<QRCode size={size} value={uri} bgColor={isDark ? '#333639' : 'white'} fgColor={isDark ? 'white' : 'black'} />
|
||||||
)}
|
)}
|
||||||
</QRCodeWrapper>
|
</QRCodeWrapper>
|
||||||
)
|
)
|
||||||
|
@ -286,7 +286,7 @@ export default function WalletModal({ pendingTransactions, confirmedTransactions
|
|||||||
return (
|
return (
|
||||||
<UpperSection>
|
<UpperSection>
|
||||||
<CloseIcon onClick={toggleWalletModal}>
|
<CloseIcon onClick={toggleWalletModal}>
|
||||||
<CloseColor/>
|
<CloseColor />
|
||||||
</CloseIcon>
|
</CloseIcon>
|
||||||
<HeaderRow>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error connecting'}</HeaderRow>
|
<HeaderRow>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error connecting'}</HeaderRow>
|
||||||
<ContentWrapper>
|
<ContentWrapper>
|
||||||
@ -313,7 +313,7 @@ export default function WalletModal({ pendingTransactions, confirmedTransactions
|
|||||||
return (
|
return (
|
||||||
<UpperSection>
|
<UpperSection>
|
||||||
<CloseIcon onClick={toggleWalletModal}>
|
<CloseIcon onClick={toggleWalletModal}>
|
||||||
<CloseColor/>
|
<CloseColor />
|
||||||
</CloseIcon>
|
</CloseIcon>
|
||||||
{walletView !== WALLET_VIEWS.ACCOUNT ? (
|
{walletView !== WALLET_VIEWS.ACCOUNT ? (
|
||||||
<HeaderRow color="blue">
|
<HeaderRow color="blue">
|
||||||
@ -358,12 +358,7 @@ export default function WalletModal({ pendingTransactions, confirmedTransactions
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal isOpen={walletModalOpen} onDismiss={toggleWalletModal} minHeight={null} maxHeight={90}>
|
||||||
isOpen={walletModalOpen}
|
|
||||||
onDismiss={toggleWalletModal}
|
|
||||||
minHeight={null}
|
|
||||||
maxHeight={90}
|
|
||||||
>
|
|
||||||
<Wrapper>{getModalContent()}</Wrapper>
|
<Wrapper>{getModalContent()}</Wrapper>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
@ -76,8 +76,8 @@ const Web3StatusConnect = styled(Web3StatusGeneric)`
|
|||||||
}
|
}
|
||||||
|
|
||||||
${({ faded }) =>
|
${({ faded }) =>
|
||||||
faded &&
|
faded &&
|
||||||
css`
|
css`
|
||||||
background-color: ${({ theme }) => theme.blue5};
|
background-color: ${({ theme }) => theme.blue5};
|
||||||
border: 1px solid ${({ theme }) => theme.blue5};
|
border: 1px solid ${({ theme }) => theme.blue5};
|
||||||
color: ${({ theme }) => theme.buttonSecondaryText};
|
color: ${({ theme }) => theme.buttonSecondaryText};
|
||||||
@ -140,29 +140,29 @@ export default function Web3Status() {
|
|||||||
// handle the logo we want to show with the account
|
// handle the logo we want to show with the account
|
||||||
function getStatusIcon() {
|
function getStatusIcon() {
|
||||||
if (connector === injected) {
|
if (connector === injected) {
|
||||||
return <Identicon/>
|
return <Identicon />
|
||||||
} else if (connector === walletconnect) {
|
} else if (connector === walletconnect) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={WalletConnectIcon} alt={''}/>
|
<img src={WalletConnectIcon} alt={''} />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === walletlink) {
|
} else if (connector === walletlink) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={CoinbaseWalletIcon} alt={''}/>
|
<img src={CoinbaseWalletIcon} alt={''} />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === fortmatic) {
|
} else if (connector === fortmatic) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={FortmaticIcon} alt={''}/>
|
<img src={FortmaticIcon} alt={''} />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
} else if (connector === portis) {
|
} else if (connector === portis) {
|
||||||
return (
|
return (
|
||||||
<IconWrapper size={16}>
|
<IconWrapper size={16}>
|
||||||
<img src={PortisIcon} alt={''}/>
|
<img src={PortisIcon} alt={''} />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ export default function Web3Status() {
|
|||||||
<Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}>
|
<Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}>
|
||||||
{hasPendingTransactions ? (
|
{hasPendingTransactions ? (
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
<Text>{pending?.length} Pending</Text> <SpinnerWrapper src={LightCircle} alt="loader"/>
|
<Text>{pending?.length} Pending</Text> <SpinnerWrapper src={LightCircle} alt="loader" />
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
) : (
|
) : (
|
||||||
<Text>{ENSName || shortenAddress(account)}</Text>
|
<Text>{ENSName || shortenAddress(account)}</Text>
|
||||||
@ -185,7 +185,7 @@ export default function Web3Status() {
|
|||||||
} else if (error) {
|
} else if (error) {
|
||||||
return (
|
return (
|
||||||
<Web3StatusError onClick={toggleWalletModal}>
|
<Web3StatusError onClick={toggleWalletModal}>
|
||||||
<NetworkIcon/>
|
<NetworkIcon />
|
||||||
<Text>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error'}</Text>
|
<Text>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error'}</Text>
|
||||||
</Web3StatusError>
|
</Web3StatusError>
|
||||||
)
|
)
|
||||||
@ -205,7 +205,7 @@ export default function Web3Status() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{getWeb3Status()}
|
{getWeb3Status()}
|
||||||
<WalletModal ENSName={ENSName} pendingTransactions={pending} confirmedTransactions={confirmed}/>
|
<WalletModal ENSName={ENSName} pendingTransactions={pending} confirmedTransactions={confirmed} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,7 @@ export class FortmaticConnector extends FortmaticConnectorCore {
|
|||||||
if (!this.fortmatic) {
|
if (!this.fortmatic) {
|
||||||
const { default: Fortmatic } = await import('fortmatic')
|
const { default: Fortmatic } = await import('fortmatic')
|
||||||
const { apiKey, chainId } = this as any
|
const { apiKey, chainId } = this as any
|
||||||
this.fortmatic = new Fortmatic(
|
this.fortmatic = new Fortmatic(apiKey, chainId === 1 || chainId === 4 ? undefined : chainIdToNetwork[chainId])
|
||||||
apiKey,
|
|
||||||
chainId === 1 || chainId === 4 ? undefined : chainIdToNetwork[chainId]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = this.fortmatic.getProvider()
|
const provider = this.fortmatic.getProvider()
|
||||||
|
@ -3,13 +3,13 @@ import { NetworkConnector as NetworkConnectorCore } from '@web3-react/network-co
|
|||||||
export class NetworkConnector extends NetworkConnectorCore {
|
export class NetworkConnector extends NetworkConnectorCore {
|
||||||
pause() {
|
pause() {
|
||||||
if ((this as any).active) {
|
if ((this as any).active) {
|
||||||
(this as any).providers[(this as any).currentChainId].stop()
|
;(this as any).providers[(this as any).currentChainId].stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resume() {
|
resume() {
|
||||||
if ((this as any).active) {
|
if ((this as any).active) {
|
||||||
(this as any).providers[(this as any).currentChainId].start()
|
;(this as any).providers[(this as any).currentChainId].start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,27 @@
|
|||||||
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
|
import { BigintIsh, Token, TokenAmount, WETH } from '@uniswap/sdk'
|
||||||
import { Token, TokenAmount, WETH } from '@uniswap/sdk'
|
import { BigNumber } from 'ethers/utils'
|
||||||
|
import React, { createContext, useCallback, useContext, useEffect, useMemo, useReducer } from 'react'
|
||||||
|
|
||||||
import { useWeb3React } from '../hooks'
|
import { useWeb3React } from '../hooks'
|
||||||
import { safeAccess, isAddress, getTokenAllowance } from '../utils'
|
import { getTokenAllowance, isAddress } from '../utils'
|
||||||
import { useBlockNumber } from './Application'
|
import { useBlockNumber } from './Application'
|
||||||
|
|
||||||
const UPDATE = 'UPDATE'
|
const UPDATE = 'UPDATE'
|
||||||
|
|
||||||
const AllowancesContext = createContext([])
|
interface AllowancesState {
|
||||||
|
[chainId: number]: {
|
||||||
|
[address: string]: {
|
||||||
|
[tokenAddress: string]: {
|
||||||
|
[spenderAddress: string]: {
|
||||||
|
value: BigintIsh
|
||||||
|
blockNumber: BigNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const AllowancesContext = createContext<[AllowancesState, any]>([{}, {}])
|
||||||
|
|
||||||
function useAllowancesContext() {
|
function useAllowancesContext() {
|
||||||
return useContext(AllowancesContext)
|
return useContext(AllowancesContext)
|
||||||
@ -20,11 +34,11 @@ function reducer(state, { type, payload }) {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[networkId]: {
|
[networkId]: {
|
||||||
...(safeAccess(state, [networkId]) || {}),
|
...state?.[networkId],
|
||||||
[address]: {
|
[address]: {
|
||||||
...(safeAccess(state, [networkId, address]) || {}),
|
...state?.[networkId]?.[address],
|
||||||
[tokenAddress]: {
|
[tokenAddress]: {
|
||||||
...(safeAccess(state, [networkId, address, tokenAddress]) || {}),
|
...state?.[networkId]?.[address]?.[tokenAddress],
|
||||||
[spenderAddress]: {
|
[spenderAddress]: {
|
||||||
value,
|
value,
|
||||||
blockNumber
|
blockNumber
|
||||||
@ -34,9 +48,8 @@ function reducer(state, { type, payload }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
throw Error(`Unexpected action type in AllowancesContext reducer: '${type}'.`)
|
throw Error(`Unexpected action type in AllowancesContext reducer: '${type}'.`)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +73,7 @@ export function useAddressAllowance(address: string, token: Token, spenderAddres
|
|||||||
const globalBlockNumber = useBlockNumber()
|
const globalBlockNumber = useBlockNumber()
|
||||||
|
|
||||||
const [state, { update }] = useAllowancesContext()
|
const [state, { update }] = useAllowancesContext()
|
||||||
const { value, blockNumber } = safeAccess(state, [chainId, address, token?.address, spenderAddress]) || {}
|
const { value, blockNumber } = state?.[chainId]?.[address]?.[token?.address]?.[spenderAddress] ?? {}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -92,6 +105,5 @@ export function useAddressAllowance(address: string, token: Token, spenderAddres
|
|||||||
}
|
}
|
||||||
}, [address, token, spenderAddress, value, blockNumber, globalBlockNumber, chainId, library, update])
|
}, [address, token, spenderAddress, value, blockNumber, globalBlockNumber, chainId, library, update])
|
||||||
|
|
||||||
const newTokenAmount: TokenAmount = value ? new TokenAmount(token, value) : null
|
return value ? new TokenAmount(token, value) : null
|
||||||
return newTokenAmount
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
|
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
|
||||||
|
|
||||||
import { useWeb3React } from '../hooks'
|
import { useWeb3React } from '../hooks'
|
||||||
import { safeAccess } from '../utils'
|
|
||||||
|
|
||||||
const BLOCK_NUMBER = 'BLOCK_NUMBER'
|
const BLOCK_NUMBER = 'BLOCK_NUMBER'
|
||||||
const USD_PRICE = 'USD_PRICE'
|
const USD_PRICE = 'USD_PRICE'
|
||||||
@ -17,22 +16,25 @@ const USER_ADVANCED = 'USER_ADVANCED'
|
|||||||
const TOGGLE_USER_ADVANCED = 'TOGGLE_USER_ADVANCED'
|
const TOGGLE_USER_ADVANCED = 'TOGGLE_USER_ADVANCED'
|
||||||
|
|
||||||
interface ApplicationState {
|
interface ApplicationState {
|
||||||
BLOCK_NUMBER: {},
|
BLOCK_NUMBER: {}
|
||||||
USD_PRICE: {},
|
USD_PRICE: {}
|
||||||
POPUP_LIST: Array<{ key: number; show: boolean; content: React.ReactElement }>,
|
POPUP_LIST: Array<{ key: number; show: boolean; content: React.ReactElement }>
|
||||||
POPUP_KEY: number,
|
POPUP_KEY: number
|
||||||
WALLET_MODAL_OPEN: boolean,
|
WALLET_MODAL_OPEN: boolean
|
||||||
USER_ADVANCED: boolean
|
USER_ADVANCED: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ApplicationContext = createContext<[ApplicationState, { [updater: string]: (...args: any[]) => void }]>([{
|
const ApplicationContext = createContext<[ApplicationState, { [updater: string]: (...args: any[]) => void }]>([
|
||||||
[BLOCK_NUMBER]: {},
|
{
|
||||||
[USD_PRICE]: {},
|
[BLOCK_NUMBER]: {},
|
||||||
[POPUP_LIST]: [],
|
[USD_PRICE]: {},
|
||||||
[POPUP_KEY]: 0,
|
[POPUP_LIST]: [],
|
||||||
[WALLET_MODAL_OPEN]: false,
|
[POPUP_KEY]: 0,
|
||||||
[USER_ADVANCED]: false
|
[WALLET_MODAL_OPEN]: false,
|
||||||
}, {}])
|
[USER_ADVANCED]: false
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
])
|
||||||
|
|
||||||
function useApplicationContext() {
|
function useApplicationContext() {
|
||||||
return useContext(ApplicationContext)
|
return useContext(ApplicationContext)
|
||||||
@ -45,7 +47,7 @@ function reducer(state: ApplicationState, { type, payload }): ApplicationState {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[BLOCK_NUMBER]: {
|
[BLOCK_NUMBER]: {
|
||||||
...(safeAccess(state, [BLOCK_NUMBER]) || {}),
|
...state?.[BLOCK_NUMBER],
|
||||||
[networkId]: blockNumber
|
[networkId]: blockNumber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,9 +82,12 @@ export default function Provider({ children }) {
|
|||||||
[USER_ADVANCED]: false
|
[USER_ADVANCED]: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateBlockNumber = useCallback((networkId, blockNumber) => {
|
const updateBlockNumber = useCallback(
|
||||||
dispatch({ type: UPDATE_BLOCK_NUMBER, payload: { networkId, blockNumber } })
|
(networkId, blockNumber) => {
|
||||||
}, [dispatch])
|
dispatch({ type: UPDATE_BLOCK_NUMBER, payload: { networkId, blockNumber } })
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
const toggleWalletModal = useCallback(() => {
|
const toggleWalletModal = useCallback(() => {
|
||||||
dispatch({ type: TOGGLE_WALLET_MODAL, payload: null })
|
dispatch({ type: TOGGLE_WALLET_MODAL, payload: null })
|
||||||
@ -92,9 +97,12 @@ export default function Provider({ children }) {
|
|||||||
dispatch({ type: TOGGLE_USER_ADVANCED, payload: null })
|
dispatch({ type: TOGGLE_USER_ADVANCED, payload: null })
|
||||||
}, [dispatch])
|
}, [dispatch])
|
||||||
|
|
||||||
const setPopups = useCallback(newList => {
|
const setPopups = useCallback(
|
||||||
dispatch({ type: ADD_POPUP, payload: { newList } })
|
newList => {
|
||||||
}, [dispatch])
|
dispatch({ type: ADD_POPUP, payload: { newList } })
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ApplicationContext.Provider
|
<ApplicationContext.Provider
|
||||||
@ -154,7 +162,7 @@ export function useBlockNumber() {
|
|||||||
|
|
||||||
const [state] = useApplicationContext()
|
const [state] = useApplicationContext()
|
||||||
|
|
||||||
return safeAccess(state, [BLOCK_NUMBER, chainId])
|
return state?.[BLOCK_NUMBER]?.[chainId]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useWalletModalOpen() {
|
export function useWalletModalOpen() {
|
||||||
@ -180,7 +188,11 @@ export function useToggleUserAdvanced() {
|
|||||||
return toggleUserAdvanced
|
return toggleUserAdvanced
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePopups(): [ApplicationState['POPUP_LIST'], (content: React.ReactElement) => void, (key: number) => void] {
|
export function usePopups(): [
|
||||||
|
ApplicationState['POPUP_LIST'],
|
||||||
|
(content: React.ReactElement) => void,
|
||||||
|
(key: number) => void
|
||||||
|
] {
|
||||||
const [state, { setPopups }] = useApplicationContext()
|
const [state, { setPopups }] = useApplicationContext()
|
||||||
|
|
||||||
const index = state[POPUP_KEY]
|
const index = state[POPUP_KEY]
|
||||||
|
@ -411,7 +411,7 @@ export function useAllBalances(): Array<TokenAmount> {
|
|||||||
if (!state || !state[chainId]) {
|
if (!state || !state[chainId]) {
|
||||||
return {}
|
return {}
|
||||||
} else {
|
} else {
|
||||||
let newBalances = {}
|
const newBalances = {}
|
||||||
Object.keys(state[chainId]).map(address => {
|
Object.keys(state[chainId]).map(address => {
|
||||||
return Object.keys(state[chainId][address]).map(tokenAddress => {
|
return Object.keys(state[chainId][address]).map(tokenAddress => {
|
||||||
if (state[chainId][address][tokenAddress].value) {
|
if (state[chainId][address][tokenAddress].value) {
|
||||||
|
@ -3,21 +3,23 @@ import React, { createContext, useContext, useReducer, useMemo, useCallback, use
|
|||||||
import TxnPopup from '../components/TxnPopup'
|
import TxnPopup from '../components/TxnPopup'
|
||||||
|
|
||||||
import { useWeb3React } from '../hooks'
|
import { useWeb3React } from '../hooks'
|
||||||
import { safeAccess } from '../utils'
|
|
||||||
import { useBlockNumber, usePopups } from './Application'
|
import { useBlockNumber, usePopups } from './Application'
|
||||||
|
|
||||||
const RESPONSE = 'response'
|
|
||||||
const CUSTOM_DATA = 'CUSTOM_DATA'
|
|
||||||
const BLOCK_NUMBER_CHECKED = 'BLOCK_NUMBER_CHECKED'
|
|
||||||
const RECEIPT = 'receipt'
|
|
||||||
const SUMMARY = 'summary'
|
|
||||||
|
|
||||||
const ADD = 'ADD'
|
const ADD = 'ADD'
|
||||||
const CHECK = 'CHECK'
|
const CHECK = 'CHECK'
|
||||||
const FINALIZE = 'FINALIZE'
|
const FINALIZE = 'FINALIZE'
|
||||||
|
|
||||||
interface TransactionState {
|
interface TransactionState {
|
||||||
|
[chainId: number]: {
|
||||||
|
[txHash: string]: {
|
||||||
|
blockNumberChecked: any
|
||||||
|
response: {
|
||||||
|
customData?: any
|
||||||
|
summary: any
|
||||||
|
}
|
||||||
|
receipt: any
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TransactionsContext = createContext<[TransactionState, { [updater: string]: (...args: any[]) => void }]>([{}, {}])
|
const TransactionsContext = createContext<[TransactionState, { [updater: string]: (...args: any[]) => void }]>([{}, {}])
|
||||||
@ -26,21 +28,21 @@ export function useTransactionsContext() {
|
|||||||
return useContext(TransactionsContext)
|
return useContext(TransactionsContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
function reducer(state, { type, payload }) {
|
function reducer(state: TransactionState, { type, payload }): TransactionState {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ADD: {
|
case ADD: {
|
||||||
const { networkId, hash, response } = payload
|
const { networkId, hash, response } = payload
|
||||||
|
|
||||||
if (safeAccess(state, [networkId, hash]) !== null) {
|
if (state[networkId]?.[hash]) {
|
||||||
throw Error('Attempted to add existing transaction.')
|
throw Error('Attempted to add existing transaction.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[networkId]: {
|
[networkId]: {
|
||||||
...(safeAccess(state, [networkId]) || {}),
|
...state[networkId],
|
||||||
[hash]: {
|
[hash]: {
|
||||||
[RESPONSE]: response
|
response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,17 +50,17 @@ function reducer(state, { type, payload }) {
|
|||||||
case CHECK: {
|
case CHECK: {
|
||||||
const { networkId, hash, blockNumber } = payload
|
const { networkId, hash, blockNumber } = payload
|
||||||
|
|
||||||
if (safeAccess(state, [networkId, hash]) === null) {
|
if (!state[networkId]?.[hash]) {
|
||||||
throw Error('Attempted to check non-existent transaction.')
|
throw Error('Attempted to check non-existent transaction.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[networkId]: {
|
[networkId]: {
|
||||||
...(safeAccess(state, [networkId]) || {}),
|
...state[networkId],
|
||||||
[hash]: {
|
[hash]: {
|
||||||
...(safeAccess(state, [networkId, hash]) || {}),
|
...state[networkId]?.[hash],
|
||||||
[BLOCK_NUMBER_CHECKED]: blockNumber
|
blockNumberChecked: blockNumber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,17 +68,17 @@ function reducer(state, { type, payload }) {
|
|||||||
case FINALIZE: {
|
case FINALIZE: {
|
||||||
const { networkId, hash, receipt } = payload
|
const { networkId, hash, receipt } = payload
|
||||||
|
|
||||||
if (safeAccess(state, [networkId, hash]) === null) {
|
if (!state[networkId]?.[hash]) {
|
||||||
throw Error('Attempted to finalize non-existent transaction.')
|
throw Error('Attempted to finalize non-existent transaction.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[networkId]: {
|
[networkId]: {
|
||||||
...(safeAccess(state, [networkId]) || {}),
|
...state[networkId],
|
||||||
[hash]: {
|
[hash]: {
|
||||||
...(safeAccess(state, [networkId, hash]) || {}),
|
...state[networkId]?.[hash],
|
||||||
[RECEIPT]: receipt
|
receipt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +117,7 @@ export function Updater() {
|
|||||||
const globalBlockNumber = useBlockNumber()
|
const globalBlockNumber = useBlockNumber()
|
||||||
|
|
||||||
const [state, { check, finalize }] = useTransactionsContext()
|
const [state, { check, finalize }] = useTransactionsContext()
|
||||||
const allTransactions = safeAccess(state, [chainId]) || {}
|
const allTransactions = state[chainId] ?? {}
|
||||||
|
|
||||||
// show popup on confirm
|
// show popup on confirm
|
||||||
const [, addPopup] = usePopups()
|
const [, addPopup] = usePopups()
|
||||||
@ -125,7 +127,7 @@ export function Updater() {
|
|||||||
let stale = false
|
let stale = false
|
||||||
Object.keys(allTransactions)
|
Object.keys(allTransactions)
|
||||||
.filter(
|
.filter(
|
||||||
hash => !allTransactions[hash][RECEIPT] && allTransactions[hash][BLOCK_NUMBER_CHECKED] !== globalBlockNumber
|
hash => !allTransactions[hash].receipt && allTransactions[hash].blockNumberChecked !== globalBlockNumber
|
||||||
)
|
)
|
||||||
.forEach(hash => {
|
.forEach(hash => {
|
||||||
library
|
library
|
||||||
@ -138,12 +140,22 @@ export function Updater() {
|
|||||||
finalize(chainId, hash, receipt)
|
finalize(chainId, hash, receipt)
|
||||||
// add success or failure popup
|
// add success or failure popup
|
||||||
if (receipt.status === 1) {
|
if (receipt.status === 1) {
|
||||||
addPopup(<TxnPopup popKey={1} hash={hash} success={true}
|
addPopup(
|
||||||
summary={allTransactions[hash]?.response?.summary}/>)
|
<TxnPopup
|
||||||
|
popKey={1}
|
||||||
|
hash={hash}
|
||||||
|
success={true}
|
||||||
|
summary={allTransactions[hash]?.response?.summary}
|
||||||
|
/>
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
addPopup(
|
addPopup(
|
||||||
<TxnPopup popKey={2} hash={hash} success={false}
|
<TxnPopup
|
||||||
summary={allTransactions[hash]?.response?.summary}/>
|
popKey={2}
|
||||||
|
hash={hash}
|
||||||
|
success={false}
|
||||||
|
summary={allTransactions[hash]?.response?.summary}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,11 +185,11 @@ export function useTransactionAdder() {
|
|||||||
if (!(chainId || chainId === 0)) {
|
if (!(chainId || chainId === 0)) {
|
||||||
throw Error(`Invalid networkId '${chainId}`)
|
throw Error(`Invalid networkId '${chainId}`)
|
||||||
}
|
}
|
||||||
const hash = safeAccess(response, ['hash'])
|
const hash = response?.hash
|
||||||
if (!hash) {
|
if (!hash) {
|
||||||
throw Error('No transaction hash found.')
|
throw Error('No transaction hash found.')
|
||||||
}
|
}
|
||||||
add(chainId, hash, { ...response, [CUSTOM_DATA]: customData, [SUMMARY]: summary })
|
add(chainId, hash, { ...response, customData: customData, summary })
|
||||||
},
|
},
|
||||||
[chainId, add]
|
[chainId, add]
|
||||||
)
|
)
|
||||||
@ -188,18 +200,18 @@ export function useAllTransactions() {
|
|||||||
|
|
||||||
const [state] = useTransactionsContext()
|
const [state] = useTransactionsContext()
|
||||||
|
|
||||||
return safeAccess(state, [chainId]) || {}
|
return state[chainId] || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePendingApproval(tokenAddress) {
|
export function usePendingApproval(tokenAddress) {
|
||||||
const allTransactions = useAllTransactions()
|
const allTransactions = useAllTransactions()
|
||||||
return (
|
return (
|
||||||
Object.keys(allTransactions).filter(hash => {
|
Object.keys(allTransactions).filter(hash => {
|
||||||
if (allTransactions[hash][RECEIPT]) {
|
if (allTransactions[hash]?.receipt) {
|
||||||
return false
|
return false
|
||||||
} else if (!allTransactions[hash][RESPONSE]) {
|
} else if (!allTransactions[hash]?.response) {
|
||||||
return false
|
return false
|
||||||
} else if (allTransactions[hash][RESPONSE][CUSTOM_DATA].approval !== tokenAddress) {
|
} else if (allTransactions[hash]?.response?.customData?.approval !== tokenAddress) {
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
|
@ -6,8 +6,6 @@ export default function useInterval(callback: () => void, delay: null | number)
|
|||||||
// Remember the latest callback.
|
// Remember the latest callback.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
savedCallback.current = callback
|
savedCallback.current = callback
|
||||||
return () => {
|
|
||||||
}
|
|
||||||
}, [callback])
|
}, [callback])
|
||||||
|
|
||||||
// Set up the interval.
|
// Set up the interval.
|
||||||
@ -17,10 +15,8 @@ export default function useInterval(callback: () => void, delay: null | number)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (delay !== null) {
|
if (delay !== null) {
|
||||||
let id = setInterval(tick, delay)
|
const id = setInterval(tick, delay)
|
||||||
return () => clearInterval(id)
|
return () => clearInterval(id)
|
||||||
}
|
}
|
||||||
return () => {
|
|
||||||
}
|
|
||||||
}, [delay])
|
}, [delay])
|
||||||
}
|
}
|
@ -99,21 +99,21 @@ export default function App() {
|
|||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppWrapper>
|
<AppWrapper>
|
||||||
<HeaderWrapper>
|
<HeaderWrapper>
|
||||||
<Header/>
|
<Header />
|
||||||
</HeaderWrapper>
|
</HeaderWrapper>
|
||||||
<BodyWrapper>
|
<BodyWrapper>
|
||||||
<Popups/>
|
<Popups />
|
||||||
<Body>
|
<Body>
|
||||||
<Web3ReactManager>
|
<Web3ReactManager>
|
||||||
<NavigationTabs/>
|
<NavigationTabs />
|
||||||
{/* this Suspense is for route code-splitting */}
|
{/* this Suspense is for route code-splitting */}
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact strict path="/" render={() => <Redirect to="/swap"/>}/>
|
<Route exact strict path="/" render={() => <Redirect to="/swap" />} />
|
||||||
<Route exact strict path="/swap" component={() => <Swap params={params}/>}/>
|
<Route exact strict path="/swap" component={() => <Swap params={params} />} />
|
||||||
<Route exact strict path="/send" component={() => <Send params={params}/>}/>
|
<Route exact strict path="/send" component={() => <Send params={params} />} />
|
||||||
<Route exact strict path="/find" component={() => <Find/>}/>
|
<Route exact strict path="/find" component={() => <Find />} />
|
||||||
<Route exact strict path="/create" component={() => <Create/>}/>
|
<Route exact strict path="/create" component={() => <Create />} />
|
||||||
<Route exact strict path="/pool" component={() => <Pool/>}/>
|
<Route exact strict path="/pool" component={() => <Pool />} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
strict
|
strict
|
||||||
@ -127,7 +127,7 @@ export default function App() {
|
|||||||
if (t0 && t1) {
|
if (t0 && t1) {
|
||||||
return <Add token0={t0} token1={t1} />
|
return <Add token0={t0} token1={t1} />
|
||||||
} else {
|
} else {
|
||||||
return <Redirect to="/pool"/>
|
return <Redirect to="/pool" />
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -142,19 +142,19 @@ export default function App() {
|
|||||||
const t1 =
|
const t1 =
|
||||||
tokens?.[1] === 'ETH' ? 'ETH' : isAddress(tokens?.[1]) ? isAddress(tokens[1]) : undefined
|
tokens?.[1] === 'ETH' ? 'ETH' : isAddress(tokens?.[1]) ? isAddress(tokens[1]) : undefined
|
||||||
if (t0 && t1) {
|
if (t0 && t1) {
|
||||||
return <Remove token0={t0} token1={t1}/>
|
return <Remove token0={t0} token1={t1} />
|
||||||
} else {
|
} else {
|
||||||
return <Redirect to="/pool"/>
|
return <Redirect to="/pool" />
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Redirect to="/"/>
|
<Redirect to="/" />
|
||||||
</Switch>
|
</Switch>
|
||||||
</Web3ReactManager>
|
</Web3ReactManager>
|
||||||
</Body>
|
</Body>
|
||||||
<Footer/>
|
<Footer />
|
||||||
</BodyWrapper>
|
</BodyWrapper>
|
||||||
<StyledRed/>
|
<StyledRed />
|
||||||
</AppWrapper>
|
</AppWrapper>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
@ -675,7 +675,7 @@ function AddLiquidity({ token0, token1 }: AddLiquidityProps) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pendingText: string = `Supplying ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${
|
const pendingText = `Supplying ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${
|
||||||
tokens[Field.INPUT]?.symbol
|
tokens[Field.INPUT]?.symbol
|
||||||
} ${'and'} ${parsedAmounts[Field.OUTPUT]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol}`
|
} ${'and'} ${parsedAmounts[Field.OUTPUT]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol}`
|
||||||
|
|
||||||
|
@ -179,15 +179,15 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
|
|
||||||
const TokensDeposited: { [field: number]: TokenAmount } = {
|
const TokensDeposited: { [field: number]: TokenAmount } = {
|
||||||
[Field.TOKEN0]:
|
[Field.TOKEN0]:
|
||||||
pair &&
|
pair &&
|
||||||
totalPoolTokens &&
|
totalPoolTokens &&
|
||||||
userLiquidity &&
|
userLiquidity &&
|
||||||
pair.getLiquidityValue(tokens[Field.TOKEN0], totalPoolTokens, userLiquidity, false),
|
pair.getLiquidityValue(tokens[Field.TOKEN0], totalPoolTokens, userLiquidity, false),
|
||||||
[Field.TOKEN1]:
|
[Field.TOKEN1]:
|
||||||
pair &&
|
pair &&
|
||||||
totalPoolTokens &&
|
totalPoolTokens &&
|
||||||
userLiquidity &&
|
userLiquidity &&
|
||||||
pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, userLiquidity, false)
|
pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, userLiquidity, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const route: Route = pair
|
const route: Route = pair
|
||||||
@ -282,7 +282,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSliderChange = (newPercent) => {
|
const handleSliderChange = newPercent => {
|
||||||
onUserInput(
|
onUserInput(
|
||||||
Field.LIQUIDITY,
|
Field.LIQUIDITY,
|
||||||
new TokenAmount(
|
new TokenAmount(
|
||||||
@ -425,6 +425,13 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetModalState() {
|
||||||
|
setSigned(false)
|
||||||
|
setSigInputs(null)
|
||||||
|
setAttemptedRemoval(false)
|
||||||
|
setPendingConfirmation(true)
|
||||||
|
}
|
||||||
|
|
||||||
async function onRemove() {
|
async function onRemove() {
|
||||||
setAttemptedRemoval(true)
|
setAttemptedRemoval(true)
|
||||||
const router = getRouterContract(chainId, library, account)
|
const router = getRouterContract(chainId, library, account)
|
||||||
@ -482,13 +489,13 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
addTransaction(
|
addTransaction(
|
||||||
response,
|
response,
|
||||||
'Remove ' +
|
'Remove ' +
|
||||||
parsedAmounts[Field.TOKEN0]?.toSignificant(3) +
|
parsedAmounts[Field.TOKEN0]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.TOKEN0]?.symbol +
|
tokens[Field.TOKEN0]?.symbol +
|
||||||
' and ' +
|
' and ' +
|
||||||
parsedAmounts[Field.TOKEN1]?.toSignificant(3) +
|
parsedAmounts[Field.TOKEN1]?.toSignificant(3) +
|
||||||
' ' +
|
' ' +
|
||||||
tokens[Field.TOKEN1]?.symbol
|
tokens[Field.TOKEN1]?.symbol
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -499,13 +506,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetModalState() {
|
|
||||||
setSigned(false)
|
|
||||||
setSigInputs(null)
|
|
||||||
setAttemptedRemoval(false)
|
|
||||||
setPendingConfirmation(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function modalHeader() {
|
function modalHeader() {
|
||||||
return (
|
return (
|
||||||
<AutoColumn gap={'sm'} style={{ marginTop: '20px' }}>
|
<AutoColumn gap={'sm'} style={{ marginTop: '20px' }}>
|
||||||
@ -514,21 +514,21 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
{!!parsedAmounts[Field.TOKEN0] && parsedAmounts[Field.TOKEN0].toSignificant(6)}
|
{!!parsedAmounts[Field.TOKEN0] && parsedAmounts[Field.TOKEN0].toSignificant(6)}
|
||||||
</Text>
|
</Text>
|
||||||
<RowFixed gap="4px">
|
<RowFixed gap="4px">
|
||||||
<TokenLogo address={tokens[Field.TOKEN0]?.address} size={'24px'}/>
|
<TokenLogo address={tokens[Field.TOKEN0]?.address} size={'24px'} />
|
||||||
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
||||||
{tokens[Field.TOKEN0]?.symbol || ''}
|
{tokens[Field.TOKEN0]?.symbol || ''}
|
||||||
</Text>
|
</Text>
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
</RowBetween>
|
</RowBetween>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<Plus size="16" color={'#888D9B'}/>
|
<Plus size="16" color={'#888D9B'} />
|
||||||
</RowFixed>
|
</RowFixed>
|
||||||
<RowBetween align="flex-end">
|
<RowBetween align="flex-end">
|
||||||
<Text fontSize={24} fontWeight={600}>
|
<Text fontSize={24} fontWeight={600}>
|
||||||
{!!parsedAmounts[Field.TOKEN1] && parsedAmounts[Field.TOKEN1].toSignificant(6)}
|
{!!parsedAmounts[Field.TOKEN1] && parsedAmounts[Field.TOKEN1].toSignificant(6)}
|
||||||
</Text>
|
</Text>
|
||||||
<RowFixed gap="4px">
|
<RowFixed gap="4px">
|
||||||
<TokenLogo address={tokens[Field.TOKEN1]?.address} size={'24px'}/>
|
<TokenLogo address={tokens[Field.TOKEN1]?.address} size={'24px'} />
|
||||||
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
<Text fontSize={24} fontWeight={500} style={{ marginLeft: '10px' }}>
|
||||||
{tokens[Field.TOKEN1]?.symbol || ''}
|
{tokens[Field.TOKEN1]?.symbol || ''}
|
||||||
</Text>
|
</Text>
|
||||||
@ -596,7 +596,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pendingText: string = `Removing ${parsedAmounts[Field.TOKEN0]?.toSignificant(6)} ${
|
const pendingText = `Removing ${parsedAmounts[Field.TOKEN0]?.toSignificant(6)} ${
|
||||||
tokens[Field.TOKEN0]?.symbol
|
tokens[Field.TOKEN0]?.symbol
|
||||||
} and ${parsedAmounts[Field.TOKEN1]?.toSignificant(6)} ${tokens[Field.TOKEN1]?.symbol}`
|
} and ${parsedAmounts[Field.TOKEN1]?.toSignificant(6)} ${tokens[Field.TOKEN1]?.symbol}`
|
||||||
|
|
||||||
@ -637,7 +637,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
</Text>
|
</Text>
|
||||||
</Row>
|
</Row>
|
||||||
{!showAdvanced && (
|
{!showAdvanced && (
|
||||||
<Slider value={parseFloat(derivedPerecent)} onChange={handleSliderChange} override={override}/>
|
<Slider value={parseFloat(derivedPerecent)} onChange={handleSliderChange} override={override} />
|
||||||
)}
|
)}
|
||||||
{!showAdvanced && (
|
{!showAdvanced && (
|
||||||
<RowBetween>
|
<RowBetween>
|
||||||
@ -660,7 +660,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
{!showAdvanced && (
|
{!showAdvanced && (
|
||||||
<>
|
<>
|
||||||
<ColumnCenter>
|
<ColumnCenter>
|
||||||
<ArrowDown size="16" color="#888D9B"/>
|
<ArrowDown size="16" color="#888D9B" />
|
||||||
</ColumnCenter>{' '}
|
</ColumnCenter>{' '}
|
||||||
<LightCard>
|
<LightCard>
|
||||||
<AutoColumn gap="10px">
|
<AutoColumn gap="10px">
|
||||||
@ -669,7 +669,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
{formattedAmounts[Field.TOKEN0] ? formattedAmounts[Field.TOKEN0] : '-'}
|
{formattedAmounts[Field.TOKEN0] ? formattedAmounts[Field.TOKEN0] : '-'}
|
||||||
</Text>
|
</Text>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<TokenLogo address={tokens[Field.TOKEN0]?.address || ''} style={{ marginRight: '12px' }}/>
|
<TokenLogo address={tokens[Field.TOKEN0]?.address || ''} style={{ marginRight: '12px' }} />
|
||||||
<Text fontSize={24} fontWeight={500}>
|
<Text fontSize={24} fontWeight={500}>
|
||||||
{tokens[Field.TOKEN0]?.symbol}
|
{tokens[Field.TOKEN0]?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -680,7 +680,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
{formattedAmounts[Field.TOKEN1] ? formattedAmounts[Field.TOKEN1] : '-'}
|
{formattedAmounts[Field.TOKEN1] ? formattedAmounts[Field.TOKEN1] : '-'}
|
||||||
</Text>
|
</Text>
|
||||||
<RowFixed>
|
<RowFixed>
|
||||||
<TokenLogo address={tokens[Field.TOKEN1]?.address || ''} style={{ marginRight: '12px' }}/>
|
<TokenLogo address={tokens[Field.TOKEN1]?.address || ''} style={{ marginRight: '12px' }} />
|
||||||
<Text fontSize={24} fontWeight={500}>
|
<Text fontSize={24} fontWeight={500}>
|
||||||
{tokens[Field.TOKEN1]?.symbol}
|
{tokens[Field.TOKEN1]?.symbol}
|
||||||
</Text>
|
</Text>
|
||||||
@ -706,7 +706,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
inputId="liquidityAmount"
|
inputId="liquidityAmount"
|
||||||
/>
|
/>
|
||||||
<ColumnCenter>
|
<ColumnCenter>
|
||||||
<ArrowDown size="16" color="#888D9B"/>
|
<ArrowDown size="16" color="#888D9B" />
|
||||||
</ColumnCenter>
|
</ColumnCenter>
|
||||||
<CurrencyInputPanel
|
<CurrencyInputPanel
|
||||||
field={Field.TOKEN0}
|
field={Field.TOKEN0}
|
||||||
@ -720,7 +720,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
|
|||||||
inputId="removeLiquidityToken0"
|
inputId="removeLiquidityToken0"
|
||||||
/>
|
/>
|
||||||
<ColumnCenter>
|
<ColumnCenter>
|
||||||
<Plus size="16" color="#888D9B"/>
|
<Plus size="16" color="#888D9B" />
|
||||||
</ColumnCenter>
|
</ColumnCenter>
|
||||||
<CurrencyInputPanel
|
<CurrencyInputPanel
|
||||||
field={Field.TOKEN1}
|
field={Field.TOKEN1}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useContext } from 'react'
|
import React, { useState, useContext } from 'react'
|
||||||
import styled, { ThemeContext } from 'styled-components'
|
import styled, { ThemeContext } from 'styled-components'
|
||||||
import { JSBI } from '@uniswap/sdk'
|
import { JSBI } from '@uniswap/sdk'
|
||||||
import { withRouter } from 'react-router-dom'
|
import { RouteComponentProps, withRouter } from 'react-router-dom'
|
||||||
|
|
||||||
import Question from '../../components/Question'
|
import Question from '../../components/Question'
|
||||||
import SearchModal from '../../components/SearchModal'
|
import SearchModal from '../../components/SearchModal'
|
||||||
@ -29,7 +29,7 @@ const FixedBottom = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`
|
`
|
||||||
|
|
||||||
function Supply({ history }) {
|
function Supply({ history }: RouteComponentProps) {
|
||||||
const { account } = useWeb3React()
|
const { account } = useWeb3React()
|
||||||
const [showPoolSearch, setShowPoolSearch] = useState(false)
|
const [showPoolSearch, setShowPoolSearch] = useState(false)
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ function Supply({ history }) {
|
|||||||
useAccountLPBalances(account)
|
useAccountLPBalances(account)
|
||||||
|
|
||||||
const filteredExchangeList = Object.keys(allPairs)
|
const filteredExchangeList = Object.keys(allPairs)
|
||||||
.filter((pairAddress, i) => {
|
.filter(pairAddress => {
|
||||||
return (
|
return (
|
||||||
allBalances &&
|
allBalances &&
|
||||||
allBalances[account] &&
|
allBalances[account] &&
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ExchangePage from '../../components/ExchangePage'
|
import ExchangePage from '../../components/ExchangePage'
|
||||||
|
import { QueryParams } from '../../utils'
|
||||||
|
|
||||||
export default function Swap({ params }) {
|
export default function Swap({ params }: { params: QueryParams }) {
|
||||||
return <ExchangePage sendingInput={false} params={params} />
|
return <ExchangePage sendingInput={false} params={params} />
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,9 @@ import styled, { keyframes } from 'styled-components'
|
|||||||
import { darken } from 'polished'
|
import { darken } from 'polished'
|
||||||
import { X } from 'react-feather'
|
import { X } from 'react-feather'
|
||||||
|
|
||||||
export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColor: string }>(
|
export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColor: string }>(({ warning, theme }) => ({
|
||||||
({ warning, theme }) => ({
|
backgroundColor: warning ? theme.red1 : theme.blue1
|
||||||
backgroundColor: warning ? theme.red1 : theme.blue1
|
}))`
|
||||||
}))`
|
|
||||||
padding: 1rem 2rem 1rem 2rem;
|
padding: 1rem 2rem 1rem 2rem;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -33,7 +32,7 @@ export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColo
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const CloseIcon = styled(X)<{ onClick: () => void}>`
|
export const CloseIcon = styled(X)<{ onClick: () => void }>`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@ import styled, {
|
|||||||
ThemeProvider as StyledComponentsThemeProvider,
|
ThemeProvider as StyledComponentsThemeProvider,
|
||||||
createGlobalStyle,
|
createGlobalStyle,
|
||||||
css,
|
css,
|
||||||
|
DefaultTheme
|
||||||
} from 'styled-components'
|
} from 'styled-components'
|
||||||
import { getQueryParam, checkSupportedTheme } from '../utils'
|
import { getQueryParam, checkSupportedTheme } from '../utils'
|
||||||
import { SUPPORTED_THEMES } from '../constants'
|
import { SUPPORTED_THEMES } from '../constants'
|
||||||
import { useDarkModeManager } from '../contexts/LocalStorage'
|
import { useDarkModeManager } from '../contexts/LocalStorage'
|
||||||
import { Text } from 'rebass'
|
import { Text } from 'rebass'
|
||||||
import { UniswapTheme } from './styled'
|
|
||||||
|
|
||||||
export * from './components'
|
export * from './components'
|
||||||
|
|
||||||
@ -19,20 +19,95 @@ const MEDIA_WIDTHS = {
|
|||||||
upToLarge: 1280
|
upToLarge: 1280
|
||||||
}
|
}
|
||||||
|
|
||||||
const mediaWidthTemplates: { [width in keyof typeof MEDIA_WIDTHS]: typeof css } =
|
const mediaWidthTemplates: { [width in keyof typeof MEDIA_WIDTHS]: typeof css } = Object.keys(MEDIA_WIDTHS).reduce(
|
||||||
Object.keys(MEDIA_WIDTHS)
|
(accumulator, size) => {
|
||||||
.reduce((accumulator, size) => {
|
accumulator[size] = (a, b, c) => css`
|
||||||
accumulator[size] = (a, b, c) => css`
|
@media (max-width: ${MEDIA_WIDTHS[size]}px) {
|
||||||
@media (max-width: ${MEDIA_WIDTHS[size]}px) {
|
${css(a, b, c)}
|
||||||
${css(a, b, c)}
|
}
|
||||||
}
|
`
|
||||||
`
|
return accumulator
|
||||||
return accumulator
|
},
|
||||||
}, {}) as any
|
{}
|
||||||
|
) as any
|
||||||
|
|
||||||
const white = '#FFFFFF'
|
const white = '#FFFFFF'
|
||||||
const black = '#000000'
|
const black = '#000000'
|
||||||
|
|
||||||
|
export function theme(darkMode: boolean): DefaultTheme {
|
||||||
|
return {
|
||||||
|
// base
|
||||||
|
white,
|
||||||
|
black,
|
||||||
|
|
||||||
|
// text
|
||||||
|
text1: darkMode ? '#FFFFFF' : '#000000',
|
||||||
|
text2: darkMode ? '#CED0D9' : '#565A69',
|
||||||
|
text3: darkMode ? '#6C7284' : '#888D9B',
|
||||||
|
text4: darkMode ? '#565A69' : '#C3C5CB',
|
||||||
|
text5: '#EDEEF2',
|
||||||
|
|
||||||
|
// backgrounds / greys
|
||||||
|
bg1: darkMode ? '#212429' : '#FFFFFF',
|
||||||
|
bg2: darkMode ? '#2C2F36' : '#F7F8FA',
|
||||||
|
bg3: darkMode ? '#40444F' : '#EDEEF2',
|
||||||
|
bg4: darkMode ? '#565A69' : '#CED0D9',
|
||||||
|
bg5: darkMode ? '#565A69' : '#888D9B',
|
||||||
|
|
||||||
|
modalBG: darkMode ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.6)',
|
||||||
|
advancedBG: darkMode ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.6)',
|
||||||
|
|
||||||
|
//blues
|
||||||
|
blue1: darkMode ? '#2172E5' : '#ff007a',
|
||||||
|
blue2: darkMode ? '#3680E7' : '#1966D2',
|
||||||
|
blue3: darkMode ? '#4D8FEA' : '#165BBB',
|
||||||
|
// blue4: darkMode ? '#153d6f70' : '#C4D9F8',
|
||||||
|
// blue5: darkMode ? '#153d6f70' : '#EBF4FF',
|
||||||
|
blue4: darkMode ? '#153d6f70' : '#F6DDE8',
|
||||||
|
blue5: darkMode ? '#153d6f70' : '#FDEAF1',
|
||||||
|
|
||||||
|
buttonSecondaryText: darkMode ? '#6da8ff' : '#ff007a',
|
||||||
|
|
||||||
|
// blue1: '#ff007a',
|
||||||
|
// blue4: '#F6DDE8',
|
||||||
|
// blue5: '#FDEAF1',
|
||||||
|
|
||||||
|
// pinks
|
||||||
|
pink1: '#DC6BE5',
|
||||||
|
pink2: darkMode ? '#2172E5' : '#ff007a',
|
||||||
|
pink3: darkMode ? '#17000b26' : '#F6DDE8',
|
||||||
|
pink4: darkMode ? '#17000b26' : '#FDEAF1',
|
||||||
|
|
||||||
|
// other
|
||||||
|
red1: '#FF6871',
|
||||||
|
green1: '#27AE60',
|
||||||
|
yellow1: '#FFE270',
|
||||||
|
yellow2: '#F3841E',
|
||||||
|
|
||||||
|
grids: {
|
||||||
|
sm: 8,
|
||||||
|
md: 12,
|
||||||
|
lg: 24
|
||||||
|
},
|
||||||
|
|
||||||
|
//shadows
|
||||||
|
shadow1: darkMode ? '#000' : '#2F80ED',
|
||||||
|
|
||||||
|
// media queries
|
||||||
|
mediaWidth: mediaWidthTemplates,
|
||||||
|
|
||||||
|
// css snippets
|
||||||
|
flexColumnNoWrap: css`
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
`,
|
||||||
|
flexRowNoWrap: css`
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function ThemeProvider({ children }) {
|
export default function ThemeProvider({ children }) {
|
||||||
const [darkMode, toggleDarkMode] = useDarkModeManager()
|
const [darkMode, toggleDarkMode] = useDarkModeManager()
|
||||||
const themeURL = checkSupportedTheme(getQueryParam(window.location, 'theme'))
|
const themeURL = checkSupportedTheme(getQueryParam(window.location, 'theme'))
|
||||||
@ -40,8 +115,8 @@ export default function ThemeProvider({ children }) {
|
|||||||
? themeURL.toUpperCase() === SUPPORTED_THEMES.DARK
|
? themeURL.toUpperCase() === SUPPORTED_THEMES.DARK
|
||||||
? true
|
? true
|
||||||
: themeURL.toUpperCase() === SUPPORTED_THEMES.LIGHT
|
: themeURL.toUpperCase() === SUPPORTED_THEMES.LIGHT
|
||||||
? false
|
? false
|
||||||
: darkMode
|
: darkMode
|
||||||
: darkMode
|
: darkMode
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
toggleDarkMode(themeToRender)
|
toggleDarkMode(themeToRender)
|
||||||
@ -49,78 +124,6 @@ export default function ThemeProvider({ children }) {
|
|||||||
return <StyledComponentsThemeProvider theme={theme(themeToRender)}>{children}</StyledComponentsThemeProvider>
|
return <StyledComponentsThemeProvider theme={theme(themeToRender)}>{children}</StyledComponentsThemeProvider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const theme: (darkMode: boolean) => UniswapTheme = darkMode => ({
|
|
||||||
// base
|
|
||||||
white,
|
|
||||||
black,
|
|
||||||
|
|
||||||
// text
|
|
||||||
text1: darkMode ? '#FFFFFF' : '#000000',
|
|
||||||
text2: darkMode ? '#CED0D9' : '#565A69',
|
|
||||||
text3: darkMode ? '#6C7284' : '#888D9B',
|
|
||||||
text4: darkMode ? '#565A69' : '#C3C5CB',
|
|
||||||
text5: '#EDEEF2',
|
|
||||||
|
|
||||||
// backgrounds / greys
|
|
||||||
bg1: darkMode ? '#212429' : '#FFFFFF',
|
|
||||||
bg2: darkMode ? '#2C2F36' : '#F7F8FA',
|
|
||||||
bg3: darkMode ? '#40444F' : '#EDEEF2',
|
|
||||||
bg4: darkMode ? '#565A69' : '#CED0D9',
|
|
||||||
bg5: darkMode ? '#565A69' : '#888D9B',
|
|
||||||
|
|
||||||
modalBG: darkMode ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.6)',
|
|
||||||
advancedBG: darkMode ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.6)',
|
|
||||||
|
|
||||||
//blues
|
|
||||||
blue1: darkMode ? '#2172E5' : '#ff007a',
|
|
||||||
blue2: darkMode ? '#3680E7' : '#1966D2',
|
|
||||||
blue3: darkMode ? '#4D8FEA' : '#165BBB',
|
|
||||||
// blue4: darkMode ? '#153d6f70' : '#C4D9F8',
|
|
||||||
// blue5: darkMode ? '#153d6f70' : '#EBF4FF',
|
|
||||||
blue4: darkMode ? '#153d6f70' : '#F6DDE8',
|
|
||||||
blue5: darkMode ? '#153d6f70' : '#FDEAF1',
|
|
||||||
|
|
||||||
buttonSecondaryText: darkMode ? '#6da8ff' : '#ff007a',
|
|
||||||
|
|
||||||
// blue1: '#ff007a',
|
|
||||||
// blue4: '#F6DDE8',
|
|
||||||
// blue5: '#FDEAF1',
|
|
||||||
|
|
||||||
// pinks
|
|
||||||
pink1: '#DC6BE5',
|
|
||||||
pink2: darkMode ? '#2172E5' : '#ff007a',
|
|
||||||
pink3: darkMode ? '#17000b26' : '#F6DDE8',
|
|
||||||
pink4: darkMode ? '#17000b26' : '#FDEAF1',
|
|
||||||
|
|
||||||
// other
|
|
||||||
red1: '#FF6871',
|
|
||||||
green1: '#27AE60',
|
|
||||||
yellow1: '#FFE270',
|
|
||||||
yellow2: '#F3841E',
|
|
||||||
|
|
||||||
grids: {
|
|
||||||
sm: 8,
|
|
||||||
md: 12,
|
|
||||||
lg: 24
|
|
||||||
},
|
|
||||||
|
|
||||||
//shadows
|
|
||||||
shadow1: darkMode ? '#000' : '#2F80ED',
|
|
||||||
|
|
||||||
// media queries
|
|
||||||
mediaWidth: mediaWidthTemplates,
|
|
||||||
|
|
||||||
// css snippets
|
|
||||||
flexColumnNoWrap: css`
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
`,
|
|
||||||
flexRowNoWrap: css`
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row nowrap;
|
|
||||||
`
|
|
||||||
})
|
|
||||||
|
|
||||||
const TextWrapper = styled(Text)`
|
const TextWrapper = styled(Text)`
|
||||||
color = ${({ color, theme }) => theme[color]}
|
color = ${({ color, theme }) => theme[color]}
|
||||||
`
|
`
|
||||||
|
118
src/theme/styled.d.ts
vendored
118
src/theme/styled.d.ts
vendored
@ -1,66 +1,62 @@
|
|||||||
import { css, FlattenSimpleInterpolation } from 'styled-components'
|
import { css, FlattenSimpleInterpolation } from 'styled-components'
|
||||||
|
|
||||||
export interface UniswapTheme {
|
|
||||||
// base
|
|
||||||
white: string
|
|
||||||
black: string
|
|
||||||
|
|
||||||
// text
|
|
||||||
text1: string
|
|
||||||
text2: string
|
|
||||||
text3: string
|
|
||||||
text4: string
|
|
||||||
text5: string
|
|
||||||
|
|
||||||
// backgrounds / greys
|
|
||||||
bg1: string
|
|
||||||
bg2: string
|
|
||||||
bg3: string
|
|
||||||
bg4: string
|
|
||||||
bg5: string
|
|
||||||
|
|
||||||
modalBG: string
|
|
||||||
advancedBG: string
|
|
||||||
|
|
||||||
//blues
|
|
||||||
blue1: string
|
|
||||||
blue2: string
|
|
||||||
blue3: string
|
|
||||||
blue4: string
|
|
||||||
blue5: string
|
|
||||||
|
|
||||||
buttonSecondaryText: string
|
|
||||||
|
|
||||||
// pinks
|
|
||||||
pink1: string
|
|
||||||
pink2: string
|
|
||||||
pink3: string
|
|
||||||
pink4: string
|
|
||||||
|
|
||||||
// other
|
|
||||||
red1: string
|
|
||||||
green1: string
|
|
||||||
yellow1: string
|
|
||||||
yellow2: string
|
|
||||||
|
|
||||||
grids: {
|
|
||||||
sm: number,
|
|
||||||
md: number,
|
|
||||||
lg: number
|
|
||||||
},
|
|
||||||
|
|
||||||
// shadows
|
|
||||||
shadow1: string
|
|
||||||
|
|
||||||
// media queries
|
|
||||||
mediaWidth: { [width in keyof typeof MEDIA_WIDTHS]: typeof css },
|
|
||||||
// css snippets
|
|
||||||
flexColumnNoWrap: FlattenSimpleInterpolation
|
|
||||||
flexRowNoWrap: FlattenSimpleInterpolation
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'styled-components' {
|
declare module 'styled-components' {
|
||||||
export interface DefaultTheme extends UniswapTheme {
|
export interface DefaultTheme {
|
||||||
|
// base
|
||||||
|
white: string
|
||||||
|
black: string
|
||||||
|
|
||||||
|
// text
|
||||||
|
text1: string
|
||||||
|
text2: string
|
||||||
|
text3: string
|
||||||
|
text4: string
|
||||||
|
text5: string
|
||||||
|
|
||||||
|
// backgrounds / greys
|
||||||
|
bg1: string
|
||||||
|
bg2: string
|
||||||
|
bg3: string
|
||||||
|
bg4: string
|
||||||
|
bg5: string
|
||||||
|
|
||||||
|
modalBG: string
|
||||||
|
advancedBG: string
|
||||||
|
|
||||||
|
//blues
|
||||||
|
blue1: string
|
||||||
|
blue2: string
|
||||||
|
blue3: string
|
||||||
|
blue4: string
|
||||||
|
blue5: string
|
||||||
|
|
||||||
|
buttonSecondaryText: string
|
||||||
|
|
||||||
|
// pinks
|
||||||
|
pink1: string
|
||||||
|
pink2: string
|
||||||
|
pink3: string
|
||||||
|
pink4: string
|
||||||
|
|
||||||
|
// other
|
||||||
|
red1: string
|
||||||
|
green1: string
|
||||||
|
yellow1: string
|
||||||
|
yellow2: string
|
||||||
|
|
||||||
|
grids: {
|
||||||
|
sm: number
|
||||||
|
md: number
|
||||||
|
lg: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// shadows
|
||||||
|
shadow1: string
|
||||||
|
|
||||||
|
// media queries
|
||||||
|
mediaWidth: { [width in keyof typeof MEDIA_WIDTHS]: typeof css }
|
||||||
|
// css snippets
|
||||||
|
flexColumnNoWrap: FlattenSimpleInterpolation
|
||||||
|
flexRowNoWrap: FlattenSimpleInterpolation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,20 +12,19 @@ import { ROUTER_ADDRESS, SUPPORTED_THEMES } from '../constants'
|
|||||||
import ERC20_ABI from '../constants/abis/erc20.json'
|
import ERC20_ABI from '../constants/abis/erc20.json'
|
||||||
import ERC20_BYTES32_ABI from '../constants/abis/erc20_bytes32.json'
|
import ERC20_BYTES32_ABI from '../constants/abis/erc20_bytes32.json'
|
||||||
|
|
||||||
|
export function isAddress(value: any): string | false {
|
||||||
|
try {
|
||||||
|
return getAddress(value.toLowerCase())
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export enum ERROR_CODES {
|
export enum ERROR_CODES {
|
||||||
TOKEN_SYMBOL = 1,
|
TOKEN_SYMBOL = 1,
|
||||||
TOKEN_DECIMALS = 2
|
TOKEN_DECIMALS = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export function safeAccess(object, path) {
|
|
||||||
return object
|
|
||||||
? path.reduce(
|
|
||||||
(accumulator, currentValue) => (accumulator && accumulator[currentValue] ? accumulator[currentValue] : null),
|
|
||||||
object
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
|
|
||||||
const ETHERSCAN_PREFIXES = {
|
const ETHERSCAN_PREFIXES = {
|
||||||
1: '',
|
1: '',
|
||||||
3: 'ropsten.',
|
3: 'ropsten.',
|
||||||
@ -49,7 +48,7 @@ export function getEtherscanLink(networkId: 1 | 3 | 4 | 5 | 42 | any, data: stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getQueryParam(windowLocation, name) {
|
export function getQueryParam(windowLocation, name) {
|
||||||
var q = windowLocation.search.match(new RegExp('[?&]' + name + '=([^&#?]*)'))
|
const q = windowLocation.search.match(new RegExp('[?&]' + name + '=([^&#?]*)'))
|
||||||
return q && q[1]
|
return q && q[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,18 +121,6 @@ export function shortenAddress(address, digits = 4) {
|
|||||||
return `${address.substring(0, digits + 2)}...${address.substring(42 - digits)}`
|
return `${address.substring(0, digits + 2)}...${address.substring(42 - digits)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shortenTransactionHash(hash, digits = 4) {
|
|
||||||
return `${hash.substring(0, digits + 2)}...${hash.substring(66 - digits)}`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isAddress(value: any): string | false {
|
|
||||||
try {
|
|
||||||
return getAddress(value.toLowerCase())
|
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function calculateGasMargin(value: BigNumber) {
|
export function calculateGasMargin(value: BigNumber) {
|
||||||
return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000)) // add 10%
|
return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000)) // add 10%
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"types": [
|
"types": [
|
||||||
"react-spring"
|
"react-spring",
|
||||||
|
"jest"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
39
yarn.lock
39
yarn.lock
@ -2630,7 +2630,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/yargs-parser" "*"
|
"@types/yargs-parser" "*"
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@^2.10.0":
|
"@typescript-eslint/eslint-plugin@^2.10.0", "@typescript-eslint/eslint-plugin@^2.31.0":
|
||||||
version "2.31.0"
|
version "2.31.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz#942c921fec5e200b79593c71fafb1e3f57aa2e36"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz#942c921fec5e200b79593c71fafb1e3f57aa2e36"
|
||||||
integrity sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==
|
integrity sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==
|
||||||
@ -2650,7 +2650,7 @@
|
|||||||
eslint-scope "^5.0.0"
|
eslint-scope "^5.0.0"
|
||||||
eslint-utils "^2.0.0"
|
eslint-utils "^2.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@^2.10.0":
|
"@typescript-eslint/parser@^2.10.0", "@typescript-eslint/parser@^2.31.0":
|
||||||
version "2.31.0"
|
version "2.31.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.31.0.tgz#beddd4e8efe64995108b229b2862cd5752d40d6f"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.31.0.tgz#beddd4e8efe64995108b229b2862cd5752d40d6f"
|
||||||
integrity sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==
|
integrity sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==
|
||||||
@ -6772,6 +6772,13 @@ escodegen@^1.11.0, escodegen@^1.9.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
|
eslint-config-prettier@^6.11.0:
|
||||||
|
version "6.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
|
||||||
|
integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==
|
||||||
|
dependencies:
|
||||||
|
get-stdin "^6.0.0"
|
||||||
|
|
||||||
eslint-config-react-app@^5.2.1:
|
eslint-config-react-app@^5.2.1:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df"
|
resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df"
|
||||||
@ -6846,12 +6853,19 @@ eslint-plugin-jsx-a11y@6.2.3:
|
|||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
jsx-ast-utils "^2.2.1"
|
jsx-ast-utils "^2.2.1"
|
||||||
|
|
||||||
|
eslint-plugin-prettier@^3.1.3:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca"
|
||||||
|
integrity sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==
|
||||||
|
dependencies:
|
||||||
|
prettier-linter-helpers "^1.0.0"
|
||||||
|
|
||||||
eslint-plugin-react-hooks@^1.6.1:
|
eslint-plugin-react-hooks@^1.6.1:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04"
|
||||||
integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==
|
integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==
|
||||||
|
|
||||||
eslint-plugin-react@7.19.0:
|
eslint-plugin-react@7.19.0, eslint-plugin-react@^7.19.0:
|
||||||
version "7.19.0"
|
version "7.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666"
|
||||||
integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==
|
integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==
|
||||||
@ -6904,7 +6918,7 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||||
|
|
||||||
eslint@^6.6.0:
|
eslint@^6.6.0, eslint@^6.8.0:
|
||||||
version "6.8.0"
|
version "6.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb"
|
||||||
integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==
|
integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==
|
||||||
@ -7800,6 +7814,11 @@ fast-deep-equal@^3.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
||||||
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
|
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
|
||||||
|
|
||||||
|
fast-diff@^1.1.2:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
|
||||||
|
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||||
|
|
||||||
fast-glob@^2.0.2:
|
fast-glob@^2.0.2:
|
||||||
version "2.2.7"
|
version "2.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
|
||||||
@ -8376,6 +8395,11 @@ get-own-enumerable-property-symbols@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
||||||
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
|
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
|
||||||
|
|
||||||
|
get-stdin@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
|
||||||
|
integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==
|
||||||
|
|
||||||
get-stream@^2.2.0:
|
get-stream@^2.2.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
|
||||||
@ -13448,6 +13472,13 @@ prepend-http@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||||
|
|
||||||
|
prettier-linter-helpers@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
|
||||||
|
integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
|
||||||
|
dependencies:
|
||||||
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
prettier@^1.17.0:
|
prettier@^1.17.0:
|
||||||
version "1.19.1"
|
version "1.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||||
|
Loading…
Reference in New Issue
Block a user