Commit 4e2c5c1e authored by ianlapham's avatar ianlapham

slippage without micro warnings on swap

parent e43d9e03
...@@ -13,6 +13,7 @@ const Base = styled(RebassButton)` ...@@ -13,6 +13,7 @@ const Base = styled(RebassButton)`
font-weight: 500; font-weight: 500;
text-align: center; text-align: center;
border-radius: 20px; border-radius: 20px;
border-radius: ${({ borderRadius }) => borderRadius && borderRadius};
outline: none; outline: none;
border: 1px solid transparent; border: 1px solid transparent;
color: white; color: white;
...@@ -40,8 +41,6 @@ export const ButtonPrimary = styled(Base)` ...@@ -40,8 +41,6 @@ export const ButtonPrimary = styled(Base)`
background-color: ${({ theme }) => theme.outlineGrey}; background-color: ${({ theme }) => theme.outlineGrey};
color: ${({ theme }) => theme.darkGrey} color: ${({ theme }) => theme.darkGrey}
cursor: auto; cursor: auto;
outline: none;
border: none;
box-shadow: none; box-shadow: none;
} }
` `
...@@ -100,6 +99,27 @@ const ButtonConfirmedStyle = styled(Base)` ...@@ -100,6 +99,27 @@ const ButtonConfirmedStyle = styled(Base)`
} }
` `
const ButtonErrorStyle = styled(Base)`
background-color: ${({ theme }) => theme.salmonRed};
border: 1px solid ${({ theme }) => theme.salmonRed};
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.salmonRed)};
background-color: ${({ theme }) => darken(0.05, theme.salmonRed)};
}
&:hover {
background-color: ${({ theme }) => darken(0.05, theme.salmonRed)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.salmonRed)};
background-color: ${({ theme }) => darken(0.1, theme.salmonRed)};
}
&:disabled {
opacity: 50%;
cursor: auto;
}
`
export function ButtonConfirmed({ children, confirmed, ...rest }) { export function ButtonConfirmed({ children, confirmed, ...rest }) {
if (confirmed) { if (confirmed) {
return <ButtonConfirmedStyle {...rest}>{children}</ButtonConfirmedStyle> return <ButtonConfirmedStyle {...rest}>{children}</ButtonConfirmedStyle>
...@@ -108,6 +128,14 @@ export function ButtonConfirmed({ children, confirmed, ...rest }) { ...@@ -108,6 +128,14 @@ export function ButtonConfirmed({ children, confirmed, ...rest }) {
} }
} }
export function ButtonError({ children, error, ...rest }) {
if (error) {
return <ButtonErrorStyle {...rest}>{children}</ButtonErrorStyle>
} else {
return <ButtonPrimary {...rest}>{children}</ButtonPrimary>
}
}
export function ButtonDropwdown({ disabled, children, ...rest }) { export function ButtonDropwdown({ disabled, children, ...rest }) {
return ( return (
<ButtonPrimary {...rest}> <ButtonPrimary {...rest}>
...@@ -129,3 +157,11 @@ export function ButtonDropwdownLight({ disabled, children, ...rest }) { ...@@ -129,3 +157,11 @@ export function ButtonDropwdownLight({ disabled, children, ...rest }) {
</ButtonEmpty> </ButtonEmpty>
) )
} }
export function ButtonRadio({ active, children, ...rest }) {
if (!active) {
return <ButtonEmpty {...rest}>{children}</ButtonEmpty>
} else {
return <ButtonPrimary {...rest}>{children}</ButtonPrimary>
}
}
...@@ -3,7 +3,7 @@ import { Box } from 'rebass/styled-components' ...@@ -3,7 +3,7 @@ import { Box } from 'rebass/styled-components'
const Card = styled(Box)` const Card = styled(Box)`
width: 100%; width: 100%;
border-radius: 20px; border-radius: 8px;
padding: 1rem; padding: 1rem;
padding: ${({ padding }) => padding}; padding: ${({ padding }) => padding};
border: ${({ border }) => border}; border: ${({ border }) => border};
...@@ -16,5 +16,5 @@ export const LightCard = styled(Card)` ...@@ -16,5 +16,5 @@ export const LightCard = styled(Card)`
` `
export const GreyCard = styled(Card)` export const GreyCard = styled(Card)`
background-color: rgba(255, 255, 255, 0.6); background-color: rgba(255, 255, 255, 0.9);
` `
This diff is collapsed.
...@@ -251,7 +251,12 @@ export default function CurrencyInputPanel({ ...@@ -251,7 +251,12 @@ export default function CurrencyInputPanel({
</LabelRow> </LabelRow>
)} )}
<InputRow> <InputRow>
<NumericalInput field={field} value={value} onUserInput={onUserInput} /> <NumericalInput
value={value}
onUserInput={val => {
onUserInput(field, val)
}}
/>
{!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>} {!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>}
{renderUnlockButton()} {renderUnlockButton()}
<CurrencySelect <CurrencySelect
......
This diff is collapsed.
...@@ -17,6 +17,7 @@ import { isMobile } from 'react-device-detect' ...@@ -17,6 +17,7 @@ import { isMobile } from 'react-device-detect'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
import { useAddressBalance } from '../../contexts/Balances' import { useAddressBalance } from '../../contexts/Balances'
import { useWalletModalToggle, usePopups } from '../../contexts/Application' import { useWalletModalToggle, usePopups } from '../../contexts/Application'
import { AutoColumn } from '../Column'
const HeaderFrame = styled.div` const HeaderFrame = styled.div`
display: flex; display: flex;
...@@ -68,7 +69,7 @@ const AccountElement = styled.div` ...@@ -68,7 +69,7 @@ const AccountElement = styled.div`
/* width: 100%; */ /* width: 100%; */
` `
const FixedPopupColumn = styled.div` const FixedPopupColumn = styled(AutoColumn)`
position: absolute; position: absolute;
top: 80px; top: 80px;
right: 20px right: 20px
...@@ -84,6 +85,15 @@ const StyledClose = styled(X)` ...@@ -84,6 +85,15 @@ const StyledClose = styled(X)`
} }
` `
const Popup = styled(Card)`
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.04), 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.04);
z-index: 9999;
border-radius: 8px;
padding: 1rem;
background: ${theme => theme.white};
`
export default function Header() { export default function Header() {
const { account, chainId } = useWeb3React() const { account, chainId } = useWeb3React()
...@@ -117,13 +127,13 @@ export default function Header() { ...@@ -117,13 +127,13 @@ export default function Header() {
</AccountElement> </AccountElement>
<Menu /> <Menu />
</HeaderElement> </HeaderElement>
<FixedPopupColumn> <FixedPopupColumn gap="20px">
{activePopups.map(item => { {activePopups.map(item => {
return ( return (
<Card bg="white" padding={'16px'} key={item.key} borderRadius={'8px'}> <Popup key={item.key}>
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} /> <StyledClose color="#888D9B" onClick={() => removePopup(item.key)} />
{item.content} {item.content}
</Card> </Popup>
) )
})} })}
</FixedPopupColumn> </FixedPopupColumn>
......
...@@ -6,7 +6,6 @@ import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg' ...@@ -6,7 +6,6 @@ import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
import { Link } from '../../theme' import { Link } from '../../theme'
import { darken, transparentize } from 'polished' import { darken, transparentize } from 'polished'
import { useAdvancedManager } from '../../contexts/LocalStorage'
import Toggle from 'react-switch' import Toggle from 'react-switch'
...@@ -140,7 +139,7 @@ const EmojiToggle = styled.span` ...@@ -140,7 +139,7 @@ const EmojiToggle = styled.span`
export default function Menu() { export default function Menu() {
const [isDark, toggleDarkMode] = useDarkModeManager() const [isDark, toggleDarkMode] = useDarkModeManager()
const [isAdvanced, toggleAdvanced] = useState() const [isAdvanced, toggleAdvanced] = useState(false)
const node = useRef() const node = useRef()
const [open, toggle] = useToggle(false) const [open, toggle] = useToggle(false)
......
...@@ -11,6 +11,8 @@ const StyledInput = styled.input` ...@@ -11,6 +11,8 @@ const StyledInput = styled.input`
flex: 1 1 auto; flex: 1 1 auto;
width: 0; width: 0;
background-color: ${({ theme }) => theme.inputBackground}; background-color: ${({ theme }) => theme.inputBackground};
font-size: ${({ fontSize }) => fontSize && fontSize};
text-align: ${({ align }) => align && align};
[type='number'] { [type='number'] {
-moz-appearance: textfield; -moz-appearance: textfield;
...@@ -32,10 +34,10 @@ function escapeRegExp(string: string): string { ...@@ -32,10 +34,10 @@ function escapeRegExp(string: string): string {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
} }
export const Input = React.memo(({ field, value, onUserInput, ...rest }: any) => { export const Input = React.memo(({ value, onUserInput, placeHolder = null, ...rest }: any) => {
function enforcer(nextUserInput: string) { function enforcer(nextUserInput: string) {
if (nextUserInput === '' || inputRegex.test(escapeRegExp(nextUserInput))) { if (nextUserInput === '' || inputRegex.test(escapeRegExp(nextUserInput))) {
onUserInput(field, nextUserInput) onUserInput(nextUserInput)
} }
} }
...@@ -53,7 +55,7 @@ export const Input = React.memo(({ field, value, onUserInput, ...rest }: any) => ...@@ -53,7 +55,7 @@ export const Input = React.memo(({ field, value, onUserInput, ...rest }: any) =>
autoCorrect="off" autoCorrect="off"
// text-specific options // text-specific options
type="text" type="text"
placeholder="0.0" placeholder={placeHolder || '0.0'}
minLength={1} minLength={1}
maxLength={79} maxLength={79}
spellCheck="false" spellCheck="false"
......
...@@ -16,7 +16,7 @@ import { Link } from '../../theme' ...@@ -16,7 +16,7 @@ import { Link } from '../../theme'
import { Text } from 'rebass' import { Text } from 'rebass'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { LightCard } from '../Card' import { LightCard } from '../Card'
import { AutoColumn, ColumnCenter } from '../Column' import Column, { AutoColumn, ColumnCenter } from '../Column'
import { ButtonPrimary, ButtonDropwdown, ButtonDropwdownLight } from '../Button' import { ButtonPrimary, ButtonDropwdown, ButtonDropwdownLight } from '../Button'
import DoubleTokenLogo from '../DoubleLogo' import DoubleTokenLogo from '../DoubleLogo'
...@@ -112,6 +112,13 @@ function PoolFinder({ history }) { ...@@ -112,6 +112,13 @@ function PoolFinder({ history }) {
</Row> </Row>
</ButtonDropwdownLight> </ButtonDropwdownLight>
)} )}
{allowImport && (
<ColumnCenter justify="center" style={{ backgroundColor: '#EBF4FF', padding: '8px', borderRadius: '12px' }}>
<Text textAlign="center" fontWeight={500} color="#2172E5">
Liquidity Found!
</Text>
</ColumnCenter>
)}
{position ? ( {position ? (
!JSBI.equal(position.raw, JSBI.BigInt(0)) ? ( !JSBI.equal(position.raw, JSBI.BigInt(0)) ? (
<PositionCard <PositionCard
...@@ -155,11 +162,7 @@ function PoolFinder({ history }) { ...@@ -155,11 +162,7 @@ function PoolFinder({ history }) {
</Text> </Text>
</LightCard> </LightCard>
)} )}
{allowImport && (
<Text textAlign="center" fontWeight={500}>
Liquidity Found!
</Text>
)}
<ButtonPrimary disabled={!allowImport} onClick={endSearch}> <ButtonPrimary disabled={!allowImport} onClick={endSearch}>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
Import Import
......
...@@ -61,11 +61,6 @@ function PositionCard({ exchangeAddress, token0, token1, history, minimal = fals ...@@ -61,11 +61,6 @@ function PositionCard({ exchangeAddress, token0, token1, history, minimal = fals
return ( return (
<DynamicCard {...rest}> <DynamicCard {...rest}>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<FixedHeightRow>
<Text fontWeight={500} fontSize={16}>
Current Position
</Text>
</FixedHeightRow>
<FixedHeightRow> <FixedHeightRow>
<RowFixed> <RowFixed>
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={24} /> <DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={24} />
......
...@@ -4,6 +4,7 @@ const Row = styled.div` ...@@ -4,6 +4,7 @@ const Row = styled.div`
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
align-items: ${({ align }) => align && align};
` `
export const RowBetween = styled(Row)` export const RowBetween = styled(Row)`
......
...@@ -411,16 +411,18 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens ...@@ -411,16 +411,18 @@ function SearchModal({ history, isOpen, onDismiss, onTokenSelect, urlAddedTokens
/> />
<RowBetween> <RowBetween>
<div> <div>
<Text> {filterType !== 'tokens' && (
Don't see a pool?{' '} <Text>
<StyledLink Don't see a pool?{' '}
onClick={() => { <StyledLink
history.push('/find') onClick={() => {
}} history.push('/find')
> }}
Import it. >
</StyledLink> Import it.
</Text> </StyledLink>
</Text>
)}
</div> </div>
<div /> <div />
<Filter title="Your Balances" filter={FILTERS.BALANCES} /> <Filter title="Your Balances" filter={FILTERS.BALANCES} />
......
...@@ -19,13 +19,6 @@ export const SUPPORTED_THEMES = { ...@@ -19,13 +19,6 @@ export const SUPPORTED_THEMES = {
LIGHT: 'LIGHT' LIGHT: 'LIGHT'
} }
export enum TRANSACTION_TYPE {
SWAP,
SEND,
ADD,
REMOVE
}
const MAINNET_WALLETS = { const MAINNET_WALLETS = {
INJECTED: { INJECTED: {
connector: injected, connector: injected,
......
...@@ -9,14 +9,14 @@ import { ChainId, WETH, Token, TokenAmount, Exchange, JSBI } from '@uniswap/sdk' ...@@ -9,14 +9,14 @@ import { ChainId, WETH, Token, TokenAmount, Exchange, JSBI } from '@uniswap/sdk'
const UPDATE = 'UPDATE' const UPDATE = 'UPDATE'
const ALL_EXCHANGES: [Token, Token][] = [ const ALL_EXCHANGES: [Token, Token][] = [
// [ [
// INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY][WETH[ChainId.RINKEBY].address], INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY][WETH[ChainId.RINKEBY].address],
// INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'] INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735']
// ] ],
// [ [
// INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'], INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'],
// INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0x8ab15C890E5C03B5F240f2D146e3DF54bEf3Df44'] INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0x8ab15C890E5C03B5F240f2D146e3DF54bEf3Df44']
// ] ]
] ]
const EXCHANGE_MAP: { const EXCHANGE_MAP: {
......
...@@ -27,11 +27,6 @@ const HeaderWrapper = styled.div` ...@@ -27,11 +27,6 @@ const HeaderWrapper = styled.div`
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
` `
const FooterWrapper = styled.div`
width: 100%;
min-height: 30px;
align-self: flex-end;
`
const BodyWrapper = styled.div` const BodyWrapper = styled.div`
display: flex; display: flex;
...@@ -50,7 +45,7 @@ const Body = styled.div` ...@@ -50,7 +45,7 @@ const Body = styled.div`
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);
border-radius: 20px; border-radius: 20px;
padding: 2rem 2rem; padding: 2rem 2rem 1rem 2rem;
` `
export default function App() { export default function App() {
......
...@@ -5,26 +5,27 @@ import { parseUnits, parseEther } from '@ethersproject/units' ...@@ -5,26 +5,27 @@ import { parseUnits, parseEther } from '@ethersproject/units'
import { WETH, TokenAmount, JSBI, Percent, Route } from '@uniswap/sdk' import { WETH, TokenAmount, JSBI, Percent, Route } from '@uniswap/sdk'
import DoubleLogo from '../../components/DoubleLogo' import DoubleLogo from '../../components/DoubleLogo'
import TokenLogo from '../../components/TokenLogo'
import SearchModal from '../../components/SearchModal' import SearchModal from '../../components/SearchModal'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { Text } from 'rebass' import { Text } from 'rebass'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { RowBetween } from '../../components/Row' import { ButtonPrimary } from '../../components/Button'
import { ChevronDown } from 'react-feather'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { ButtonPrimary, ButtonEmpty } from '../../components/Button' import Row, { RowBetween, RowFlat, RowFixed } from '../../components/Row'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
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 { useTransactionAdder } from '../../contexts/Transactions' import { useTransactionAdder } from '../../contexts/Transactions'
import { useExchange, useTotalSupply } from '../../contexts/Exchanges' import { useExchange, useTotalSupply } from '../../contexts/Exchanges'
import { BigNumber } from 'ethers/utils' import { BigNumber } from 'ethers/utils'
import { TRANSACTION_TYPE, ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
// denominated in bips // denominated in bips
...@@ -41,7 +42,7 @@ const Wrapper = styled.div` ...@@ -41,7 +42,7 @@ const Wrapper = styled.div`
const FixedBottom = styled.div` const FixedBottom = styled.div`
position: absolute; position: absolute;
bottom: -240px; bottom: -200px;
width: 100%; width: 100%;
` `
...@@ -145,6 +146,7 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -145,6 +146,7 @@ export default function AddLiquidity({ token0, token1 }) {
// modal states // modal states
const [showSearch, setShowSearch] = useState<boolean>(false) const [showSearch, setShowSearch] = useState<boolean>(false)
const [showConfirm, setShowConfirm] = useState<boolean>(false) const [showConfirm, setShowConfirm] = useState<boolean>(false)
const [attemptingTxn, setAttemptingTxn] = useState<boolean>(false) // clicke confirm
const [pendingConfirmation, setPendingConfirmation] = useState<boolean>(true) const [pendingConfirmation, setPendingConfirmation] = useState<boolean>(true)
// input state // input state
...@@ -369,7 +371,10 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -369,7 +371,10 @@ export default function AddLiquidity({ token0, token1 }) {
return null return null
} }
const [, addPopup] = usePopups()
async function onAdd() { async function onAdd() {
setAttemptingTxn(true)
const router = getRouterContract(chainId, library, account) const router = getRouterContract(chainId, library, account)
const minTokenInput = calculateSlippageAmount(parsedAmounts[Field.INPUT])[0] const minTokenInput = calculateSlippageAmount(parsedAmounts[Field.INPUT])[0]
...@@ -428,26 +433,112 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -428,26 +433,112 @@ export default function AddLiquidity({ token0, token1 }) {
}) })
.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)
setAttemptingTxn(false)
setShowConfirm(false) setShowConfirm(false)
}) })
} }
const modalHeader = () => {
return (
<AutoColumn gap="20px">
<RowFlat style={{ marginTop: '60px' }}>
<Text fontSize="48px" fontWeight={500} lineHeight="32px" marginRight={10}>
{liquidityMinted?.toFixed(6)}
</Text>
<DoubleLogo a0={tokens[Field.INPUT]?.symbol || ''} a1={tokens[Field.OUTPUT]?.symbol || ''} size={30} />
</RowFlat>
<Row>
<Text fontSize="24px">
{tokens[Field.INPUT]?.symbol + ':' + tokens[Field.OUTPUT]?.symbol + ' Pool Tokens'}
</Text>
</Row>
</AutoColumn>
)
}
const modalBottom = () => {
return (
<>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
{tokens[Field.INPUT]?.symbol} Deposited
</Text>
<RowFixed>
<TokenLogo address={tokens[Field.INPUT]?.address || ''} style={{ marginRight: '8px' }} />
<Text fontWeight={500} fontSize={16}>
{!!parsedAmounts[Field.INPUT] && parsedAmounts[Field.INPUT].toSignificant(6)}
</Text>
</RowFixed>
</RowBetween>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
{tokens[Field.OUTPUT]?.symbol} Deposited
</Text>
<RowFixed>
<TokenLogo address={tokens[Field.OUTPUT]?.address || ''} style={{ marginRight: '8px' }} />
<Text fontWeight={500} fontSize={16}>
{!!parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.OUTPUT].toSignificant(6)}
</Text>
</RowFixed>
</RowBetween>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
Rate
</Text>
<Text fontWeight={500} fontSize={16}>
{`1 ${tokens[Field.INPUT]?.symbol} = ${route?.midPrice &&
route?.midPrice?.raw?.denominator &&
route.midPrice.adjusted.toFixed(8)} ${tokens[Field.OUTPUT]?.symbol}`}
</Text>
</RowBetween>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
Minted Pool Share:
</Text>
<Text fontWeight={500} fontSize={16}>
{poolTokenPercentage?.toFixed(6) + '%'}
</Text>
</RowBetween>
<ButtonPrimary style={{ margin: '20px 0' }} onClick={onAdd}>
<Text fontWeight={500} fontSize={20}>
Confirm Supply
</Text>
</ButtonPrimary>
<Text fontSize={12} color="#565A69" textAlign="center">
{`Output is estimated. You will receive at least ${liquidityMinted?.toFixed(6)} UNI ${
tokens[Field.INPUT]?.symbol
}/${tokens[Field.OUTPUT]?.symbol} or the transaction will revert.`}
</Text>
</>
)
}
const pendingText = `Supplied ${parsedAmounts[Field.INPUT]?.toSignificant(6)} ${
tokens[Field.INPUT]?.symbol
} ${'and'} ${parsedAmounts[Field.OUTPUT]?.toSignificant(6)} ${tokens[Field.OUTPUT]?.symbol}`
return ( return (
<Wrapper> <Wrapper>
<ConfirmationModal <ConfirmationModal
isOpen={showConfirm} isOpen={showConfirm}
onDismiss={() => { onDismiss={() => {
setPendingConfirmation(true)
setAttemptingTxn(false)
setShowConfirm(false) setShowConfirm(false)
}} }}
liquidityAmount={liquidityMinted} attemptingTxn={attemptingTxn}
amount0={parsedAmounts[Field.INPUT]}
amount1={parsedAmounts[Field.OUTPUT]}
poolTokenPercentage={poolTokenPercentage}
price={route?.midPrice && route?.midPrice?.raw?.denominator}
transactionType={TRANSACTION_TYPE.ADD}
contractCall={onAdd}
pendingConfirmation={pendingConfirmation} pendingConfirmation={pendingConfirmation}
hash={txHash ? txHash : ''} hash={txHash ? txHash : ''}
topContent={() => modalHeader()}
bottomContent={modalBottom}
pendingText={pendingText}
title="You will receive"
/> />
<SearchModal <SearchModal
isOpen={showSearch} isOpen={showSearch}
...@@ -456,22 +547,6 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -456,22 +547,6 @@ export default function AddLiquidity({ token0, token1 }) {
}} }}
/> />
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<ButtonEmpty
padding={'1rem'}
onClick={() => {
setShowSearch(true)
}}
>
<RowBetween>
<DoubleLogo a0={exchange?.token0?.address || ''} a1={exchange?.token1?.address || ''} size={24} />
<Text fontSize={20}>
{exchange?.token0 && exchange?.token1
? exchange.token0.symbol + ' / ' + exchange.token1.symbol + ' Pool'
: ''}
</Text>
<ChevronDown size={24} />
</RowBetween>
</ButtonEmpty>
{noLiquidity && ( {noLiquidity && (
<ColumnCenter> <ColumnCenter>
<Text fontWeight={500} style={{ textAlign: 'center' }}> <Text fontWeight={500} style={{ textAlign: 'center' }}>
......
...@@ -6,15 +6,17 @@ import { TokenAmount, JSBI, Route, WETH, Percent } from '@uniswap/sdk' ...@@ -6,15 +6,17 @@ import { TokenAmount, JSBI, Route, WETH, Percent } from '@uniswap/sdk'
import Slider from '../../components/Slider' import Slider from '../../components/Slider'
import TokenLogo from '../../components/TokenLogo' import TokenLogo from '../../components/TokenLogo'
import DoubleLogo from '../../components/DoubleLogo'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { Text } from 'rebass' import { Text } from 'rebass'
import { LightCard } from '../../components/Card' import { LightCard } from '../../components/Card'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { ButtonConfirmed } from '../../components/Button'
import { ArrowDown, Plus } from 'react-feather' import { ArrowDown, Plus } from 'react-feather'
import { RowBetween, RowFixed } from '../../components/Row'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import Row, { RowBetween, RowFixed } from '../../components/Row'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
...@@ -25,7 +27,6 @@ import { useExchange, useTotalSupply } from '../../contexts/Exchanges' ...@@ -25,7 +27,6 @@ import { useExchange, useTotalSupply } from '../../contexts/Exchanges'
import { BigNumber } from 'ethers/utils' import { BigNumber } from 'ethers/utils'
import { splitSignature } from '@ethersproject/bytes' import { splitSignature } from '@ethersproject/bytes'
import { TRANSACTION_TYPE } from '../../constants'
import { ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
...@@ -138,6 +139,10 @@ function reducer( ...@@ -138,6 +139,10 @@ function reducer(
} }
} }
const ConfirmedText = styled(Text)`
color: ${({ theme, confirmed }) => (confirmed ? theme.connectedGreen : theme.white)};
`
export default function RemoveLiquidity({ token0, token1 }) { export default function RemoveLiquidity({ token0, token1 }) {
const { account, chainId, library } = useWeb3React() const { account, chainId, library } = useWeb3React()
const routerAddress = ROUTER_ADDRESSES[chainId] const routerAddress = ROUTER_ADDRESSES[chainId]
...@@ -302,19 +307,19 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -302,19 +307,19 @@ export default function RemoveLiquidity({ token0, token1 }) {
: false : false
// errors // errors
const [generalError, setGeneralError] = useState() const [generalError, setGeneralError] = useState('')
const [inputError, setInputError] = useState() const [inputError, setInputError] = useState('')
const [outputError, setOutputError] = useState() const [outputError, setOutputError] = useState('')
const [poolTokenError, setPoolTokenError] = useState() const [poolTokenError, setPoolTokenError] = useState('')
const [isValid, setIsValid] = useState(false) const [isValid, setIsValid] = useState(false)
// update errors live // update errors live
useEffect(() => { useEffect(() => {
// reset errors // reset errors
setGeneralError(null) setGeneralError('')
setInputError(null) setInputError('')
setOutputError(null) setOutputError('')
setPoolTokenError(null) setPoolTokenError('')
setIsValid(true) setIsValid(true)
if (formattedAmounts[Field.TOKEN0] === '') { if (formattedAmounts[Field.TOKEN0] === '') {
...@@ -480,28 +485,103 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -480,28 +485,103 @@ export default function RemoveLiquidity({ token0, token1 }) {
setPendingConfirmation(true) setPendingConfirmation(true)
} }
function modalHeader() {
return (
<AutoColumn gap="16px">
<Row style={{ marginTop: '40px' }}>
<TokenLogo address={tokens[Field.TOKEN0]?.symbol} size={'30px'} />
<Text fontSize="24px" marginLeft={10}>
{tokens[Field.TOKEN0]?.symbol}{' '}
{!!parsedAmounts[Field.TOKEN0] && parsedAmounts[Field.TOKEN0].toSignificant(8)}
</Text>
</Row>
<Row>
<TokenLogo address={tokens[Field.TOKEN1]?.symbol} size={'30px'} />
<Text fontSize="24px" marginLeft={10}>
{tokens[Field.TOKEN1]?.symbol}{' '}
{!!parsedAmounts[Field.TOKEN1] && parsedAmounts[Field.TOKEN1].toSignificant(8)}
</Text>
</Row>
</AutoColumn>
)
}
function modalBottom() {
return (
<>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
{'UNI ' + tokens[Field.TOKEN0]?.symbol + ':' + tokens[Field.TOKEN1]?.symbol} Burned
</Text>
<RowFixed>
<DoubleLogo
a0={tokens[Field.TOKEN0]?.address || ''}
a1={tokens[Field.TOKEN1]?.address || ''}
margin={true}
/>
<Text fontWeight={500} fontSize={16}>
{parsedAmounts[Field.LIQUIDITY]?.toSignificant(6)}
</Text>
</RowFixed>
</RowBetween>
<RowBetween>
<Text color="#565A69" fontWeight={500} fontSize={16}>
Rate
</Text>
<Text fontWeight={500} fontSize={16}>
{`1 ${tokens[Field.TOKEN0]?.symbol} = ${route?.midPrice && route.midPrice.adjusted.toFixed(8)} ${
tokens[Field.TOKEN1]?.symbol
}`}
</Text>
</RowBetween>
<RowBetween gap="20px">
<ButtonConfirmed
style={{ margin: '20px 0' }}
width="48%"
onClick={onSign}
confirmed={signed}
disabled={signed}
>
<ConfirmedText fontWeight={500} fontSize={20} confirmed={signed}>
{signed ? 'Signed' : 'Sign'}
</ConfirmedText>
</ButtonConfirmed>
<ButtonPrimary width="48%" disabled={!signed} style={{ margin: '20px 0' }} onClick={onRemove}>
<Text fontWeight={500} fontSize={20}>
Confirm Remove
</Text>
</ButtonPrimary>
</RowBetween>
<Text fontSize={12} color="#565A69" textAlign="center">
{`Output is estimated. You will receive at least ${parsedAmounts[Field.TOKEN0]?.toFixed(6)} ${
tokens[Field.TOKEN0]?.symbol
} and at least ${parsedAmounts[Field.TOKEN1]?.toFixed(6)} ${
tokens[Field.TOKEN1]?.symbol
} or the transaction will revert.`}
</Text>
</>
)
}
const pendingText = `Removed ${parsedAmounts[Field.TOKEN0]?.toSignificant(6)} ${
tokens[Field.TOKEN0]?.symbol
} and ${parsedAmounts[Field.TOKEN1]?.toSignificant(6)} ${tokens[Field.TOKEN1]?.symbol}`
return ( return (
<Wrapper> <Wrapper>
{!!parsedAmounts[Field.TOKEN0] && !!parsedAmounts[Field.TOKEN1] && !!parsedAmounts[Field.LIQUIDITY] && ( <ConfirmationModal
<ConfirmationModal isOpen={showConfirm}
isOpen={showConfirm} onDismiss={() => {
onDismiss={() => { resetModalState()
resetModalState() setShowConfirm(false)
setShowConfirm(false) }}
}} attemptingTxn={attemptedRemoval}
amount0={parsedAmounts[Field.TOKEN0]} pendingConfirmation={pendingConfirmation}
amount1={parsedAmounts[Field.TOKEN1]} hash={txHash ? txHash : ''}
price={route?.midPrice} topContent={modalHeader}
liquidityAmount={parsedAmounts[Field.LIQUIDITY]} bottomContent={modalBottom}
transactionType={TRANSACTION_TYPE.REMOVE} pendingText={pendingText}
contractCall={onRemove} title="You will remove"
extraCall={onSign} />
signed={signed}
attemptedRemoval={attemptedRemoval}
pendingConfirmation={pendingConfirmation}
hash={txHash ? txHash : ''}
/>
)}
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<LightCard> <LightCard>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
......
...@@ -3,22 +3,22 @@ import styled from 'styled-components' ...@@ -3,22 +3,22 @@ import styled from 'styled-components'
import { JSBI } from '@uniswap/sdk' import { JSBI } from '@uniswap/sdk'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { useWeb3React } from '@web3-react/core' import Card from '../../components/Card'
import { useAllTokens } from '../../contexts/Tokens'
import { useAllExchanges } from '../../contexts/Exchanges'
import { useAllBalances, useAccountLPBalances } from '../../contexts/Balances'
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 Row, { RowBetween } from '../../components/Row' import Row, { RowBetween } from '../../components/Row'
import Card, { LightCard } from '../../components/Card'
import { Link } from '../../theme' import { Link } from '../../theme'
import { Text } from 'rebass' import { Text } from 'rebass'
import { AutoColumn } from '../../components/Column' import { AutoColumn } from '../../components/Column'
import { ArrowRight } from 'react-feather' import { ArrowRight } from 'react-feather'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { useWeb3React } from '@web3-react/core'
import { useAllTokens } from '../../contexts/Tokens'
import { useAllExchanges } from '../../contexts/Exchanges'
import { useAllBalances, useAccountLPBalances } from '../../contexts/Balances'
const Positions = styled.div` const Positions = styled.div`
position: relative; position: relative;
margin-top: 38px; margin-top: 38px;
...@@ -71,19 +71,16 @@ function Supply({ history }) { ...@@ -71,19 +71,16 @@ function Supply({ history }) {
</ButtonPrimary> </ButtonPrimary>
<Positions> <Positions>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<RowBetween> {filteredExchangeList?.length !== 0 && (
<Text fontWeight={500}>Your Pooled Liquidity</Text> <RowBetween>
<Question text="filler text" /> <Text fontWeight={500}>Your Pooled Liquidity</Text>
</RowBetween> <Question text="filler text" />
{filteredExchangeList} </RowBetween>
{filteredExchangeList?.length === 0 && (
<LightCard bg="rgba(255, 255, 255, 0.6)" padding={'45px'}>
<Text color="#C3C5CB">Add liquidity to see your positions</Text>
</LightCard>
)} )}
{filteredExchangeList}
<AutoColumn justify="center"> <AutoColumn justify="center">
<Text color="#AEAEAE"> <Text color="#AEAEAE">
Already have liquidity?{' '} {filteredExchangeList?.length !== 0 ? `Don't see your ` : 'Already have '} liquidity?{' '}
<Link <Link
onClick={() => { onClick={() => {
history.push('/find') history.push('/find')
......
...@@ -45,6 +45,7 @@ export const Link = styled.a.attrs({ ...@@ -45,6 +45,7 @@ export const Link = styled.a.attrs({
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
color: ${({ theme }) => theme.royalBlue}; color: ${({ theme }) => theme.royalBlue};
font-weight: 500;
:focus { :focus {
outline: none; outline: none;
......
...@@ -3,6 +3,7 @@ import { ThemeProvider as StyledComponentsThemeProvider, createGlobalStyle, css ...@@ -3,6 +3,7 @@ import { ThemeProvider as StyledComponentsThemeProvider, createGlobalStyle, css
import { getQueryParam, checkSupportedTheme } from '../utils' import { getQueryParam, checkSupportedTheme } from '../utils'
import { SUPPORTED_THEMES } from '../constants' import { SUPPORTED_THEMES } from '../constants'
import { useDarkModeManager } from '../contexts/LocalStorage' import { useDarkModeManager } from '../contexts/LocalStorage'
import { Text } from 'rebass'
export * from './components' export * from './components'
...@@ -117,6 +118,19 @@ const theme = darkMode => ({ ...@@ -117,6 +118,19 @@ const theme = darkMode => ({
` `
}) })
export const TYPE = {
main: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().mineshaftGray} {...rest}>
{children}
</Text>
),
blue: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().royalBlue} {...rest}>
{children}
</Text>
)
}
export const GlobalStyle = createGlobalStyle` export const GlobalStyle = createGlobalStyle`
@import url('https://rsms.me/inter/inter.css'); @import url('https://rsms.me/inter/inter.css');
html { font-family: 'Inter', sans-serif; } html { font-family: 'Inter', sans-serif; }
......
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