Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
3e299ff2
Unverified
Commit
3e299ff2
authored
Oct 26, 2018
by
Kenny Tran
Committed by
GitHub
Oct 26, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #85 from kennyt/design-feedback
Design feedback
parents
5987095e
ae9fa925
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
595 additions
and
85 deletions
+595
-85
dropup-blue.svg
src/assets/images/dropup-blue.svg
+3
-0
address-input-panel.scss
src/components/AddressInputPanel/address-input-panel.scss
+3
-1
currency-panel.scss
src/components/CurrencyInputPanel/currency-panel.scss
+9
-0
index.js
src/components/CurrencyInputPanel/index.js
+13
-2
header.scss
src/components/Header/header.scss
+2
-2
index.js
src/components/Header/index.js
+0
-5
index.js
src/components/TokenLogo/index.js
+14
-5
web3-status.scss
src/components/Web3Status/web3-status.scss
+1
-1
AddLiquidity.js
src/pages/Pool/AddLiquidity.js
+121
-18
index.js
src/pages/Send/index.js
+188
-25
index.js
src/pages/Swap/index.js
+196
-24
swap.scss
src/pages/Swap/swap.scss
+45
-2
No files found.
src/assets/images/dropup-blue.svg
0 → 100644
View file @
3e299ff2
<svg
width=
"12"
height=
"7"
viewBox=
"0 0 12 7"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
d=
"M11.4673 6L6.23364 1L0.999995 6"
stroke=
"#388DFF"
/>
</svg>
src/components/AddressInputPanel/address-input-panel.scss
View file @
3e299ff2
...
...
@@ -4,12 +4,14 @@
@extend
%col-nowrap
;
&
__input
{
font-size
:
.75
rem
;
font-size
:
1
rem
;
outline
:
none
;
border
:
none
;
flex
:
1
1
auto
;
width
:
0
;
color
:
$royal-blue
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
&
:
:
placeholder
{
color
:
$chalice-gray
;
...
...
src/components/CurrencyInputPanel/currency-panel.scss
View file @
3e299ff2
...
...
@@ -59,6 +59,15 @@
&
--error
{
color
:
$salmon-red
;
}
&
[
type
=
'number'
]
{
-moz-appearance
:textfield
;
}
&
:
:-
webkit-outer-spin-button
,
&::-
webkit-inner-spin-button
{
-webkit-appearance
:
none
;
}
}
&
__extra-text
{
...
...
src/components/CurrencyInputPanel/index.js
View file @
3e299ff2
...
...
@@ -210,15 +210,16 @@ class CurrencyInputPanel extends Component {
exchangeAddresses
:
{
fromToken
},
web3
,
disableUnlock
,
value
,
}
=
this
.
props
;
if
(
disableUnlock
||
!
selectedTokenAddress
||
selectedTokenAddress
===
'
ETH
'
)
{
return
;
}
const
{
value
,
decimals
,
label
}
=
selectors
().
getApprovals
(
selectedTokenAddress
,
account
,
fromToken
[
selectedTokenAddress
]);
const
{
value
:
allowance
,
decimals
,
label
}
=
selectors
().
getApprovals
(
selectedTokenAddress
,
account
,
fromToken
[
selectedTokenAddress
]);
if
(
!
label
||
value
.
isGreaterThan
(
BN
(
10
**
22
)))
{
if
(
!
label
||
allowance
.
isGreaterThanOrEqualTo
(
BN
(
value
*
10
**
decimals
||
0
)))
{
return
;
}
...
...
@@ -272,11 +273,21 @@ class CurrencyInputPanel extends Component {
<
div
className
=
"
currency-input-panel__input-row
"
>
<
input
type
=
"
number
"
min
=
"
0
"
className
=
{
classnames
(
'
currency-input-panel__input
'
,{
'
currency-input-panel__input--error
'
:
errorMessage
,
})}
placeholder
=
"
0.0
"
onChange
=
{
e
=>
onValueChange
(
e
.
target
.
value
)}
onKeyPress
=
{
e
=>
{
const
charCode
=
e
.
which
?
e
.
which
:
e
.
keyCode
;
// Prevent 'minus' character
if
(
charCode
===
45
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
}
}}
value
=
{
value
}
/
>
{
this
.
renderUnlockButton
()
}
...
...
src/components/Header/header.scss
View file @
3e299ff2
...
...
@@ -5,7 +5,7 @@
&
__top
{
@extend
%row-nowrap
;
padding
:
1
.5rem
;
padding
:
1
.5rem
1
.5rem
.5rem
1
.5rem
;
align-items
:
center
;
}
...
...
@@ -22,7 +22,7 @@
}
&
__navigation
{
margin
:
0
.75
rem
;
margin
-bottom
:
2
rem
;
}
&
--inactive
{
...
...
src/components/Header/index.js
View file @
3e299ff2
...
...
@@ -121,11 +121,6 @@ function Header (props) {
<
/div
>
<
Web3Status
isConnected
/>
<
/div
>
<
NavigationTabs
className
=
{
classnames
(
'
header__navigation
'
,
{
'
header--inactive
'
:
!
props
.
isConnected
,
})}
/
>
<
/div
>
)
}
...
...
src/components/TokenLogo/index.js
View file @
3e299ff2
...
...
@@ -3,6 +3,14 @@ import PropTypes from 'prop-types';
import
EthereumLogo
from
'
../../assets/images/ethereum-logo.png
'
;
import
GenericTokenLogo
from
'
../../assets/images/generic-token-logo.png
'
;
const
RINKEBY_TOKEN_MAP
=
{
'
0xDA5B056Cfb861282B4b59d29c9B395bcC238D29B
'
:
'
0x0d8775f648430679a709e98d2b0cb6250d2887ef
'
,
'
0x2448eE2641d78CC42D7AD76498917359D961A783
'
:
'
0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359
'
,
'
0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85
'
:
'
0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2
'
,
'
0x879884c3C46A24f56089f3bBbe4d5e38dB5788C0
'
:
'
0xd26114cd6ee289accf82350c8d8487fedb8a0c07
'
,
'
0xF22e3F33768354c9805d046af3C0926f27741B43
'
:
'
0xe41d2489571d322189246dafa5ebde1f4699f498
'
,
};
const
TOKEN_ICON_API
=
'
https://raw.githubusercontent.com/TrustWallet/tokens/master/images
'
;
const
BAD_IMAGES
=
{};
export
default
class
TokenLogo
extends
Component
{
...
...
@@ -14,7 +22,7 @@ export default class TokenLogo extends Component {
static
defaultProps
=
{
address
:
''
,
size
:
'
1
.5
rem
'
,
size
:
'
1rem
'
,
className
:
''
,
};
...
...
@@ -25,13 +33,14 @@ export default class TokenLogo extends Component {
render
()
{
const
{
address
,
size
,
className
}
=
this
.
props
;
let
path
=
GenericTokenLogo
;
const
mainAddress
=
RINKEBY_TOKEN_MAP
[
address
]
?
RINKEBY_TOKEN_MAP
[
address
]
:
address
;
if
(
a
ddress
===
'
ETH
'
)
{
if
(
mainA
ddress
===
'
ETH
'
)
{
path
=
EthereumLogo
;
}
if
(
!
this
.
state
.
error
&&
!
BAD_IMAGES
[
address
]
)
{
path
=
`
${
TOKEN_ICON_API
}
/
${
a
ddress
}
.png`
;
if
(
!
this
.
state
.
error
&&
!
BAD_IMAGES
[
mainAddress
]
&&
mainAddress
!==
'
ETH
'
)
{
path
=
`
${
TOKEN_ICON_API
}
/
${
mainA
ddress
}
.png`
;
}
return
(
...
...
@@ -44,7 +53,7 @@ export default class TokenLogo extends Component {
}}
onError
=
{()
=>
{
this
.
setState
({
error
:
true
});
BAD_IMAGES
[
a
ddress
]
=
true
;
BAD_IMAGES
[
mainA
ddress
]
=
true
;
}}
/
>
);
...
...
src/components/Web3Status/web3-status.scss
View file @
3e299ff2
...
...
@@ -7,7 +7,7 @@
line-height
:
1rem
;
align-items
:
center
;
border
:
1px
solid
$mercury-gray
;
padding
:
.5rem
1rem
;
padding
:
.5rem
;
border-radius
:
2rem
;
color
:
$dove-gray
;
font-weight
:
400
;
...
...
src/pages/Pool/AddLiquidity.js
View file @
3e299ff2
...
...
@@ -2,10 +2,15 @@ import React, { Component } from 'react';
import
{
drizzleConnect
}
from
'
drizzle-react
'
;
import
PropTypes
from
'
prop-types
'
;
import
classnames
from
"
classnames
"
;
import
{
CSSTransitionGroup
}
from
"
react-transition-group
"
;
import
CurrencyInputPanel
from
'
../../components/CurrencyInputPanel
'
;
import
OversizedPanel
from
'
../../components/OversizedPanel
'
;
import
NavigationTabs
from
'
../../components/NavigationTabs
'
;
import
Modal
from
'
../../components/Modal
'
;
import
{
selectors
,
sync
}
from
'
../../ducks/web3connect
'
;
import
ArrowDown
from
'
../../assets/images/arrow-down-blue.svg
'
;
import
DropdownBlue
from
"
../../assets/images/dropdown-blue.svg
"
;
import
DropupBlue
from
"
../../assets/images/dropup-blue.svg
"
;
import
ModeSelector
from
'
./ModeSelector
'
;
import
{
BigNumber
as
BN
}
from
'
bignumber.js
'
;
import
EXCHANGE_ABI
from
'
../../abi/exchange
'
;
...
...
@@ -32,11 +37,12 @@ class AddLiquidity extends Component {
inputCurrency
:
'
ETH
'
,
outputCurrency
:
''
,
lastEditedField
:
''
,
showSummaryModal
:
false
,
};
shouldComponentUpdate
(
nextProps
,
nextState
)
{
const
{
isConnected
,
account
,
exchangeAddresses
,
balances
,
web3
}
=
this
.
props
;
const
{
inputValue
,
outputValue
,
inputCurrency
,
outputCurrency
,
lastEditedField
}
=
this
.
state
;
const
{
inputValue
,
outputValue
,
inputCurrency
,
outputCurrency
,
lastEditedField
,
showSummaryModal
}
=
this
.
state
;
return
isConnected
!==
nextProps
.
isConnected
||
account
!==
nextProps
.
account
||
...
...
@@ -47,7 +53,8 @@ class AddLiquidity extends Component {
outputValue
!==
nextState
.
outputValue
||
inputCurrency
!==
nextState
.
inputCurrency
||
outputCurrency
!==
nextState
.
outputCurrency
||
lastEditedField
!==
nextState
.
lastEditedField
;
lastEditedField
!==
nextState
.
lastEditedField
||
showSummaryModal
!==
nextState
.
showSummaryModal
;
}
getBalance
(
currency
)
{
...
...
@@ -61,6 +68,27 @@ class AddLiquidity extends Component {
return
`Balance:
${
value
.
dividedBy
(
10
**
decimals
).
toFixed
(
4
)}
`
;
}
isUnapproved
()
{
const
{
account
,
exchangeAddresses
,
selectors
}
=
this
.
props
;
const
{
outputCurrency
,
outputValue
}
=
this
.
state
;
if
(
!
outputCurrency
)
{
return
false
;
}
const
{
value
:
allowance
,
label
,
decimals
}
=
selectors
().
getApprovals
(
outputCurrency
,
account
,
exchangeAddresses
.
fromToken
[
outputCurrency
]
);
if
(
label
&&
allowance
.
isLessThan
(
BN
(
outputValue
*
10
**
decimals
||
0
)))
{
return
true
;
}
return
false
;
}
onAddLiquidity
=
async
()
=>
{
const
{
account
,
web3
,
exchangeAddresses
:
{
fromToken
},
selectors
}
=
this
.
props
;
const
{
inputValue
,
outputValue
,
outputCurrency
}
=
this
.
state
;
...
...
@@ -155,8 +183,10 @@ class AddLiquidity extends Component {
let
inputError
;
let
outputError
;
let
isValid
=
true
;
const
inputIsZero
=
BN
(
inputValue
).
isZero
();
const
outputIsZero
=
BN
(
outputValue
).
isZero
();
if
(
!
inputValue
||
!
outputValue
||
!
inputCurrency
||
!
outputCurrency
)
{
if
(
!
inputValue
||
inputIsZero
||
!
outputValue
||
outputIsZero
||
!
inputCurrency
||
!
outputCurrency
||
this
.
isUnapproved
()
)
{
isValid
=
false
;
}
...
...
@@ -229,10 +259,12 @@ class AddLiquidity extends Component {
inputCurrency
,
outputCurrency
,
}
=
this
.
state
;
const
inputIsZero
=
BN
(
inputValue
).
isZero
();
const
outputIsZero
=
BN
(
outputValue
).
isZero
();
if
(
!
inputCurrency
||
!
outputCurrency
)
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
Select
a
token
to
continue
.
<
/div
>
<
/div
>
)
...
...
@@ -240,7 +272,7 @@ class AddLiquidity extends Component {
if
(
inputCurrency
===
outputCurrency
)
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
Must
be
different
token
.
<
/div
>
<
/div
>
)
...
...
@@ -248,22 +280,66 @@ class AddLiquidity extends Component {
if
(
!
[
inputCurrency
,
outputCurrency
].
includes
(
'
ETH
'
))
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
One
of
the
input
must
be
ETH
.
<
/div
>
<
/div
>
)
}
if
(
inputIsZero
||
outputIsZero
)
{
return
(
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
Amount
cannot
be
zero
.
<
/div
>
<
/div
>
)
}
if
(
this
.
isUnapproved
())
{
return
(
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
Please
unlock
token
to
continue
.
<
/div
>
<
/div
>
)
}
const
{
value
,
decimals
,
label
}
=
selectors
().
getTokenBalance
(
outputCurrency
,
fromToken
[
outputCurrency
]);
if
(
!
inputValue
||
!
outputValue
)
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
key
=
"
summary
"
className
=
"
swap__summary-wrapper
"
>
<
div
>
{
`Enter a
${
inputCurrency
}
or
${
label
}
value to continue.`
}
<
/div
>
<
/div
>
)
}
return
[
<
div
key
=
"
open-details
"
className
=
"
swap__summary-wrapper swap__open-details-container
"
onClick
=
{()
=>
this
.
setState
({
showSummaryModal
:
true
})}
>
<
span
>
Transaction
Details
<
/span
>
<
img
src
=
{
DropdownBlue
}
/
>
<
/div>
,
this
.
renderSummaryModal
()
];
}
renderSummaryModal
()
{
const
{
selectors
,
exchangeAddresses
:
{
fromToken
}
}
=
this
.
props
;
const
{
inputValue
,
outputValue
,
inputCurrency
,
outputCurrency
,
showSummaryModal
,
}
=
this
.
state
;
if
(
!
showSummaryModal
)
{
return
null
;
}
const
{
value
,
decimals
,
label
}
=
selectors
().
getTokenBalance
(
outputCurrency
,
fromToken
[
outputCurrency
]);
const
SLIPPAGE
=
0.025
;
const
minOutput
=
BN
(
outputValue
).
multipliedBy
(
1
-
SLIPPAGE
);
const
maxOutput
=
BN
(
outputValue
).
multipliedBy
(
1
+
SLIPPAGE
);
...
...
@@ -272,13 +348,34 @@ class AddLiquidity extends Component {
const
maxPercentage
=
maxOutput
.
dividedBy
(
maxOutput
.
plus
(
tokenReserve
)).
multipliedBy
(
100
);
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
>
You
are
adding
between
{
b
(
`
${
minOutput
.
toFixed
(
2
)}
-
${
maxOutput
.
toFixed
(
2
)}
${
label
}
`
)}
+
{
b
(
`
${
BN
(
inputValue
).
toFixed
(
2
)}
ETH`
)}
into
the
liquidity
pool
.
<
/div
>
<
Modal
key
=
"
modal
"
onClose
=
{()
=>
this
.
setState
({
showSummaryModal
:
false
})}
>
<
CSSTransitionGroup
transitionName
=
"
summary-modal
"
transitionAppear
=
{
true
}
transitionLeave
=
{
true
}
transitionAppearTimeout
=
{
200
}
transitionLeaveTimeout
=
{
200
}
transitionEnterTimeout
=
{
200
}
>
<
div
className
=
"
swap__summary-modal
"
>
<
div
key
=
"
open-details
"
className
=
"
swap__open-details-container
"
onClick
=
{()
=>
this
.
setState
({
showSummaryModal
:
false
})}
>
<
span
>
Transaction
Details
<
/span
>
<
img
src
=
{
DropupBlue
}
/
>
<
/div
>
<
div
>
<
div
>
You
are
adding
between
{
b
(
`
${
minOutput
.
toFixed
(
5
)}
-
${
maxOutput
.
toFixed
(
5
)}
${
label
}
`
)}
+
{
b
(
`
${
BN
(
inputValue
).
toFixed
(
5
)}
ETH`
)}
into
the
liquidity
pool
.
<
/div
>
<
div
className
=
"
pool__last-summary-text
"
>
You
will
receive
between
{
b
(
`
${
minPercentage
.
toFixed
(
2
)}
%`
)}
and
{
b
(
`
${
maxPercentage
.
toFixed
(
2
)}
%`
)}
of
the
{
`
${
label
}
/ETH`
}
pool
tokens
.
You
will
receive
between
{
b
(
`
${
minPercentage
.
toFixed
(
5
)}
%`
)}
and
{
b
(
`
${
maxPercentage
.
toFixed
(
5
)}
%`
)}
of
the
{
`
${
label
}
/ETH`
}
pool
tokens
.
<
/div
>
<
/div
>
)
<
/div
>
<
/CSSTransitionGroup
>
<
/Modal
>
);
}
render
()
{
...
...
@@ -296,12 +393,18 @@ class AddLiquidity extends Component {
const
{
inputError
,
outputError
,
isValid
}
=
this
.
validate
();
return
(
return
[
<
div
key
=
"
content
"
className
=
{
classnames
(
'
swap__content
'
,
{
'
swap--inactive
'
:
!
isConnected
,
})}
>
<
NavigationTabs
className
=
{
classnames
(
'
header__navigation
'
,
{
'
header--inactive
'
:
!
isConnected
,
})}
/
>
<
ModeSelector
/>
<
CurrencyInputPanel
title
=
"
Deposit
"
...
...
@@ -333,7 +436,6 @@ class AddLiquidity extends Component {
<
OversizedPanel
hideBottom
>
{
this
.
renderInfo
()
}
<
/OversizedPanel
>
{
this
.
renderSummary
()
}
<
div
className
=
"
pool__cta-container
"
>
<
button
className
=
{
classnames
(
'
pool__cta-btn
'
,
{
...
...
@@ -346,8 +448,9 @@ class AddLiquidity extends Component {
Add
Liquidity
<
/button
>
<
/div
>
<
/div
>
);
<
/div>
,
this
.
renderSummary
()
];
}
}
...
...
src/pages/Send/index.js
View file @
3e299ff2
This diff is collapsed.
Click to expand it.
src/pages/Swap/index.js
View file @
3e299ff2
...
...
@@ -4,9 +4,14 @@ import PropTypes from 'prop-types';
import
classnames
from
'
classnames
'
;
import
{
BigNumber
as
BN
}
from
"
bignumber.js
"
;
import
{
selectors
}
from
'
../../ducks/web3connect
'
;
import
{
CSSTransitionGroup
}
from
"
react-transition-group
"
;
import
Header
from
'
../../components/Header
'
;
import
NavigationTabs
from
'
../../components/NavigationTabs
'
;
import
Modal
from
'
../../components/Modal
'
;
import
CurrencyInputPanel
from
'
../../components/CurrencyInputPanel
'
;
import
OversizedPanel
from
'
../../components/OversizedPanel
'
;
import
DropdownBlue
from
"
../../assets/images/dropdown-blue.svg
"
;
import
DropupBlue
from
"
../../assets/images/dropup-blue.svg
"
;
import
ArrowDown
from
'
../../assets/images/arrow-down-blue.svg
'
;
import
EXCHANGE_ABI
from
'
../../abi/exchange
'
;
...
...
@@ -28,10 +33,11 @@ class Swap extends Component {
state
=
{
inputValue
:
''
,
outputValue
:
''
,
inputCurrency
:
''
,
inputCurrency
:
'
ETH
'
,
outputCurrency
:
''
,
inputAmountB
:
''
,
lastEditedField
:
''
,
showSummaryModal
:
false
,
};
shouldComponentUpdate
(
nextProps
,
nextState
)
{
...
...
@@ -46,6 +52,7 @@ class Swap extends Component {
outputCurrency
:
''
,
inputAmountB
:
''
,
lastEditedField
:
''
,
showSummaryModal
:
false
,
});
}
...
...
@@ -63,8 +70,11 @@ class Swap extends Component {
let
inputError
=
''
;
let
outputError
=
''
;
let
isValid
=
true
;
let
isUnapproved
=
this
.
isUnapproved
();
const
inputIsZero
=
BN
(
inputValue
).
isZero
();
const
outputIsZero
=
BN
(
outputValue
).
isZero
();
if
(
!
inputValue
||
!
outputValue
||
!
inputCurrency
||
!
outputCurrency
)
{
if
(
!
inputValue
||
inputIsZero
||
!
outputValue
||
outputIsZero
||
!
inputCurrency
||
!
outputCurrency
||
isUnapproved
)
{
isValid
=
false
;
}
...
...
@@ -85,13 +95,40 @@ class Swap extends Component {
};
}
isUnapproved
()
{
const
{
account
,
exchangeAddresses
,
selectors
}
=
this
.
props
;
const
{
inputCurrency
,
inputValue
}
=
this
.
state
;
if
(
!
inputCurrency
||
inputCurrency
===
'
ETH
'
)
{
return
false
;
}
const
{
value
:
allowance
,
label
,
decmals
}
=
selectors
().
getApprovals
(
inputCurrency
,
account
,
exchangeAddresses
.
fromToken
[
inputCurrency
]
);
if
(
label
&&
allowance
.
isLessThan
(
BN
(
inputValue
*
10
**
decimals
||
0
)))
{
return
true
;
}
return
false
;
}
recalcForm
()
{
const
{
inputCurrency
,
outputCurrency
}
=
this
.
state
;
const
{
inputCurrency
,
outputCurrency
,
lastEditedField
}
=
this
.
state
;
if
(
!
inputCurrency
||
!
outputCurrency
)
{
return
;
}
const
editedValue
=
lastEditedField
===
INPUT
?
this
.
state
.
inputValue
:
this
.
state
.
outputValue
;
if
(
BN
(
editedValue
).
isZero
())
{
return
;
}
if
(
inputCurrency
===
outputCurrency
)
{
this
.
setState
({
inputValue
:
''
,
...
...
@@ -446,12 +483,8 @@ class Swap extends Component {
outputCurrency
,
}
=
this
.
state
;
const
{
selectors
,
account
}
=
this
.
props
;
const
{
label
:
inputLabel
}
=
selectors
().
getBalance
(
account
,
inputCurrency
);
const
{
label
:
outputLabel
}
=
selectors
().
getBalance
(
account
,
outputCurrency
);
const
SLIPPAGE
=
0.025
;
const
minOutput
=
BN
(
outputValue
).
multipliedBy
(
1
-
SLIPPAGE
).
toFixed
(
2
);
const
maxOutput
=
BN
(
outputValue
).
multipliedBy
(
1
+
SLIPPAGE
).
toFixed
(
2
);
const
inputIsZero
=
BN
(
inputValue
).
isZero
();
const
outputIsZero
=
BN
(
outputValue
).
isZero
();
if
(
!
inputCurrency
||
!
outputCurrency
)
{
return
(
...
...
@@ -469,14 +502,146 @@ class Swap extends Component {
)
}
if
(
inputIsZero
||
outputIsZero
)
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
>
You
are
selling
{
b
(
`
${
inputValue
}
${
inputLabel
}
`
)}
<
/div
>
<
div
>
You
will
receive
between
{
b
(
minOutput
)}
and
{
b
(
`
${
maxOutput
}
${
outputLabel
}
`
)}
<
/div
>
<
div
>
Amount
cannot
be
zero
.
<
/div
>
<
/div
>
)
}
if
(
this
.
isUnapproved
())
{
return
(
<
div
className
=
"
swap__summary-wrapper
"
>
<
div
>
Please
unlock
token
to
continue
.
<
/div
>
<
/div
>
);
}
return
[
<
div
key
=
"
open-details
"
className
=
"
swap__summary-wrapper swap__open-details-container
"
onClick
=
{()
=>
this
.
setState
({
showSummaryModal
:
true
})}
>
<
span
>
Transaction
Details
<
/span
>
<
img
src
=
{
DropdownBlue
}
/
>
<
/div>
,
this
.
renderSummaryModal
()
];
}
renderSummaryModal
()
{
const
{
inputValue
,
inputCurrency
,
inputError
,
outputValue
,
outputCurrency
,
outputError
,
showSummaryModal
,
inputAmountB
,
lastEditedField
,
}
=
this
.
state
;
const
{
selectors
,
account
}
=
this
.
props
;
if
(
!
this
.
state
.
showSummaryModal
)
{
return
null
;
}
const
ALLOWED_SLIPPAGE
=
0.025
;
const
TOKEN_ALLOWED_SLIPPAGE
=
0.04
;
const
type
=
getSwapType
(
inputCurrency
,
outputCurrency
);
const
{
label
:
inputLabel
,
decimals
:
inputDecimals
}
=
selectors
().
getBalance
(
account
,
inputCurrency
);
const
{
label
:
outputLabel
,
decimals
:
outputDecimals
}
=
selectors
().
getBalance
(
account
,
outputCurrency
);
const
label
=
lastEditedField
===
INPUT
?
outputLabel
:
inputLabel
;
let
minOutput
;
let
maxInput
;
if
(
lastEditedField
===
INPUT
)
{
switch
(
type
)
{
case
'
ETH_TO_TOKEN
'
:
minOutput
=
BN
(
outputValue
).
multipliedBy
(
1
-
ALLOWED_SLIPPAGE
).
toFixed
(
5
)
break
;
case
'
TOKEN_TO_ETH
'
:
minOutput
=
BN
(
outputValue
).
multipliedBy
(
1
-
ALLOWED_SLIPPAGE
).
toFixed
(
5
);
break
;
case
'
TOKEN_TO_TOKEN
'
:
minOutput
=
BN
(
outputValue
).
multipliedBy
(
1
-
TOKEN_ALLOWED_SLIPPAGE
).
toFixed
(
5
);
break
;
default
:
break
;
}
}
if
(
lastEditedField
===
OUTPUT
)
{
switch
(
type
)
{
case
'
ETH_TO_TOKEN
'
:
maxInput
=
BN
(
inputValue
).
multipliedBy
(
1
+
ALLOWED_SLIPPAGE
).
toFixed
(
5
);
break
;
case
'
TOKEN_TO_ETH
'
:
maxInput
=
BN
(
inputValue
).
multipliedBy
(
1
+
ALLOWED_SLIPPAGE
).
toFixed
(
5
);
break
;
case
'
TOKEN_TO_TOKEN
'
:
maxInput
=
BN
(
inputValue
).
multipliedBy
(
1
+
TOKEN_ALLOWED_SLIPPAGE
).
toFixed
(
5
);
break
;
default
:
break
;
}
}
let
description
;
if
(
lastEditedField
===
INPUT
)
{
description
=
(
<
div
>
<
div
>
You
are
selling
{
b
(
`
${
inputValue
}
${
inputLabel
}
`
)}.
<
/div
>
<
div
className
=
"
send__last-summary-text
"
>
You
will
receive
between
{
b
(
`
${
minOutput
}
${
outputLabel
}
`
)}
and
{
b
(
`
${
outputValue
}
${
outputLabel
}
`
)}.
<
/div
>
<
/div
>
);
}
else
{
description
=
(
<
div
>
<
div
>
You
are
selling
between
{
b
(
`
${
inputValue
}
${
inputLabel
}
`
)}
to
{
b
(
`
${
maxInput
}
${
inputLabel
}
`
)}.
<
/div
>
<
div
className
=
"
send__last-summary-text
"
>
You
will
receive
{
b
(
`
${
outputValue
}
${
outputLabel
}
`
)}.
<
/div
>
<
/div
>
);
}
return
(
<
Modal
key
=
"
modal
"
onClose
=
{()
=>
this
.
setState
({
showSummaryModal
:
false
})}
>
<
CSSTransitionGroup
transitionName
=
"
summary-modal
"
transitionAppear
=
{
true
}
transitionLeave
=
{
true
}
transitionAppearTimeout
=
{
200
}
transitionLeaveTimeout
=
{
200
}
transitionEnterTimeout
=
{
200
}
>
<
div
className
=
"
swap__summary-modal
"
>
<
div
key
=
"
open-details
"
className
=
"
swap__open-details-container
"
onClick
=
{()
=>
this
.
setState
({
showSummaryModal
:
false
})}
>
<
span
>
Transaction
Details
<
/span
>
<
img
src
=
{
DropupBlue
}
/
>
<
/div
>
{
description
}
<
/div
>
<
/CSSTransitionGroup
>
<
/Modal
>
);
}
renderExchangeRate
()
{
const
{
account
,
selectors
}
=
this
.
props
;
const
{
exchangeRate
,
inputCurrency
,
outputCurrency
}
=
this
.
state
;
...
...
@@ -530,6 +695,11 @@ class Swap extends Component {
'
swap--inactive
'
:
!
this
.
props
.
isConnected
,
})}
>
<
NavigationTabs
className
=
{
classnames
(
'
header__navigation
'
,
{
'
header--inactive
'
:
!
this
.
props
.
isConnected
,
})}
/
>
<
CurrencyInputPanel
title
=
"
Input
"
description
=
{
lastEditedField
===
OUTPUT
?
estimatedText
:
''
}
...
...
@@ -565,8 +735,7 @@ class Swap extends Component {
disableUnlock
/>
{
this
.
renderExchangeRate
()
}
{
this
.
renderSummary
()
}
<
/div
>
<
div
className
=
"
swap__cta-container
"
>
<
button
className
=
{
classnames
(
'
swap__cta-btn
'
,
{
'
swap--inactive
'
:
!
this
.
props
.
isConnected
,
...
...
@@ -577,6 +746,9 @@ class Swap extends Component {
Swap
<
/button
>
<
/div
>
<
/div
>
{
this
.
renderSummary
()
}
<
/div
>
);
}
}
...
...
src/pages/Swap/swap.scss
View file @
3e299ff2
...
...
@@ -11,7 +11,6 @@
&
__content
{
padding
:
1rem
.75rem
;
margin-top
:
1rem
;
flex
:
1
1
auto
;
height
:
0
;
overflow-y
:
auto
;
...
...
@@ -46,16 +45,52 @@
}
&
__summary-wrapper
{
margin
:
2rem
1rem
0
;
margin
:
2rem
1rem
;
color
:
#737373
;
font-size
:
.75rem
;
text-align
:
center
;
}
&
__summary-modal
{
background-color
:
$white
;
position
:
relative
;
bottom
:
12rem
;
height
:
12rem
;
z-index
:
2000
;
padding
:
1rem
;
border-top-left-radius
:
1rem
;
border-top-right-radius
:
1rem
;
transition
:
250ms
ease-in-out
;
.swap__open-details-container
{
padding
:
0
.5rem
0
;
margin-bottom
:
1rem
;
}
}
&
__open-details-container
{
@extend
%row-nowrap
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
.625rem
1rem
;
font-size
:
.75rem
;
color
:
$royal-blue
;
img
{
height
:
.75rem
;
width
:
.75rem
;
}
}
&
__highlight-text
{
color
:
$royal-blue
;
}
&
__cta-container
{
display
:
flex
;
margin-top
:
1
.5rem
;
}
&
__cta-btn
{
@extend
%primary-button
;
margin
:
1rem
auto
;
...
...
@@ -69,3 +104,11 @@
margin-top
:
5px
;
}
}
.summary-modal-appear
{
bottom
:
0
;
}
.summary-modal-appear.modal-container-appear-active
{
bottom
:
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment