modal responsiveness, 1 token addition, token selection (#329)
* improve modal responsiveness * add MATIC * fix modal min height reversion * add token population via route
This commit is contained in:
parent
58804714be
commit
727d289413
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,6 +17,8 @@
|
|||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
|
||||||
|
/.netlify
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html />
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
@ -7,6 +7,7 @@ import escapeStringRegex from 'escape-string-regexp'
|
|||||||
import { lighten, darken } from 'polished'
|
import { lighten, darken } from 'polished'
|
||||||
import Tooltip from '@reach/tooltip'
|
import Tooltip from '@reach/tooltip'
|
||||||
import '@reach/tooltip/styles.css'
|
import '@reach/tooltip/styles.css'
|
||||||
|
import { isMobile } from 'react-device-detect'
|
||||||
|
|
||||||
import { BorderlessInput } from '../../theme'
|
import { BorderlessInput } from '../../theme'
|
||||||
import { useTokenContract } from '../../hooks'
|
import { useTokenContract } from '../../hooks'
|
||||||
@ -166,6 +167,7 @@ const TokenList = styled.div`
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
`
|
`
|
||||||
|
|
||||||
const TokenModalRow = styled.div`
|
const TokenModalRow = styled.div`
|
||||||
@ -427,7 +429,7 @@ function CurrencySelectModal({ isOpen, onDismiss, onTokenSelect }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onDismiss={onDismiss} initialFocusRef={inputRef}>
|
<Modal isOpen={isOpen} onDismiss={onDismiss} minHeight={50} initialFocusRef={isMobile ? undefined : inputRef}>
|
||||||
<TokenModal>
|
<TokenModal>
|
||||||
<SearchContainer>
|
<SearchContainer>
|
||||||
<StyledBorderlessInput ref={inputRef} type="text" placeholder={t('searchOrPaste')} onChange={onInput} />
|
<StyledBorderlessInput ref={inputRef} type="text" placeholder={t('searchOrPaste')} onChange={onInput} />
|
||||||
|
@ -24,16 +24,16 @@ const StyledDialogContent = styled(FilteredDialogContent)`
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
width: 50vw;
|
width: 50vw;
|
||||||
max-width: 650px;
|
max-width: 650px;
|
||||||
${({ theme }) => theme.mediaWidth.upToMedium`width: 75vw;`}
|
${({ theme }) => theme.mediaWidth.upToMedium`width: 65vw;`}
|
||||||
${({ theme }) => theme.mediaWidth.upToSmall`width: 90vw;`}
|
${({ theme }) => theme.mediaWidth.upToSmall`width: 80vw;`}
|
||||||
|
max-height: 50vh;
|
||||||
${({ minHeight }) =>
|
${({ minHeight }) =>
|
||||||
minHeight &&
|
minHeight &&
|
||||||
css`
|
css`
|
||||||
min-height: ${minHeight}vh;
|
min-height: ${minHeight}vh;
|
||||||
`}
|
`}
|
||||||
max-height: 50vh;
|
${({ theme }) => theme.mediaWidth.upToMedium`max-height: 65vh;`}
|
||||||
${({ theme }) => theme.mediaHeight.upToMedium`max-height: 75vh;`}
|
${({ theme }) => theme.mediaWidth.upToSmall`max-height: 80vh;`}
|
||||||
${({ theme }) => theme.mediaHeight.upToSmall`max-height: 90vh;`}
|
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 1.5rem;
|
border-radius: 1.5rem;
|
||||||
@ -48,7 +48,7 @@ const HiddenCloseButton = styled.button`
|
|||||||
border: none;
|
border: none;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function Modal({ isOpen, onDismiss, minHeight = 50, initialFocusRef, children }) {
|
export default function Modal({ isOpen, onDismiss, minHeight = false, initialFocusRef, children }) {
|
||||||
const transitions = useTransition(isOpen, null, {
|
const transitions = useTransition(isOpen, null, {
|
||||||
config: { duration: 125 },
|
config: { duration: 125 },
|
||||||
from: { opacity: 0 },
|
from: { opacity: 0 },
|
||||||
|
@ -167,6 +167,12 @@ const INITIAL_TOKENS_CONTEXT = {
|
|||||||
[DECIMALS]: 18,
|
[DECIMALS]: 18,
|
||||||
[EXCHANGE_ADDRESS]: '0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2'
|
[EXCHANGE_ADDRESS]: '0xC6581Ce3A005e2801c1e0903281BBd318eC5B5C2'
|
||||||
},
|
},
|
||||||
|
'0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0': {
|
||||||
|
[NAME]: 'Matic Token',
|
||||||
|
[SYMBOL]: 'MATIC',
|
||||||
|
[DECIMALS]: 18,
|
||||||
|
[EXCHANGE_ADDRESS]: '0x9a7A75E66B325a3BD46973B2b57c9b8d9D26a621'
|
||||||
|
},
|
||||||
'0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2': {
|
'0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2': {
|
||||||
[NAME]: 'Maker',
|
[NAME]: 'Maker',
|
||||||
[SYMBOL]: 'MKR',
|
[SYMBOL]: 'MKR',
|
||||||
|
@ -5,6 +5,7 @@ import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom'
|
|||||||
import Web3ReactManager from '../components/Web3ReactManager'
|
import Web3ReactManager from '../components/Web3ReactManager'
|
||||||
import Header from '../components/Header'
|
import Header from '../components/Header'
|
||||||
import NavigationTabs from '../components/NavigationTabs'
|
import NavigationTabs from '../components/NavigationTabs'
|
||||||
|
import { isAddress } from '../utils'
|
||||||
|
|
||||||
const Swap = lazy(() => import('./Swap'))
|
const Swap = lazy(() => import('./Swap'))
|
||||||
const Send = lazy(() => import('./Send'))
|
const Send = lazy(() => import('./Send'))
|
||||||
@ -46,7 +47,31 @@ export default function App() {
|
|||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact strict path="/swap" component={Swap} />
|
<Route exact strict path="/swap" component={Swap} />
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
strict
|
||||||
|
path="/swap/:tokenAddress?"
|
||||||
|
render={({ match }) => {
|
||||||
|
if (isAddress(match.params.tokenAddress)) {
|
||||||
|
return <Swap initialCurrency={isAddress(match.params.tokenAddress)} />
|
||||||
|
} else {
|
||||||
|
return <Redirect to={{ pathname: '/swap' }} />
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Route exact strict path="/send" component={Send} />
|
<Route exact strict path="/send" component={Send} />
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
strict
|
||||||
|
path="/send/:tokenAddress?"
|
||||||
|
render={({ match }) => {
|
||||||
|
if (isAddress(match.params.tokenAddress)) {
|
||||||
|
return <Send initialCurrency={isAddress(match.params.tokenAddress)} />
|
||||||
|
} else {
|
||||||
|
return <Redirect to={{ pathname: '/send' }} />
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={[
|
path={[
|
||||||
'/add-liquidity',
|
'/add-liquidity',
|
||||||
|
@ -116,7 +116,6 @@ function ModeSelector({ location: { pathname }, history }) {
|
|||||||
onDismiss={() => {
|
onDismiss={() => {
|
||||||
setModalIsOpen(false)
|
setModalIsOpen(false)
|
||||||
}}
|
}}
|
||||||
minHeight={null}
|
|
||||||
>
|
>
|
||||||
<PoolModal>
|
<PoolModal>
|
||||||
{poolTabOrder.map(({ path, textKey, regex }) => (
|
{poolTabOrder.map(({ path, textKey, regex }) => (
|
||||||
|
@ -123,12 +123,14 @@ function calculateEtherTokenInputFromOutput(outputAmount, inputReserve, outputRe
|
|||||||
return numerator.div(denominator).add(ethers.constants.One)
|
return numerator.div(denominator).add(ethers.constants.One)
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialSwapState = {
|
function getInitialSwapState(outputCurrency) {
|
||||||
|
return {
|
||||||
independentValue: '', // this is a user input
|
independentValue: '', // this is a user input
|
||||||
dependentValue: '', // this is a calculated number
|
dependentValue: '', // this is a calculated number
|
||||||
independentField: INPUT,
|
independentField: INPUT,
|
||||||
inputCurrency: 'ETH',
|
inputCurrency: 'ETH',
|
||||||
outputCurrency: ''
|
outputCurrency: outputCurrency ? outputCurrency : ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function swapStateReducer(state, action) {
|
function swapStateReducer(state, action) {
|
||||||
@ -180,7 +182,7 @@ function swapStateReducer(state, action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return initialSwapState
|
return getInitialSwapState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,7 +238,7 @@ function getMarketRate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Swap() {
|
export default function Swap({ initialCurrency }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { account } = useWeb3Context()
|
const { account } = useWeb3Context()
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ export default function Swap() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// core swap state
|
// core swap state
|
||||||
const [swapState, dispatchSwapState] = useReducer(swapStateReducer, initialSwapState)
|
const [swapState, dispatchSwapState] = useReducer(swapStateReducer, initialCurrency, getInitialSwapState)
|
||||||
const { independentValue, dependentValue, independentField, inputCurrency, outputCurrency } = swapState
|
const { independentValue, dependentValue, independentField, inputCurrency, outputCurrency } = swapState
|
||||||
|
|
||||||
const [recipient, setRecipient] = useState({ address: '', name: '' })
|
const [recipient, setRecipient] = useState({ address: '', name: '' })
|
||||||
|
@ -122,12 +122,14 @@ function calculateEtherTokenInputFromOutput(outputAmount, inputReserve, outputRe
|
|||||||
return numerator.div(denominator).add(ethers.constants.One)
|
return numerator.div(denominator).add(ethers.constants.One)
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialSwapState = {
|
function getInitialSwapState(outputCurrency) {
|
||||||
|
return {
|
||||||
independentValue: '', // this is a user input
|
independentValue: '', // this is a user input
|
||||||
dependentValue: '', // this is a calculated number
|
dependentValue: '', // this is a calculated number
|
||||||
independentField: INPUT,
|
independentField: INPUT,
|
||||||
inputCurrency: 'ETH',
|
inputCurrency: 'ETH',
|
||||||
outputCurrency: ''
|
outputCurrency: outputCurrency ? outputCurrency : ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function swapStateReducer(state, action) {
|
function swapStateReducer(state, action) {
|
||||||
@ -180,7 +182,7 @@ function swapStateReducer(state, action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return initialSwapState
|
return getInitialSwapState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,7 +238,7 @@ function getMarketRate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Swap() {
|
export default function Swap({ initialCurrency }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { account } = useWeb3Context()
|
const { account } = useWeb3Context()
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ export default function Swap() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// core swap state
|
// core swap state
|
||||||
const [swapState, dispatchSwapState] = useReducer(swapStateReducer, initialSwapState)
|
const [swapState, dispatchSwapState] = useReducer(swapStateReducer, initialCurrency, getInitialSwapState)
|
||||||
const { independentValue, dependentValue, independentField, inputCurrency, outputCurrency } = swapState
|
const { independentValue, dependentValue, independentField, inputCurrency, outputCurrency } = swapState
|
||||||
|
|
||||||
// get swap type from the currency types
|
// get swap type from the currency types
|
||||||
|
@ -18,15 +18,6 @@ const mediaWidthTemplates = Object.keys(MEDIA_WIDTHS).reduce((accumulator, size)
|
|||||||
return accumulator
|
return accumulator
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
const mediaHeightTemplates = Object.keys(MEDIA_WIDTHS).reduce((accumulator, size) => {
|
|
||||||
accumulator[size] = (...args) => css`
|
|
||||||
@media (max-height: ${MEDIA_WIDTHS[size] / (16 / 9)}px) {
|
|
||||||
${css(...args)}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
return accumulator
|
|
||||||
}, {})
|
|
||||||
|
|
||||||
const flexColumnNoWrap = css`
|
const flexColumnNoWrap = css`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
@ -64,7 +55,6 @@ const theme = {
|
|||||||
connectedGreen: '#27AE60',
|
connectedGreen: '#27AE60',
|
||||||
// media queries
|
// media queries
|
||||||
mediaWidth: mediaWidthTemplates,
|
mediaWidth: mediaWidthTemplates,
|
||||||
mediaHeight: mediaHeightTemplates,
|
|
||||||
// css snippets
|
// css snippets
|
||||||
flexColumnNoWrap,
|
flexColumnNoWrap,
|
||||||
flexRowNoWrap
|
flexRowNoWrap
|
||||||
|
Loading…
Reference in New Issue
Block a user