Commit 50c9d997 authored by Ian Lapham's avatar Ian Lapham Committed by GitHub

UI Updates, Route Context Updates (#679)

* UI updates, big fixes on route hook

* fix bug on all pair list

* logout fix and  add mainnet WETH
parent af6add09
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
"swapAnyway": "Swap Anyway", "swapAnyway": "Swap Anyway",
"send": "Send", "send": "Send",
"sendAnyway": "Send Anyway", "sendAnyway": "Send Anyway",
"pool": "Supply", "pool": "Pool",
"betaWarning": "This project is in beta. Use at your own risk.", "betaWarning": "This project is in beta. Use at your own risk.",
"input": "Input", "input": "Input",
"output": "Output", "output": "Output",
...@@ -85,5 +85,7 @@ ...@@ -85,5 +85,7 @@
"enterTokenCont": "Enter a token address to continue", "enterTokenCont": "Enter a token address to continue",
"priceChange": "Expected price slippage", "priceChange": "Expected price slippage",
"forAtLeast": "for at least ", "forAtLeast": "for at least ",
"brokenToken": "The selected token is not compatible with Uniswap V1. Adding liquidity will result in locked funds." "brokenToken": "The selected token is not compatible with Uniswap V1. Adding liquidity will result in locked funds.",
"toleranceExplanation": "Lowering this limit decreases your risk of frontrunning. However, this makes more likely that your transaction will fail due to normal price movements.",
"tokenSearchPlaceholder": "Search name or paste token address"
} }
...@@ -2,8 +2,7 @@ import React, { useState, useEffect } from 'react' ...@@ -2,8 +2,7 @@ import React, { useState, useEffect } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { transparentize } from 'polished' import { transparentize } from 'polished'
import QR from '../../assets/svg/QR.svg' // import QR from '../../assets/svg/QR.svg'
import { isAddress } from '../../utils' import { isAddress } from '../../utils'
import { useWeb3React, useDebounce } from '../../hooks' import { useWeb3React, useDebounce } from '../../hooks'
...@@ -15,6 +14,8 @@ const InputPanel = styled.div` ...@@ -15,6 +14,8 @@ const InputPanel = styled.div`
background-color: ${({ theme }) => theme.bg1}; background-color: ${({ theme }) => theme.bg1};
z-index: 1; z-index: 1;
width: 100%; width: 100%;
height: 60px;
` `
const ContainerRow = styled.div` const ContainerRow = styled.div`
...@@ -22,6 +23,7 @@ const ContainerRow = styled.div` ...@@ -22,6 +23,7 @@ const ContainerRow = styled.div`
justify-content: center; justify-content: center;
align-items: center; align-items: center;
border-radius: 1.25rem; border-radius: 1.25rem;
height: 60px;
border: 1px solid ${({ error, theme }) => (error ? theme.red1 : theme.bg3)}; border: 1px solid ${({ error, theme }) => (error ? theme.red1 : theme.bg3)};
background-color: ${({ theme }) => theme.bg1}; background-color: ${({ theme }) => theme.bg1};
` `
...@@ -43,25 +45,26 @@ const Input = styled.input` ...@@ -43,25 +45,26 @@ const Input = styled.input`
flex: 1 1 auto; flex: 1 1 auto;
width: 0; width: 0;
background-color: ${({ theme }) => theme.bg1}; background-color: ${({ theme }) => theme.bg1};
font-size: 20px;
color: ${({ error, theme }) => (error ? theme.red1 : theme.blue1)}; color: ${({ error, theme }) => (error ? theme.red1 : theme.blue1)};
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
font-weight: 500;
::placeholder { ::placeholder {
color: ${({ theme }) => theme.text4}; color: ${({ theme }) => theme.text4};
} }
` `
const QRWrapper = styled.div` // const QRWrapper = styled.div`
display: flex; // display: flex;
align-items: center; // align-items: center;
justify-content: center; // justify-content: center;
border: 1px solid ${({ theme }) => theme.bg3}; // border: 1px solid ${({ theme }) => theme.bg3};
background: #fbfbfb; // background: #fbfbfb;
padding: 4px; // padding: 4px;
border-radius: 8px; // border-radius: 8px;
` // `
export default function AddressInputPanel({ initialInput = '', onChange, onError }) { export default function AddressInputPanel({ initialInput = '', onChange, onError }) {
const { library } = useWeb3React() const { library } = useWeb3React()
...@@ -172,14 +175,14 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError ...@@ -172,14 +175,14 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError
autoCorrect="off" autoCorrect="off"
autoCapitalize="off" autoCapitalize="off"
spellCheck="false" spellCheck="false"
placeholder="0x1234..." placeholder="Recipient Address"
error={input !== '' && error} error={input !== '' && error}
onChange={onInput} onChange={onInput}
value={input} value={input}
/> />
<QRWrapper> {/* <QRWrapper>
<img src={QR} alt="" /> <img src={QR} alt="" />
</QRWrapper> </QRWrapper> */}
</InputRow> </InputRow>
</InputContainer> </InputContainer>
</ContainerRow> </ContainerRow>
......
...@@ -7,6 +7,7 @@ import { Link } from '../../theme/components' ...@@ -7,6 +7,7 @@ import { Link } from '../../theme/components'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { AutoColumn } from '../../components/Column' import { AutoColumn } from '../../components/Column'
import { ButtonRadio } from '../Button' import { ButtonRadio } from '../Button'
import { useTranslation } from 'react-i18next'
import Row, { RowBetween, RowFixed } from '../../components/Row' import Row, { RowBetween, RowFixed } from '../../components/Row'
const InputWrapper = styled(RowBetween)` const InputWrapper = styled(RowBetween)`
...@@ -27,6 +28,9 @@ const SLIPPAGE_INDEX = { ...@@ -27,6 +28,9 @@ const SLIPPAGE_INDEX = {
} }
export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippage, setAllowedSlippage }) { export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippage, setAllowedSlippage }) {
// text translation
const { t } = useTranslation()
const [deadlineInput, setDeadlineInput] = useState(15) const [deadlineInput, setDeadlineInput] = useState(15)
const [slippageInput, setSlippageInput] = useState() const [slippageInput, setSlippageInput] = useState()
const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[3]) const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[3])
...@@ -82,8 +86,8 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -82,8 +86,8 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
back back
</Link> </Link>
<RowBetween> <RowBetween>
<TYPE.main>Limit additional price impact</TYPE.main> <TYPE.main>Limit front-running tolerance</TYPE.main>
<QuestionHelper text="" /> <QuestionHelper text={t('toleranceExplanation')} />
</RowBetween> </RowBetween>
<Row> <Row>
<ButtonRadio <ButtonRadio
......
...@@ -44,6 +44,24 @@ export const ButtonPrimary = styled(Base)` ...@@ -44,6 +44,24 @@ export const ButtonPrimary = styled(Base)`
} }
` `
export const ButtonLight = styled(Base)`
background-color: ${({ theme }) => theme.blue5};
color: ${({ theme }) => theme.blue1};
font-size: 20px;
font-weight: 500;
&:focus {
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.05, theme.blue5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.blue5)};
}
&:hover {
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.blue5)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.1, theme.blue5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.1, theme.blue5)};
}
`
export const ButtonSecondary = styled(Base)` export const ButtonSecondary = styled(Base)`
background-color: #ebf4ff; background-color: #ebf4ff;
color: #2172e5; color: #2172e5;
...@@ -73,8 +91,6 @@ export const ButtonPink = styled(Base)` ...@@ -73,8 +91,6 @@ export const ButtonPink = styled(Base)`
background-color: ${({ theme }) => theme.pink2}; background-color: ${({ theme }) => theme.pink2};
color: white; color: white;
padding: 10px;
&:focus { &:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.pink2)}; box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.pink2)};
background-color: ${({ theme }) => darken(0.05, theme.pink2)}; background-color: ${({ theme }) => darken(0.05, theme.pink2)};
......
...@@ -18,12 +18,24 @@ export const LightCard = styled(Card)` ...@@ -18,12 +18,24 @@ export const LightCard = styled(Card)`
` `
export const GreyCard = styled(Card)` export const GreyCard = styled(Card)`
background-color: rgba(255, 255, 255, 0.9); background-color: rgba(255, 255, 255, 0.6);
`
export const YellowCard = styled(Card)`
background-color: rgba(243, 190, 30, 0.3);
color: ${({ theme }) => theme.yellow2};
fontweight: 500;
`
export const PinkCard = styled(Card)`
background-color: rgba(255, 0, 122, 0.03);
color: ${({ theme }) => theme.pink2};
fontweight: 500;
` `
const BlueCardStyled = styled(Card)` const BlueCardStyled = styled(Card)`
background-color: #ebf4ff; background-color: ${({ theme }) => theme.blue5};
color: #2172e5; color: ${({ theme }) => theme.blue1};
border-radius: 12px; border-radius: 12px;
padding: 8px; padding: 8px;
width: fit-content; width: fit-content;
......
...@@ -23,6 +23,8 @@ const Section = styled(AutoColumn)` ...@@ -23,6 +23,8 @@ const Section = styled(AutoColumn)`
const BottomSection = styled(Section)` const BottomSection = styled(Section)`
background-color: ${({ theme }) => theme.bg2}; background-color: ${({ theme }) => theme.bg2};
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
` `
const ConfirmedIcon = styled(ColumnCenter)` const ConfirmedIcon = styled(ColumnCenter)`
......
import React, { useState } from 'react' import React, { useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import '@reach/tooltip/styles.css' import '@reach/tooltip/styles.css'
import { ethers } from 'ethers'
import { darken } from 'polished' import { darken } from 'polished'
import { WETH } from '@uniswap/sdk'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import DoubleLogo from '../DoubleLogo' import DoubleLogo from '../DoubleLogo'
...@@ -16,30 +14,7 @@ import { Input as NumericalInput } from '../NumericalInput' ...@@ -16,30 +14,7 @@ import { Input as NumericalInput } from '../NumericalInput'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useTokenContract } from '../../hooks'
import { calculateGasMargin } from '../../utils'
import { useAddressBalance } from '../../contexts/Balances' import { useAddressBalance } from '../../contexts/Balances'
import { useTransactionAdder, usePendingApproval } from '../../contexts/Transactions'
import { ROUTER_ADDRESSES } from '../../constants'
const GAS_MARGIN = ethers.utils.bigNumberify(1000)
const SubCurrencySelect = styled.button`
${({ theme }) => theme.flexRowNoWrap}
padding: 4px 50px 4px 15px;
margin-right: -40px;
line-height: 0;
align-items: center;
border-radius: 2.5rem;
height: 2rem;
outline: none;
cursor: pointer;
user-select: none;
background: ${({ theme }) => theme.blue5};
border: 1px solid ${({ theme }) => theme.blue1};
color: ${({ theme }) => theme.blue1};
`
const InputRow = styled.div` const InputRow = styled.div`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
...@@ -156,8 +131,6 @@ export default function CurrencyInputPanel({ ...@@ -156,8 +131,6 @@ export default function CurrencyInputPanel({
urlAddedTokens = [], // used urlAddedTokens = [], // used
onTokenSelection = null, onTokenSelection = null,
token = null, token = null,
showUnlock = false, // used to show unlock if approval needed
disableUnlock = false,
disableTokenSelect = false, disableTokenSelect = false,
hideBalance = false, hideBalance = false,
isExchange = false, isExchange = false,
...@@ -167,59 +140,11 @@ export default function CurrencyInputPanel({ ...@@ -167,59 +140,11 @@ export default function CurrencyInputPanel({
showSendWithSwap = false showSendWithSwap = false
}) { }) {
const { t } = useTranslation() const { t } = useTranslation()
const { account, chainId } = useWeb3React() const { account } = useWeb3React()
const routerAddress = ROUTER_ADDRESSES[chainId]
const addTransaction = useTransactionAdder()
const [modalOpen, setModalOpen] = useState(false) const [modalOpen, setModalOpen] = useState(false)
const userTokenBalance = useAddressBalance(account, token) const userTokenBalance = useAddressBalance(account, token)
const tokenContract = useTokenContract(token?.address)
const pendingApproval = usePendingApproval(token?.address)
function renderUnlockButton() {
if (
disableUnlock ||
!showUnlock ||
token?.address === 'ETH' ||
token?.address === WETH[chainId].address ||
!token?.address
) {
return null
} else {
if (!pendingApproval) {
return (
<SubCurrencySelect
onClick={async () => {
let estimatedGas
let useUserBalance = false
estimatedGas = await tokenContract.estimate
.approve(routerAddress, ethers.constants.MaxUint256)
.catch(e => {
console.log('Error setting max token approval.')
})
if (!estimatedGas) {
// general fallback for tokens who restrict approval amounts
estimatedGas = await tokenContract.estimate.approve(routerAddress, userTokenBalance)
useUserBalance = true
}
tokenContract
.approve(routerAddress, useUserBalance ? userTokenBalance : ethers.constants.MaxUint256, {
gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN)
})
.then(response => {
addTransaction(response, { approval: token?.address })
})
}}
>
{t('unlock')}
</SubCurrencySelect>
)
} else {
return <SubCurrencySelect>{t('pending')}</SubCurrencySelect>
}
}
}
return ( return (
<InputPanel> <InputPanel>
...@@ -234,7 +159,7 @@ export default function CurrencyInputPanel({ ...@@ -234,7 +159,7 @@ export default function CurrencyInputPanel({
}} }}
/> />
{!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>} {!!token?.address && !atMax && <StyledBalanceMax onClick={onMax}>MAX</StyledBalanceMax>}
{renderUnlockButton()} {/* {renderUnlockButton()} */}
</> </>
)} )}
<CurrencySelect <CurrencySelect
...@@ -288,6 +213,7 @@ export default function CurrencyInputPanel({ ...@@ -288,6 +213,7 @@ export default function CurrencyInputPanel({
field={field} field={field}
onTokenSelect={onTokenSelection} onTokenSelect={onTokenSelection}
showSendWithSwap={showSendWithSwap} showSendWithSwap={showSendWithSwap}
hiddenToken={token?.address}
/> />
)} )}
</InputPanel> </InputPanel>
......
This diff is collapsed.
...@@ -4,7 +4,7 @@ import styled from 'styled-components' ...@@ -4,7 +4,7 @@ import styled from 'styled-components'
import Row from '../Row' import Row from '../Row'
import Menu from '../Menu' import Menu from '../Menu'
import Logo from '../../assets/svg/logo.svg' import Logo from '../../assets/svg/logo.svg'
import Card from '../Card' import Card, { YellowCard } from '../Card'
import Web3Status from '../Web3Status' import Web3Status from '../Web3Status'
import { X } from 'react-feather' import { X } from 'react-feather'
import { Link } from '../../theme' import { Link } from '../../theme'
...@@ -59,6 +59,7 @@ const AccountElement = styled.div` ...@@ -59,6 +59,7 @@ const AccountElement = styled.div`
border: 1px solid ${({ theme }) => theme.bg3}; border: 1px solid ${({ theme }) => theme.bg3};
border-radius: 8px; border-radius: 8px;
padding-left: ${({ active }) => (active ? '8px' : 0)}; padding-left: ${({ active }) => (active ? '8px' : 0)};
white-space: nowrap;
:focus { :focus {
border: 1px solid blue; border: 1px solid blue;
...@@ -119,6 +120,26 @@ export default function Header() { ...@@ -119,6 +120,26 @@ export default function Header() {
)} )}
<Web3Status onClick={toggleWalletModal} /> <Web3Status onClick={toggleWalletModal} />
</AccountElement> </AccountElement>
{chainId === 4 && (
<YellowCard style={{ width: 'fit-content', marginLeft: '10px' }} padding={'6px'}>
Rinkeby Testnet
</YellowCard>
)}
{chainId === 3 && (
<YellowCard style={{ width: 'fit-content', marginLeft: '10px' }} padding={'6px'}>
Ropsten Testnet
</YellowCard>
)}
{chainId === 5 && (
<YellowCard style={{ width: 'fit-content', marginLeft: '10px' }} padding={'6px'}>
Goerli Testnet
</YellowCard>
)}
{chainId === 42 && (
<YellowCard style={{ width: 'fit-content', marginLeft: '10px' }} padding={'6px'}>
Kovan Testnet
</YellowCard>
)}
<Menu /> <Menu />
</HeaderElement> </HeaderElement>
<FixedPopupColumn gap="20px"> <FixedPopupColumn gap="20px">
......
...@@ -66,7 +66,7 @@ const StyledDialogContent = styled(FilteredDialogContent)` ...@@ -66,7 +66,7 @@ const StyledDialogContent = styled(FilteredDialogContent)`
min-height: ${minHeight}vh; min-height: ${minHeight}vh;
`} `}
display: flex; display: flex;
overflow: hidden; /* overflow: hidden; */
border-radius: 10px; border-radius: 10px;
${({ theme }) => theme.mediaWidth.upToMedium` ${({ theme }) => theme.mediaWidth.upToMedium`
width: 65vw; width: 65vw;
......
...@@ -22,9 +22,9 @@ const tabOrder = [ ...@@ -22,9 +22,9 @@ const tabOrder = [
regex: /\/send/ regex: /\/send/
}, },
{ {
path: '/supply', path: '/pool',
textKey: 'pool', textKey: 'pool',
regex: /\/supply/ regex: /\/pool/
} }
] ]
...@@ -105,7 +105,7 @@ function NavigationTabs({ location: { pathname }, history }) { ...@@ -105,7 +105,7 @@ function NavigationTabs({ location: { pathname }, history }) {
{adding || removing ? ( {adding || removing ? (
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem' }}> <RowBetween style={{ padding: '1rem' }}>
<HistoryLink to="/supply"> <HistoryLink to="/pool">
<ArrowLink /> <ArrowLink />
</HistoryLink> </HistoryLink>
<ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText> <ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText>
...@@ -115,7 +115,7 @@ function NavigationTabs({ location: { pathname }, history }) { ...@@ -115,7 +115,7 @@ function NavigationTabs({ location: { pathname }, history }) {
) : finding ? ( ) : finding ? (
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem' }}> <RowBetween style={{ padding: '1rem' }}>
<HistoryLink to="/supply"> <HistoryLink to="/pool">
<ArrowLink /> <ArrowLink />
</HistoryLink> </HistoryLink>
<ActiveText>Find a Pool</ActiveText> <ActiveText>Find a Pool</ActiveText>
......
import React from 'react' import React, { useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { darken } from 'polished'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { Percent, Pair } from '@uniswap/sdk' import { Percent, Pair } from '@uniswap/sdk'
...@@ -13,6 +14,7 @@ import DoubleLogo from '../DoubleLogo' ...@@ -13,6 +14,7 @@ import DoubleLogo from '../DoubleLogo'
import { Text } from 'rebass' import { Text } from 'rebass'
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 { ButtonSecondary } from '../Button' import { ButtonSecondary } from '../Button'
import { RowBetween, RowFixed } from '../Row' import { RowBetween, RowFixed } from '../Row'
...@@ -20,12 +22,22 @@ const FixedHeightRow = styled(RowBetween)` ...@@ -20,12 +22,22 @@ const FixedHeightRow = styled(RowBetween)`
height: 24px; height: 24px;
` `
const HoverCard = styled(Card)`
border: 1px solid ${({ theme }) => theme.bg3};
:hover {
cursor: pointer;
border: 1px solid ${({ theme }) => darken(0.06, theme.bg3)};
}
`
function PositionCard({ pairAddress, token0, token1, history, minimal = false, ...rest }) { function PositionCard({ pairAddress, token0, token1, history, minimal = false, ...rest }) {
const { account } = useWeb3React() const { account } = useWeb3React()
const allBalances = useAllBalances() const allBalances = useAllBalances()
const tokenAmount0 = allBalances?.[pairAddress]?.[token0.address] const [showMore, setShowMore] = useState(false)
const tokenAmount1 = allBalances?.[pairAddress]?.[token1.address]
const tokenAmount0 = allBalances?.[pairAddress]?.[token0?.address]
const tokenAmount1 = allBalances?.[pairAddress]?.[token1?.address]
const pair = tokenAmount0 && tokenAmount1 && new Pair(tokenAmount0, tokenAmount1) const pair = tokenAmount0 && tokenAmount1 && new Pair(tokenAmount0, tokenAmount1)
...@@ -46,97 +58,154 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -46,97 +58,154 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
userPoolBalance && userPoolBalance &&
pair.getLiquidityValue(token1, totalPoolTokens, userPoolBalance, false) pair.getLiquidityValue(token1, totalPoolTokens, userPoolBalance, false)
function DynamicCard({ children, ...rest }) { if (minimal) {
if (!minimal) { return (
return ( <GreyCard {...rest}>
<Card border="1px solid #EDEEF2" {...rest}> <AutoColumn gap="20px">
{children}
</Card>
)
} else {
return <GreyCard {...rest}>{children}</GreyCard>
}
}
return (
<DynamicCard {...rest}>
<AutoColumn gap="20px">
<FixedHeightRow>
<RowFixed>
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={24} />
<Text fontWeight={500} fontSize={20}>
{token0?.symbol}:{token1?.symbol}
</Text>
</RowFixed>
<Text fontWeight={500} fontSize={20}>
{userPoolBalance ? userPoolBalance.toFixed(6) : '-'}
</Text>
</FixedHeightRow>
<AutoColumn gap="12px">
<FixedHeightRow> <FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}> <RowFixed>
{token0?.symbol} Deposited: <Text fontWeight={500} fontSize={20}>
</Text> Current Position
{token0Deposited ? ( </Text>
<RowFixed> </RowFixed>
<TokenLogo address={token0?.address || ''} />
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token0Deposited?.toFixed(8)}
</Text>
</RowFixed>
) : (
'-'
)}
</FixedHeightRow> </FixedHeightRow>
<FixedHeightRow> <FixedHeightRow onClick={() => setShowMore(!showMore)}>
<Text color="#888D9B" fontSize={16} fontWeight={500}> <RowFixed>
{token1?.symbol} Deposited: <DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={24} />
</Text> <Text fontWeight={500} fontSize={20}>
{token1Deposited ? ( {token0?.symbol}:{token1?.symbol}
<RowFixed> </Text>
<TokenLogo address={token1.address || ''} /> </RowFixed>
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}> <RowFixed>
{token1Deposited?.toFixed(8)} <Text fontWeight={500} fontSize={20}>
</Text> {userPoolBalance ? userPoolBalance.toFixed(6) : '-'}
</RowFixed> </Text>
) : ( </RowFixed>
'-'
)}
</FixedHeightRow> </FixedHeightRow>
{!minimal && ( <AutoColumn gap="12px">
<FixedHeightRow> <FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}> <Text color="#888D9B" fontSize={16} fontWeight={500}>
Your pool share: {token0?.symbol}:
</Text> </Text>
{token0Deposited ? (
<RowFixed>
{!minimal && <TokenLogo address={token0?.address || ''} />}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token0Deposited?.toFixed(8)}
</Text>
</RowFixed>
) : (
'-'
)}
</FixedHeightRow>
<FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}> <Text color="#888D9B" fontSize={16} fontWeight={500}>
{poolTokenPercentage ? poolTokenPercentage.toFixed(2) + '%' : '-'} {token1?.symbol}:
</Text> </Text>
{token1Deposited ? (
<RowFixed>
{!minimal && <TokenLogo address={token1?.address || ''} />}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token1Deposited?.toFixed(8)}
</Text>
</RowFixed>
) : (
'-'
)}
</FixedHeightRow> </FixedHeightRow>
</AutoColumn>
</AutoColumn>
</GreyCard>
)
} else
return (
<HoverCard {...rest} onClick={() => setShowMore(!showMore)}>
<AutoColumn gap="20px">
<FixedHeightRow>
<RowFixed>
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={24} />
<Text fontWeight={500} fontSize={20}>
{token0?.symbol}:{token1?.symbol}
</Text>
</RowFixed>
<RowFixed>
<Text fontWeight={500} fontSize={20}>
{userPoolBalance ? userPoolBalance.toFixed(6) : '-'}
</Text>
{showMore ? (
<ChevronUp size="30" style={{ marginLeft: '10px' }} />
) : (
<ChevronDown size="30" style={{ marginLeft: '10px' }} />
)}
</RowFixed>
</FixedHeightRow>
{showMore && (
<AutoColumn gap="12px">
<FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}>
{token0?.symbol}:
</Text>
{token0Deposited ? (
<RowFixed>
{!minimal && <TokenLogo address={token0?.address || ''} />}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token0Deposited?.toFixed(8)}
</Text>
</RowFixed>
) : (
'-'
)}
</FixedHeightRow>
<FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}>
{token1?.symbol}:
</Text>
{token1Deposited ? (
<RowFixed>
{!minimal && <TokenLogo address={token1?.address || ''} />}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token1Deposited?.toFixed(8)}
</Text>
</RowFixed>
) : (
'-'
)}
</FixedHeightRow>
{!minimal && (
<FixedHeightRow>
<Text color="#888D9B" fontSize={16} fontWeight={500}>
Your pool share:
</Text>
<Text color="#888D9B" fontSize={16} fontWeight={500}>
{poolTokenPercentage ? poolTokenPercentage.toFixed(2) + '%' : '-'}
</Text>
</FixedHeightRow>
)}
</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>
{!minimal && ( </HoverCard>
<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>
</DynamicCard>
)
} }
export default withRouter(PositionCard) export default withRouter(PositionCard)
...@@ -105,10 +105,11 @@ const PaddedItem = styled(RowBetween)` ...@@ -105,10 +105,11 @@ const PaddedItem = styled(RowBetween)`
` `
const MenuItem = styled(PaddedItem)` const MenuItem = styled(PaddedItem)`
cursor: pointer; cursor: ${({ disabled }) => !disabled && 'pointer'};
:hover { :hover {
background-color: ${({ theme }) => theme.bg2}; background-color: ${({ theme, disabled }) => !disabled && theme.bg2};
} }
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
` `
// filters on results // filters on results
const FILTERS = { const FILTERS = {
...@@ -132,6 +133,7 @@ function SearchModal({ ...@@ -132,6 +133,7 @@ function SearchModal({
const allTokens = useAllTokens() const allTokens = useAllTokens()
const allPairs = useAllPairs() const allPairs = useAllPairs()
const allBalances = useAllBalances() const allBalances = useAllBalances()
const [searchQuery, setSearchQuery] = useState('') const [searchQuery, setSearchQuery] = useState('')
...@@ -175,9 +177,6 @@ function SearchModal({ ...@@ -175,9 +177,6 @@ function SearchModal({
} }
}) })
.map(k => { .map(k => {
if (k === hiddenToken) {
return false
}
return { return {
name: allTokens[k].name, name: allTokens[k].name,
symbol: allTokens[k].symbol, symbol: allTokens[k].symbol,
...@@ -185,7 +184,7 @@ function SearchModal({ ...@@ -185,7 +184,7 @@ function SearchModal({
balance: allBalances?.[account]?.[k] balance: allBalances?.[account]?.[k]
} }
}) })
}, [allTokens, allBalances, account, sortDirection, hiddenToken]) }, [allTokens, allBalances, account, sortDirection])
const filteredTokenList = useMemo(() => { const filteredTokenList = useMemo(() => {
return tokenList.filter(tokenEntry => { return tokenList.filter(tokenEntry => {
...@@ -350,7 +349,17 @@ function SearchModal({ ...@@ -350,7 +349,17 @@ function SearchModal({
const zeroBalance = balance && JSBI.equal(JSBI.BigInt(0), balance.raw) const zeroBalance = balance && JSBI.equal(JSBI.BigInt(0), balance.raw)
return ( return (
<MenuItem key={address} onClick={() => (zeroBalance ? _onTokenSelect(address, true) : _onTokenSelect(address))}> <MenuItem
key={address}
onClick={() =>
hiddenToken && hiddenToken === address
? () => {}
: zeroBalance
? _onTokenSelect(address, true)
: _onTokenSelect(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>
...@@ -428,7 +437,7 @@ function SearchModal({ ...@@ -428,7 +437,7 @@ function SearchModal({
</RowBetween> </RowBetween>
<Input <Input
type={'text'} type={'text'}
placeholder={'Search name or address'} placeholder={t('tokenSearchPlaceholder')}
value={searchQuery} value={searchQuery}
ref={inputRef} ref={inputRef}
onChange={onInput} onChange={onInput}
...@@ -447,6 +456,7 @@ function SearchModal({ ...@@ -447,6 +456,7 @@ function SearchModal({
</StyledLink> </StyledLink>
</Text> </Text>
)} )}
{filterType === 'tokens' && <Text>Token Symbol</Text>}
</div> </div>
<div /> <div />
<Filter title="Your Balances" filter={FILTERS.BALANCES} /> <Filter title="Your Balances" filter={FILTERS.BALANCES} />
......
import React from 'react'
import { Link } from '../../theme/components'
import { TYPE } from '../../theme'
import { AutoColumn } from '../Column'
import { useWeb3React } from '../../hooks'
import { getEtherscanLink } from '../../utils'
export default function TxnPopup({ hash, success }) {
const { chainId } = useWeb3React()
if (success) {
return (
<AutoColumn gap="12px">
<TYPE.body>Transaction Confirmed</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>
)
} 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>
)
}
}
...@@ -2,7 +2,7 @@ import React from 'react' ...@@ -2,7 +2,7 @@ import React from 'react'
import styled, { css } from 'styled-components' import styled, { css } from 'styled-components'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useWeb3React, UnsupportedChainIdError } from '@web3-react/core' import { useWeb3React, UnsupportedChainIdError } from '@web3-react/core'
import { darken, transparentize } from 'polished' import { darken } from 'polished'
import { Activity } from 'react-feather' import { Activity } from 'react-feather'
import { shortenAddress } from '../../utils' import { shortenAddress } from '../../utils'
...@@ -10,8 +10,6 @@ import { useENSName } from '../../hooks' ...@@ -10,8 +10,6 @@ import { useENSName } from '../../hooks'
import WalletModal from '../WalletModal' import WalletModal from '../WalletModal'
import { useAllTransactions } from '../../contexts/Transactions' import { useAllTransactions } from '../../contexts/Transactions'
import { useWalletModalToggle } from '../../contexts/Application' import { useWalletModalToggle } from '../../contexts/Application'
import { Spinner } from '../../theme'
import Circle from '../../assets/images/circle.svg'
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors' 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'
...@@ -46,39 +44,40 @@ const Web3StatusError = styled(Web3StatusGeneric)` ...@@ -46,39 +44,40 @@ const Web3StatusError = styled(Web3StatusGeneric)`
` `
const Web3StatusConnect = styled(Web3StatusGeneric)` const Web3StatusConnect = styled(Web3StatusGeneric)`
background-color: transparent; background-color: ${({ theme }) => theme.blue4};
border: 1px solid ${({ theme }) => theme.blue1}; border: 1px solid ${({ theme }) => theme.blue4};
border: none;
color: ${({ theme }) => theme.blue1}; color: ${({ theme }) => theme.blue1};
font-weight: 500; font-weight: 500;
:hover, :hover,
:focus { :focus {
border: 1px solid ${({ theme }) => darken(0.1, theme.blue1)}; border: 1px solid ${({ theme }) => darken(0.1, theme.blue4)};
color: ${({ theme }) => darken(0.1, theme.blue1)}; color: ${({ theme }) => darken(0.1, theme.blue1)};
} }
${({ faded }) => ${({ faded }) =>
faded && faded &&
css` css`
background-color: transparent; background-color: ${({ theme }) => theme.blue5};
border: 1px solid ${({ theme }) => theme.blue1}; border: 1px solid ${({ theme }) => theme.blue5};
color: ${({ theme }) => theme.blue1}; color: ${({ theme }) => theme.blue1};
:hover, :hover,
:focus { :focus {
border: 1px solid ${({ theme }) => darken(0.1, theme.blue1)}; border: 1px solid ${({ theme }) => darken(0.1, theme.blue4)};
color: ${({ theme }) => darken(0.1, theme.blue1)}; color: ${({ theme }) => darken(0.1, theme.blue1)};
} }
`} `}
` `
const Web3StatusConnected = styled(Web3StatusGeneric)` const Web3StatusConnected = styled(Web3StatusGeneric)`
background-color: ${({ pending, theme }) => (pending ? theme.blue5 : theme.bg1)}; background-color: ${({ pending, theme }) => (pending ? theme.blue1 : theme.bg1)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.blue1 : theme.bg3)}; border: 1px solid ${({ pending, theme }) => (pending ? theme.blue1 : theme.bg3)};
color: ${({ pending, theme }) => (pending ? theme.blue1 : theme.text3)}; color: ${({ pending, theme }) => (pending ? theme.white : theme.text3)};
font-weight: 400; font-weight: 400;
:hover { :hover {
background-color: ${({ pending, theme }) => (pending ? transparentize(0.9, theme.blue1) : darken(0.05, theme.bg1))}; background-color: ${({ pending, theme }) => (pending ? darken(0.05, theme.blue1) : darken(0.05, theme.bg1))};
:focus { :focus {
border: 1px solid ${({ pending, theme }) => (pending ? darken(0.1, theme.blue1) : darken(0.1, theme.bg3))}; border: 1px solid ${({ pending, theme }) => (pending ? darken(0.1, theme.blue1) : darken(0.1, theme.bg3))};
...@@ -93,6 +92,8 @@ const Text = styled.p` ...@@ -93,6 +92,8 @@ const Text = styled.p`
white-space: nowrap; white-space: nowrap;
margin: 0 0.5rem 0 0.25rem; margin: 0 0.5rem 0 0.25rem;
font-size: 0.83rem; font-size: 0.83rem;
width: fit-content;
font-weight: 500;
` `
const NetworkIcon = styled(Activity)` const NetworkIcon = styled(Activity)`
...@@ -102,10 +103,6 @@ const NetworkIcon = styled(Activity)` ...@@ -102,10 +103,6 @@ const NetworkIcon = styled(Activity)`
height: 16px; height: 16px;
` `
const SpinnerWrapper = styled(Spinner)`
margin: 0 0.25rem 0 0.25rem;
`
const IconWrapper = styled.div` const IconWrapper = styled.div`
${({ theme }) => theme.flexColumnNoWrap}; ${({ theme }) => theme.flexColumnNoWrap};
align-items: center; align-items: center;
...@@ -166,9 +163,12 @@ export default function Web3Status() { ...@@ -166,9 +163,12 @@ export default function Web3Status() {
if (account) { if (account) {
return ( return (
<Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}> <Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}>
{hasPendingTransactions && <SpinnerWrapper src={Circle} alt="loader" />} {hasPendingTransactions ? (
<Text>{ENSName || shortenAddress(account)}</Text> <Text>{pending?.length} Pending</Text>
{getStatusIcon()} ) : (
<Text>{ENSName || shortenAddress(account)}</Text>
)}
{!hasPendingTransactions && getStatusIcon()}
</Web3StatusConnected> </Web3StatusConnected>
) )
} else if (error) { } else if (error) {
......
...@@ -5,6 +5,7 @@ import { INITIAL_TOKENS_CONTEXT } from './Tokens' ...@@ -5,6 +5,7 @@ import { INITIAL_TOKENS_CONTEXT } from './Tokens'
import { ChainId, WETH, Token, TokenAmount, Pair, JSBI } from '@uniswap/sdk' import { ChainId, WETH, Token, TokenAmount, Pair, JSBI } from '@uniswap/sdk'
const UPDATE = 'UPDATE' const UPDATE = 'UPDATE'
const UPDATE_PAIR_ENTITY = 'UPDATE_PAIR_ENTITY'
const ALL_PAIRS: [Token, Token][] = [ const ALL_PAIRS: [Token, Token][] = [
[ [
...@@ -12,8 +13,8 @@ const ALL_PAIRS: [Token, Token][] = [ ...@@ -12,8 +13,8 @@ const ALL_PAIRS: [Token, Token][] = [
INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'] //dai INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'] //dai
], ],
[ [
INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'], INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735'], // dai
INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0x8ab15C890E5C03B5F240f2D146e3DF54bEf3Df44'] INITIAL_TOKENS_CONTEXT[ChainId.RINKEBY]['0x8ab15C890E5C03B5F240f2D146e3DF54bEf3Df44'] // mkr
] ]
] ]
...@@ -22,16 +23,20 @@ const PAIR_MAP: { ...@@ -22,16 +23,20 @@ const PAIR_MAP: {
} = ALL_PAIRS.reduce((pairMap, [tokenA, tokenB]) => { } = ALL_PAIRS.reduce((pairMap, [tokenA, tokenB]) => {
const tokens: [Token, Token] = tokenA?.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] const tokens: [Token, Token] = tokenA?.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA]
// ensure exchanges are unique // ensure exchanges are unique
if (pairMap?.[tokens[0].chainId]?.[tokens[0].address]?.[tokens[1].address] !== undefined) if (pairMap?.[tokens[0].chainId]?.[tokens[0].address]?.[tokens[1].address]?.address !== undefined)
throw Error(`Duplicate exchange: ${tokenA} ${tokenB}`) throw Error(`Duplicate exchange: ${tokenA} ${tokenB}`)
return { return {
...pairMap, ...pairMap,
[tokens[0].chainId]: { [tokens[0].chainId]: {
...pairMap?.[tokens[0].chainId], ...pairMap?.[tokens[0].chainId],
[tokens[0].address]: { addresses: {
...pairMap?.[tokens[0].chainId]?.[tokens[0].address], ...pairMap?.[tokens[0].chainId]?.['addresses'],
[tokens[1].address]: Pair.getAddress(...tokens) [tokens[0].address]: {
} ...pairMap?.[tokens[0].chainId]?.[tokens[0].address],
[tokens[1].address]: Pair.getAddress(...tokens)
}
},
entities: {}
} }
} }
}, {}) }, {})
...@@ -53,9 +58,25 @@ function reducer(state, { type, payload }) { ...@@ -53,9 +58,25 @@ function reducer(state, { type, payload }) {
...state, ...state,
[tokensSorted[0].chainId]: { [tokensSorted[0].chainId]: {
...state?.[tokensSorted[0].chainId], ...state?.[tokensSorted[0].chainId],
[tokensSorted[0].address]: { addresses: {
...state?.[tokensSorted[0].chainId]?.[tokensSorted[0].address], ...state?.[tokensSorted[0].chainId]['addresses'],
[tokensSorted[1].address]: Pair.getAddress(tokensSorted[0], tokensSorted[1]) [tokensSorted[0].address]: {
...state?.[tokensSorted[0].chainId]?.[tokensSorted[0].address],
[tokensSorted[1].address]: Pair.getAddress(tokensSorted[0], tokensSorted[1])
}
}
}
}
}
case UPDATE_PAIR_ENTITY: {
const { pairAddress, pair, chainId } = payload
return {
...state,
[chainId]: {
...state?.[chainId],
entities: {
...state?.[chainId]?.['entities'],
[pairAddress]: pair
} }
} }
} }
...@@ -73,8 +94,16 @@ export default function Provider({ children }) { ...@@ -73,8 +94,16 @@ export default function Provider({ children }) {
dispatch({ type: UPDATE, payload: { chainId, tokens } }) dispatch({ type: UPDATE, payload: { chainId, tokens } })
}, []) }, [])
const updatePairEntity = useCallback((pairAddress, pair, chainId) => {
dispatch({ type: UPDATE_PAIR_ENTITY, payload: { pairAddress, pair, chainId } })
}, [])
return ( return (
<PairContext.Provider value={useMemo(() => [state, { update }], [state, update])}>{children}</PairContext.Provider> <PairContext.Provider
value={useMemo(() => [state, { update, updatePairEntity }], [state, update, updatePairEntity])}
>
{children}
</PairContext.Provider>
) )
} }
...@@ -84,7 +113,7 @@ export function usePairAddress(tokenA?: Token, tokenB?: Token): string | undefin ...@@ -84,7 +113,7 @@ export function usePairAddress(tokenA?: Token, tokenB?: Token): string | undefin
const tokens: [Token, Token] = tokenA && tokenB && tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] const tokens: [Token, Token] = tokenA && tokenB && tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA]
const address = state?.[chainId]?.[tokens[0]?.address]?.[tokens[1]?.address] const address = state?.[chainId]?.['addresses']?.[tokens[0]?.address]?.[tokens[1]?.address]
useEffect(() => { useEffect(() => {
if (address === undefined && tokenA && tokenB) { if (address === undefined && tokenA && tokenB) {
...@@ -97,36 +126,29 @@ export function usePairAddress(tokenA?: Token, tokenB?: Token): string | undefin ...@@ -97,36 +126,29 @@ export function usePairAddress(tokenA?: Token, tokenB?: Token): string | undefin
} }
export function usePair(tokenA?: Token, tokenB?: Token): Pair | undefined { export function usePair(tokenA?: Token, tokenB?: Token): Pair | undefined {
const { chainId } = useWeb3React()
const [state, { updatePairEntity }] = usePairContext()
const address = usePairAddress(tokenA, tokenB) const address = usePairAddress(tokenA, tokenB)
const pair = state?.[chainId]?.['entities']?.[address]
const tokenAmountA = useAddressBalance(address, tokenA) const tokenAmountA = useAddressBalance(address, tokenA)
const tokenAmountB = useAddressBalance(address, tokenB) const tokenAmountB = useAddressBalance(address, tokenB)
const [pair, setPair] = useState<Pair>()
useEffect(() => { useEffect(() => {
if (!pair && tokenAmountA && tokenAmountB) { if (!pair && tokenAmountA && tokenAmountB) {
setPair(new Pair(tokenAmountA, tokenAmountB)) updatePairEntity(address, new Pair(tokenAmountA, tokenAmountB), chainId)
} }
}, [pair, tokenAmountA, tokenAmountB]) }, [pair, tokenAmountA, tokenAmountB, address, updatePairEntity, chainId])
return useMemo(() => { return pair
return pair
}, [pair])
}
export function useAllPairsRaw() {
const { chainId } = useWeb3React()
const [state] = usePairContext()
const allExchangeDetails = state?.[chainId]
return allExchangeDetails
} }
export function useAllPairs() { export function useAllPairs() {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const [state] = usePairContext() const [state] = usePairContext()
const allPairDetails = state?.[chainId] const allPairDetails = state?.[chainId]?.['addresses']
const allPairs = useMemo(() => { const allPairs = useMemo(() => {
if (!allPairDetails) { if (!allPairDetails) {
...@@ -136,10 +158,14 @@ export function useAllPairs() { ...@@ -136,10 +158,14 @@ export function useAllPairs() {
Object.keys(allPairDetails).map(token0Address => { Object.keys(allPairDetails).map(token0Address => {
return Object.keys(allPairDetails[token0Address]).map(token1Address => { return Object.keys(allPairDetails[token0Address]).map(token1Address => {
const pairAddress = allPairDetails[token0Address][token1Address] const pairAddress = allPairDetails[token0Address][token1Address]
return (formattedExchanges[pairAddress] = { if (pairAddress) {
token0: token0Address, return (formattedExchanges[pairAddress] = {
token1: token1Address token0: token0Address,
}) token1: token1Address
})
} else {
return null
}
}) })
}) })
return formattedExchanges return formattedExchanges
......
...@@ -30,7 +30,7 @@ function reducer(state: RouteState, { type, payload }) { ...@@ -30,7 +30,7 @@ function reducer(state: RouteState, { type, payload }) {
[chainId]: { [chainId]: {
...state[chainId], ...state[chainId],
[tokens[0]]: { [tokens[0]]: {
...state[tokens[0]], ...state[chainId]?.[tokens[0]],
[tokens[1]]: { [tokens[1]]: {
route route
} }
...@@ -77,14 +77,14 @@ export function useRoute(tokenA: Token, tokenB: Token) { ...@@ -77,14 +77,14 @@ export function useRoute(tokenA: Token, tokenB: Token) {
const defaultPair = usePair(tokenA, tokenB) const defaultPair = usePair(tokenA, tokenB)
// get token<->WETH pairs // get token<->WETH pairs
const aToETH = usePair(tokenA && !tokenA.equals(WETH[chainId]) ? tokenA : null, WETH[chainId]) const aToETH = usePair(tokenA && chainId && !tokenA.equals(WETH[chainId]) ? tokenA : null, WETH[chainId])
const bToETH = usePair(tokenB && !tokenB.equals(WETH[chainId]) ? tokenB : null, WETH[chainId]) const bToETH = usePair(tokenB && chainId && !tokenB.equals(WETH[chainId]) ? tokenB : null, WETH[chainId])
// needs to route through WETH // needs to route through WETH
const requiresHop = const requiresHop =
defaultPair && defaultPair &&
JSBI.equal(defaultPair.reserve0.raw, JSBI.BigInt(0)) && JSBI.equal(defaultPair?.reserve0?.raw, JSBI.BigInt(0)) &&
JSBI.equal(defaultPair.reserve1.raw, JSBI.BigInt(0)) JSBI.equal(defaultPair?.reserve1?.raw, JSBI.BigInt(0))
useEffect(() => { useEffect(() => {
if (!route && tokenA && tokenB) { if (!route && tokenA && tokenB) {
......
...@@ -6,6 +6,9 @@ import { isAddress, getTokenName, getTokenSymbol, getTokenDecimals, safeAccess } ...@@ -6,6 +6,9 @@ import { isAddress, getTokenName, getTokenSymbol, getTokenDecimals, safeAccess }
const UPDATE = 'UPDATE' const UPDATE = 'UPDATE'
export const ALL_TOKENS = [ export const ALL_TOKENS = [
//Mainnet Tokens
WETH[ChainId.MAINNET],
// Rinkeby Tokens // Rinkeby Tokens
WETH[ChainId.RINKEBY], WETH[ChainId.RINKEBY],
new Token(ChainId.RINKEBY, '0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735', 18, 'DAI', 'Dai Stablecoin'), new Token(ChainId.RINKEBY, '0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735', 18, 'DAI', 'Dai Stablecoin'),
......
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react' import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
import TxnPopup from '../components/TxnPopup'
import { useWeb3React } from '../hooks' import { useWeb3React } from '../hooks'
import { safeAccess } from '../utils' import { safeAccess } from '../utils'
import { useBlockNumber } from './Application' import { useBlockNumber, usePopups } from './Application'
const RESPONSE = 'response' const RESPONSE = 'response'
const CUSTOM_DATA = 'CUSTOM_DATA' const CUSTOM_DATA = 'CUSTOM_DATA'
...@@ -110,6 +112,9 @@ export function Updater() { ...@@ -110,6 +112,9 @@ export function Updater() {
const [state, { check, finalize }] = useTransactionsContext() const [state, { check, finalize }] = useTransactionsContext()
const allTransactions = safeAccess(state, [chainId]) || {} const allTransactions = safeAccess(state, [chainId]) || {}
// show popup on confirm
const [, addPopup] = usePopups()
useEffect(() => { useEffect(() => {
if ((chainId || chainId === 0) && library) { if ((chainId || chainId === 0) && library) {
let stale = false let stale = false
...@@ -126,6 +131,7 @@ export function Updater() { ...@@ -126,6 +131,7 @@ 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} />)
} }
} }
}) })
...@@ -138,7 +144,7 @@ export function Updater() { ...@@ -138,7 +144,7 @@ export function Updater() {
stale = true stale = true
} }
} }
}, [chainId, library, allTransactions, globalBlockNumber, check, finalize]) }, [chainId, library, allTransactions, globalBlockNumber, check, finalize, addPopup])
return null return null
} }
......
import React, { Suspense, lazy } from 'react' import React, { Suspense, lazy, useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { transparentize } from 'polished'
import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom' import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom'
import { Text } from 'rebass'
import Header from '../components/Header' import Header from '../components/Header'
import NavigationTabs from '../components/NavigationTabs' import NavigationTabs from '../components/NavigationTabs'
import Web3ReactManager from '../components/Web3ReactManager' import Web3ReactManager from '../components/Web3ReactManager'
import { useWeb3React } from '../hooks' import { TYPE } from '../theme'
import { Hover } from '../theme/components'
import { AutoColumn } from '../components/Column'
import { PinkCard } from '../components/Card'
import { ButtonPink } from '../components/Button'
import { isAddress, getAllQueryParams } from '../utils' import { isAddress, getAllQueryParams } from '../utils'
const Swap = lazy(() => import('./Swap')) const Swap = lazy(() => import('./Swap'))
...@@ -29,29 +33,6 @@ const HeaderWrapper = styled.div` ...@@ -29,29 +33,6 @@ const HeaderWrapper = styled.div`
justify-content: space-between; justify-content: space-between;
` `
const BetaMessage = styled.div`
${({ theme }) => theme.flexRowNoWrap}
cursor: pointer;
max-height: 40px;
flex: 1 0 auto;
align-items: center;
position: relative;
padding: 0.5rem 1rem;
margin-bottom: 1rem;
border: 1px solid ${({ theme }) => transparentize(0.6, theme.pink1)};
background-color: ${({ theme }) => transparentize(0.9, theme.pink1)};
border-radius: 1rem;
font-size: 0.75rem;
line-height: 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: ${({ theme }) => theme.pink1};
min-width: 380px;
text-align: center;
justify-content: center;
`
const BodyWrapper = styled.div` const BodyWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -61,6 +42,12 @@ const BodyWrapper = styled.div` ...@@ -61,6 +42,12 @@ const BodyWrapper = styled.div`
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding-top: 40px; padding-top: 40px;
& > * {
max-width: calc(355px + 4rem);
width: 90%;
margin-bottom: 20px;
}
` `
const Body = styled.div` const Body = styled.div`
...@@ -76,7 +63,7 @@ const Body = styled.div` ...@@ -76,7 +63,7 @@ const Body = styled.div`
export default function App() { export default function App() {
const params = getAllQueryParams() const params = getAllQueryParams()
const { chainId } = useWeb3React() const [showMigrationMessage, toggleShowMigrationMessage] = useState(true)
return ( return (
<> <>
...@@ -86,17 +73,18 @@ export default function App() { ...@@ -86,17 +73,18 @@ export default function App() {
<Header /> <Header />
</HeaderWrapper> </HeaderWrapper>
<BodyWrapper> <BodyWrapper>
{chainId === 1 && ( {showMigrationMessage && (
<BetaMessage>Incorrect network. This site is intended to be used on Ethereum testnets only.</BetaMessage> <PinkCard padding="20px">
)} <AutoColumn justify={'center'} gap={'20px'}>
<TYPE.largeHeader>Uniswap has upgraded.</TYPE.largeHeader>
{(chainId === 3 || chainId === 4 || chainId === 5 || chainId === 42) && ( <Text textAlign="center">Are you a liquidity provider? Upgrade now using the migration helper.</Text>
<BetaMessage> <ButtonPink width={'265px'}>Migrate your liquidity </ButtonPink>
Connected to{' '} <Hover onClick={() => toggleShowMigrationMessage(false)}>
{chainId === 3 ? 'Ropsten ' : chainId === 4 ? 'Rinkeby' : chainId === 5 ? 'Goerli' : 'Kovan'} testnet. <Text textAlign="center">Dismiss</Text>
</BetaMessage> </Hover>
</AutoColumn>
</PinkCard>
)} )}
<Body> <Body>
<Web3ReactManager> <Web3ReactManager>
<BrowserRouter> <BrowserRouter>
...@@ -138,7 +126,7 @@ export default function App() { ...@@ -138,7 +126,7 @@ export default function App() {
} }
}} }}
/> />
<Route exaxct path={'/supply'} component={() => <Pool params={params} />} /> <Route exaxct path={'/pool'} component={() => <Pool params={params} />} />
<Route <Route
exact exact
strict strict
...@@ -154,7 +142,7 @@ export default function App() { ...@@ -154,7 +142,7 @@ export default function App() {
if (t0 && t1) { if (t0 && t1) {
return <Add params={params} token0={t0} token1={t1} /> return <Add params={params} token0={t0} token1={t1} />
} else { } else {
return <Redirect to={{ pathname: '/supply' }} /> return <Redirect to={{ pathname: '/pool' }} />
} }
}} }}
/> />
...@@ -173,7 +161,7 @@ export default function App() { ...@@ -173,7 +161,7 @@ export default function App() {
if (t0 && t1) { if (t0 && t1) {
return <Remove params={params} token0={t0} token1={t1} /> return <Remove params={params} token0={t0} token1={t1} />
} else { } else {
return <Redirect to={{ pathname: '/supply' }} /> return <Redirect to={{ pathname: '/pool' }} />
} }
}} }}
/> />
......
...@@ -11,23 +11,23 @@ import PositionCard from '../../components/PositionCard' ...@@ -11,23 +11,23 @@ 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 { TYPE } from '../../theme'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { ButtonPrimary } from '../../components/Button'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { ButtonPrimary, ButtonLight } from '../../components/Button'
import Row, { RowBetween, RowFlat, RowFixed } from '../../components/Row' import Row, { RowBetween, RowFlat, RowFixed } from '../../components/Row'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
import { usePopups } from '../../contexts/Application' import { usePopups } from '../../contexts/Application'
import { useWeb3React } from '../../hooks'
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 { usePair, useTotalSupply } from '../../contexts/Pairs' import { usePair, useTotalSupply } from '../../contexts/Pairs'
import { useWeb3React, useTokenContract } from '../../hooks'
import { useTransactionAdder, usePendingApproval } from '../../contexts/Transactions'
import { BigNumber } from 'ethers/utils' import { BigNumber } from 'ethers/utils'
import { ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
import { TYPE } from '../../theme'
// denominated in bips // denominated in bips
const ALLOWED_SLIPPAGE = 200 const ALLOWED_SLIPPAGE = 200
...@@ -43,7 +43,7 @@ const Wrapper = styled.div` ...@@ -43,7 +43,7 @@ const Wrapper = styled.div`
const FixedBottom = styled.div` const FixedBottom = styled.div`
position: absolute; position: absolute;
bottom: -200px; bottom: -220px;
width: 100%; width: 100%;
` `
...@@ -158,6 +158,14 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -158,6 +158,14 @@ export default function AddLiquidity({ token0, token1 }) {
[Field.OUTPUT]: useToken(fieldData[Field.OUTPUT].address) [Field.OUTPUT]: useToken(fieldData[Field.OUTPUT].address)
} }
// token contracts for approvals and direct sends
const tokenContractInput: ethers.Contract = useTokenContract(tokens[Field.INPUT]?.address)
const tokenContractOutput: ethers.Contract = useTokenContract(tokens[Field.OUTPUT]?.address)
// check on pending approvals for token amounts
const pendingApprovalInput = usePendingApproval(tokens[Field.INPUT]?.address)
const pendingApprovalOutput = usePendingApproval(tokens[Field.OUTPUT]?.address)
// exhchange data // exhchange data
const pair: Pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT]) const pair: Pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT])
const route: Route = pair ? new Route([pair], tokens[independentField]) : undefined const route: Route = pair ? new Route([pair], tokens[independentField]) : undefined
...@@ -456,6 +464,28 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -456,6 +464,28 @@ export default function AddLiquidity({ token0, token1 }) {
}) })
} }
async function approveAmount(field) {
let estimatedGas
let useUserBalance = false
const tokenContract = field === Field.INPUT ? tokenContractInput : tokenContractOutput
estimatedGas = await tokenContract.estimate.approve(routerAddress, ethers.constants.MaxUint256).catch(e => {
console.log('Error setting max token approval.')
})
if (!estimatedGas) {
// general fallback for tokens who restrict approval amounts
estimatedGas = await tokenContract.estimate.approve(routerAddress, userBalances[field])
useUserBalance = true
}
tokenContract
.approve(routerAddress, useUserBalance ? userBalances[field] : ethers.constants.MaxUint256, {
gasLimit: calculateGasMargin(estimatedGas, GAS_MARGIN)
})
.then(response => {
addTransaction(response, { approval: tokens[field]?.address })
})
}
const modalHeader = () => { const modalHeader = () => {
return ( return (
<AutoColumn gap="20px"> <AutoColumn gap="20px">
...@@ -569,7 +599,6 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -569,7 +599,6 @@ export default function AddLiquidity({ token0, token1 }) {
onTokenSelection={onTokenSelection} onTokenSelection={onTokenSelection}
error={inputError} error={inputError}
pair={pair} pair={pair}
showUnlock={showInputUnlock}
disableTokenSelect disableTokenSelect
/> />
<ColumnCenter> <ColumnCenter>
...@@ -587,7 +616,6 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -587,7 +616,6 @@ export default function AddLiquidity({ token0, token1 }) {
onTokenSelection={onTokenSelection} onTokenSelection={onTokenSelection}
error={outputError} error={outputError}
pair={pair} pair={pair}
showUnlock={showOutputUnlock}
disableTokenSelect disableTokenSelect
/> />
{!noLiquidity && ( {!noLiquidity && (
...@@ -599,16 +627,34 @@ export default function AddLiquidity({ token0, token1 }) { ...@@ -599,16 +627,34 @@ export default function AddLiquidity({ token0, token1 }) {
</div> </div>
</RowBetween> </RowBetween>
)} )}
<ButtonPrimary {showOutputUnlock ? (
onClick={() => { <ButtonLight
setShowConfirm(true) onClick={() => {
}} approveAmount(Field.OUTPUT)
disabled={!isValid} }}
> >
<Text fontSize={20} fontWeight={500}> {pendingApprovalOutput ? 'Waiting for unlock' : 'Unlock ' + tokens[Field.OUTPUT]?.symbol}
{generalError ? generalError : inputError ? inputError : outputError ? outputError : 'Supply'} </ButtonLight>
</Text> ) : showInputUnlock ? (
</ButtonPrimary> <ButtonLight
onClick={() => {
approveAmount(Field.INPUT)
}}
>
{pendingApprovalInput ? 'Waiting for unlock' : 'Unlock ' + tokens[Field.INPUT]?.symbol}
</ButtonLight>
) : (
<ButtonPrimary
onClick={() => {
setShowConfirm(true)
}}
disabled={!isValid}
>
<Text fontSize={20} fontWeight={500}>
{generalError ? generalError : inputError ? inputError : outputError ? outputError : 'Supply'}
</Text>
</ButtonPrimary>
)}
{!noLiquidity && ( {!noLiquidity && (
<FixedBottom> <FixedBottom>
<PositionCard <PositionCard
......
...@@ -10,6 +10,7 @@ import DoubleLogo from '../../components/DoubleLogo' ...@@ -10,6 +10,7 @@ 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 { TYPE } from '../../theme'
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'
...@@ -29,7 +30,6 @@ import { BigNumber } from 'ethers/utils' ...@@ -29,7 +30,6 @@ import { BigNumber } from 'ethers/utils'
import { splitSignature } from '@ethersproject/bytes' import { splitSignature } from '@ethersproject/bytes'
import { ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { getRouterContract, calculateGasMargin } from '../../utils' import { getRouterContract, calculateGasMargin } from '../../utils'
import { TYPE } from '../../theme'
// denominated in seconds // denominated in seconds
const DEADLINE_FROM_NOW = 60 * 15 const DEADLINE_FROM_NOW = 60 * 15
...@@ -42,7 +42,7 @@ const Wrapper = styled.div` ...@@ -42,7 +42,7 @@ const Wrapper = styled.div`
const FixedBottom = styled.div` const FixedBottom = styled.div`
position: absolute; position: absolute;
bottom: -200px; bottom: -220px;
width: 100%; width: 100%;
` `
......
...@@ -3,15 +3,13 @@ import styled from 'styled-components' ...@@ -3,15 +3,13 @@ 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 Card from '../../components/Card'
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 { 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 { RowBetween } from '../../components/Row'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { useAllPairs } from '../../contexts/Pairs' import { useAllPairs } from '../../contexts/Pairs'
...@@ -23,11 +21,6 @@ const Positions = styled.div` ...@@ -23,11 +21,6 @@ const Positions = styled.div`
position: relative; position: relative;
margin-top: 38px; margin-top: 38px;
` `
const FixedBottom = styled.div`
position: absolute;
bottom: -260px;
width: 100%;
`
function Supply({ history }) { function Supply({ history }) {
const { account } = useWeb3React() const { account } = useWeb3React()
...@@ -40,6 +33,8 @@ function Supply({ history }) { ...@@ -40,6 +33,8 @@ function Supply({ history }) {
// initiate listener for LP balances // initiate listener for LP balances
useAccountLPBalances(account) useAccountLPBalances(account)
// console.log(allPairs)
const filteredExchangeList = Object.keys(allPairs) const filteredExchangeList = Object.keys(allPairs)
.filter((pairAddress, i) => { .filter((pairAddress, i) => {
return ( return (
...@@ -67,7 +62,7 @@ function Supply({ history }) { ...@@ -67,7 +62,7 @@ function Supply({ history }) {
setShowPoolSearch(true) setShowPoolSearch(true)
}} }}
> >
<Text fontSize={20}>Join a pool</Text> <Text fontSize={20}>Join {filteredExchangeList?.length > 0 ? 'another' : 'a'} pool</Text>
</ButtonPrimary> </ButtonPrimary>
<Positions> <Positions>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
...@@ -80,34 +75,17 @@ function Supply({ history }) { ...@@ -80,34 +75,17 @@ function Supply({ history }) {
{filteredExchangeList} {filteredExchangeList}
<AutoColumn justify="center"> <AutoColumn justify="center">
<Text color="#AEAEAE"> <Text color="#AEAEAE">
{filteredExchangeList?.length !== 0 ? `Don't see your ` : 'Already have '} liquidity?{' '} {filteredExchangeList?.length !== 0 ? `Don't see a pool you joined? ` : 'Already joined a pool?'}{' '}
<Link <Link
onClick={() => { onClick={() => {
history.push('/find') history.push('/find')
}} }}
> >
Find it now. Find it.
</Link> </Link>
</Text> </Text>
</AutoColumn> </AutoColumn>
</AutoColumn> </AutoColumn>
<FixedBottom>
<Card bg="rgba(255, 255, 255, 0.6)" padding={'24px'}>
<AutoColumn gap="30px">
<Text fontSize="20px" fontWeight={500}>
Earn fees with pooled market making.
</Text>
<Text fontSize="12px">
<Link>Provide liquidity </Link>to earn .3% spread fees for providing market depth.
</Text>
<Link>
<Row>
Learn More <ArrowRight size="16" />
</Row>
</Link>
</AutoColumn>
</Card>
</FixedBottom>
</Positions> </Positions>
<SearchModal isOpen={showPoolSearch} onDismiss={() => setShowPoolSearch(false)} /> <SearchModal isOpen={showPoolSearch} onDismiss={() => setShowPoolSearch(false)} />
</> </>
......
...@@ -71,3 +71,9 @@ export const Spinner = styled.img` ...@@ -71,3 +71,9 @@ export const Spinner = styled.img`
width: 16px; width: 16px;
height: 16px; height: 16px;
` `
export const Hover = styled.div`
:hover {
cursor: pointer;
}
`
...@@ -75,6 +75,7 @@ const theme = darkMode => ({ ...@@ -75,6 +75,7 @@ const theme = darkMode => ({
red1: '#FF6871', red1: '#FF6871',
green1: '#27AE60', green1: '#27AE60',
yellow1: '#FFE270', yellow1: '#FFE270',
yellow2: '#F3841E',
//shadows //shadows
shadow1: darkMode ? '#000' : '#2F80ED', shadow1: darkMode ? '#000' : '#2F80ED',
...@@ -99,7 +100,17 @@ export const TYPE = { ...@@ -99,7 +100,17 @@ export const TYPE = {
</Text> </Text>
), ),
largeHeader: ({ children, ...rest }) => ( largeHeader: ({ children, ...rest }) => (
<Text fontWeight={600} fontSize={24} color={theme().black} {...rest}> <Text fontWeight={600} fontSize={24} {...rest}>
{children}
</Text>
),
mediumHeader: ({ children, ...rest }) => (
<Text fontWeight={500} fontSize={20} color={theme().text1} {...rest}>
{children}
</Text>
),
subHeader: ({ children, ...rest }) => (
<Text fontWeight={400} fontSize={14} color={theme().text1} {...rest}>
{children} {children}
</Text> </Text>
), ),
...@@ -113,6 +124,11 @@ export const TYPE = { ...@@ -113,6 +124,11 @@ export const TYPE = {
{children} {children}
</Text> </Text>
), ),
green: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().green1} {...rest}>
{children}
</Text>
),
gray: ({ children, ...rest }) => ( gray: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().bg3} {...rest}> <Text fontWeight={500} color={theme().bg3} {...rest}>
{children} {children}
......
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