From 0304bc8a67ad32b30cf8ada54ce1a6a2713beaf6 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 11 Jun 2017 20:00:28 -0500 Subject: [PATCH 01/19] Swap: Redux actions; Redux Reducers --- common/actions/swap.js | 42 ++++++++++++++++++++++++++++ common/reducers/index.js | 3 ++ common/reducers/swap.js | 60 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 common/actions/swap.js create mode 100644 common/reducers/swap.js diff --git a/common/actions/swap.js b/common/actions/swap.js new file mode 100644 index 00000000..b51e8db1 --- /dev/null +++ b/common/actions/swap.js @@ -0,0 +1,42 @@ +// @flow +export const SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND'; +export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; +export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; +export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; +export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; + + +export const SWAP_ORIGIN_KIND_TO = (value: any) => { + return { + type: SWAP_ORIGIN_KIND, + value + }; +}; + +export const SWAP_DESTINATION_KIND_TO = (value: any) => { + return { + type: SWAP_DESTINATION_KIND, + value + } +} + +export const SWAP_ORIGIN_AMOUNT_TO = (value: any) => { + return { + type: SWAP_ORIGIN_AMOUNT, + value + }; +}; + +export const SWAP_DESTINATION_AMOUNT_TO = (value: any) => { + return { + type: SWAP_DESTINATION_AMOUNT, + value + } +} + +export const SWAP_UPDATE_BITY_RATES_TO = (value: any) => { + return { + type: SWAP_UPDATE_BITY_RATES, + value + } +} diff --git a/common/reducers/index.js b/common/reducers/index.js index 28b1f155..03af9db1 100644 --- a/common/reducers/index.js +++ b/common/reducers/index.js @@ -1,5 +1,7 @@ import * as generateWallet from './generateWallet' import * as config from './config' +import * as swap from './swap' + import { reducer as formReducer } from 'redux-form' import {combineReducers} from 'redux'; import {routerReducer} from 'react-router-redux' @@ -7,6 +9,7 @@ import {routerReducer} from 'react-router-redux' export default combineReducers({ ...generateWallet, ...config, + ...swap, form: formReducer, routing: routerReducer }) diff --git a/common/reducers/swap.js b/common/reducers/swap.js new file mode 100644 index 00000000..8ef090f9 --- /dev/null +++ b/common/reducers/swap.js @@ -0,0 +1,60 @@ +import { + SWAP_DESTINATION_AMOUNT, + SWAP_DESTINATION_KIND, + SWAP_ORIGIN_AMOUNT, + SWAP_ORIGIN_KIND, + SWAP_UPDATE_BITY_RATES +} from 'actions/swap'; + +import {without} from 'lodash'; +const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; + +const initialState = { + originAmount: 0, + destinationAmount: 0, + originKind: 'BTC', + destinationKind: 'ETH', + destinationKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, 'BTC'), + originKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, 'REP'), + bityRates: {} +}; + + +export function swap(state = initialState, action) { + switch (action.type) { + case SWAP_ORIGIN_KIND: { + return { + ...state, + originKind: action.value, + destinationKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, action.value), + destinationKind: without(ALL_CRYPTO_KIND_OPTIONS, action.value)[0] + }; + } + case SWAP_DESTINATION_KIND: { + return { + ...state, + destinationKind: action.value + }; + } + case SWAP_ORIGIN_AMOUNT: + return { + ...state, + originAmount: action.value + }; + case SWAP_DESTINATION_AMOUNT: + return { + ...state, + destinationAmount: action.value + }; + case SWAP_UPDATE_BITY_RATES: + return { + ...state, + bityRates: { + ...state.bityRates, + ...action.value + } + }; + default: + return state + } +} From e8a10b384896a6a2c4d08837e4fd155fb05f6f76 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 11 Jun 2017 20:01:27 -0500 Subject: [PATCH 02/19] Swap: Initial Bity API Class --- common/api/bity.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 common/api/bity.js diff --git a/common/api/bity.js b/common/api/bity.js new file mode 100644 index 00000000..b7b820c7 --- /dev/null +++ b/common/api/bity.js @@ -0,0 +1,82 @@ +import axios from 'axios'; + +// https://stackoverflow.com/questions/9828684/how-to-get-all-arguments-of-a-callback-function +export function combineAndUpper() { + let args = []; + let newString = ''; + for (let i = 0; i < arguments.length; ++i) args[i] = arguments[i]; + args.forEach((each) => { + newString = newString.concat(each.toUpperCase()) + }); + return newString +} + +export default class Bity { + constructor() { + this.SERVERURL = 'https://myetherapi.com'; + this.bityAPI = 'https://bity.com/api'; + this.decimals = 6; + this.ethExplorer = 'https://etherscan.io/tx/[[txHash]]'; + this.btcExplorer = 'https://blockchain.info/tx/[[txHash]]'; + this.validStatus = ['RCVE', 'FILL', 'CONF', 'EXEC']; + this.invalidStatus = ['CANC']; + this.mainPairs = ['REP', 'ETH']; + this.min = 0.01; + this.max = 3; + this.priceLoaded = false; + this.postConfig = { + headers: { + 'Content-Type': 'application/json; charset=UTF-8' + } + }; + } + + findRateFromBityRateList(rateObjects, pairName) { + return rateObjects.find(x => x.pair === pairName); + } + + _getRate(bityRates, origin, destination) { + let pairName = combineAndUpper(origin, destination); + let rateObjects = bityRates.data.objects; + return this.findRateFromBityRateList(rateObjects, pairName); + } + + /** + * Gives you multiple rates from Bitys API without making multiple API calls + * @param arrayOfOriginAndDestinationDicts - [{origin: 'BTC', destination: 'ETH'}, {origin: 'BTC', destination: 'REP}] + */ + getMultipleRates(arrayOfOriginAndDestinationDicts) { + let mappedRates = {}; + return this.requestAllRates() + .then((bityRates) => { + arrayOfOriginAndDestinationDicts.forEach((each) => { + let origin = each.origin; + let destination = each.destination; + let pairName = combineAndUpper(origin, destination); + let rate = this._getRate(bityRates, origin, destination); + mappedRates[pairName] = parseFloat(rate.rate_we_sell) + }); + return mappedRates + }) + // TODO - catch errors + } + + getAllRates() { + let mappedRates = {}; + return this.requestAllRates() + .then((bityRates) => { + bityRates.data.objects.forEach((each) => { + let pairName = each.pair; + mappedRates[pairName] = parseFloat(each.rate_we_sell) + }); + return mappedRates + }) + // TODO - catch errors + } + + requestAllRates() { + let path = '/v1/rate2/'; + let bityURL = this.bityAPI + path + return axios.get(bityURL) + } +} From d745729d95a3ab36d3b5c3ad7936d3630a8ba23f Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 11 Jun 2017 20:02:39 -0500 Subject: [PATCH 03/19] Swap: Initial Swap Home View --- .../Tabs/Swap/components/currentRates.js | 73 +++++++++ .../Tabs/Swap/components/wantToSwapMy.js | 143 ++++++++++++++++++ common/containers/Tabs/Swap/index.js | 120 +++++++++++++++ common/libs/inputValidator.js | 15 ++ common/routing/index.jsx | 2 + 5 files changed, 353 insertions(+) create mode 100644 common/containers/Tabs/Swap/components/currentRates.js create mode 100644 common/containers/Tabs/Swap/components/wantToSwapMy.js create mode 100644 common/containers/Tabs/Swap/index.js create mode 100644 common/libs/inputValidator.js diff --git a/common/containers/Tabs/Swap/components/currentRates.js b/common/containers/Tabs/Swap/components/currentRates.js new file mode 100644 index 00000000..e22e1870 --- /dev/null +++ b/common/containers/Tabs/Swap/components/currentRates.js @@ -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 ( +
+
+
{translate('SWAP_rates')}
+
+
+
+

+ + ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed(6)} BTC +

+

+ + ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed(6)} REP +

+
+
+

+ + BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed(6)} ETH +

+

+ + BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed(6)} REP +

+
+ + + +
+
+ ) + } +} diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js new file mode 100644 index 00000000..f31e3ea8 --- /dev/null +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -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 ( +
+

{translate('SWAP_init_1')}

+ + 0) ? 'is-valid' : 'is-invalid'}`} + type="number" + placeholder="Amount" + onChange={(e) => this.onChangeOriginAmount(e.target.value)} + value={originAmount}/> + + + + +

{translate('SWAP_init_2')}

+ + 0) ? 'is-valid' : 'is-invalid'}`} + type="number" + placeholder="Amount" + value={destinationAmount} + onChange={(e) => this.onChangeDestinationAmount(e.target.value)}/> + + + + + +
+ + {translate('SWAP_init_CTA')} + +
+
+ + ) + } +} diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js new file mode 100644 index 00000000..5042e031 --- /dev/null +++ b/common/containers/Tabs/Swap/index.js @@ -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 ( +
+
+
+ + +
+
+
+ ) + } +} + +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) diff --git a/common/libs/inputValidator.js b/common/libs/inputValidator.js new file mode 100644 index 00000000..a2bf1abf --- /dev/null +++ b/common/libs/inputValidator.js @@ -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)) +} diff --git a/common/routing/index.jsx b/common/routing/index.jsx index 3173bd88..17d500f7 100644 --- a/common/routing/index.jsx +++ b/common/routing/index.jsx @@ -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 = () => ( + From 81d5f641006eccfdcb64f2327dfd675eac65873f Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 11 Jun 2017 20:05:36 -0500 Subject: [PATCH 04/19] Swap: add axios and lodash to package.json --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 9e46cf62..09b5355a 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "main": "common/index.jsx", "description": "MyEtherWallet v4", "dependencies": { + "axios": "^0.16.2", + "lodash": "^4.17.4", "prop-types": "^15.5.8", "react": "^15.4.2", "react-dom": "^15.4.2", From fb73be421450f065684873a604180f4c8dc143f1 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 14:47:00 -0500 Subject: [PATCH 05/19] WIP address comments --- common/actions/swap.js | 10 ++++---- common/api/bity.js | 24 +++++++++---------- common/containers/App/index.jsx | 9 ++----- .../Tabs/Swap/components/wantToSwapMy.js | 4 ++-- common/reducers/swap.js | 2 +- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index b51e8db1..1bdd4b83 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -6,35 +6,35 @@ export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; -export const SWAP_ORIGIN_KIND_TO = (value: any) => { +export const SWAP_ORIGIN_KIND_TO = (value) => { return { type: SWAP_ORIGIN_KIND, value }; }; -export const SWAP_DESTINATION_KIND_TO = (value: any) => { +export const SWAP_DESTINATION_KIND_TO = (value) => { return { type: SWAP_DESTINATION_KIND, value } } -export const SWAP_ORIGIN_AMOUNT_TO = (value: any) => { +export const SWAP_ORIGIN_AMOUNT_TO = (value) => { return { type: SWAP_ORIGIN_AMOUNT, value }; }; -export const SWAP_DESTINATION_AMOUNT_TO = (value: any) => { +export const SWAP_DESTINATION_AMOUNT_TO = (value) => { return { type: SWAP_DESTINATION_AMOUNT, value } } -export const SWAP_UPDATE_BITY_RATES_TO = (value: any) => { +export const SWAP_UPDATE_BITY_RATES_TO = (value) => { return { type: SWAP_UPDATE_BITY_RATES, value diff --git a/common/api/bity.js b/common/api/bity.js index b7b820c7..6b7f6b29 100644 --- a/common/api/bity.js +++ b/common/api/bity.js @@ -2,7 +2,7 @@ import axios from 'axios'; // https://stackoverflow.com/questions/9828684/how-to-get-all-arguments-of-a-callback-function export function combineAndUpper() { - let args = []; + const args = []; let newString = ''; for (let i = 0; i < arguments.length; ++i) args[i] = arguments[i]; args.forEach((each) => { @@ -36,8 +36,8 @@ export default class Bity { } _getRate(bityRates, origin, destination) { - let pairName = combineAndUpper(origin, destination); - let rateObjects = bityRates.data.objects; + const pairName = combineAndUpper(origin, destination); + const rateObjects = bityRates.data.objects; return this.findRateFromBityRateList(rateObjects, pairName); } @@ -46,14 +46,14 @@ export default class Bity { * @param arrayOfOriginAndDestinationDicts - [{origin: 'BTC', destination: 'ETH'}, {origin: 'BTC', destination: 'REP}] */ getMultipleRates(arrayOfOriginAndDestinationDicts) { - let mappedRates = {}; + const mappedRates = {}; return this.requestAllRates() .then((bityRates) => { arrayOfOriginAndDestinationDicts.forEach((each) => { - let origin = each.origin; - let destination = each.destination; - let pairName = combineAndUpper(origin, destination); - let rate = this._getRate(bityRates, origin, destination); + const origin = each.origin; + const destination = each.destination; + const pairName = combineAndUpper(origin, destination); + const rate = this._getRate(bityRates, origin, destination); mappedRates[pairName] = parseFloat(rate.rate_we_sell) }); return mappedRates @@ -62,11 +62,11 @@ export default class Bity { } getAllRates() { - let mappedRates = {}; + const mappedRates = {}; return this.requestAllRates() .then((bityRates) => { bityRates.data.objects.forEach((each) => { - let pairName = each.pair; + const pairName = each.pair; mappedRates[pairName] = parseFloat(each.rate_we_sell) }); return mappedRates @@ -75,8 +75,8 @@ export default class Bity { } requestAllRates() { - let path = '/v1/rate2/'; - let bityURL = this.bityAPI + path + const path = '/v1/rate2/'; + const bityURL = this.bityAPI + path; return axios.get(bityURL) } } diff --git a/common/containers/App/index.jsx b/common/containers/App/index.jsx index a018c1bf..4dea2e1f 100644 --- a/common/containers/App/index.jsx +++ b/common/containers/App/index.jsx @@ -27,11 +27,6 @@ class App extends Component { nodeSelection: PropTypes.object }; - componentWillMount() { - let { handleWindowResize } = this.props; - window.addEventListener('resize', handleWindowResize); - } - render() { let { children, @@ -41,11 +36,11 @@ class App extends Component { changeNode, nodeSelection } = this.props; - + let headerProps = { changeLanguage, languageSelection, - + location, changeNode, nodeSelection }; diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index f31e3ea8..21158372 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -79,7 +79,7 @@ export default class WantToSwapMy extends Component { } render() { - let { + const { originAmount, destinationAmount, originKind, @@ -90,7 +90,7 @@ export default class WantToSwapMy extends Component { return (
-

{translate('SWAP_init_1')}

+

{translate('SWAP_init_1')}

0) ? 'is-valid' : 'is-invalid'}`} diff --git a/common/reducers/swap.js b/common/reducers/swap.js index 8ef090f9..a40d133b 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -6,7 +6,7 @@ import { SWAP_UPDATE_BITY_RATES } from 'actions/swap'; -import {without} from 'lodash'; +import without from 'lodash/without'; const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; const initialState = { From 3333169c27857d0ab69af4c6fc31df655ba188ba Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 15:00:15 -0500 Subject: [PATCH 06/19] Fix duplicate location key due to bad marge --- common/containers/App/index.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/common/containers/App/index.jsx b/common/containers/App/index.jsx index fdb6a9aa..4b78d126 100644 --- a/common/containers/App/index.jsx +++ b/common/containers/App/index.jsx @@ -41,7 +41,6 @@ class App extends Component { location, changeLanguage, languageSelection, - location, changeNode, nodeSelection }; From f2b8045c2173b6d4250dff804701ae38961a7b25 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 19:56:11 -0500 Subject: [PATCH 07/19] address additional comments --- common/actions/swap.js | 7 +-- common/api/bity.js | 22 +------- common/config/bity.js | 18 ++++++ .../Tabs/Swap/components/wantToSwapMy.js | 55 +++++++++++-------- 4 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 common/config/bity.js diff --git a/common/actions/swap.js b/common/actions/swap.js index 1bdd4b83..c4825565 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -1,4 +1,3 @@ -// @flow export const SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND'; export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; @@ -18,7 +17,7 @@ export const SWAP_DESTINATION_KIND_TO = (value) => { type: SWAP_DESTINATION_KIND, value } -} +}; export const SWAP_ORIGIN_AMOUNT_TO = (value) => { return { @@ -32,11 +31,11 @@ export const SWAP_DESTINATION_AMOUNT_TO = (value) => { type: SWAP_DESTINATION_AMOUNT, value } -} +}; export const SWAP_UPDATE_BITY_RATES_TO = (value) => { return { type: SWAP_UPDATE_BITY_RATES, value } -} +}; diff --git a/common/api/bity.js b/common/api/bity.js index 6b7f6b29..c9d1393c 100644 --- a/common/api/bity.js +++ b/common/api/bity.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import bityConfig from 'config/bity'; // https://stackoverflow.com/questions/9828684/how-to-get-all-arguments-of-a-callback-function export function combineAndUpper() { @@ -12,25 +13,6 @@ export function combineAndUpper() { } export default class Bity { - constructor() { - this.SERVERURL = 'https://myetherapi.com'; - this.bityAPI = 'https://bity.com/api'; - this.decimals = 6; - this.ethExplorer = 'https://etherscan.io/tx/[[txHash]]'; - this.btcExplorer = 'https://blockchain.info/tx/[[txHash]]'; - this.validStatus = ['RCVE', 'FILL', 'CONF', 'EXEC']; - this.invalidStatus = ['CANC']; - this.mainPairs = ['REP', 'ETH']; - this.min = 0.01; - this.max = 3; - this.priceLoaded = false; - this.postConfig = { - headers: { - 'Content-Type': 'application/json; charset=UTF-8' - } - }; - } - findRateFromBityRateList(rateObjects, pairName) { return rateObjects.find(x => x.pair === pairName); } @@ -76,7 +58,7 @@ export default class Bity { requestAllRates() { const path = '/v1/rate2/'; - const bityURL = this.bityAPI + path; + const bityURL = bityConfig.bityAPI + path; return axios.get(bityURL) } } diff --git a/common/config/bity.js b/common/config/bity.js new file mode 100644 index 00000000..2c4b0632 --- /dev/null +++ b/common/config/bity.js @@ -0,0 +1,18 @@ +export default { + SERVERURL: 'https://myetherapi.com', + bityAPI: 'https://bity.com/api', + decimals: 6, + ethExplorer: 'https://etherscan.io/tx/[[txHash]]', + btcExplorer: 'https://blockchain.info/tx/[[txHash]]', + validStatus: ['RCVE', 'FILL', 'CONF', 'EXEC'], + invalidStatus: ['CANC'], + mainPairs: ['REP', 'ETH'], + min: 0.01, + max: 3, + priceLoaded: false, + postConfig: { + headers: { + 'Content-Type': 'application/json; charse:UTF-8' + } + } +} diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index 21158372..1a6481d1 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -7,6 +7,35 @@ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } + +class CoinTypeDropDown extends Component { + constructor(props) { + super(props) + } + + static propTypes = { + kind: PropTypes.any, + onChange: PropTypes.any, + kindOptions: PropTypes.any + }; + + render() { + return ( + + ) + } + + +} + export default class WantToSwapMy extends Component { constructor(props) { super(props) @@ -91,25 +120,14 @@ export default class WantToSwapMy extends Component { return (

{translate('SWAP_init_1')}

- 0) ? 'is-valid' : 'is-invalid'}`} type="number" placeholder="Amount" onChange={(e) => this.onChangeOriginAmount(e.target.value)} value={originAmount}/> + - - -

{translate('SWAP_init_2')}

this.onChangeDestinationAmount(e.target.value)}/> - - - - +
From 192efd440466a1950e1eb838fb0e8bc8e10f542e Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 20:00:54 -0500 Subject: [PATCH 08/19] reformat --- .../Tabs/Swap/components/wantToSwapMy.js | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index 1a6481d1..5a6ec8c3 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -20,20 +20,20 @@ class CoinTypeDropDown extends Component { }; render() { - return ( - - ) + return ( + + + + ) } - - } export default class WantToSwapMy extends Component { @@ -126,7 +126,8 @@ export default class WantToSwapMy extends Component { placeholder="Amount" onChange={(e) => this.onChangeOriginAmount(e.target.value)} value={originAmount}/> - +

{translate('SWAP_init_2')}

@@ -136,7 +137,8 @@ export default class WantToSwapMy extends Component { placeholder="Amount" value={destinationAmount} onChange={(e) => this.onChangeDestinationAmount(e.target.value)}/> - +
From c77f5ef300713d139e304e89cd38a2d7b0c788d3 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 23:53:32 -0500 Subject: [PATCH 09/19] address sleep() hack -- get state directly from redux instead of relying on props --- common/actions/swap.js | 5 +- .../Tabs/Swap/components/wantToSwapMy.js | 46 +++++++++---------- common/containers/Tabs/Swap/index.js | 17 +++++-- common/reducers/swap.js | 12 ++--- 4 files changed, 44 insertions(+), 36 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index c4825565..f1d1b007 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -3,7 +3,7 @@ export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; - +export const SWAP_DESTINATION_KIND_OPTIONS = 'SWAP_DESTINATION_KIND_OPTIONS' export const SWAP_ORIGIN_KIND_TO = (value) => { return { @@ -39,3 +39,6 @@ export const SWAP_UPDATE_BITY_RATES_TO = (value) => { value } }; + + + diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index 5a6ec8c3..fa9c1b24 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -3,14 +3,10 @@ import PropTypes from 'prop-types'; import translate from 'translations'; import {combineAndUpper} from 'api/bity'; -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - class CoinTypeDropDown extends Component { - constructor(props) { - super(props) + constructor(props, context) { + super(props, context) } static propTypes = { @@ -37,8 +33,8 @@ class CoinTypeDropDown extends Component { } export default class WantToSwapMy extends Component { - constructor(props) { - super(props) + constructor(props, context) { + super(props, context) } static propTypes = { @@ -52,7 +48,9 @@ export default class WantToSwapMy extends Component { swapOriginKindTo: PropTypes.func, swapDestinationKindTo: PropTypes.func, swapOriginAmountTo: PropTypes.func, - swapDestinationAmountTo: PropTypes.func + swapDestinationAmountTo: PropTypes.func, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func + }; onClickStartSwap() { @@ -86,23 +84,19 @@ export default class WantToSwapMy extends Component { } 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 newDestinationKind = event.target.value; + this.props.swapDestinationKindTo(newDestinationKind); + let pairName = combineAndUpper(this.props.originKind, newDestinationKind); let bityRate = this.props.bityRates[pairName]; - this.props.swapOriginAmountTo(parseFloat(this.props.destinationAmount) * bityRate) + this.props.swapDestinationAmountTo(parseFloat(this.props.originAmount) * 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 newOriginKind = event.target.value; + this.props.swapOriginKindTo(newOriginKind); + // https://github.com/reactjs/redux/issues/1543#issuecomment-201399259 + let destinationKind = store.getState().swap.destinationKind; + let pairName = combineAndUpper(newOriginKind, destinationKind); let bityRate = this.props.bityRates[pairName]; this.props.swapDestinationAmountTo(parseFloat(this.props.originAmount) * bityRate) } @@ -126,7 +120,9 @@ export default class WantToSwapMy extends Component { placeholder="Amount" onChange={(e) => this.onChangeOriginAmount(e.target.value)} value={originAmount}/> -

{translate('SWAP_init_2')}

@@ -137,7 +133,9 @@ export default class WantToSwapMy extends Component { placeholder="Amount" value={destinationAmount} onChange={(e) => this.onChangeDestinationAmount(e.target.value)}/> -
diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 5042e031..1858dde5 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -7,7 +7,8 @@ import { SWAP_DESTINATION_KIND_TO, SWAP_ORIGIN_AMOUNT_TO, SWAP_ORIGIN_KIND_TO, - SWAP_UPDATE_BITY_RATES_TO + SWAP_UPDATE_BITY_RATES_TO, + SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO } from 'actions/swap'; import PropTypes from 'prop-types'; @@ -31,8 +32,8 @@ class Swap extends Component { swapDestinationKindTo: PropTypes.func, swapOriginAmountTo: PropTypes.func, swapDestinationAmountTo: PropTypes.func, - swapUpdateBityRatesTo: PropTypes.func - + swapUpdateBityRatesTo: PropTypes.func, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func }; render() { @@ -47,7 +48,8 @@ class Swap extends Component { swapOriginKindTo, swapDestinationKindTo, swapOriginAmountTo, - swapDestinationAmountTo + swapDestinationAmountTo, + swapOriginKindAndDestinationKindAndDestinationOptionsTo } = this.props; let wantToSwapMyProps = { @@ -61,7 +63,8 @@ class Swap extends Component { swapOriginKindTo, swapDestinationKindTo, swapOriginAmountTo, - swapDestinationAmountTo + swapDestinationAmountTo, + swapOriginKindAndDestinationKindAndDestinationOptionsTo }; @@ -113,6 +116,10 @@ function mapDispatchToProps(dispatch) { }, swapUpdateBityRatesTo: (bityRates) => { dispatch(SWAP_UPDATE_BITY_RATES_TO(bityRates)) + }, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: (originKind, destinationKind) => { + dispatch(SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO(originKind, destinationKind)) + } } } diff --git a/common/reducers/swap.js b/common/reducers/swap.js index a40d133b..c6690c61 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -6,16 +6,16 @@ import { SWAP_UPDATE_BITY_RATES } from 'actions/swap'; -import without from 'lodash/without'; -const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; +export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; + const initialState = { originAmount: 0, destinationAmount: 0, originKind: 'BTC', destinationKind: 'ETH', - destinationKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, 'BTC'), - originKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, 'REP'), + destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== 'BTC'), + originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== 'REP'), bityRates: {} }; @@ -26,8 +26,8 @@ export function swap(state = initialState, action) { return { ...state, originKind: action.value, - destinationKindOptions: without(ALL_CRYPTO_KIND_OPTIONS, action.value), - destinationKind: without(ALL_CRYPTO_KIND_OPTIONS, action.value)[0] + destinationKind: action.value === state.destinationKind ? ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== action.value)[0] : state.destinationKind, + destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== action.value) }; } case SWAP_DESTINATION_KIND: { From 3cf43d04ad2ca222fa97f5ce98492e8930a3def6 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 18 Jun 2017 23:56:32 -0500 Subject: [PATCH 10/19] address additional comments --- common/containers/Tabs/Swap/index.js | 23 +++++++++++++---------- common/index.jsx | 1 + 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 1858dde5..07894f82 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -6,9 +6,9 @@ import { SWAP_DESTINATION_AMOUNT_TO, SWAP_DESTINATION_KIND_TO, SWAP_ORIGIN_AMOUNT_TO, + SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO, SWAP_ORIGIN_KIND_TO, - SWAP_UPDATE_BITY_RATES_TO, - SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO + SWAP_UPDATE_BITY_RATES_TO } from 'actions/swap'; import PropTypes from 'prop-types'; @@ -36,6 +36,17 @@ class Swap extends Component { swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func }; + componentDidMount() { + let {bityRates} = this.props; + + if (!bityRates.ETHBTC || !bityRates.ETHREP || !bityRates.BTCETH || !bityRates.BTCREP) { + this.bity.getAllRates() + .then((data) => { + this.props.swapUpdateBityRatesTo(data); + }) + } + } + render() { let { bityRates, @@ -67,14 +78,6 @@ class Swap extends Component { swapOriginKindAndDestinationKindAndDestinationOptionsTo }; - - if (!bityRates.ETHBTC || !bityRates.ETHREP || !bityRates.BTCETH || !bityRates.BTCREP) { - this.bity.getAllRates() - .then((data) => { - this.props.swapUpdateBityRatesTo(data); - }) - } - return (
diff --git a/common/index.jsx b/common/index.jsx index aef1ef3b..e025c889 100644 --- a/common/index.jsx +++ b/common/index.jsx @@ -37,6 +37,7 @@ const configureStore = () => { const renderRoot = (Root) => { let store = configureStore(); + window.store = store; let syncedHistory = syncHistoryWithStore(history, store); render( Date: Sun, 18 Jun 2017 23:57:46 -0500 Subject: [PATCH 11/19] deleted common/libs/inputValidator.js --- common/libs/inputValidator.js | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 common/libs/inputValidator.js diff --git a/common/libs/inputValidator.js b/common/libs/inputValidator.js deleted file mode 100644 index a2bf1abf..00000000 --- a/common/libs/inputValidator.js +++ /dev/null @@ -1,15 +0,0 @@ -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)) -} From f32a2d663160776c76dbde6f7c7ca30f7cf05088 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 00:37:17 -0500 Subject: [PATCH 12/19] Reformat: common/containers/Tabs/Swap/components/wantToSwapMy.js --- .../Tabs/Swap/components/wantToSwapMy.js | 274 +++++++++--------- 1 file changed, 145 insertions(+), 129 deletions(-) diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index fa9c1b24..5498e7aa 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -1,150 +1,166 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import translate from 'translations'; -import {combineAndUpper} from 'api/bity'; - +import { combineAndUpper } from 'api/bity'; class CoinTypeDropDown extends Component { - constructor(props, context) { - super(props, context) - } + constructor(props, context) { + super(props, context); + } - static propTypes = { - kind: PropTypes.any, - onChange: PropTypes.any, - kindOptions: PropTypes.any - }; + static propTypes = { + kind: PropTypes.any, + onChange: PropTypes.any, + kindOptions: PropTypes.any + }; - render() { - return ( - - - - ) - } + render() { + return ( + + + + ); + } } export default class WantToSwapMy extends Component { - constructor(props, context) { - super(props, context) + constructor(props, context) { + super(props, context); + } + + 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, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: 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(''); } + }; - 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, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func - - }; - - onClickStartSwap() { - + 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(''); } + } - 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('') - } - }; + async onChangeDestinationKind(event) { + let newDestinationKind = event.target.value; + this.props.swapDestinationKindTo(newDestinationKind); + let pairName = combineAndUpper(this.props.originKind, newDestinationKind); + let bityRate = this.props.bityRates[pairName]; + this.props.swapDestinationAmountTo( + parseFloat(this.props.originAmount) * bityRate + ); + } - 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 onChangeOriginKind(event) { + let newOriginKind = event.target.value; + this.props.swapOriginKindTo(newOriginKind); + // https://github.com/reactjs/redux/issues/1543#issuecomment-201399259 + let destinationKind = store.getState().swap.destinationKind; + let pairName = combineAndUpper(newOriginKind, destinationKind); + let bityRate = this.props.bityRates[pairName]; + this.props.swapDestinationAmountTo( + parseFloat(this.props.originAmount) * bityRate + ); + } - async onChangeDestinationKind(event) { - let newDestinationKind = event.target.value; - this.props.swapDestinationKindTo(newDestinationKind); - let pairName = combineAndUpper(this.props.originKind, newDestinationKind); - let bityRate = this.props.bityRates[pairName]; - this.props.swapDestinationAmountTo(parseFloat(this.props.originAmount) * bityRate) - } + render() { + const { + originAmount, + destinationAmount, + originKind, + destinationKind, + destinationKindOptions, + originKindOptions + } = this.props; - async onChangeOriginKind(event) { - let newOriginKind = event.target.value; - this.props.swapOriginKindTo(newOriginKind); - // https://github.com/reactjs/redux/issues/1543#issuecomment-201399259 - let destinationKind = store.getState().swap.destinationKind; - let pairName = combineAndUpper(newOriginKind, destinationKind); - let bityRate = this.props.bityRates[pairName]; - this.props.swapDestinationAmountTo(parseFloat(this.props.originAmount) * bityRate) - } + return ( +
+

{translate('SWAP_init_1')}

+ 0 + ? 'is-valid' + : 'is-invalid'}`} + type="number" + placeholder="Amount" + onChange={e => this.onChangeOriginAmount(e.target.value)} + value={originAmount} + /> - render() { - const { - originAmount, - destinationAmount, - originKind, - destinationKind, - destinationKindOptions, - originKindOptions - } = this.props; + - return ( -
-

{translate('SWAP_init_1')}

- 0) ? 'is-valid' : 'is-invalid'}`} - type="number" - placeholder="Amount" - onChange={(e) => this.onChangeOriginAmount(e.target.value)} - value={originAmount}/> +

{translate('SWAP_init_2')}

- + 0 + ? 'is-valid' + : 'is-invalid'}`} + type="number" + placeholder="Amount" + value={destinationAmount} + onChange={e => this.onChangeDestinationAmount(e.target.value)} + /> + -

{translate('SWAP_init_2')}

- - 0) ? 'is-valid' : 'is-invalid'}`} - type="number" - placeholder="Amount" - value={destinationAmount} - onChange={(e) => this.onChangeDestinationAmount(e.target.value)}/> - - - -
-
- - ) - } + +
+ ); + } } From 67a5eee0a9110152e8bb3c2c8ca19dacd9776fff Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 00:39:07 -0500 Subject: [PATCH 13/19] Reformat --- common/actions/swap.js | 54 ++--- common/api/bity.js | 94 ++++--- common/config/bity.js | 32 +-- .../Tabs/Swap/components/currentRates.js | 174 ++++++++----- common/containers/Tabs/Swap/index.js | 229 +++++++++--------- common/reducers/swap.js | 106 ++++---- 6 files changed, 373 insertions(+), 316 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index f1d1b007..26af68ce 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -3,42 +3,38 @@ export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; -export const SWAP_DESTINATION_KIND_OPTIONS = 'SWAP_DESTINATION_KIND_OPTIONS' -export const SWAP_ORIGIN_KIND_TO = (value) => { - return { - type: SWAP_ORIGIN_KIND, - value - }; +export const SWAP_ORIGIN_KIND_TO = value => { + return { + type: SWAP_ORIGIN_KIND, + value + }; }; -export const SWAP_DESTINATION_KIND_TO = (value) => { - return { - type: SWAP_DESTINATION_KIND, - value - } +export const SWAP_DESTINATION_KIND_TO = value => { + return { + type: SWAP_DESTINATION_KIND, + value + }; }; -export const SWAP_ORIGIN_AMOUNT_TO = (value) => { - return { - type: SWAP_ORIGIN_AMOUNT, - value - }; +export const SWAP_ORIGIN_AMOUNT_TO = value => { + return { + type: SWAP_ORIGIN_AMOUNT, + value + }; }; -export const SWAP_DESTINATION_AMOUNT_TO = (value) => { - return { - type: SWAP_DESTINATION_AMOUNT, - value - } +export const SWAP_DESTINATION_AMOUNT_TO = value => { + return { + type: SWAP_DESTINATION_AMOUNT, + value + }; }; -export const SWAP_UPDATE_BITY_RATES_TO = (value) => { - return { - type: SWAP_UPDATE_BITY_RATES, - value - } +export const SWAP_UPDATE_BITY_RATES_TO = value => { + return { + type: SWAP_UPDATE_BITY_RATES, + value + }; }; - - - diff --git a/common/api/bity.js b/common/api/bity.js index c9d1393c..cf3a7f9e 100644 --- a/common/api/bity.js +++ b/common/api/bity.js @@ -3,62 +3,60 @@ import bityConfig from 'config/bity'; // https://stackoverflow.com/questions/9828684/how-to-get-all-arguments-of-a-callback-function export function combineAndUpper() { - const args = []; - let newString = ''; - for (let i = 0; i < arguments.length; ++i) args[i] = arguments[i]; - args.forEach((each) => { - newString = newString.concat(each.toUpperCase()) - }); - return newString + const args = []; + let newString = ''; + for (let i = 0; i < arguments.length; ++i) args[i] = arguments[i]; + args.forEach(each => { + newString = newString.concat(each.toUpperCase()); + }); + return newString; } export default class Bity { - findRateFromBityRateList(rateObjects, pairName) { - return rateObjects.find(x => x.pair === pairName); - } + findRateFromBityRateList(rateObjects, pairName) { + return rateObjects.find(x => x.pair === pairName); + } - _getRate(bityRates, origin, destination) { - const pairName = combineAndUpper(origin, destination); - const rateObjects = bityRates.data.objects; - return this.findRateFromBityRateList(rateObjects, pairName); - } + _getRate(bityRates, origin, destination) { + const pairName = combineAndUpper(origin, destination); + const rateObjects = bityRates.data.objects; + return this.findRateFromBityRateList(rateObjects, pairName); + } - /** + /** * Gives you multiple rates from Bitys API without making multiple API calls * @param arrayOfOriginAndDestinationDicts - [{origin: 'BTC', destination: 'ETH'}, {origin: 'BTC', destination: 'REP}] */ - getMultipleRates(arrayOfOriginAndDestinationDicts) { - const mappedRates = {}; - return this.requestAllRates() - .then((bityRates) => { - arrayOfOriginAndDestinationDicts.forEach((each) => { - const origin = each.origin; - const destination = each.destination; - const pairName = combineAndUpper(origin, destination); - const rate = this._getRate(bityRates, origin, destination); - mappedRates[pairName] = parseFloat(rate.rate_we_sell) - }); - return mappedRates - }) - // TODO - catch errors - } + getMultipleRates(arrayOfOriginAndDestinationDicts) { + const mappedRates = {}; + return this.requestAllRates().then(bityRates => { + arrayOfOriginAndDestinationDicts.forEach(each => { + const origin = each.origin; + const destination = each.destination; + const pairName = combineAndUpper(origin, destination); + const rate = this._getRate(bityRates, origin, destination); + mappedRates[pairName] = parseFloat(rate.rate_we_sell); + }); + return mappedRates; + }); + // TODO - catch errors + } - getAllRates() { - const mappedRates = {}; - return this.requestAllRates() - .then((bityRates) => { - bityRates.data.objects.forEach((each) => { - const pairName = each.pair; - mappedRates[pairName] = parseFloat(each.rate_we_sell) - }); - return mappedRates - }) - // TODO - catch errors - } + getAllRates() { + const mappedRates = {}; + return this.requestAllRates().then(bityRates => { + bityRates.data.objects.forEach(each => { + const pairName = each.pair; + mappedRates[pairName] = parseFloat(each.rate_we_sell); + }); + return mappedRates; + }); + // TODO - catch errors + } - requestAllRates() { - const path = '/v1/rate2/'; - const bityURL = bityConfig.bityAPI + path; - return axios.get(bityURL) - } + requestAllRates() { + const path = '/v1/rate2/'; + const bityURL = bityConfig.bityAPI + path; + return axios.get(bityURL); + } } diff --git a/common/config/bity.js b/common/config/bity.js index 2c4b0632..b3350f3d 100644 --- a/common/config/bity.js +++ b/common/config/bity.js @@ -1,18 +1,18 @@ export default { - SERVERURL: 'https://myetherapi.com', - bityAPI: 'https://bity.com/api', - decimals: 6, - ethExplorer: 'https://etherscan.io/tx/[[txHash]]', - btcExplorer: 'https://blockchain.info/tx/[[txHash]]', - validStatus: ['RCVE', 'FILL', 'CONF', 'EXEC'], - invalidStatus: ['CANC'], - mainPairs: ['REP', 'ETH'], - min: 0.01, - max: 3, - priceLoaded: false, - postConfig: { - headers: { - 'Content-Type': 'application/json; charse:UTF-8' - } + SERVERURL: 'https://myetherapi.com', + bityAPI: 'https://bity.com/api', + decimals: 6, + ethExplorer: 'https://etherscan.io/tx/[[txHash]]', + btcExplorer: 'https://blockchain.info/tx/[[txHash]]', + validStatus: ['RCVE', 'FILL', 'CONF', 'EXEC'], + invalidStatus: ['CANC'], + mainPairs: ['REP', 'ETH'], + min: 0.01, + max: 3, + priceLoaded: false, + postConfig: { + headers: { + 'Content-Type': 'application/json; charse:UTF-8' } -} + } +}; diff --git a/common/containers/Tabs/Swap/components/currentRates.js b/common/containers/Tabs/Swap/components/currentRates.js index e22e1870..577df5a4 100644 --- a/common/containers/Tabs/Swap/components/currentRates.js +++ b/common/containers/Tabs/Swap/components/currentRates.js @@ -1,73 +1,117 @@ -import React, {Component} from 'react'; +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 + constructor(props) { + super(props); + this.state = { + ETHBTCAmount: 1, + ETHREPAmount: 1, + BTCETHAmount: 1, + BTCREPAmount: 1 }; + } - onChange = (event) => { - const target = event.target; - const value = target.value; - const name = target.name; - this.setState({ - [name]: value - }); - }; + static propTypes = { + ETHBTC: PropTypes.number, + ETHREP: PropTypes.number, + BTCETH: PropTypes.number, + BTCREP: PropTypes.number + }; - // TODO - A little code duplication here, but simple enough to where it doesn't seem worth the time to fix. - render() { - return ( -
-
-
{translate('SWAP_rates')}
-
-
-
-

- - ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed(6)} BTC -

-

- - ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed(6)} REP -

-
-
-

- - BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed(6)} ETH -

-

- - BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed(6)} REP -

-
- - - -
-
- ) - } + 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 ( +
+
+
+ {translate('SWAP_rates')} +
+
+
+
+

+ + + ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed( + 6 + )}{' '} + BTC + +

+

+ + + ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed( + 6 + )}{' '} + REP + +

+
+
+

+ + + BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed( + 6 + )}{' '} + ETH + +

+

+ + + BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed( + 6 + )}{' '} + REP + +

+
+ + + +
+
+ ); + } } diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 07894f82..146c7831 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -1,130 +1,141 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; import WantToSwapMy from './components/wantToSwapMy'; import CurrentRates from './components/currentRates'; -import {connect} from 'react-redux'; +import { connect } from 'react-redux'; import { - SWAP_DESTINATION_AMOUNT_TO, - SWAP_DESTINATION_KIND_TO, - SWAP_ORIGIN_AMOUNT_TO, - SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO, - SWAP_ORIGIN_KIND_TO, - SWAP_UPDATE_BITY_RATES_TO + SWAP_DESTINATION_AMOUNT_TO, + SWAP_DESTINATION_KIND_TO, + SWAP_ORIGIN_AMOUNT_TO, + SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_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(); - } + 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, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func + 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, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func + }; + + componentDidMount() { + let { bityRates } = this.props; + + if ( + !bityRates.ETHBTC || + !bityRates.ETHREP || + !bityRates.BTCETH || + !bityRates.BTCREP + ) { + this.bity.getAllRates().then(data => { + this.props.swapUpdateBityRatesTo(data); + }); + } + } + + render() { + let { + bityRates, + originAmount, + destinationAmount, + originKind, + destinationKind, + destinationKindOptions, + originKindOptions, + swapOriginKindTo, + swapDestinationKindTo, + swapOriginAmountTo, + swapDestinationAmountTo, + swapOriginKindAndDestinationKindAndDestinationOptionsTo + } = this.props; + + let wantToSwapMyProps = { + bityRates, + originAmount, + destinationAmount, + originKind, + destinationKind, + destinationKindOptions, + originKindOptions, + swapOriginKindTo, + swapDestinationKindTo, + swapOriginAmountTo, + swapDestinationAmountTo, + swapOriginKindAndDestinationKindAndDestinationOptionsTo }; - componentDidMount() { - let {bityRates} = this.props; - - if (!bityRates.ETHBTC || !bityRates.ETHREP || !bityRates.BTCETH || !bityRates.BTCREP) { - this.bity.getAllRates() - .then((data) => { - this.props.swapUpdateBityRatesTo(data); - }) - } - } - - render() { - let { - bityRates, - originAmount, - destinationAmount, - originKind, - destinationKind, - destinationKindOptions, - originKindOptions, - swapOriginKindTo, - swapDestinationKindTo, - swapOriginAmountTo, - swapDestinationAmountTo, - swapOriginKindAndDestinationKindAndDestinationOptionsTo - } = this.props; - - let wantToSwapMyProps = { - bityRates, - originAmount, - destinationAmount, - originKind, - destinationKind, - destinationKindOptions, - originKindOptions, - swapOriginKindTo, - swapDestinationKindTo, - swapOriginAmountTo, - swapDestinationAmountTo, - swapOriginKindAndDestinationKindAndDestinationOptionsTo - }; - - return ( -
-
-
- - -
-
-
- ) - } + return ( +
+
+
+ + +
+
+
+ ); + } } 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 - } + 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)) - }, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: (originKind, destinationKind) => { - dispatch(SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO(originKind, destinationKind)) - - } + 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)); + }, + swapOriginKindAndDestinationKindAndDestinationOptionsTo: ( + originKind, + destinationKind + ) => { + dispatch( + SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO( + originKind, + destinationKind + ) + ); } + }; } -export default connect(mapStateToProps, mapDispatchToProps)(Swap) +export default connect(mapStateToProps, mapDispatchToProps)(Swap); diff --git a/common/reducers/swap.js b/common/reducers/swap.js index c6690c61..475cb0b4 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -1,60 +1,68 @@ import { - SWAP_DESTINATION_AMOUNT, - SWAP_DESTINATION_KIND, - SWAP_ORIGIN_AMOUNT, - SWAP_ORIGIN_KIND, - SWAP_UPDATE_BITY_RATES + SWAP_DESTINATION_AMOUNT, + SWAP_DESTINATION_KIND, + SWAP_ORIGIN_AMOUNT, + SWAP_ORIGIN_KIND, + SWAP_UPDATE_BITY_RATES } from 'actions/swap'; export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; - const initialState = { - originAmount: 0, - destinationAmount: 0, - originKind: 'BTC', - destinationKind: 'ETH', - destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== 'BTC'), - originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== 'REP'), - bityRates: {} + originAmount: 0, + destinationAmount: 0, + originKind: 'BTC', + destinationKind: 'ETH', + destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( + element => element !== 'BTC' + ), + originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( + element => element !== 'REP' + ), + bityRates: {} }; - export function swap(state = initialState, action) { - switch (action.type) { - case SWAP_ORIGIN_KIND: { - return { - ...state, - originKind: action.value, - destinationKind: action.value === state.destinationKind ? ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== action.value)[0] : state.destinationKind, - destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== action.value) - }; - } - case SWAP_DESTINATION_KIND: { - return { - ...state, - destinationKind: action.value - }; - } - case SWAP_ORIGIN_AMOUNT: - return { - ...state, - originAmount: action.value - }; - case SWAP_DESTINATION_AMOUNT: - return { - ...state, - destinationAmount: action.value - }; - case SWAP_UPDATE_BITY_RATES: - return { - ...state, - bityRates: { - ...state.bityRates, - ...action.value - } - }; - default: - return state + switch (action.type) { + case SWAP_ORIGIN_KIND: { + return { + ...state, + originKind: action.value, + destinationKind: action.value === state.destinationKind + ? ALL_CRYPTO_KIND_OPTIONS.filter( + element => element !== action.value + )[0] + : state.destinationKind, + destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( + element => element !== action.value + ) + }; } + case SWAP_DESTINATION_KIND: { + return { + ...state, + destinationKind: action.value + }; + } + case SWAP_ORIGIN_AMOUNT: + return { + ...state, + originAmount: action.value + }; + case SWAP_DESTINATION_AMOUNT: + return { + ...state, + destinationAmount: action.value + }; + case SWAP_UPDATE_BITY_RATES: + return { + ...state, + bityRates: { + ...state.bityRates, + ...action.value + } + }; + default: + return state; + } } From 6f638c66da7c4a8eb327a1adf6bd0c94a4a92a04 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 00:39:57 -0500 Subject: [PATCH 14/19] remove unused actions --- common/containers/Tabs/Swap/index.js | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 146c7831..0c8f0a71 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -6,7 +6,6 @@ import { SWAP_DESTINATION_AMOUNT_TO, SWAP_DESTINATION_KIND_TO, SWAP_ORIGIN_AMOUNT_TO, - SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO, SWAP_ORIGIN_KIND_TO, SWAP_UPDATE_BITY_RATES_TO } from 'actions/swap'; @@ -32,8 +31,7 @@ class Swap extends Component { swapDestinationKindTo: PropTypes.func, swapOriginAmountTo: PropTypes.func, swapDestinationAmountTo: PropTypes.func, - swapUpdateBityRatesTo: PropTypes.func, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func + swapUpdateBityRatesTo: PropTypes.func }; componentDidMount() { @@ -63,8 +61,7 @@ class Swap extends Component { swapOriginKindTo, swapDestinationKindTo, swapOriginAmountTo, - swapDestinationAmountTo, - swapOriginKindAndDestinationKindAndDestinationOptionsTo + swapDestinationAmountTo } = this.props; let wantToSwapMyProps = { @@ -78,8 +75,7 @@ class Swap extends Component { swapOriginKindTo, swapDestinationKindTo, swapOriginAmountTo, - swapDestinationAmountTo, - swapOriginKindAndDestinationKindAndDestinationOptionsTo + swapDestinationAmountTo }; return ( @@ -123,17 +119,6 @@ function mapDispatchToProps(dispatch) { }, swapUpdateBityRatesTo: bityRates => { dispatch(SWAP_UPDATE_BITY_RATES_TO(bityRates)); - }, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: ( - originKind, - destinationKind - ) => { - dispatch( - SWAP_ORIGIN_KIND_AND_DESTINATION_KIND_AND_DESTINATION_OPTIONS_TO( - originKind, - destinationKind - ) - ); } }; } From 67d57c3d4ba000b3e0e813884dfa93e5e6c714f7 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 00:49:52 -0500 Subject: [PATCH 15/19] remove eslint warning because store was undefined since it was global --- common/containers/Tabs/Swap/components/wantToSwapMy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index 5498e7aa..befcbadd 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -99,6 +99,7 @@ export default class WantToSwapMy extends Component { let newOriginKind = event.target.value; this.props.swapOriginKindTo(newOriginKind); // https://github.com/reactjs/redux/issues/1543#issuecomment-201399259 + let store = window.store; let destinationKind = store.getState().swap.destinationKind; let pairName = combineAndUpper(newOriginKind, destinationKind); let bityRate = this.props.bityRates[pairName]; From e7d8284d699cd1a5c4cf3cc76c7a566a091fd9ce Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 18:35:14 -0500 Subject: [PATCH 16/19] move state building into swap reducer instead of in wantToSwapMy component --- common/actions/swap.js | 26 ++++++--- common/actions/swapConstants.js | 5 ++ .../Tabs/Swap/components/wantToSwapMy.js | 42 +++++--------- common/containers/Tabs/Swap/index.js | 58 +++++-------------- common/reducers/swap.js | 50 +++++++++++++--- 5 files changed, 95 insertions(+), 86 deletions(-) create mode 100644 common/actions/swapConstants.js diff --git a/common/actions/swap.js b/common/actions/swap.js index 26af68ce..5f54b07a 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -1,20 +1,28 @@ -export const SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND'; -export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; -export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; -export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; -export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; +import { + SWAP_DESTINATION_AMOUNT, + SWAP_DESTINATION_KIND, + SWAP_ORIGIN_AMOUNT, + SWAP_ORIGIN_KIND, + SWAP_UPDATE_BITY_RATES +} from './swapConstants'; -export const SWAP_ORIGIN_KIND_TO = value => { +export const SWAP_ORIGIN_KIND_TO = (originKind, bityRates) => { return { type: SWAP_ORIGIN_KIND, - value + payload: { + originKind, + bityRates + } }; }; -export const SWAP_DESTINATION_KIND_TO = value => { +export const SWAP_DESTINATION_KIND_TO = (destinationKind, bityRates) => { return { type: SWAP_DESTINATION_KIND, - value + payload: { + destinationKind, + bityRates + } }; }; diff --git a/common/actions/swapConstants.js b/common/actions/swapConstants.js new file mode 100644 index 00000000..ca72fc2c --- /dev/null +++ b/common/actions/swapConstants.js @@ -0,0 +1,5 @@ +export const SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND'; +export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND'; +export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT'; +export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT'; +export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES'; diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index befcbadd..c8e4a51a 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -44,10 +44,10 @@ export default class WantToSwapMy extends Component { destinationKind: PropTypes.string, destinationKindOptions: PropTypes.array, originKindOptions: PropTypes.array, - swapOriginKindTo: PropTypes.func, - swapDestinationKindTo: PropTypes.func, - swapOriginAmountTo: PropTypes.func, - swapDestinationAmountTo: PropTypes.func, + SWAP_ORIGIN_KIND_TO: PropTypes.func, + SWAP_DESTINATION_KIND_TO: PropTypes.func, + SWAP_ORIGIN_AMOUNT_TO: PropTypes.func, + SWAP_DESTINATION_AMOUNT_TO: PropTypes.func, swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func }; @@ -61,51 +61,41 @@ export default class WantToSwapMy extends Component { this.props.destinationKind ); let bityRate = this.props.bityRates[pairName]; - this.props.swapOriginAmountTo(originAmountAsNumber); - this.props.swapDestinationAmountTo(originAmountAsNumber * bityRate); + this.props.SWAP_ORIGIN_AMOUNT_TO(originAmountAsNumber); + this.props.SWAP_DESTINATION_AMOUNT_TO(originAmountAsNumber * bityRate); } else { - this.props.swapOriginAmountTo(''); - this.props.swapDestinationAmountTo(''); + this.props.SWAP_ORIGIN_AMOUNT_TO(''); + this.props.SWAP_DESTINATION_AMOUNT_TO(''); } }; onChangeDestinationAmount(amount) { let destinationAmountAsNumber = parseFloat(amount); if (destinationAmountAsNumber) { - this.props.swapDestinationAmountTo(destinationAmountAsNumber); + this.props.SWAP_DESTINATION_AMOUNT_TO(destinationAmountAsNumber); let pairName = combineAndUpper( this.props.destinationKind, this.props.originKind ); let bityRate = this.props.bityRates[pairName]; - this.props.swapOriginAmountTo(destinationAmountAsNumber * bityRate); + this.props.SWAP_ORIGIN_AMOUNT_TO(destinationAmountAsNumber * bityRate); } else { - this.props.swapOriginAmountTo(''); - this.props.swapDestinationAmountTo(''); + this.props.SWAP_ORIGIN_AMOUNT_TO(''); + this.props.SWAP_DESTINATION_AMOUNT_TO(''); } } async onChangeDestinationKind(event) { let newDestinationKind = event.target.value; - this.props.swapDestinationKindTo(newDestinationKind); - let pairName = combineAndUpper(this.props.originKind, newDestinationKind); - let bityRate = this.props.bityRates[pairName]; - this.props.swapDestinationAmountTo( - parseFloat(this.props.originAmount) * bityRate + this.props.SWAP_DESTINATION_KIND_TO( + newDestinationKind, + this.props.bityRates ); } async onChangeOriginKind(event) { let newOriginKind = event.target.value; - this.props.swapOriginKindTo(newOriginKind); - // https://github.com/reactjs/redux/issues/1543#issuecomment-201399259 - let store = window.store; - let destinationKind = store.getState().swap.destinationKind; - let pairName = combineAndUpper(newOriginKind, destinationKind); - let bityRate = this.props.bityRates[pairName]; - this.props.swapDestinationAmountTo( - parseFloat(this.props.originAmount) * bityRate - ); + this.props.SWAP_ORIGIN_KIND_TO(newOriginKind, this.props.bityRates); } render() { diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 0c8f0a71..e428371b 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -2,13 +2,7 @@ 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 * as swapActions from 'actions/swap'; import PropTypes from 'prop-types'; import Bity from 'api/bity'; @@ -27,11 +21,11 @@ class Swap extends Component { destinationKind: PropTypes.string, destinationKindOptions: PropTypes.array, originKindOptions: PropTypes.array, - swapOriginKindTo: PropTypes.func, - swapDestinationKindTo: PropTypes.func, - swapOriginAmountTo: PropTypes.func, - swapDestinationAmountTo: PropTypes.func, - swapUpdateBityRatesTo: PropTypes.func + SWAP_ORIGIN_KIND_TO: PropTypes.func, + SWAP_DESTINATION_KIND_TO: PropTypes.func, + SWAP_ORIGIN_AMOUNT_TO: PropTypes.func, + SWAP_DESTINATION_AMOUNT_TO: PropTypes.func, + SWAP_UPDATE_BITY_RATES_TO: PropTypes.func }; componentDidMount() { @@ -44,7 +38,7 @@ class Swap extends Component { !bityRates.BTCREP ) { this.bity.getAllRates().then(data => { - this.props.swapUpdateBityRatesTo(data); + this.props.SWAP_UPDATE_BITY_RATES_TO(data); }); } } @@ -58,10 +52,10 @@ class Swap extends Component { destinationKind, destinationKindOptions, originKindOptions, - swapOriginKindTo, - swapDestinationKindTo, - swapOriginAmountTo, - swapDestinationAmountTo + SWAP_ORIGIN_KIND_TO, + SWAP_DESTINATION_KIND_TO, + SWAP_ORIGIN_AMOUNT_TO, + SWAP_DESTINATION_AMOUNT_TO } = this.props; let wantToSwapMyProps = { @@ -72,10 +66,10 @@ class Swap extends Component { destinationKind, destinationKindOptions, originKindOptions, - swapOriginKindTo, - swapDestinationKindTo, - swapOriginAmountTo, - swapDestinationAmountTo + SWAP_ORIGIN_KIND_TO, + SWAP_DESTINATION_KIND_TO, + SWAP_ORIGIN_AMOUNT_TO, + SWAP_DESTINATION_AMOUNT_TO }; return ( @@ -103,24 +97,4 @@ function mapStateToProps(state) { }; } -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); +export default connect(mapStateToProps, swapActions)(Swap); diff --git a/common/reducers/swap.js b/common/reducers/swap.js index 475cb0b4..ddfce4ef 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -4,7 +4,8 @@ import { SWAP_ORIGIN_AMOUNT, SWAP_ORIGIN_KIND, SWAP_UPDATE_BITY_RATES -} from 'actions/swap'; +} from 'actions/swapConstants'; +import { combineAndUpper } from 'api/bity'; export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; @@ -22,26 +23,57 @@ const initialState = { bityRates: {} }; +const buildDestinationAmount = ( + originAmount, + originKind, + destinationKind, + bityRates +) => { + let pairName = combineAndUpper(originKind, destinationKind); + let bityRate = bityRates[pairName]; + return originAmount * bityRate; +}; + +const buildDestinationKind = (originKind, destinationKind) => { + if (originKind === destinationKind) { + return ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== originKind)[0]; + } else { + return destinationKind; + } +}; + export function swap(state = initialState, action) { switch (action.type) { case SWAP_ORIGIN_KIND: { + const newDestinationKind = buildDestinationKind( + action.payload.originKind, + state.destinationKind + ); return { ...state, - originKind: action.value, - destinationKind: action.value === state.destinationKind - ? ALL_CRYPTO_KIND_OPTIONS.filter( - element => element !== action.value - )[0] - : state.destinationKind, + originKind: action.payload.originKind, + destinationKind: newDestinationKind, destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( - element => element !== action.value + element => element !== action.payload.originKind + ), + destinationAmount: buildDestinationAmount( + state.originAmount, + action.payload.originKind, + newDestinationKind, + action.payload.bityRates ) }; } case SWAP_DESTINATION_KIND: { return { ...state, - destinationKind: action.value + destinationKind: action.payload.destinationKind, + destinationAmount: buildDestinationAmount( + state.originAmount, + state.originKind, + action.payload.destinationKind, + action.payload.bityRates + ) }; } case SWAP_ORIGIN_AMOUNT: From c820cf8ce3ae8a65f3b810a7c20040b97beecfb5 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 18:35:52 -0500 Subject: [PATCH 17/19] remove unused propType --- common/containers/Tabs/Swap/components/wantToSwapMy.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index c8e4a51a..8a25e992 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -47,8 +47,7 @@ export default class WantToSwapMy extends Component { SWAP_ORIGIN_KIND_TO: PropTypes.func, SWAP_DESTINATION_KIND_TO: PropTypes.func, SWAP_ORIGIN_AMOUNT_TO: PropTypes.func, - SWAP_DESTINATION_AMOUNT_TO: PropTypes.func, - swapOriginKindAndDestinationKindAndDestinationOptionsTo: PropTypes.func + SWAP_DESTINATION_AMOUNT_TO: PropTypes.func }; onClickStartSwap() {} From e6ce0b928aff7816b18adcab41326193cd9ff865 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Mon, 19 Jun 2017 18:41:45 -0500 Subject: [PATCH 18/19] don't put store on window anymore --- common/index.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/common/index.jsx b/common/index.jsx index e025c889..aef1ef3b 100644 --- a/common/index.jsx +++ b/common/index.jsx @@ -37,7 +37,6 @@ const configureStore = () => { const renderRoot = (Root) => { let store = configureStore(); - window.store = store; let syncedHistory = syncHistoryWithStore(history, store); render( Date: Mon, 19 Jun 2017 18:47:11 -0500 Subject: [PATCH 19/19] don't pass around bityRates when you can access from state in reducer --- common/actions/swap.js | 14 ++++---------- .../Tabs/Swap/components/wantToSwapMy.js | 7 ++----- common/reducers/swap.js | 16 ++++++++-------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index 5f54b07a..334d6a7e 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -6,23 +6,17 @@ import { SWAP_UPDATE_BITY_RATES } from './swapConstants'; -export const SWAP_ORIGIN_KIND_TO = (originKind, bityRates) => { +export const SWAP_ORIGIN_KIND_TO = value => { return { type: SWAP_ORIGIN_KIND, - payload: { - originKind, - bityRates - } + value }; }; -export const SWAP_DESTINATION_KIND_TO = (destinationKind, bityRates) => { +export const SWAP_DESTINATION_KIND_TO = value => { return { type: SWAP_DESTINATION_KIND, - payload: { - destinationKind, - bityRates - } + value }; }; diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index 8a25e992..a8efd912 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -86,15 +86,12 @@ export default class WantToSwapMy extends Component { async onChangeDestinationKind(event) { let newDestinationKind = event.target.value; - this.props.SWAP_DESTINATION_KIND_TO( - newDestinationKind, - this.props.bityRates - ); + this.props.SWAP_DESTINATION_KIND_TO(newDestinationKind); } async onChangeOriginKind(event) { let newOriginKind = event.target.value; - this.props.SWAP_ORIGIN_KIND_TO(newOriginKind, this.props.bityRates); + this.props.SWAP_ORIGIN_KIND_TO(newOriginKind); } render() { diff --git a/common/reducers/swap.js b/common/reducers/swap.js index ddfce4ef..b827df05 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -46,33 +46,33 @@ export function swap(state = initialState, action) { switch (action.type) { case SWAP_ORIGIN_KIND: { const newDestinationKind = buildDestinationKind( - action.payload.originKind, + action.value, state.destinationKind ); return { ...state, - originKind: action.payload.originKind, + originKind: action.value, destinationKind: newDestinationKind, destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( - element => element !== action.payload.originKind + element => element !== action.value ), destinationAmount: buildDestinationAmount( state.originAmount, - action.payload.originKind, + action.value, newDestinationKind, - action.payload.bityRates + state.bityRates ) }; } case SWAP_DESTINATION_KIND: { return { ...state, - destinationKind: action.payload.destinationKind, + destinationKind: action.value, destinationAmount: buildDestinationAmount( state.originAmount, state.originKind, - action.payload.destinationKind, - action.payload.bityRates + action.value, + state.bityRates ) }; }