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:
Noah Zinsmeister 2019-06-14 10:39:33 -04:00 committed by GitHub
parent 58804714be
commit 727d289413
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 65 additions and 37 deletions

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) {
independentValue: '', // this is a user input return {
dependentValue: '', // this is a calculated number independentValue: '', // this is a user input
independentField: INPUT, dependentValue: '', // this is a calculated number
inputCurrency: 'ETH', independentField: INPUT,
outputCurrency: '' inputCurrency: 'ETH',
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) {
independentValue: '', // this is a user input return {
dependentValue: '', // this is a calculated number independentValue: '', // this is a user input
independentField: INPUT, dependentValue: '', // this is a calculated number
inputCurrency: 'ETH', independentField: INPUT,
outputCurrency: '' inputCurrency: 'ETH',
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