mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-25 01:08:14 +00:00
Swap: Initial Swap Home View
This commit is contained in:
parent
e8a10b3848
commit
d745729d95
73
common/containers/Tabs/Swap/components/currentRates.js
Normal file
73
common/containers/Tabs/Swap/components/currentRates.js
Normal file
@ -0,0 +1,73 @@
|
||||
import React, {Component} from 'react';
|
||||
import translate from 'translations';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
|
||||
export default class CurrentRates extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
ETHBTCAmount: 1,
|
||||
ETHREPAmount: 1,
|
||||
BTCETHAmount: 1,
|
||||
BTCREPAmount: 1
|
||||
}
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
ETHBTC: PropTypes.number,
|
||||
ETHREP: PropTypes.number,
|
||||
BTCETH: PropTypes.number,
|
||||
BTCREP: PropTypes.number
|
||||
};
|
||||
|
||||
onChange = (event) => {
|
||||
const target = event.target;
|
||||
const value = target.value;
|
||||
const name = target.name;
|
||||
this.setState({
|
||||
[name]: value
|
||||
});
|
||||
};
|
||||
|
||||
// TODO - A little code duplication here, but simple enough to where it doesn't seem worth the time to fix.
|
||||
render() {
|
||||
return (
|
||||
<article className="swap-rates">
|
||||
<section className="row">
|
||||
<h5 className="col-xs-6 col-xs-offset-3">{translate('SWAP_rates')}</h5>
|
||||
</section>
|
||||
<section className="row order-panel">
|
||||
<div className="col-sm-6 order-info">
|
||||
<p className="mono">
|
||||
<input className="form-control input-sm" onChange={this.onChange}
|
||||
value={this.state.ETHBTCAmount} name="ETHBTCAmount"/>
|
||||
<span>ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed(6)} BTC</span>
|
||||
</p>
|
||||
<p className="mono">
|
||||
<input className="form-control input-sm" onChange={this.onChange}
|
||||
value={this.state.ETHREPAmount} name="ETHREPAmount"/>
|
||||
<span>ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed(6)} REP</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-sm-6 order-info">
|
||||
<p className="mono">
|
||||
<input className="form-control input-sm" onChange={this.onChange}
|
||||
value={this.state.BTCETHAmount} name="BTCETHAmount"/>
|
||||
<span>BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed(6)} ETH</span>
|
||||
</p>
|
||||
<p className="mono">
|
||||
<input className="form-control input-sm" onChange={this.onChange}
|
||||
value={this.state.BTCREPAmount} name="BTCREPAmount"/>
|
||||
<span>BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed(6)} REP</span>
|
||||
</p>
|
||||
</div>
|
||||
<a className="link bity-logo" href="https://bity.com/af/jshkb37v" target="_blank">
|
||||
<img src={'https://www.myetherwallet.com/images/logo-bity-white.svg'}
|
||||
width={120} height={49}/>
|
||||
</a>
|
||||
</section>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
}
|
143
common/containers/Tabs/Swap/components/wantToSwapMy.js
Normal file
143
common/containers/Tabs/Swap/components/wantToSwapMy.js
Normal file
@ -0,0 +1,143 @@
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import translate from 'translations';
|
||||
import {combineAndUpper} from 'api/bity';
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export default class WantToSwapMy extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
bityRates: PropTypes.any,
|
||||
originAmount: PropTypes.any,
|
||||
destinationAmount: PropTypes.any,
|
||||
originKind: PropTypes.string,
|
||||
destinationKind: PropTypes.string,
|
||||
destinationKindOptions: PropTypes.array,
|
||||
originKindOptions: PropTypes.array,
|
||||
swapOriginKindTo: PropTypes.func,
|
||||
swapDestinationKindTo: PropTypes.func,
|
||||
swapOriginAmountTo: PropTypes.func,
|
||||
swapDestinationAmountTo: PropTypes.func
|
||||
};
|
||||
|
||||
onClickStartSwap() {
|
||||
|
||||
}
|
||||
|
||||
onChangeOriginAmount = (amount) => {
|
||||
let originAmountAsNumber = parseFloat(amount);
|
||||
if (originAmountAsNumber) {
|
||||
let pairName = combineAndUpper(this.props.originKind, this.props.destinationKind);
|
||||
let bityRate = this.props.bityRates[pairName];
|
||||
this.props.swapOriginAmountTo(originAmountAsNumber);
|
||||
this.props.swapDestinationAmountTo(originAmountAsNumber * bityRate)
|
||||
} else {
|
||||
this.props.swapOriginAmountTo('');
|
||||
this.props.swapDestinationAmountTo('')
|
||||
}
|
||||
};
|
||||
|
||||
onChangeDestinationAmount(amount) {
|
||||
let destinationAmountAsNumber = parseFloat(amount);
|
||||
if (destinationAmountAsNumber) {
|
||||
this.props.swapDestinationAmountTo(destinationAmountAsNumber);
|
||||
let pairName = combineAndUpper(this.props.destinationKind, this.props.originKind);
|
||||
let bityRate = this.props.bityRates[pairName];
|
||||
this.props.swapOriginAmountTo(destinationAmountAsNumber * bityRate)
|
||||
} else {
|
||||
this.props.swapOriginAmountTo('');
|
||||
this.props.swapDestinationAmountTo('')
|
||||
}
|
||||
}
|
||||
|
||||
async onChangeDestinationKind(event) {
|
||||
let toKind = event.target.value;
|
||||
this.props.swapDestinationKindTo(toKind);
|
||||
// TODO - can't find a way around this without bringing in annoying deps. Even though redux action is sync,
|
||||
// it seems it happens in the background and values don't get updated in time
|
||||
await sleep(100);
|
||||
let pairName = combineAndUpper(this.props.destinationKind, this.props.originKind);
|
||||
let bityRate = this.props.bityRates[pairName];
|
||||
this.props.swapOriginAmountTo(parseFloat(this.props.destinationAmount) * bityRate)
|
||||
}
|
||||
|
||||
async onChangeOriginKind(event) {
|
||||
let toKind = event.target.value;
|
||||
this.props.swapOriginKindTo(toKind);
|
||||
// TODO - can't find a way around this without bringing in annoying deps. Even though redux action is sync,
|
||||
// it seems it happens in the background and values don't get updated in time
|
||||
await sleep(100);
|
||||
let pairName = combineAndUpper(this.props.originKind, this.props.destinationKind);
|
||||
let bityRate = this.props.bityRates[pairName];
|
||||
this.props.swapDestinationAmountTo(parseFloat(this.props.originAmount) * bityRate)
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
originAmount,
|
||||
destinationAmount,
|
||||
originKind,
|
||||
destinationKind,
|
||||
destinationKindOptions,
|
||||
originKindOptions
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<article className="swap-panel">
|
||||
<h1 className="ng-scope">{translate('SWAP_init_1')}</h1>
|
||||
|
||||
<input
|
||||
className={`form-control ${(this.props.originAmount !== '' && this.props.originAmount > 0) ? 'is-valid' : 'is-invalid'}`}
|
||||
type="number"
|
||||
placeholder="Amount"
|
||||
onChange={(e) => this.onChangeOriginAmount(e.target.value)}
|
||||
value={originAmount}/>
|
||||
|
||||
<span className="dropdown">
|
||||
<select value={originKind}
|
||||
className="btn btn-default"
|
||||
onChange={this.onChangeOriginKind.bind(this)}>
|
||||
{
|
||||
originKindOptions.map((obj, i) => {
|
||||
return <option value={obj} key={i}>{obj}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</span>
|
||||
<h1>{translate('SWAP_init_2')}</h1>
|
||||
|
||||
<input
|
||||
className={`form-control ${(this.props.destinationAmount !== '' && this.props.destinationAmount > 0) ? 'is-valid' : 'is-invalid'}`}
|
||||
type="number"
|
||||
placeholder="Amount"
|
||||
value={destinationAmount}
|
||||
onChange={(e) => this.onChangeDestinationAmount(e.target.value)}/>
|
||||
|
||||
<span className="dropdown">
|
||||
<select value={destinationKind}
|
||||
className="btn btn-default"
|
||||
onChange={this.onChangeDestinationKind.bind(this)}>
|
||||
{
|
||||
destinationKindOptions.map((obj, i) => {
|
||||
return <option value={obj} key={i}>{obj}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<div className="col-xs-12 clearfix text-center">
|
||||
<a onClick={this.onClickStartSwap} className="btn btn-info btn-lg">
|
||||
<span>{translate('SWAP_init_CTA')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
120
common/containers/Tabs/Swap/index.js
Normal file
120
common/containers/Tabs/Swap/index.js
Normal file
@ -0,0 +1,120 @@
|
||||
import React, {Component} from 'react';
|
||||
import WantToSwapMy from './components/wantToSwapMy';
|
||||
import CurrentRates from './components/currentRates';
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
SWAP_DESTINATION_AMOUNT_TO,
|
||||
SWAP_DESTINATION_KIND_TO,
|
||||
SWAP_ORIGIN_AMOUNT_TO,
|
||||
SWAP_ORIGIN_KIND_TO,
|
||||
SWAP_UPDATE_BITY_RATES_TO
|
||||
} from 'actions/swap';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import Bity from 'api/bity';
|
||||
|
||||
class Swap extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.bity = new Bity();
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
bityRates: PropTypes.any,
|
||||
originAmount: PropTypes.any,
|
||||
destinationAmount: PropTypes.any,
|
||||
originKind: PropTypes.string,
|
||||
destinationKind: PropTypes.string,
|
||||
destinationKindOptions: PropTypes.array,
|
||||
originKindOptions: PropTypes.array,
|
||||
swapOriginKindTo: PropTypes.func,
|
||||
swapDestinationKindTo: PropTypes.func,
|
||||
swapOriginAmountTo: PropTypes.func,
|
||||
swapDestinationAmountTo: PropTypes.func,
|
||||
swapUpdateBityRatesTo: PropTypes.func
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
let {
|
||||
bityRates,
|
||||
originAmount,
|
||||
destinationAmount,
|
||||
originKind,
|
||||
destinationKind,
|
||||
destinationKindOptions,
|
||||
originKindOptions,
|
||||
swapOriginKindTo,
|
||||
swapDestinationKindTo,
|
||||
swapOriginAmountTo,
|
||||
swapDestinationAmountTo
|
||||
} = this.props;
|
||||
|
||||
let wantToSwapMyProps = {
|
||||
bityRates,
|
||||
originAmount,
|
||||
destinationAmount,
|
||||
originKind,
|
||||
destinationKind,
|
||||
destinationKindOptions,
|
||||
originKindOptions,
|
||||
swapOriginKindTo,
|
||||
swapDestinationKindTo,
|
||||
swapOriginAmountTo,
|
||||
swapDestinationAmountTo
|
||||
};
|
||||
|
||||
|
||||
if (!bityRates.ETHBTC || !bityRates.ETHREP || !bityRates.BTCETH || !bityRates.BTCREP) {
|
||||
this.bity.getAllRates()
|
||||
.then((data) => {
|
||||
this.props.swapUpdateBityRatesTo(data);
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="container" style={{minHeight: '50%'}}>
|
||||
<div className="tab-content">
|
||||
<main className="tab-pane swap-tab">
|
||||
<CurrentRates {...bityRates}/>
|
||||
<WantToSwapMy {...wantToSwapMyProps}/>
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
originAmount: state.swap.originAmount,
|
||||
destinationAmount: state.swap.destinationAmount,
|
||||
originKind: state.swap.originKind,
|
||||
destinationKind: state.swap.destinationKind,
|
||||
destinationKindOptions: state.swap.destinationKindOptions,
|
||||
originKindOptions: state.swap.originKindOptions,
|
||||
bityRates: state.swap.bityRates
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
swapOriginKindTo: (originValue) => {
|
||||
dispatch(SWAP_ORIGIN_KIND_TO(originValue))
|
||||
},
|
||||
swapDestinationKindTo: (destinationValue) => {
|
||||
dispatch(SWAP_DESTINATION_KIND_TO(destinationValue))
|
||||
},
|
||||
swapOriginAmountTo: (originAmount) => {
|
||||
dispatch(SWAP_ORIGIN_AMOUNT_TO(originAmount))
|
||||
},
|
||||
swapDestinationAmountTo: (destinationValue) => {
|
||||
dispatch(SWAP_DESTINATION_AMOUNT_TO(destinationValue))
|
||||
},
|
||||
swapUpdateBityRatesTo: (bityRates) => {
|
||||
dispatch(SWAP_UPDATE_BITY_RATES_TO(bityRates))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Swap)
|
15
common/libs/inputValidator.js
Normal file
15
common/libs/inputValidator.js
Normal file
@ -0,0 +1,15 @@
|
||||
export function isInt(n) {
|
||||
return Number(n) === n && n % 1 === 0;
|
||||
}
|
||||
|
||||
export function isFloat(n) {
|
||||
return Number(n) === n && n % 1 !== 0;
|
||||
}
|
||||
|
||||
export function isEmpty(n) {
|
||||
return n === ''
|
||||
}
|
||||
|
||||
export function isFloatOrInt(n) {
|
||||
return (isFloat(n) || isInt(n))
|
||||
}
|
@ -5,6 +5,7 @@ import {App} from 'containers';
|
||||
import GenerateWallet from 'containers/Tabs/GenerateWallet'
|
||||
import ViewWallet from 'containers/Tabs/ViewWallet'
|
||||
import Help from 'containers/Tabs/Help'
|
||||
import Swap from 'containers/Tabs/Swap'
|
||||
|
||||
export const history = getHistory()
|
||||
|
||||
@ -13,6 +14,7 @@ export const Routing = () => (
|
||||
<Route name="GenerateWallet" path="/" component={GenerateWallet}/>
|
||||
<Route name="ViewWallet" path="/view-wallet" component={ViewWallet}/>
|
||||
<Route name="Help" path="/help" component={Help}/>
|
||||
<Route name="Swap" path="/swap" component={Swap}/>
|
||||
|
||||
<Redirect from="/*" to="/"/>
|
||||
</Route>
|
||||
|
Loading…
x
Reference in New Issue
Block a user