Commit 76dbc9fa authored by Ian Lapham's avatar Ian Lapham Committed by GitHub

Multiple UI changes (#700)

* small layout and text changes, bug fixes

* UI changes, add summary to txns

* Remove updates, small changes on send, common bases
parent 006fe9b3
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52 (66869) - http://www.bohemiancoding.com/sketch -->
<title>Path</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="check-circle-(1)" transform="translate(1.000000, 0.000000)" stroke="#D9EAFF" stroke-width="2">
<path d="M20,10.08 L20,11 C19.9974678,15.4286859 17.082294,19.328213 12.8353524,20.583901 C8.58841086,21.839589 4.02139355,20.1523121 1.61095509,16.4370663 C-0.799483376,12.7218205 -0.479136554,7.86363898 2.39827419,4.49707214 C5.27568494,1.13050531 10.0247126,0.0575252842 14.07,1.86" id="Path"></path>
</g>
</g>
</svg>
\ No newline at end of file
...@@ -9,14 +9,13 @@ import Copy from './Copy' ...@@ -9,14 +9,13 @@ import Copy from './Copy'
import Circle from '../../assets/images/circle.svg' import Circle from '../../assets/images/circle.svg'
import { transparentize } from 'polished' import { transparentize } from 'polished'
import { useAllTransactions } from '../../contexts/Transactions'
const TransactionStatusWrapper = styled.div` const TransactionStatusWrapper = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
min-width: 12px; min-width: 12px;
overflow: hidden; word-break: break-word;
text-overflow: ellipsis;
white-space: nowrap;
` `
const TransactionWrapper = styled.div` const TransactionWrapper = styled.div`
...@@ -25,17 +24,14 @@ const TransactionWrapper = styled.div` ...@@ -25,17 +24,14 @@ const TransactionWrapper = styled.div`
width: 100%; width: 100%;
margin-top: 0.75rem; margin-top: 0.75rem;
a { a {
/* flex: 1 1 auto; */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0; min-width: 0;
max-width: 250px; word-break: break-word;
} }
` `
const TransactionStatusText = styled.span` const TransactionStatusText = styled.span`
margin-left: 0.5rem; margin-left: 0.5rem;
word-break: keep-all;
` `
const rotate = keyframes` const rotate = keyframes`
...@@ -76,11 +72,14 @@ const ButtonWrapper = styled.div` ...@@ -76,11 +72,14 @@ const ButtonWrapper = styled.div`
export default function Transaction({ hash, pending }) { export default function Transaction({ hash, pending }) {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const allTransactions = useAllTransactions()
const summary = allTransactions?.[hash]?.response?.summary
return ( return (
<TransactionWrapper key={hash}> <TransactionWrapper key={hash}>
<TransactionStatusWrapper> <TransactionStatusWrapper>
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>{hash} </Link> <Link href={getEtherscanLink(chainId, hash, 'transaction')}>{summary ? summary : hash} </Link>
<Copy toCopy={hash} /> <Copy toCopy={hash} />
</TransactionStatusWrapper> </TransactionStatusWrapper>
{pending ? ( {pending ? (
......
...@@ -79,8 +79,8 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError ...@@ -79,8 +79,8 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError
}, [onChange, data.address, data.name]) }, [onChange, data.address, data.name])
useEffect(() => { useEffect(() => {
onError(error) onError(error, input)
}, [onError, error]) }, [onError, error, input])
// run parser on debounced input // run parser on debounced input
useEffect(() => { useEffect(() => {
......
...@@ -31,9 +31,9 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -31,9 +31,9 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
// text translation // text translation
const { t } = useTranslation() const { t } = useTranslation()
const [deadlineInput, setDeadlineInput] = useState(15) const [deadlineInput, setDeadlineInput] = useState(20)
const [slippageInput, setSlippageInput] = useState() const [slippageInput, setSlippageInput] = useState()
const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[3]) const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[2])
const [slippageInputError, setSlippageInputError] = useState(null) // error const [slippageInputError, setSlippageInputError] = useState(null) // error
...@@ -65,9 +65,9 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -65,9 +65,9 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
useEffect(() => { useEffect(() => {
if (allowedSlippage === 10) { if (allowedSlippage === 10) {
setActiveIndex(1) setActiveIndex(1)
} else if (allowedSlippage === 100) { } else if (allowedSlippage === 50) {
setActiveIndex(2) setActiveIndex(2)
} else if (allowedSlippage === 200) { } else if (allowedSlippage === 100) {
setActiveIndex(3) setActiveIndex(3)
} else { } else {
setActiveIndex(4) setActiveIndex(4)
...@@ -108,25 +108,25 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -108,25 +108,25 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
padding="4px 6px" padding="4px 6px"
borderRadius="8px" borderRadius="8px"
style={{ marginRight: '16px' }} style={{ marginRight: '16px' }}
width={'60px'} width={'180px'}
onClick={() => { onClick={() => {
setActiveIndex(SLIPPAGE_INDEX[2]) setActiveIndex(SLIPPAGE_INDEX[2])
setAllowedSlippage(100) setAllowedSlippage(50)
}} }}
> >
1% 0.5% (suggested)
</ButtonRadio> </ButtonRadio>
<ButtonRadio <ButtonRadio
active={SLIPPAGE_INDEX[3] === activeIndex} active={SLIPPAGE_INDEX[3] === activeIndex}
padding="4px" padding="4px"
borderRadius="8px" borderRadius="8px"
width={'140px'} width={'60px'}
onClick={() => { onClick={() => {
setActiveIndex(SLIPPAGE_INDEX[3]) setActiveIndex(SLIPPAGE_INDEX[3])
setAllowedSlippage(200) setAllowedSlippage(100)
}} }}
> >
2% (suggested) 1%
</ButtonRadio> </ButtonRadio>
</Row> </Row>
<RowFixed> <RowFixed>
......
...@@ -115,13 +115,13 @@ export const ButtonEmpty = styled(Base)` ...@@ -115,13 +115,13 @@ export const ButtonEmpty = styled(Base)`
color: black; color: black;
&:focus { &:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, '#edeef2')}; box-shadow: 0 0 0 1px ${({ theme }) => theme.bg3};
} }
&:hover { &:hover {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, '#edeef2')}; box-shadow: 0 0 0 1px ${({ theme }) => theme.bg3};
} }
&:active { &:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, '#edeef2')}; box-shadow: 0 0 0 1px ${({ theme }) => theme.bg3};
} }
&:disabled { &:disabled {
opacity: 50%; opacity: 50%;
......
...@@ -83,7 +83,7 @@ function ConfirmationModal({ ...@@ -83,7 +83,7 @@ function ConfirmationModal({
{!pendingConfirmation ? 'Transaction Submitted' : 'Waiting For Confirmation'} {!pendingConfirmation ? 'Transaction Submitted' : 'Waiting For Confirmation'}
</Text> </Text>
<AutoColumn gap="12px" justify={'center'}> <AutoColumn gap="12px" justify={'center'}>
<Text fontWeight={600} fontSize={16} color="#2172E5"> <Text fontWeight={600} fontSize={16} color="#2172E5" textAlign="center">
{pendingText} {pendingText}
</Text> </Text>
</AutoColumn> </AutoColumn>
...@@ -102,7 +102,7 @@ function ConfirmationModal({ ...@@ -102,7 +102,7 @@ function ConfirmationModal({
</> </>
)} )}
{pendingConfirmation && <div style={{ height: '138px' }} />} {pendingConfirmation && <div style={{ height: '138px' }} />}
<Text fontSize={12} color="#565A69"> <Text fontSize={12} color="#565A69" textAlign="center">
{pendingConfirmation {pendingConfirmation
? 'Confirm this transaction in your wallet' ? 'Confirm this transaction in your wallet'
: `Estimated time until confirmation: 3 min`} : `Estimated time until confirmation: 3 min`}
......
...@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react' ...@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { Token, JSBI, WETH } from '@uniswap/sdk' import { Token, JSBI, WETH } from '@uniswap/sdk'
import Row from '../Row' import Row, { AutoRow } from '../Row'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import SearchModal from '../SearchModal' import SearchModal from '../SearchModal'
import AddLiquidity from '../../pages/Supply/AddLiquidity' import AddLiquidity from '../../pages/Supply/AddLiquidity'
...@@ -53,7 +53,7 @@ function CreatePool({ history }) { ...@@ -53,7 +53,7 @@ function CreatePool({ history }) {
<BlueCard> <BlueCard>
<AutoColumn gap="10px"> <AutoColumn gap="10px">
<TYPE.blue>{'Step ' + step + '.'} </TYPE.blue> <TYPE.blue>{'Step ' + step + '.'} </TYPE.blue>
{step === 1 && <TYPE.blue fontWeight={400}>Select or add your 2nd token to continue.</TYPE.blue>} {step === 1 && <TYPE.blue fontWeight={400}>Select or add a second token to continue.</TYPE.blue>}
</AutoColumn> </AutoColumn>
</BlueCard> </BlueCard>
<AutoColumn gap="24px"> <AutoColumn gap="24px">
...@@ -73,11 +73,14 @@ function CreatePool({ history }) { ...@@ -73,11 +73,14 @@ function CreatePool({ history }) {
setActiveField(Fields.TOKEN0) setActiveField(Fields.TOKEN0)
}} }}
> >
<Row> <Row align="flex-end">
<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>
<TYPE.darkGray fontWeight={500} fontSize={16} marginLeft={'8px'}>
{token0.symbol === 'ETH' && '(default)'}
</TYPE.darkGray>
</Row> </Row>
</ButtonDropwdownLight> </ButtonDropwdownLight>
)} )}
...@@ -109,12 +112,13 @@ function CreatePool({ history }) { ...@@ -109,12 +112,13 @@ function CreatePool({ history }) {
</Row> </Row>
</ButtonDropwdownLight> </ButtonDropwdownLight>
)} )}
{pairExists ? ( {pairExists ? (
<TYPE.body> <AutoRow padding="10px" justify="center">
Pool already exists! Join the pool{' '} <TYPE.body textAlign="center">
<Link onClick={() => history.push('/add/' + token0Address + '-' + token1Address)}>here.</Link> Pool already exists!
</TYPE.body> <Link onClick={() => history.push('/add/' + token0Address + '-' + token1Address)}> Join the pool.</Link>
</TYPE.body>
</AutoRow>
) : ( ) : (
<ButtonPrimary disabled={step !== 2}> <ButtonPrimary disabled={step !== 2}>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
...@@ -133,6 +137,7 @@ function CreatePool({ history }) { ...@@ -133,6 +137,7 @@ function CreatePool({ history }) {
setShowSearch(false) setShowSearch(false)
}} }}
hiddenToken={activeField === Fields.TOKEN0 ? token1Address : token0Address} hiddenToken={activeField === Fields.TOKEN0 ? token1Address : token0Address}
showCommonBases={true}
/> />
</AutoColumn> </AutoColumn>
) )
......
...@@ -111,9 +111,9 @@ export default function CurrencyInputPanel({ ...@@ -111,9 +111,9 @@ export default function CurrencyInputPanel({
hideBalance = false, hideBalance = false,
isExchange = false, isExchange = false,
pair = null, // used for double token logo pair = null, // used for double token logo
customBalance = null, // used for LP balances instead of token balance
hideInput = false, hideInput = false,
showSendWithSwap = false showSendWithSwap = false,
otherSelectedTokenAddress = null
}) { }) {
const { t } = useTranslation() const { t } = useTranslation()
...@@ -134,7 +134,6 @@ export default function CurrencyInputPanel({ ...@@ -134,7 +134,6 @@ export default function CurrencyInputPanel({
{!!token?.address && !atMax && type !== 'OUTPUT' && ( {!!token?.address && !atMax && type !== 'OUTPUT' && (
<StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax> <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>
)} )}
{/* {renderUnlockButton()} */}
</> </>
)} )}
<CurrencySelect <CurrencySelect
...@@ -165,26 +164,6 @@ export default function CurrencyInputPanel({ ...@@ -165,26 +164,6 @@ export default function CurrencyInputPanel({
</Aligner> </Aligner>
</CurrencySelect> </CurrencySelect>
</InputRow> </InputRow>
{/* {!hideBalance && !!token && (
<LabelRow>
<RowBetween>
<Text fontSize={16} fontWeight={400}>
{'-'}
</Text>
{!!token?.address && type !== 'OUTPUT' && !atMax ? (
<MiniMax onClick={onMax}>MAX</MiniMax>
) : (
<Clear>Clear</Clear>
)}
<ErrorSpan data-tip={'Enter max'} error={!!error} onClick={() => {}}></ErrorSpan>
<ClickableText fontWeight={500} onClick={onMax}>
<TYPE.body>
{customBalance ? customBalance?.toSignificant(4) : userTokenBalance?.toSignificant(4)} {token.symbol}
</TYPE.body>
</ClickableText>
</RowBetween>
</LabelRow>
)} */}
</Container> </Container>
{!disableTokenSelect && ( {!disableTokenSelect && (
<SearchModal <SearchModal
...@@ -198,6 +177,8 @@ export default function CurrencyInputPanel({ ...@@ -198,6 +177,8 @@ export default function CurrencyInputPanel({
onTokenSelect={onTokenSelection} onTokenSelect={onTokenSelection}
showSendWithSwap={showSendWithSwap} showSendWithSwap={showSendWithSwap}
hiddenToken={token?.address} hiddenToken={token?.address}
otherSelectedTokenAddress={otherSelectedTokenAddress}
otherSelectedText={field === 0 ? ' Selected as output' : 'Selected as input'}
/> />
)} )}
</InputPanel> </InputPanel>
......
...@@ -13,7 +13,7 @@ import AddressInputPanel from '../AddressInputPanel' ...@@ -13,7 +13,7 @@ import AddressInputPanel from '../AddressInputPanel'
import ConfirmationModal from '../ConfirmationModal' import ConfirmationModal from '../ConfirmationModal'
import CurrencyInputPanel from '../CurrencyInputPanel' import CurrencyInputPanel from '../CurrencyInputPanel'
import { Copy } from 'react-feather' import Copy from '../AccountDetails/Copy'
import { Link } from '../../theme/components' import { Link } from '../../theme/components'
import { Text } from 'rebass' import { Text } from 'rebass'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
...@@ -26,9 +26,7 @@ import { ButtonPrimary, ButtonError, ButtonLight } from '../Button' ...@@ -26,9 +26,7 @@ import { ButtonPrimary, ButtonError, ButtonLight } from '../Button'
import { usePair } from '../../contexts/Pairs' import { usePair } from '../../contexts/Pairs'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { usePopups } from '../../contexts/Application'
import { useRoute } from '../../contexts/Routes' import { useRoute } from '../../contexts/Routes'
// import { useTranslation } from 'react-i18next'
import { useAddressAllowance } from '../../contexts/Allowances' import { useAddressAllowance } from '../../contexts/Allowances'
import { useWeb3React, useTokenContract } from '../../hooks' import { useWeb3React, useTokenContract } from '../../hooks'
import { useAddressBalance, useAllBalances } from '../../contexts/Balances' import { useAddressBalance, useAllBalances } from '../../contexts/Balances'
...@@ -244,10 +242,10 @@ const SWAP_TYPE = { ...@@ -244,10 +242,10 @@ const SWAP_TYPE = {
const GAS_MARGIN = ethers.utils.bigNumberify(1000) const GAS_MARGIN = ethers.utils.bigNumberify(1000)
// default allowed slippage, in bips // default allowed slippage, in bips
const INITIAL_ALLOWED_SLIPPAGE = 200 const INITIAL_ALLOWED_SLIPPAGE = 50
// 15 minutes, denominated in seconds // 15 minutes, denominated in seconds
const DEFAULT_DEADLINE_FROM_NOW = 60 * 15 const DEFAULT_DEADLINE_FROM_NOW = 60 * 20
// used for warning states based on slippage in bips // used for warning states based on slippage in bips
const ALLOWED_SLIPPAGE_MEDIUM = 100 const ALLOWED_SLIPPAGE_MEDIUM = 100
...@@ -261,13 +259,13 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -261,13 +259,13 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
const routerAddress: string = ROUTER_ADDRESSES[chainId] const routerAddress: string = ROUTER_ADDRESSES[chainId]
// adding notifications on txns // adding notifications on txns
const [, addPopup] = usePopups()
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
// sending state // sending state
const [sending] = useState<boolean>(sendingInput) const [sending] = useState<boolean>(sendingInput)
const [sendingWithSwap, setSendingWithSwap] = useState<boolean>(false) const [sendingWithSwap, setSendingWithSwap] = useState<boolean>(false)
const [recipient, setRecipient] = useState<string>('') const [recipient, setRecipient] = useState<string>('')
const [ENS, setENS] = useState<string>('')
// trade details, check query params for initial state // trade details, check query params for initial state
const [state, dispatch] = useReducer( const [state, dispatch] = useReducer(
...@@ -313,7 +311,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -313,7 +311,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
// check on pending approvals for token amounts // check on pending approvals for token amounts
const pendingApprovalInput = usePendingApproval(tokens[Field.INPUT]?.address) const pendingApprovalInput = usePendingApproval(tokens[Field.INPUT]?.address)
const pendingApprovalOutput = usePendingApproval(tokens[Field.OUTPUT]?.address)
// check for imported tokens to show warning // check for imported tokens to show warning
const importedTokenInput = tokens[Field.INPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.INPUT]?.address] const importedTokenInput = tokens[Field.INPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.INPUT]?.address]
...@@ -341,7 +338,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -341,7 +338,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
// approvals // approvals
const inputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.INPUT], routerAddress) const inputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.INPUT], routerAddress)
const outputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.OUTPUT], routerAddress)
// all balances for detecting a swap with send // all balances for detecting a swap with send
const allBalances: TokenAmount[] = useAllBalances() const allBalances: TokenAmount[] = useAllBalances()
...@@ -502,14 +498,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -502,14 +498,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0]) new TokenAmount(tokens[Field.INPUT], calculateSlippageAmount(parsedAmounts[Field.OUTPUT])?.[0])
} }
const showInputUnlock: 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)
const showOutputUnlock: boolean =
parsedAmounts[Field.OUTPUT] &&
outputApproval &&
JSBI.greaterThan(parsedAmounts[Field.OUTPUT].raw, outputApproval.raw)
// function for a pure send // function for a pure send
async function onSend() { async function onSend() {
setAttemptingTxn(true) setAttemptingTxn(true)
...@@ -522,15 +513,18 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -522,15 +513,18 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
.sendTransaction({ to: recipient.toString(), value: hex(parsedAmounts[Field.INPUT].raw) }) .sendTransaction({ to: recipient.toString(), value: hex(parsedAmounts[Field.INPUT].raw) })
.then(response => { .then(response => {
setTxHash(response.hash) setTxHash(response.hash)
addTransaction(response) addTransaction(
response,
'Send ' +
parsedAmounts[Field.INPUT]?.toSignificant(3) +
' ' +
tokens[Field.INPUT]?.symbol +
' to ' +
recipient
)
setPendingConfirmation(false) setPendingConfirmation(false)
}) })
.catch(e => { .catch(() => {
addPopup(
<AutoColumn gap="sm">
<Text>Transaction Failed: try again.</Text>
</AutoColumn>
)
resetModal() resetModal()
setShowConfirm(false) setShowConfirm(false)
}) })
...@@ -548,15 +542,18 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -548,15 +542,18 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
}) })
.then(response => { .then(response => {
setTxHash(response.hash) setTxHash(response.hash)
addTransaction(response) addTransaction(
response,
'Send ' +
parsedAmounts[Field.INPUT]?.toSignificant(3) +
' ' +
tokens[Field.INPUT]?.symbol +
' to ' +
recipient
)
setPendingConfirmation(false) setPendingConfirmation(false)
}) })
.catch(e => { .catch(() => {
addPopup(
<AutoColumn gap="sm">
<Text>Transaction Failed: try again.</Text>
</AutoColumn>
)
resetModal() resetModal()
setShowConfirm(false) setShowConfirm(false)
}) })
...@@ -659,21 +656,26 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -659,21 +656,26 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
}) })
.then(response => { .then(response => {
setTxHash(response.hash) setTxHash(response.hash)
addTransaction(response) addTransaction(
response,
'Swap ' +
slippageAdjustedAmounts?.[Field.INPUT]?.toSignificant(3) +
' ' +
tokens[Field.INPUT]?.symbol +
' for ' +
slippageAdjustedAmounts?.[Field.OUTPUT]?.toSignificant(3) +
' ' +
tokens[Field.OUTPUT]?.symbol
)
setPendingConfirmation(false) setPendingConfirmation(false)
}) })
.catch(() => { .catch(() => {
addPopup(
<AutoColumn gap="sm">
<Text>Transaction Failed: try again.</Text>
</AutoColumn>
)
resetModal() resetModal()
setShowConfirm(false) setShowConfirm(false)
}) })
} }
async function approveAmount(field) { async function approveAmount(field: Field) {
let estimatedGas let estimatedGas
let useUserBalance = false let useUserBalance = false
const tokenContract = field === Field.INPUT ? tokenContractInput : tokenContractOutput const tokenContract = field === Field.INPUT ? tokenContractInput : tokenContractOutput
...@@ -691,7 +693,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -691,7 +693,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN) gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN)
}) })
.then(response => { .then(response => {
addTransaction(response, { approval: tokens[field]?.address }) addTransaction(response, 'Approve ' + tokens[field]?.symbol, { approval: tokens[field]?.address })
}) })
} }
...@@ -717,12 +719,12 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -717,12 +719,12 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
} }
if (!parsedAmounts[Field.INPUT]) { if (!parsedAmounts[Field.INPUT]) {
setGeneralError('Enter an amount') setInputError('Enter an amount')
setIsValid(false) setIsValid(false)
} }
if (!parsedAmounts[Field.OUTPUT] && !ignoreOutput) { if (!parsedAmounts[Field.OUTPUT] && !ignoreOutput) {
setGeneralError('Enter an amount') setOutputError('Enter an amount')
setIsValid(false) setIsValid(false)
} }
...@@ -755,22 +757,35 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -755,22 +757,35 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
parsedAmounts[Field.INPUT] && parsedAmounts[Field.INPUT] &&
JSBI.lessThan(userBalances[Field.INPUT].raw, parsedAmounts[Field.INPUT]?.raw) JSBI.lessThan(userBalances[Field.INPUT].raw, parsedAmounts[Field.INPUT]?.raw)
) { ) {
setInputError('Insufficient balance.') setInputError('Insufficient ' + tokens[Field.INPUT]?.symbol + ' balance')
setIsValid(false)
}
// check for null trade entitiy if not enough balance for trade
if (
(!sending || sendingWithSwap) &&
userBalances[Field.INPUT] &&
!trade &&
parsedAmounts[independentField] &&
!parsedAmounts[dependentField] &&
tokens[dependentField]
) {
setInputError('Insufficient ' + tokens[Field.INPUT]?.symbol + ' balance')
setIsValid(false) setIsValid(false)
} }
}, [ }, [
pair, sending,
sendingWithSwap,
dependentField,
ignoreOutput, ignoreOutput,
independentField,
pair,
parsedAmounts, parsedAmounts,
recipient,
recipientError, recipientError,
sending, route,
sendingWithSwap,
showInputUnlock,
showOutputUnlock,
tokens, tokens,
userBalances, trade,
route userBalances
]) ])
// warnings on slippage // warnings on slippage
...@@ -785,6 +800,10 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -785,6 +800,10 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
// reset modal state when closed // reset modal state when closed
function resetModal() { function resetModal() {
// clear input if txn submitted
if (!pendingConfirmation) {
onUserInput(Field.INPUT, '')
}
setPendingConfirmation(true) setPendingConfirmation(true)
setAttemptingTxn(false) setAttemptingTxn(false)
setShowAdvanced(false) setShowAdvanced(false)
...@@ -796,14 +815,33 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -796,14 +815,33 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
<AutoColumn gap="lg" style={{ marginTop: '40px' }}> <AutoColumn gap="lg" style={{ marginTop: '40px' }}>
<RowBetween> <RowBetween>
<Text fontSize={36} fontWeight={500}> <Text fontSize={36} fontWeight={500}>
{parsedAmounts[Field.INPUT]?.toFixed(8)} {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>
<TYPE.blue fontSize={36}> {ENS ? (
{recipient?.slice(0, 6)}...{recipient?.slice(36, 42)} <AutoColumn gap="lg">
</TYPE.blue> <TYPE.blue fontSize={36}>{ENS}</TYPE.blue>
<AutoRow gap="10px">
<Link href={getEtherscanLink(chainId, ENS, 'address')}>
<TYPE.blue fontSize={18}>
{recipient?.slice(0, 8)}...{recipient?.slice(34, 42)}
</TYPE.blue>
</Link>
<Copy toCopy={recipient} />
</AutoRow>
</AutoColumn>
) : (
<AutoRow gap="10px">
<Link href={getEtherscanLink(chainId, ENS, 'address')}>
<TYPE.blue fontSize={36}>
{recipient?.slice(0, 6)}...{recipient?.slice(36, 42)}
</TYPE.blue>
</Link>
<Copy toCopy={recipient} />
</AutoRow>
)}
</AutoColumn> </AutoColumn>
) )
} }
...@@ -847,7 +885,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -847,7 +885,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowFixed> <RowFixed>
<ArrowDown size="16" color="#888D9B" /> <ArrowDown size="16" color={'#888D9B'} />
</RowFixed> </RowFixed>
<RowBetween align="flex-end"> <RowBetween align="flex-end">
<Text fontSize={36} fontWeight={500} color={warningHigh ? '#FF6871' : '#2172E5'}> <Text fontSize={36} fontWeight={500} color={warningHigh ? '#FF6871' : '#2172E5'}>
...@@ -898,11 +936,19 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -898,11 +936,19 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</Text> </Text>
</ButtonError> </ButtonError>
<AutoColumn justify="center" gap="lg"> <AutoColumn justify="center" gap="lg">
<TYPE.italic textAlign="center" style={{ width: '80%' }}> {independentField === Field.INPUT ? (
{`Output is estimated. You will receive at least ${slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant( <TYPE.italic textAlign="center" style={{ width: '80%' }}>
6 {`Output is estimated. You will receive at least ${slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant(
)} ${tokens[Field.OUTPUT]?.symbol} or the transaction will revert.`} 6
</TYPE.italic> )} ${tokens[Field.OUTPUT]?.symbol} or the transaction will revert.`}
</TYPE.italic>
) : (
<TYPE.italic textAlign="center" style={{ width: '80%' }}>
{`Input is estimated. You will sell at most ${slippageAdjustedAmounts[Field.INPUT]?.toSignificant(6)} ${
tokens[Field.INPUT]?.symbol
} or the transaction will revert.`}
</TYPE.italic>
)}
<Link <Link
onClick={() => { onClick={() => {
setShowAdvanced(true) setShowAdvanced(true)
...@@ -918,7 +964,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -918,7 +964,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
const PriceBar = function() { const PriceBar = function() {
return ( return (
// <GreyCard>
<AutoRow justify="space-between"> <AutoRow justify="space-between">
<AutoColumn justify="center"> <AutoColumn justify="center">
<Text fontWeight={500} fontSize={16} color="#000000"> <Text fontWeight={500} fontSize={16} color="#000000">
...@@ -951,7 +996,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -951,7 +996,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</Text> </Text>
</AutoColumn> </AutoColumn>
</AutoRow> </AutoRow>
// </GreyCard>
) )
} }
...@@ -960,7 +1004,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -960,7 +1004,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
? sendingWithSwap ? sendingWithSwap
? `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}`
: ` Swapped ${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}`
...@@ -983,6 +1027,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -983,6 +1027,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
} else { } else {
setRecipient('') setRecipient('')
} }
if (result.name) {
setENS(result.name)
}
} }
return ( return (
...@@ -1015,7 +1062,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1015,7 +1062,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</MaxButton> </MaxButton>
)} )}
<StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)} /> <StyledNumerical value={formattedAmounts[Field.INPUT]} onUserInput={val => onUserInput(Field.INPUT, val)} />
{/* {!parsedAmounts[Field.INPUT] && <TYPE.gray>Enter an amount.</TYPE.gray>} */}
<CurrencyInputPanel <CurrencyInputPanel
field={Field.INPUT} field={Field.INPUT}
value={formattedAmounts[Field.INPUT]} value={formattedAmounts[Field.INPUT]}
...@@ -1031,6 +1077,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1031,6 +1077,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
hideBalance={true} hideBalance={true}
hideInput={true} hideInput={true}
showSendWithSwap={true} showSendWithSwap={true}
otherSelectedTokenAddress={tokens[Field.OUTPUT]?.address}
/> />
</InputGroup> </InputGroup>
</> </>
...@@ -1051,6 +1098,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1051,6 +1098,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
maxAmountInput && onMaxInput(maxAmountInput.toExact()) maxAmountInput && onMaxInput(maxAmountInput.toExact())
}} }}
onTokenSelection={address => onTokenSelection(Field.INPUT, address)} onTokenSelection={address => onTokenSelection(Field.INPUT, address)}
otherSelectedTokenAddress={tokens[Field.OUTPUT]?.address}
/> />
{sendingWithSwap ? ( {sendingWithSwap ? (
<ColumnCenter> <ColumnCenter>
...@@ -1066,7 +1114,11 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1066,7 +1114,11 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
) : ( ) : (
<Hover> <Hover>
<ColumnCenter> <ColumnCenter>
<ArrowDown size="16" onClick={onSwapTokens} /> <ArrowDown
size="16"
onClick={onSwapTokens}
color={tokens[Field.INPUT] && tokens[Field.OUTPUT] ? '#2172E5' : '#888D9B'}
/>
</ColumnCenter> </ColumnCenter>
</Hover> </Hover>
)} )}
...@@ -1083,6 +1135,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1083,6 +1135,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)} onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)}
error={outputError} error={outputError}
pair={pair} pair={pair}
otherSelectedTokenAddress={tokens[Field.INPUT]?.address}
/> />
{sendingWithSwap && ( {sendingWithSwap && (
<RowBetween padding="0 8px"> <RowBetween padding="0 8px">
...@@ -1094,12 +1147,19 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1094,12 +1147,19 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
)} )}
{sending && ( {sending && (
<AutoColumn gap="sm"> <AutoColumn gap="lg">
{!sendingWithSwap && (
<Hover onClick={() => setSendingWithSwap(true)}>
<TYPE.blue textAlign="center">Add a swap +</TYPE.blue>
</Hover>
)}
<AddressInputPanel <AddressInputPanel
onChange={_onRecipient} onChange={_onRecipient}
onError={(error: boolean) => { onError={(error: boolean, input) => {
if (error) { if (error && input !== '') {
setRecipientError('Invalid Recipient') setRecipientError('Invalid Recipient')
} else if (error && input === '') {
setRecipientError('Enter a Recipient')
} else { } else {
setRecipientError(null) setRecipientError(null)
} }
...@@ -1111,7 +1171,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1111,7 +1171,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
<BottomGrouping> <BottomGrouping>
{noRoute ? ( {noRoute ? (
<GreyCard style={{ textAlign: 'center' }}> <GreyCard style={{ textAlign: 'center' }}>
{/* <RowBetween style={{ margin: '10px 0' }}> */}
<TYPE.main>No exchange for this pair.</TYPE.main> <TYPE.main>No exchange for this pair.</TYPE.main>
<Link <Link
...@@ -1122,22 +1181,8 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1122,22 +1181,8 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
{' '} {' '}
Create one now Create one now
</Link> </Link>
{/* </RowBetween> */}
</GreyCard> </GreyCard>
) : showOutputUnlock ? ( ) : showInputApprove && !inputError ? (
<ButtonLight
onClick={() => {
!pendingApprovalOutput && approveAmount(Field.OUTPUT)
}}
disabled={pendingApprovalOutput}
>
{pendingApprovalOutput ? (
<Dots>Unlocking {tokens[Field.OUTPUT]?.symbol}</Dots>
) : (
'Unlock ' + tokens[Field.OUTPUT]?.symbol
)}
</ButtonLight>
) : showInputUnlock ? (
<ButtonLight <ButtonLight
onClick={() => { onClick={() => {
approveAmount(Field.INPUT) approveAmount(Field.INPUT)
...@@ -1145,9 +1190,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1145,9 +1190,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
disabled={pendingApprovalInput} disabled={pendingApprovalInput}
> >
{pendingApprovalInput ? ( {pendingApprovalInput ? (
<Dots>Unlocking {tokens[Field.INPUT]?.symbol}</Dots> <Dots>Approving {tokens[Field.INPUT]?.symbol}</Dots>
) : ( ) : (
'Unlock ' + tokens[Field.INPUT]?.symbol 'Approve ' + tokens[Field.INPUT]?.symbol
)} )}
</ButtonLight> </ButtonLight>
) : ( ) : (
...@@ -1181,7 +1226,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1181,7 +1226,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
)} )}
</BottomGrouping> </BottomGrouping>
<FixedBottom> <FixedBottom>
{!noRoute && tokens[Field.OUTPUT] && ( {!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
<GreyCard pt={2} mb={2}> <GreyCard pt={2} mb={2}>
<PriceBar /> <PriceBar />
</GreyCard> </GreyCard>
...@@ -1197,7 +1242,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1197,7 +1242,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
<Link href={getEtherscanLink(chainId, tokens[Field.INPUT]?.address, 'address')}> <Link href={getEtherscanLink(chainId, tokens[Field.INPUT]?.address, 'address')}>
(View on Etherscan) (View on Etherscan)
</Link> </Link>
<Copy size={'16'} /> <Copy toCopy={tokens[Field.INPUT]?.address} />
</AutoRow> </AutoRow>
<TYPE.subHeader> <TYPE.subHeader>
Please verify the legitimacy of this token before making any transactions. Please verify the legitimacy of this token before making any transactions.
...@@ -1231,7 +1276,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1231,7 +1276,7 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</RowBetween> </RowBetween>
<Text color="#565A69" lineHeight="145.23%;"> <Text color="#565A69" lineHeight="145.23%;">
This trade will move the price by {slippageFromTrade.toFixed(2)}%. This pool probably doesn’t have This trade will move the price by {slippageFromTrade.toFixed(2)}%. This pool probably doesn’t have
enough liquidity. Are you sure you want to continue this trade? enough liquidity to support this trade. Are you sure you want to continue this trade?
</Text> </Text>
</AutoColumn> </AutoColumn>
</GreyCard> </GreyCard>
......
...@@ -3,13 +3,13 @@ import styled from 'styled-components' ...@@ -3,13 +3,13 @@ import styled from 'styled-components'
import Row from '../Row' import Row from '../Row'
import Menu from '../Menu' import Menu from '../Menu'
import { Link } from '../../theme'
import { Text } from 'rebass'
import { YellowCard } from '../Card'
import Web3Status from '../Web3Status' import Web3Status from '../Web3Status'
import { Link } from '../../theme'
import { Text } from 'rebass'
import { WETH } from '@uniswap/sdk' import { WETH } from '@uniswap/sdk'
import { isMobile } from 'react-device-detect' import { isMobile } from 'react-device-detect'
import { YellowCard } from '../Card'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
import { useAddressBalance } from '../../contexts/Balances' import { useAddressBalance } from '../../contexts/Balances'
import { useWalletModalToggle } from '../../contexts/Application' import { useWalletModalToggle } from '../../contexts/Application'
......
...@@ -119,7 +119,7 @@ export default function Menu() { ...@@ -119,7 +119,7 @@ export default function Menu() {
Code Code
</MenuItem> </MenuItem>
<MenuItem id="link" href="https://uniswap.info/"> <MenuItem id="link" href="https://uniswap.info/">
Stats Analytics
</MenuItem> </MenuItem>
</MenuFlyout> </MenuFlyout>
) : ( ) : (
......
...@@ -5,6 +5,7 @@ const StyledInput = styled.input` ...@@ -5,6 +5,7 @@ const StyledInput = styled.input`
color: ${({ error, theme }) => error && theme.red1}; color: ${({ error, theme }) => error && theme.red1};
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
width: 0; width: 0;
position: relative;
font-size: 24px; font-size: 24px;
font-weight: 500; font-weight: 500;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
......
...@@ -155,15 +155,15 @@ function PoolFinder({ history }) { ...@@ -155,15 +155,15 @@ function PoolFinder({ history }) {
border="1px solid #EDEEF2" border="1px solid #EDEEF2"
/> />
) : ( ) : (
<LightCard padding="45px"> <LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center"> <AutoColumn gap="sm" justify="center">
<Text color="">No position found.</Text> <Text textAlign="center">Pool found, you don’t have liquidity on this pair yet.</Text>
<Link <Link
onClick={() => { onClick={() => {
history.push('/add/' + token0Address + '-' + token1Address) history.push('/add/' + token0Address + '-' + token1Address)
}} }}
> >
Add liquidity to this pair instead. <Text textAlign="center">Add liquidity to this pair instead.</Text>
</Link> </Link>
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
......
...@@ -33,7 +33,6 @@ const MobilePopupWrapper = styled.div` ...@@ -33,7 +33,6 @@ const MobilePopupWrapper = styled.div`
const MobilePopupInner = styled.div` const MobilePopupInner = styled.div`
height: 99%; height: 99%;
box-sizing: border-box; box-sizing: border-box;
white-space: nowrap;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
display: flex; display: flex;
...@@ -58,7 +57,7 @@ const FixedPopupColumn = styled(AutoColumn)` ...@@ -58,7 +57,7 @@ const FixedPopupColumn = styled(AutoColumn)`
const Popup = styled.div` const Popup = styled.div`
display: inline-block; display: inline-block;
width: 100%; width: 100%;
height: 120px; min-height: 120px;
padding: 1em; padding: 1em;
box-sizing: border-box; box-sizing: border-box;
background-color: white; background-color: white;
...@@ -67,7 +66,7 @@ const Popup = styled.div` ...@@ -67,7 +66,7 @@ const Popup = styled.div`
border-radius: 10px; border-radius: 10px;
padding: 20px; padding: 20px;
padding-right: 35px; padding-right: 35px;
whitespace: normal; z-index: 2;
${({ theme }) => theme.mediaWidth.upToSmall` ${({ theme }) => theme.mediaWidth.upToSmall`
min-width: 290px; min-width: 290px;
...@@ -104,12 +103,12 @@ export default function App() { ...@@ -104,12 +103,12 @@ export default function App() {
{showMessage && ( {showMessage && (
<PinkCard padding="20px" style={{ zIndex: '2' }}> <PinkCard padding="20px" style={{ zIndex: '2' }}>
<AutoColumn justify={'center'} gap={'20px'}> <AutoColumn justify={'center'} gap={'20px'}>
<Hover onClick={() => hideMigrationMessage()}>
<StyledClose />
</Hover>
<TYPE.largeHeader>Uniswap has upgraded.</TYPE.largeHeader> <TYPE.largeHeader>Uniswap has upgraded.</TYPE.largeHeader>
<Text textAlign="center">Are you a liquidity provider? Upgrade now using the migration helper.</Text> <Text textAlign="center">Are you a liquidity provider? Upgrade now using the migration helper.</Text>
<ButtonPink width={'265px'}>Migrate your liquidity </ButtonPink> <ButtonPink width={'265px'}>Migrate your liquidity </ButtonPink>
<Hover onClick={() => hideMigrationMessage()}>
<Text textAlign="center">Dismiss</Text>
</Hover>
</AutoColumn> </AutoColumn>
</PinkCard> </PinkCard>
)} )}
...@@ -135,12 +134,12 @@ export default function App() { ...@@ -135,12 +134,12 @@ export default function App() {
{showMessage && ( {showMessage && (
<MobileCardPink> <MobileCardPink>
<AutoColumn justify={'center'} gap={'20px'}> <AutoColumn justify={'center'} gap={'20px'}>
<Hover onClick={() => hideMigrationMessage()}>
<StyledClose />
</Hover>
<Text>Uniswap has upgraded.</Text> <Text>Uniswap has upgraded.</Text>
<Text textAlign="center">Are you a liquidity provider? Upgrade now using the migration helper.</Text> <Text textAlign="center">Are you a liquidity provider? Upgrade now using the migration helper.</Text>
<ButtonPink width={'265px'}>Migrate your liquidity </ButtonPink> <ButtonPink width={'265px'}>Migrate your liquidity </ButtonPink>
<Hover onClick={() => hideMigrationMessage()}>
<Text textAlign="center">Dismiss</Text>
</Hover>
</AutoColumn> </AutoColumn>
</MobileCardPink> </MobileCardPink>
)} )}
......
...@@ -12,11 +12,12 @@ import Card from '../Card' ...@@ -12,11 +12,12 @@ import Card from '../Card'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import DoubleLogo from '../DoubleLogo' import DoubleLogo from '../DoubleLogo'
import { Text } from 'rebass' import { Text } from 'rebass'
import { Link } from '../../theme/components'
import { GreyCard } from '../../components/Card' import { GreyCard } from '../../components/Card'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import { ChevronDown, ChevronUp } from 'react-feather' import { ChevronDown, ChevronUp } from 'react-feather'
import { ButtonSecondary } from '../Button' import { ButtonSecondary } from '../Button'
import { RowBetween, RowFixed } from '../Row' import { RowBetween, RowFixed, AutoRow } from '../Row'
const FixedHeightRow = styled(RowBetween)` const FixedHeightRow = styled(RowBetween)`
height: 24px; height: 24px;
...@@ -138,9 +139,9 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -138,9 +139,9 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
{userPoolBalance ? userPoolBalance.toFixed(6) : '-'} {userPoolBalance ? userPoolBalance.toFixed(6) : '-'}
</Text> </Text>
{showMore ? ( {showMore ? (
<ChevronUp size="30" style={{ marginLeft: '10px' }} /> <ChevronUp size="20" style={{ marginLeft: '10px' }} />
) : ( ) : (
<ChevronDown size="30" style={{ marginLeft: '10px' }} /> <ChevronDown size="20" style={{ marginLeft: '10px' }} />
)} )}
</RowFixed> </RowFixed>
</FixedHeightRow> </FixedHeightRow>
...@@ -149,9 +150,8 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -149,9 +150,8 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
<FixedHeightRow> <FixedHeightRow>
<RowFixed> <RowFixed>
{!minimal && <TokenLogo size="16px" style={{ marginRight: '4px' }} address={token0?.address || ''} />} {!minimal && <TokenLogo size="16px" style={{ marginRight: '4px' }} address={token0?.address || ''} />}
<Text color="#888D9B" fontSize={14} fontWeight={500}> <Text color="#888D9B" fontSize={14} fontWeight={500}>
{token0?.symbol}: Your {token0?.symbol}:
</Text> </Text>
</RowFixed> </RowFixed>
{token0Deposited ? ( {token0Deposited ? (
...@@ -168,7 +168,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -168,7 +168,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
<RowFixed> <RowFixed>
{!minimal && <TokenLogo size="16px" style={{ marginRight: '4px' }} address={token1?.address || ''} />} {!minimal && <TokenLogo size="16px" style={{ marginRight: '4px' }} address={token1?.address || ''} />}
<Text color="#888D9B" fontSize={14} fontWeight={500}> <Text color="#888D9B" fontSize={14} fontWeight={500}>
{token1?.symbol}: Your {token1?.symbol}:
</Text> </Text>
</RowFixed> </RowFixed>
{token1Deposited ? ( {token1Deposited ? (
...@@ -189,28 +189,29 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -189,28 +189,29 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
</Text> </Text>
</FixedHeightRow> </FixedHeightRow>
)} )}
<RowBetween marginTop="10px">
<ButtonSecondary
width="48%"
onClick={() => {
history.push('/add/' + token0?.address + '-' + token1?.address)
}}
>
Add
</ButtonSecondary>
<ButtonSecondary
width="48%"
onClick={() => {
history.push('/remove/' + token0?.address + '-' + token1?.address)
}}
>
Remove
</ButtonSecondary>
</RowBetween>
<AutoRow justify="center" marginTop={'10px'}>
<Link>View analytics</Link>
</AutoRow>
</AutoColumn> </AutoColumn>
)} )}
{showMore && (
<RowBetween>
<ButtonSecondary
width="48%"
onClick={() => {
history.push('/add/' + token0?.address + '-' + token1?.address)
}}
>
Add
</ButtonSecondary>
<ButtonSecondary
width="48%"
onClick={() => {
history.push('/remove/' + token0?.address + '-' + token1?.address)
}}
>
Remove
</ButtonSecondary>
</RowBetween>
)}
</AutoColumn> </AutoColumn>
</HoverCard> </HoverCard>
) )
......
...@@ -2,27 +2,28 @@ import React, { useState, useRef, useMemo, useEffect } from 'react' ...@@ -2,27 +2,28 @@ import React, { useState, useRef, useMemo, useEffect } from 'react'
import '@reach/tooltip/styles.css' import '@reach/tooltip/styles.css'
import styled from 'styled-components' import styled from 'styled-components'
import escapeStringRegex from 'escape-string-regexp' import escapeStringRegex from 'escape-string-regexp'
import { JSBI } from '@uniswap/sdk' import { JSBI, WETH } from '@uniswap/sdk'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { ethers } from 'ethers' import { ethers } from 'ethers'
import { isMobile } from 'react-device-detect' import { isMobile } from 'react-device-detect'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { COMMON_BASES } from '../../constants'
import { Link as StyledLink } from '../../theme/components' import { Link as StyledLink } from '../../theme/components'
import { Hover } from '../../theme'
import Modal from '../Modal' import Modal from '../Modal'
import Circle from '../../assets/images/circle.svg' import Circle from '../../assets/images/circle.svg'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import DoubleTokenLogo from '../DoubleLogo' import DoubleTokenLogo from '../DoubleLogo'
import Column, { AutoColumn } from '../Column' import Column, { AutoColumn } from '../Column'
import { Text } from 'rebass' import { Text } from 'rebass'
import { Hover } from '../../theme'
import { LightCard } from '../Card' import { LightCard } from '../Card'
import { ArrowLeft } from 'react-feather' import { ArrowLeft } from 'react-feather'
import { CloseIcon } from '../../theme/components' import { CloseIcon } from '../../theme/components'
import { ColumnCenter } from '../../components/Column' import { ColumnCenter } from '../../components/Column'
import { Spinner, TYPE } from '../../theme' import { Spinner, TYPE } from '../../theme'
import { ButtonSecondary } from '../Button' import { ButtonSecondary } from '../Button'
import { RowBetween, RowFixed } from '../Row' import { RowBetween, RowFixed, AutoRow } from '../Row'
import { isAddress } from '../../utils' import { isAddress } from '../../utils'
import { useAllPairs } from '../../contexts/Pairs' import { useAllPairs } from '../../contexts/Pairs'
...@@ -31,6 +32,7 @@ import { useSavedTokens } from '../../contexts/LocalStorage' ...@@ -31,6 +32,7 @@ import { useSavedTokens } from '../../contexts/LocalStorage'
import { useAllBalances } from '../../contexts/Balances' import { useAllBalances } from '../../contexts/Balances'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useToken, useAllTokens, INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens' import { useToken, useAllTokens, INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens'
import QuestionHelper from '../Question'
const TokenModalInfo = styled.div` const TokenModalInfo = styled.div`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
...@@ -52,6 +54,11 @@ const FadedSpan = styled.span` ...@@ -52,6 +54,11 @@ const FadedSpan = styled.span`
color: ${({ theme }) => theme.blue1}; color: ${({ theme }) => theme.blue1};
` `
const GreySpan = styled.span`
color: ${({ theme }) => theme.text3};
font-weight: 400;
`
const SpinnerWrapper = styled(Spinner)` const SpinnerWrapper = styled(Spinner)`
margin: 0 0.25rem 0 0.25rem; margin: 0 0.25rem 0 0.25rem;
color: ${({ theme }) => theme.text4}; color: ${({ theme }) => theme.text4};
...@@ -79,11 +86,6 @@ const Input = styled.input` ...@@ -79,11 +86,6 @@ const Input = styled.input`
} }
` `
const TokenModal = styled.div`
${({ theme }) => theme.flexColumnNoWrap}
width: 100%;
`
const FilterWrapper = styled(RowFixed)` const FilterWrapper = styled(RowFixed)`
padding: 8px; padding: 8px;
background-color: ${({ selected, theme }) => selected && theme.bg2}; background-color: ${({ selected, theme }) => selected && theme.bg2};
...@@ -105,7 +107,6 @@ const PaddedColumn = styled(AutoColumn)` ...@@ -105,7 +107,6 @@ const PaddedColumn = styled(AutoColumn)`
const PaddedItem = styled(RowBetween)` const PaddedItem = styled(RowBetween)`
padding: 4px 24px; padding: 4px 24px;
/* width: calc(100% - 48px); */
height: 56px; height: 56px;
` `
...@@ -116,6 +117,22 @@ const MenuItem = styled(PaddedItem)` ...@@ -116,6 +117,22 @@ const MenuItem = styled(PaddedItem)`
} }
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)}; opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
` `
const BaseWrapper = styled(AutoRow)`
border: 1px solid ${({ theme, disable }) => (disable ? 'transparent' : theme.bg3)};
padding: 0 6px;
border-radius: 10px;
width: 120px;
:hover {
cursor: ${({ disable }) => !disable && 'pointer'};
background-color: ${({ theme, disable }) => !disable && theme.bg2};
}
background-color: ${({ theme, disable }) => disable && theme.bg3};
opacity: ${({ disable }) => disable && '0.4'};
`
// filters on results // filters on results
const FILTERS = { const FILTERS = {
VOLUME: 'VOLUME', VOLUME: 'VOLUME',
...@@ -131,7 +148,10 @@ function SearchModal({ ...@@ -131,7 +148,10 @@ function SearchModal({
urlAddedTokens, urlAddedTokens,
filterType, filterType,
hiddenToken, hiddenToken,
showSendWithSwap showSendWithSwap,
otherSelectedTokenAddress,
otherSelectedText,
showCommonBases = false
}) { }) {
const { t } = useTranslation() const { t } = useTranslation()
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
...@@ -367,59 +387,75 @@ function SearchModal({ ...@@ -367,59 +387,75 @@ function SearchModal({
return <TokenModalInfo>{t('noToken')}</TokenModalInfo> return <TokenModalInfo>{t('noToken')}</TokenModalInfo>
} }
return filteredTokenList.map(({ address, symbol, balance }) => { return filteredTokenList
const urlAdded = urlAddedTokens && urlAddedTokens.hasOwnProperty(address) .sort((a, b) => {
const customAdded = if (b?.address === WETH[chainId]?.address) {
address !== 'ETH' && return 1
INITIAL_TOKENS_CONTEXT[chainId] && } else
!INITIAL_TOKENS_CONTEXT[chainId].hasOwnProperty(address) && return parseFloat(a?.balance?.toExact()) > parseFloat(b?.balance?.toExact())
!urlAdded ? sortDirection
? -1
: 1
: sortDirection
? 1
: -1
})
.map(({ address, symbol, balance }) => {
const urlAdded = urlAddedTokens && urlAddedTokens.hasOwnProperty(address)
const customAdded =
address !== 'ETH' &&
INITIAL_TOKENS_CONTEXT[chainId] &&
!INITIAL_TOKENS_CONTEXT[chainId].hasOwnProperty(address) &&
!urlAdded
const zeroBalance = balance && JSBI.equal(JSBI.BigInt(0), balance.raw) const zeroBalance = balance && JSBI.equal(JSBI.BigInt(0), balance.raw)
// if token import page dont show preset list, else show all // if token import page dont show preset list, else show all
return ( return (
<MenuItem <MenuItem
key={address} key={address}
onClick={() => (hiddenToken && hiddenToken === address ? () => {} : _onTokenSelect(address))} onClick={() => (hiddenToken && hiddenToken === address ? () => {} : _onTokenSelect(address))}
disabled={hiddenToken && hiddenToken === address} disabled={hiddenToken && hiddenToken === address}
> >
<RowFixed> <RowFixed>
<TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }} /> <TokenLogo address={address} size={'24px'} style={{ marginRight: '14px' }} />
<Column> <Column>
<Text fontWeight={500}>{symbol}</Text> <Text fontWeight={500}>
<FadedSpan> {symbol}
{urlAdded && '(Added by URL)'} {customAdded && '(Added by user)'} {otherSelectedTokenAddress === address && <GreySpan> ({otherSelectedText})</GreySpan>}
</FadedSpan> </Text>
</Column> <FadedSpan>
</RowFixed> {urlAdded && '(Added by URL)'} {customAdded && '(Added by user)'}
<AutoColumn gap="4px" justify="end"> </FadedSpan>
{balance ? ( </Column>
<Text> </RowFixed>
{zeroBalance && showSendWithSwap ? ( <AutoColumn gap="4px" justify="end">
<ColumnCenter {balance ? (
justify="center" <Text>
style={{ backgroundColor: '#EBF4FF', padding: '8px', borderRadius: '12px' }} {zeroBalance && showSendWithSwap ? (
> <ColumnCenter
<Text textAlign="center" fontWeight={500} color="#2172E5"> justify="center"
Send With Swap style={{ backgroundColor: '#EBF4FF', padding: '8px', borderRadius: '12px' }}
</Text> >
</ColumnCenter> <Text textAlign="center" fontWeight={500} color="#2172E5">
) : balance ? ( Send With Swap
balance.toSignificant(6) </Text>
) : ( </ColumnCenter>
'-' ) : balance ? (
)} balance.toSignificant(6)
</Text> ) : (
) : account ? ( '-'
<SpinnerWrapper src={Circle} alt="loader" /> )}
) : ( </Text>
'-' ) : account ? (
)} <SpinnerWrapper src={Circle} alt="loader" />
</AutoColumn> ) : (
</MenuItem> '-'
) )}
}) </AutoColumn>
</MenuItem>
)
})
} }
const Filter = ({ title, filter }) => { const Filter = ({ title, filter }) => {
...@@ -451,9 +487,9 @@ function SearchModal({ ...@@ -451,9 +487,9 @@ function SearchModal({
maxHeight={50} maxHeight={50}
initialFocusRef={isMobile ? undefined : inputRef} initialFocusRef={isMobile ? undefined : inputRef}
> >
<TokenModal> <Column style={{ width: '100%' }}>
{showTokenImport ? ( {showTokenImport ? (
<PaddedColumn gap="20px"> <PaddedColumn gap="lg">
<RowBetween> <RowBetween>
<RowFixed> <RowFixed>
<Hover> <Hover>
...@@ -470,11 +506,11 @@ function SearchModal({ ...@@ -470,11 +506,11 @@ function SearchModal({
<CloseIcon onClick={onDismiss} /> <CloseIcon onClick={onDismiss} />
</RowBetween> </RowBetween>
<TYPE.body style={{ marginTop: '40px' }}> <TYPE.body style={{ marginTop: '40px' }}>
To import a custom token, paste the token address in the search bar. To import a custom token, paste token address in the search bar.
</TYPE.body> </TYPE.body>
<Input <Input
type={'text'} type={'text'}
placeholder={t('tokenSearchPlaceholder')} placeholder={'0x0000000000...'}
value={searchQuery} value={searchQuery}
ref={inputRef} ref={inputRef}
onChange={onInput} onChange={onInput}
...@@ -520,6 +556,33 @@ function SearchModal({ ...@@ -520,6 +556,33 @@ function SearchModal({
ref={inputRef} ref={inputRef}
onChange={onInput} onChange={onInput}
/> />
{showCommonBases && (
<AutoColumn gap="md">
<AutoRow>
<Text fontWeight={500} fontSize={16}>
Common Bases
</Text>
<QuestionHelper text="These tokens are commonly used in pairs." />
</AutoRow>
<AutoRow gap="10px">
{COMMON_BASES[chainId].map(token => {
return (
<BaseWrapper
gap="6px"
onClick={() => hiddenToken !== token.address && _onTokenSelect(token.address)}
disable={hiddenToken === token.address}
key={token.address}
>
<TokenLogo address={token.address} />
<Text fontWeight={500} fontSize={16}>
{token.symbol}
</Text>
</BaseWrapper>
)
})}
</AutoRow>
</AutoColumn>
)}
<RowBetween> <RowBetween>
<div> <div>
{filterType !== 'tokens' && ( {filterType !== 'tokens' && (
...@@ -554,7 +617,7 @@ function SearchModal({ ...@@ -554,7 +617,7 @@ function SearchModal({
)} )}
{!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: '#E1E1E1' }} />} {!showTokenImport && <div style={{ width: '100%', height: '1px', backgroundColor: '#E1E1E1' }} />}
{!showTokenImport && <TokenList>{filterType === 'tokens' ? renderTokenList() : renderPairsList()}</TokenList>} {!showTokenImport && <TokenList>{filterType === 'tokens' ? renderTokenList() : renderPairsList()}</TokenList>}
</TokenModal> </Column>
</Modal> </Modal>
) )
} }
......
import React from 'react' import React, { useState, useEffect } from 'react'
import Slider from '@material-ui/core/Slider' import Slider from '@material-ui/core/Slider'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import { useDebounce } from '../../hooks'
// const marks = [ // const marks = [
// { // {
...@@ -65,11 +66,29 @@ const StyledSlider = withStyles({ ...@@ -65,11 +66,29 @@ const StyledSlider = withStyles({
} }
})(Slider) })(Slider)
export default function InputSlider({ value, onChange }) { export default function InputSlider({ value, onChange, override }) {
const [internalVal, setInternalVal] = useState(0)
const debouncedInternalValue = useDebounce(internalVal, 10)
function handleChange(e, val) {
setInternalVal(val)
console.log(val)
console.log(debouncedInternalValue)
if (val === debouncedInternalValue) {
onChange(e, val)
}
}
useEffect(() => {
if (override && value !== internalVal) {
setInternalVal(value)
}
}, [internalVal, override, value])
return ( return (
<StyledSlider <StyledSlider
value={typeof value === 'number' ? value : 0} value={typeof internalVal === 'number' ? internalVal : 0}
onChange={onChange} onChange={handleChange}
aria-labelledby="input-slider" aria-labelledby="input-slider"
// marks={marks} // marks={marks}
/> />
......
...@@ -7,23 +7,14 @@ import { AutoColumn } from '../Column' ...@@ -7,23 +7,14 @@ import { AutoColumn } from '../Column'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
import { getEtherscanLink } from '../../utils' import { getEtherscanLink } from '../../utils'
export default function TxnPopup({ hash, success }) { export default function TxnPopup({ hash, success, summary }) {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
if (success) {
return ( return (
<AutoColumn gap="12px"> <AutoColumn gap="12px">
<TYPE.body>Transaction Confirmed</TYPE.body> <TYPE.body>Transaction {success ? 'confirmed.' : 'failed.'}</TYPE.body>
<TYPE.green>Hash: {hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.green> <TYPE.green>{summary ? summary : 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.green>
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link> <Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link>
</AutoColumn> </AutoColumn>
) )
} else {
return (
<AutoColumn gap="12px">
<TYPE.body>Transaction Failed</TYPE.body>
<TYPE.green>Hash: {hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.green>
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link>
</AutoColumn>
)
}
} }
...@@ -5,18 +5,37 @@ import { useWeb3React, UnsupportedChainIdError } from '@web3-react/core' ...@@ -5,18 +5,37 @@ import { useWeb3React, UnsupportedChainIdError } from '@web3-react/core'
import { darken, lighten } from 'polished' import { darken, lighten } from 'polished'
import { Activity } from 'react-feather' import { Activity } from 'react-feather'
import { shortenAddress } from '../../utils' import Identicon from '../Identicon'
import { useENSName } from '../../hooks' import PortisIcon from '../../assets/images/portisIcon.png'
import WalletModal from '../WalletModal' import WalletModal from '../WalletModal'
import { useAllTransactions } from '../../contexts/Transactions' import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import { useWalletModalToggle } from '../../contexts/Application'
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg' import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg' import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import PortisIcon from '../../assets/images/portisIcon.png' import { Spinner } from '../../theme'
import LightCircle from '../../assets/svg/lightcircle.svg'
import { RowBetween } from '../Row'
import { useENSName } from '../../hooks'
import { shortenAddress } from '../../utils'
import { useAllTransactions } from '../../contexts/Transactions'
import { NetworkContextName } from '../../constants' import { NetworkContextName } from '../../constants'
import Identicon from '../Identicon' import { useWalletModalToggle } from '../../contexts/Application'
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors'
const SpinnerWrapper = styled(Spinner)`
margin: 0 0.25rem 0 0.25rem;
`
const IconWrapper = styled.div`
${({ theme }) => theme.flexColumnNoWrap};
align-items: center;
justify-content: center;
& > * {
height: ${({ size }) => (size ? size + 'px' : '32px')};
width: ${({ size }) => (size ? size + 'px' : '32px')};
}
`
const Web3StatusGeneric = styled.button` const Web3StatusGeneric = styled.button`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
...@@ -103,16 +122,6 @@ const NetworkIcon = styled(Activity)` ...@@ -103,16 +122,6 @@ const NetworkIcon = styled(Activity)`
height: 16px; height: 16px;
` `
const IconWrapper = styled.div`
${({ theme }) => theme.flexColumnNoWrap};
align-items: center;
justify-content: center;
& > * {
height: ${({ size }) => (size ? size + 'px' : '32px')};
width: ${({ size }) => (size ? size + 'px' : '32px')};
}
`
export default function Web3Status() { export default function Web3Status() {
const { t } = useTranslation() const { t } = useTranslation()
const { active, account, connector, error } = useWeb3React() const { active, account, connector, error } = useWeb3React()
...@@ -164,7 +173,9 @@ export default function Web3Status() { ...@@ -164,7 +173,9 @@ export default function Web3Status() {
return ( return (
<Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}> <Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}>
{hasPendingTransactions ? ( {hasPendingTransactions ? (
<Text>{pending?.length} Pending</Text> <RowBetween>
<Text>{pending?.length} Pending</Text> <SpinnerWrapper src={LightCircle} alt="loader" />
</RowBetween>
) : ( ) : (
<Text>{ENSName || shortenAddress(account)}</Text> <Text>{ENSName || shortenAddress(account)}</Text>
)} )}
......
import { injected, walletconnect, walletlink, fortmatic, portis } from '../connectors' import { injected, walletconnect, walletlink, fortmatic, portis } from '../connectors'
import { ChainId, WETH, Token } from '@uniswap/sdk'
export const FACTORY_ADDRESSES = { export const FACTORY_ADDRESSES = {
1: '', 1: '',
...@@ -16,6 +17,14 @@ export const ROUTER_ADDRESSES = { ...@@ -16,6 +17,14 @@ export const ROUTER_ADDRESSES = {
42: '0xcDbE04934d89e97a24BCc07c3562DC8CF17d8167' 42: '0xcDbE04934d89e97a24BCc07c3562DC8CF17d8167'
} }
export const COMMON_BASES = {
1: [WETH[ChainId.MAINNET]],
4: [
WETH[ChainId.RINKEBY],
new Token(ChainId.RINKEBY, '0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735', 18, 'DAI', 'Dai Stablecoin')
]
}
export const SUPPORTED_THEMES = { export const SUPPORTED_THEMES = {
DARK: 'DARK', DARK: 'DARK',
LIGHT: 'LIGHT' LIGHT: 'LIGHT'
......
...@@ -10,6 +10,7 @@ const RESPONSE = 'response' ...@@ -10,6 +10,7 @@ const RESPONSE = 'response'
const CUSTOM_DATA = 'CUSTOM_DATA' const CUSTOM_DATA = 'CUSTOM_DATA'
const BLOCK_NUMBER_CHECKED = 'BLOCK_NUMBER_CHECKED' const BLOCK_NUMBER_CHECKED = 'BLOCK_NUMBER_CHECKED'
const RECEIPT = 'receipt' const RECEIPT = 'receipt'
const SUMMARY = 'summary'
const ADD = 'ADD' const ADD = 'ADD'
const CHECK = 'CHECK' const CHECK = 'CHECK'
...@@ -131,7 +132,14 @@ export function Updater() { ...@@ -131,7 +132,14 @@ export function Updater() {
check(chainId, hash, globalBlockNumber) check(chainId, hash, globalBlockNumber)
} else { } else {
finalize(chainId, hash, receipt) finalize(chainId, hash, receipt)
addPopup(<TxnPopup hash={hash} success={true} />) // add success or failure popup
if (receipt.status === 1) {
addPopup(<TxnPopup hash={hash} success={true} summary={allTransactions[hash]?.response?.summary} />)
} else {
addPopup(
<TxnPopup hash={hash} success={false} summary={allTransactions[hash]?.response?.summary} />
)
}
} }
} }
}) })
...@@ -155,17 +163,15 @@ export function useTransactionAdder() { ...@@ -155,17 +163,15 @@ export function useTransactionAdder() {
const [, { add }] = useTransactionsContext() const [, { add }] = useTransactionsContext()
return useCallback( return useCallback(
(response, customData = {}) => { (response, summary = '', customData = {}) => {
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 = safeAccess(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 }) add(chainId, hash, { ...response, [CUSTOM_DATA]: customData, [SUMMARY]: summary })
}, },
[chainId, add] [chainId, add]
) )
...@@ -181,7 +187,6 @@ export function useAllTransactions() { ...@@ -181,7 +187,6 @@ export function useAllTransactions() {
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]) {
......
...@@ -51,6 +51,7 @@ const BodyWrapper = styled.div` ...@@ -51,6 +51,7 @@ const BodyWrapper = styled.div`
const Body = styled.div` const Body = styled.div`
max-width: 355px; max-width: 355px;
width: 100%; width: 100%;
min-height: 340px;
background: ${({ theme }) => theme.bg1}; background: ${({ theme }) => theme.bg1};
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04), box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
0px 24px 32px rgba(0, 0, 0, 0.01); 0px 24px 32px rgba(0, 0, 0, 0.01);
......
...@@ -14,14 +14,12 @@ import CurrencyInputPanel from '../../components/CurrencyInputPanel' ...@@ -14,14 +14,12 @@ import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { Text } from 'rebass' import { Text } from 'rebass'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { BlueCard, LightCard } from '../../components/Card'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { ButtonPrimary, ButtonLight } from '../../components/Button' import { ButtonPrimary, ButtonLight } from '../../components/Button'
import { BlueCard, LightCard, GreyCard } from '../../components/Card'
import Row, { AutoRow, RowBetween, RowFlat, RowFixed } from '../../components/Row' import Row, { AutoRow, RowBetween, RowFlat, RowFixed } from '../../components/Row'
import { GreyCard } from '../../components/Card'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { usePopups } from '../../contexts/Application'
import { useAddressBalance } from '../../contexts/Balances' import { useAddressBalance } from '../../contexts/Balances'
import { useAddressAllowance } from '../../contexts/Allowances' import { useAddressAllowance } from '../../contexts/Allowances'
import { usePair, useTotalSupply } from '../../contexts/Pairs' import { usePair, useTotalSupply } from '../../contexts/Pairs'
...@@ -33,10 +31,10 @@ import { ROUTER_ADDRESSES } from '../../constants' ...@@ -33,10 +31,10 @@ import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
// denominated in bips // denominated in bips
const ALLOWED_SLIPPAGE = 200 const ALLOWED_SLIPPAGE = 50
// denominated in seconds // denominated in seconds
const DEADLINE_FROM_NOW = 60 * 15 const DEADLINE_FROM_NOW = 60 * 20
const GAS_MARGIN: BigNumber = ethers.utils.bigNumberify(1000) const GAS_MARGIN: BigNumber = ethers.utils.bigNumberify(1000)
...@@ -140,7 +138,6 @@ function reducer( ...@@ -140,7 +138,6 @@ function reducer(
function AddLiquidity({ token0, token1, step = false }) { function AddLiquidity({ token0, token1, step = false }) {
const { account, chainId, library } = useWeb3React() const { account, chainId, library } = useWeb3React()
const [, addPopup] = usePopups()
const routerAddress: string = ROUTER_ADDRESSES[chainId] const routerAddress: string = ROUTER_ADDRESSES[chainId]
...@@ -179,8 +176,8 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -179,8 +176,8 @@ function AddLiquidity({ token0, token1, step = false }) {
// state for amount approvals // state for amount approvals
const inputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.INPUT], routerAddress) const inputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.INPUT], routerAddress)
const outputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.OUTPUT], routerAddress) const outputApproval: TokenAmount = useAddressAllowance(account, tokens[Field.OUTPUT], routerAddress)
const [showInputUnlock, setShowInputUnlock] = useState<boolean>(false) const [showInputApprove, setShowInputApprove] = useState<boolean>(false)
const [showOutputUnlock, setShowOutputUnlock] = useState<boolean>(false) const [showOutputApprove, setShowOutputApprove] = useState<boolean>(false)
// get user-pecific and token-specific lookup data // get user-pecific and token-specific lookup data
const userBalances: { [field: number]: TokenAmount } = { const userBalances: { [field: number]: TokenAmount } = {
...@@ -314,12 +311,12 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -314,12 +311,12 @@ function AddLiquidity({ token0, token1, step = false }) {
: undefined : undefined
}) })
// monitor parsed amounts and update unlocked buttons // monitor parsed amounts and update approve buttons
useEffect(() => { useEffect(() => {
setShowInputUnlock( setShowInputApprove(
parsedAmounts[Field.INPUT] && inputApproval && JSBI.greaterThan(parsedAmounts[Field.INPUT].raw, inputApproval.raw) parsedAmounts[Field.INPUT] && inputApproval && JSBI.greaterThan(parsedAmounts[Field.INPUT].raw, inputApproval.raw)
) )
setShowOutputUnlock( setShowOutputApprove(
parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.OUTPUT] &&
outputApproval && outputApproval &&
JSBI.greaterThan(parsedAmounts[Field.OUTPUT].raw, outputApproval.raw) JSBI.greaterThan(parsedAmounts[Field.OUTPUT].raw, outputApproval.raw)
...@@ -362,7 +359,7 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -362,7 +359,7 @@ function AddLiquidity({ token0, token1, step = false }) {
userBalances?.[Field.INPUT] && userBalances?.[Field.INPUT] &&
JSBI.greaterThan(parsedAmounts?.[Field.INPUT]?.raw, userBalances?.[Field.INPUT]?.raw) JSBI.greaterThan(parsedAmounts?.[Field.INPUT]?.raw, userBalances?.[Field.INPUT]?.raw)
) { ) {
setInputError('Insufficient balance.') setInputError('Insufficient ' + tokens[Field.INPUT]?.symbol + ' balance')
setIsValid(false) setIsValid(false)
} }
if ( if (
...@@ -370,10 +367,10 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -370,10 +367,10 @@ function AddLiquidity({ token0, token1, step = false }) {
userBalances?.[Field.OUTPUT] && userBalances?.[Field.OUTPUT] &&
JSBI.greaterThan(parsedAmounts?.[Field.OUTPUT]?.raw, userBalances?.[Field.OUTPUT]?.raw) JSBI.greaterThan(parsedAmounts?.[Field.OUTPUT]?.raw, userBalances?.[Field.OUTPUT]?.raw)
) { ) {
setOutputError('Insufficient balance.') setOutputError('Insufficient ' + tokens[Field.OUTPUT]?.symbol + ' balance')
setIsValid(false) setIsValid(false)
} }
}, [noLiquidity, parsedAmounts, showInputUnlock, showOutputUnlock, userBalances]) }, [noLiquidity, parsedAmounts, showInputApprove, showOutputApprove, tokens, userBalances])
// state for txn // state for txn
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
...@@ -450,16 +447,21 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -450,16 +447,21 @@ function AddLiquidity({ token0, token1, step = false }) {
}) })
.then(response => { .then(response => {
setTxHash(response.hash) setTxHash(response.hash)
addTransaction(response) addTransaction(
response,
'Add ' +
parsedAmounts[Field.INPUT]?.toSignificant(3) +
' ' +
tokens[Field.INPUT]?.symbol +
' and ' +
parsedAmounts[Field.OUTPUT]?.toSignificant(3) +
' ' +
tokens[Field.OUTPUT]?.symbol
)
setPendingConfirmation(false) setPendingConfirmation(false)
}) })
.catch((e: Error) => { .catch((e: Error) => {
console.log(e) console.log(e)
addPopup(
<AutoColumn gap="10px">
<Text>Transaction Failed: try again.</Text>
</AutoColumn>
)
setPendingConfirmation(true) setPendingConfirmation(true)
setAttemptingTxn(false) setAttemptingTxn(false)
setShowConfirm(false) setShowConfirm(false)
...@@ -484,7 +486,7 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -484,7 +486,7 @@ function AddLiquidity({ token0, token1, step = false }) {
gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN) gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN)
}) })
.then(response => { .then(response => {
addTransaction(response, { approval: tokens[field]?.address }) addTransaction(response, 'Approve ' + tokens[field]?.symbol, { approval: tokens[field]?.address })
}) })
} }
...@@ -584,9 +586,8 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -584,9 +586,8 @@ function AddLiquidity({ token0, token1, step = false }) {
</> </>
) )
} }
const PriceBar = function(props) { const PriceBar = () => {
return ( return (
// <GreyCard>
<AutoRow justify="space-between"> <AutoRow justify="space-between">
<AutoColumn justify="center"> <AutoColumn justify="center">
<Text fontWeight={500} fontSize={16} color="#000000"> <Text fontWeight={500} fontSize={16} color="#000000">
...@@ -609,17 +610,15 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -609,17 +610,15 @@ function AddLiquidity({ token0, token1, step = false }) {
{poolTokenPercentage ? poolTokenPercentage?.toFixed(2) : '0.0'} {poolTokenPercentage ? poolTokenPercentage?.toFixed(2) : '0.0'}
{'%'} {'%'}
</Text> </Text>
<Text fontWeight={500} fontSize={14} color="#888D9B" pt={1}> <Text fontWeight={500} fontSize={14} color="#888D9B" pt={1}>
Pool Share Pool Share
</Text> </Text>
</AutoColumn> </AutoColumn>
</AutoRow> </AutoRow>
// </GreyCard>
) )
} }
const pendingText: string = `Supplied ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${ const pendingText: string = `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}`
...@@ -655,7 +654,7 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -655,7 +654,7 @@ function AddLiquidity({ token0, token1, step = false }) {
<TYPE.blue fontWeight={400}> <TYPE.blue fontWeight={400}>
You are the first liquidity provider. The ratio of tokens you add will set the price of this pool. You are the first liquidity provider. The ratio of tokens you add will set the price of this pool.
</TYPE.blue> </TYPE.blue>
<TYPE.blue fontWeight={400}>Once you are happy with the rate. Click create pool to review.</TYPE.blue> <TYPE.blue fontWeight={400}>Once you are happy with the rate click supply to review.</TYPE.blue>
</AutoColumn> </AutoColumn>
</BlueCard> </BlueCard>
</ColumnCenter> </ColumnCenter>
...@@ -689,30 +688,21 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -689,30 +688,21 @@ function AddLiquidity({ token0, token1, step = false }) {
error={outputError} error={outputError}
pair={pair} pair={pair}
/> />
{/* {!noLiquidity && ( {showOutputApprove ? (
<RowBetween>
Rate:
<div>
1 {tokens[independentField]?.symbol} = {route?.midPrice?.toSignificant(6)}
{tokens[dependentField]?.symbol}
</div>
</RowBetween>
)} */}
{showOutputUnlock ? (
<ButtonLight <ButtonLight
onClick={() => { onClick={() => {
approveAmount(Field.OUTPUT) approveAmount(Field.OUTPUT)
}} }}
> >
{pendingApprovalOutput ? 'Waiting for unlock' : 'Unlock ' + tokens[Field.OUTPUT]?.symbol} {pendingApprovalOutput ? 'Waiting for approve' : 'Approve ' + tokens[Field.OUTPUT]?.symbol}
</ButtonLight> </ButtonLight>
) : showInputUnlock ? ( ) : showInputApprove ? (
<ButtonLight <ButtonLight
onClick={() => { onClick={() => {
approveAmount(Field.INPUT) approveAmount(Field.INPUT)
}} }}
> >
{pendingApprovalInput ? 'Waiting for unlock' : 'Unlock ' + tokens[Field.INPUT]?.symbol} {pendingApprovalInput ? 'Waiting for approve' : 'Approve ' + tokens[Field.INPUT]?.symbol}
</ButtonLight> </ButtonLight>
) : ( ) : (
<ButtonPrimary <ButtonPrimary
...@@ -734,11 +724,6 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -734,11 +724,6 @@ function AddLiquidity({ token0, token1, step = false }) {
{tokens[Field.OUTPUT] && ( {tokens[Field.OUTPUT] && (
<GreyCard pt={2} mb={2}> <GreyCard pt={2} mb={2}>
<PriceBar /> <PriceBar />
{/* <AutoRow justify="center" gap="8px">
<Link fontSize="14px" fontWeight={400} href="">
Show Advanced
</Link>
</AutoRow> */}
</GreyCard> </GreyCard>
)} )}
<PositionCard <PositionCard
......
...@@ -4,10 +4,10 @@ import { ethers } from 'ethers' ...@@ -4,10 +4,10 @@ import { ethers } from 'ethers'
import { parseUnits } from '@ethersproject/units' import { parseUnits } from '@ethersproject/units'
import { TokenAmount, JSBI, Route, WETH, Percent, Token, Pair } from '@uniswap/sdk' import { TokenAmount, JSBI, Route, WETH, Percent, Token, Pair } from '@uniswap/sdk'
import Slider from '../../components/Slider'
import TokenLogo from '../../components/TokenLogo' import TokenLogo from '../../components/TokenLogo'
import DoubleLogo from '../../components/DoubleLogo' import DoubleLogo from '../../components/DoubleLogo'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
// import NumericalInput from '../../components/NumericalInput'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
...@@ -32,7 +32,7 @@ import { ROUTER_ADDRESSES } from '../../constants' ...@@ -32,7 +32,7 @@ import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
// denominated in seconds // denominated in seconds
const DEADLINE_FROM_NOW = 60 * 15 const DEADLINE_FROM_NOW = 60 * 20
const GAS_MARGIN: BigNumber = ethers.utils.bigNumberify(1000) const GAS_MARGIN: BigNumber = ethers.utils.bigNumberify(1000)
...@@ -44,6 +44,7 @@ const FixedBottom = styled.div` ...@@ -44,6 +44,7 @@ const FixedBottom = styled.div`
position: absolute; position: absolute;
top: 100px; top: 100px;
width: 100%; width: 100%;
margin-bottom: 80px;
` `
const ClickableText = styled(Text)` const ClickableText = styled(Text)`
...@@ -52,6 +53,11 @@ const ClickableText = styled(Text)` ...@@ -52,6 +53,11 @@ const ClickableText = styled(Text)`
} }
` `
// const CustomNumericalInput = styled(NumericalInput)`
// font-size: 72px;
// font-weight: 500;
// `
const MaxButton = styled.button` const MaxButton = styled.button`
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
background-color: ${({ theme }) => theme.blue5}; background-color: ${({ theme }) => theme.blue5};
...@@ -195,16 +201,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -195,16 +201,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
dispatch({ type: RemoveAction.TYPE, payload: { field, typedValue } }) dispatch({ type: RemoveAction.TYPE, payload: { field, typedValue } })
}, []) }, [])
const handleSliderChange = (event, newPercent) => {
onUserInput(
Field.LIQUIDITY,
new TokenAmount(
pair?.liquidityToken,
JSBI.divide(JSBI.multiply(userLiquidity.raw, JSBI.BigInt(newPercent)), JSBI.BigInt(100))
).toExact()
)
}
const parsedAmounts: { [field: number]: TokenAmount } = {} const parsedAmounts: { [field: number]: TokenAmount } = {}
let poolTokenAmount let poolTokenAmount
try { try {
...@@ -270,12 +266,34 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -270,12 +266,34 @@ export default function RemoveLiquidity({ token0, token1 }) {
parsedAmounts[Field.LIQUIDITY] && parsedAmounts[Field.LIQUIDITY] &&
pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false) pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false)
// controlled input for percetange input
// const [percentageInput, setPercentageInput] = useState(0)
// derived percent for advanced mode // derived percent for advanced mode
const derivedPerecent = const derivedPerecent =
userLiquidity && userLiquidity &&
parsedAmounts[Field.LIQUIDITY] && parsedAmounts[Field.LIQUIDITY] &&
new Percent(parsedAmounts[Field.LIQUIDITY]?.raw, userLiquidity.raw).toFixed(0) new Percent(parsedAmounts[Field.LIQUIDITY]?.raw, userLiquidity.raw).toFixed(0)
const handlePresetPercentage = newPercent => {
onUserInput(
Field.LIQUIDITY,
new TokenAmount(
pair?.liquidityToken,
JSBI.divide(JSBI.multiply(userLiquidity.raw, JSBI.BigInt(newPercent)), JSBI.BigInt(100))
).toExact()
)
}
// update controlled perctenage when derived is updated
// useEffect(() => {
// if (derivedPerecent) {
// setPercentageInput(parseFloat(derivedPerecent))
// } else {
// setPercentageInput(0)
// }
// }, [derivedPerecent])
// get formatted amounts // get formatted amounts
const formattedAmounts = { const formattedAmounts = {
[Field.LIQUIDITY]: [Field.LIQUIDITY]:
...@@ -467,7 +485,17 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -467,7 +485,17 @@ export default function RemoveLiquidity({ token0, token1 }) {
.then(response => { .then(response => {
setPendingConfirmation(false) setPendingConfirmation(false)
setTxHash(response.hash) setTxHash(response.hash)
addTransaction(response) addTransaction(
response,
'Remove ' +
parsedAmounts[Field.TOKEN0]?.toSignificant(3) +
' ' +
tokens[Field.TOKEN0]?.symbol +
' and ' +
parsedAmounts[Field.TOKEN1]?.toSignificant(3) +
' ' +
tokens[Field.TOKEN1]?.symbol
)
}) })
.catch(e => { .catch(e => {
console.log(e) console.log(e)
...@@ -560,7 +588,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -560,7 +588,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
</> </>
) )
} }
const pendingText: string = `Removed ${parsedAmounts[Field.TOKEN0]?.toSignificant(6)} ${ const pendingText: string = `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}`
...@@ -578,7 +606,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -578,7 +606,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
topContent={modalHeader} topContent={modalHeader}
bottomContent={modalBottom} bottomContent={modalBottom}
pendingText={pendingText} pendingText={pendingText}
title="You will remove" title="You will recieve"
/> />
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<LightCard> <LightCard>
...@@ -595,13 +623,28 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -595,13 +623,28 @@ export default function RemoveLiquidity({ token0, token1 }) {
{showAdvanced ? 'Hide Advanced' : 'Show Advanced'} {showAdvanced ? 'Hide Advanced' : 'Show Advanced'}
</ClickableText> </ClickableText>
</RowBetween> </RowBetween>
<RowBetween style={{ alignItems: 'flex-end' }}> <Row style={{ alignItems: 'flex-end' }}>
{/* <CustomNumericalInput value={percentageInput} onUserInput={input => handlePresetPercentage(input)} /> */}
<Text fontSize={72} fontWeight={500}> <Text fontSize={72} fontWeight={500}>
{derivedPerecent ? (parseInt(derivedPerecent) < 1 ? '<1' : derivedPerecent) : '0'}% {derivedPerecent ? (parseInt(derivedPerecent) < 1 ? '<1' : derivedPerecent) : '0'}%
</Text> </Text>
{!showAdvanced && <MaxButton onClick={e => handleSliderChange(e, 100)}>Max</MaxButton>} </Row>
</RowBetween> {!showAdvanced && (
{!showAdvanced && <Slider value={parseFloat(derivedPerecent)} onChange={handleSliderChange} />} <RowBetween>
<MaxButton onClick={e => handlePresetPercentage(25)} width="20%">
25%
</MaxButton>
<MaxButton onClick={e => handlePresetPercentage(50)} width="20%">
50%
</MaxButton>
<MaxButton onClick={e => handlePresetPercentage(75)} width="20%">
75%
</MaxButton>
<MaxButton onClick={e => handlePresetPercentage(100)} width="20%">
Max
</MaxButton>
</RowBetween>
)}
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
{!showAdvanced && ( {!showAdvanced && (
...@@ -664,7 +707,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -664,7 +707,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
token={tokens[Field.TOKEN0]} token={tokens[Field.TOKEN0]}
error={inputError} error={inputError}
disableTokenSelect disableTokenSelect
customBalance={TokensDeposited[Field.TOKEN0]}
/> />
<ColumnCenter> <ColumnCenter>
<Plus size="16" color="#888D9B" /> <Plus size="16" color="#888D9B" />
...@@ -678,7 +720,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -678,7 +720,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
token={tokens[Field.TOKEN1]} token={tokens[Field.TOKEN1]}
error={outputError} error={outputError}
disableTokenSelect disableTokenSelect
customBalance={TokensDeposited[Field.TOKEN1]}
/> />
</> </>
)} )}
......
...@@ -6,11 +6,11 @@ import { withRouter } from 'react-router-dom' ...@@ -6,11 +6,11 @@ import { 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'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
import { Link } from '../../theme' import { Link, TYPE } from '../../theme'
import { Text } from 'rebass' import { Text } from 'rebass'
import { LightCard } from '../../components/Card'
import { RowBetween } from '../../components/Row' import { RowBetween } from '../../components/Row'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { GreyCard } from '../../components/Card'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { useAllPairs } from '../../contexts/Pairs' import { useAllPairs } from '../../contexts/Pairs'
...@@ -71,25 +71,29 @@ function Supply({ history }) { ...@@ -71,25 +71,29 @@ function Supply({ history }) {
</ButtonPrimary> </ButtonPrimary>
<Positions> <Positions>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
{filteredExchangeList?.length !== 0 && ( <RowBetween padding={'0 8px'}>
<RowBetween padding={'0 8px'}> <Text fontWeight={500}>Your Pooled Liquidity</Text>
<Text fontWeight={500}>Your Pooled Liquidity</Text> <Question text="filler text" />
<Question text="filler text" /> </RowBetween>
</RowBetween> {filteredExchangeList?.length === 0 && (
<LightCard
padding="40px
"
>
<TYPE.body textAlign="center">No liquidity found.</TYPE.body>
</LightCard>
)} )}
{filteredExchangeList} {filteredExchangeList}
<GreyCard style={{ textAlign: 'center', padding: '0.5rem 1.25rem 1rem 1.25rem' }}> <Text color="#AEAEAE" textAlign="center">
<Text color="#AEAEAE"> {filteredExchangeList?.length !== 0 ? `Don't see a pool you joined? ` : 'Already joined a pool? '}{' '}
{filteredExchangeList?.length !== 0 ? `Don't see a pool you joined? ` : 'Already joined a pool?'}{' '} <Link
<Link onClick={() => {
onClick={() => { history.push('/find')
history.push('/find') }}
}} >
> Import it.
Import it. </Link>
</Link> </Text>
</Text>
</GreyCard>
</AutoColumn> </AutoColumn>
<FixedBottom> <FixedBottom>
<ColumnCenter> <ColumnCenter>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment