diff --git a/app/components/DepositWithdraw/DepositWithdrawAssetSelector.js b/app/components/DepositWithdraw/DepositWithdrawAssetSelector.js index 9ce470b9f5..5c94e89a1c 100644 --- a/app/components/DepositWithdraw/DepositWithdrawAssetSelector.js +++ b/app/components/DepositWithdraw/DepositWithdrawAssetSelector.js @@ -2,76 +2,141 @@ import React from "react"; import {connect} from "alt-react"; import BindToChainState from "../Utility/BindToChainState"; import GatewayStore from "stores/GatewayStore"; -import TypeAhead from "../Utility/TypeAhead"; import counterpart from "counterpart"; +import {Select} from "bitshares-ui-style-guide"; class DepositWithdrawAssetSelector extends React.Component { constructor(props) { super(props); - } - render() { - const {props} = this; - const {include} = props; - let idMap = {}; - - let getCoinOption = item => { - /* Gateway Specific Settings */ - let [gateway, backedCoin] = item.symbol.split("."); - - // Return null if backedCoin is already stored - if (!idMap[backedCoin] && backedCoin && gateway) { - idMap[backedCoin] = true; - - return { - id: backedCoin, - label: backedCoin, - gateway: gateway, - gateFee: item.gateFee, - issuer: item.issuerId || "1.2.96397" //Fall back to open ledger - }; - } else { - return null; - } + this.state = { + assets: [] }; + } - let coinArr = []; + componentDidMount() { + this.getAssets(); + } - if (!(this.props.includeBTS === false)) { - coinArr.push({id: "BTS", label: "BTS", gateway: ""}); - } + getAssets() { + let {backedCoins, include, includeBTS} = this.props; + let {assets} = this.state; - props.backedCoins.forEach(coin => { - coinArr = coinArr - .concat(coin.map(getCoinOption)) - .filter(item => { - return item; + let idMap = {}; + + backedCoins.forEach(coin => { + assets = assets + .concat(coin.map( + item => { + /* Gateway Specific Settings */ + let [gateway, backedCoin] = item.symbol.split("."); + + // Return null if backedCoin is already stored + if (!idMap[backedCoin] && backedCoin && gateway) { + idMap[backedCoin] = true; + + return { + id: backedCoin, + label: backedCoin, + gateway: gateway, + gateFee: item.gateFee, + issuer: item.issuerId || "1.2.96397" //Fall back to open ledger + }; + } else { + return null; + } + } + )) + .filter(item => { + return item; }) .filter(item => { - if (item.id == "BTS") return true; - if (include) { - return include.includes(item.id); - } + if (item.id == "BTS") { return true; } + if (include) { return include.includes(item.id); } return true; }); }); - let coinItems = coinArr.sort(function(a, b) { - if (a.id && b.id) return a.id.localeCompare(b.id); + if (!(includeBTS === false)) { + assets.push({id: "BTS", label: "BTS", gateway: ""}); + } + + this.setState({ + assets: assets }); - let i18n = - props.usageContext == "withdraw" - ? "gateway.asset_search_withdraw" - : "gateway.asset_search_deposit"; + } + + getSelectedAssetArray(selectedAsset) { + let {assets} = this.state; + + let asset; + + assets.map(a => { + if(a.id == selectedAsset) { + asset = a; + } + }); + + return asset; + } + + _onSelect(selectedAsset) { + let {onSelect} = this.props; + let asset = this.getSelectedAssetArray(selectedAsset); + + if(onSelect) { + onSelect(asset); + } + } + + _onInputChanged(selectedAsset) { + let {onChange} = this.props; + let asset = this.getSelectedAssetArray(selectedAsset); + + if(onChange) { + onChange(asset.id); + } + } + + render() { + let {usageContext} = this.props; + + let coinItems = this.state.assets.sort(function(a, b) { + if (a.id && b.id) return a.id.localeCompare(b.id); + }); return ( - + ); } } diff --git a/app/components/Modal/DepositModal.jsx b/app/components/Modal/DepositModal.jsx index 7567002bbe..8df1f284cd 100644 --- a/app/components/Modal/DepositModal.jsx +++ b/app/components/Modal/DepositModal.jsx @@ -24,14 +24,7 @@ class DepositModalContent extends DecimalChecker { constructor() { super(); - this.state = { - depositAddress: "", - selectedAsset: "", - selectedGateway: null, - fetchingAddress: false, - backingAsset: null, - gatewayStatus: availableGateways - }; + this.state = this._intitalState(); this.deposit_address_cache = new BlockTradesDepositAddressCache(); this.addDepositAddress = this.addDepositAddress.bind(this); @@ -48,23 +41,23 @@ class DepositModalContent extends DecimalChecker { shouldComponentUpdate(np, ns) { if(np.asset !== this.props.asset) { + this.setState(this._intitalState()); this._setDepositAsset(np.asset); } return !utils.are_equal_shallow(ns, this.state); } - onGatewayChanged(e) { - if (!e.target.value) return; - this._getDepositAddress(this.state.selectedAsset, e.target.value); + onGatewayChanged(selectedGateway) { + this._getDepositAddress(this.state.selectedAsset, selectedGateway); } - onAssetSelected(asset, assetDetails) { - if (assetDetails.gateway == "") - return this.setState({selectedAsset: asset, selectedGateway: null}); + onAssetSelected(asset) { + if (asset.gateway == "") + return this.setState({selectedAsset: asset.id, selectedGateway: null}); let {selectedAsset, selectedGateway} = _onAssetSelected.call( this, - asset, + asset.id, "depositAllowed", (availableGateways, balancesByGateway) => { if (availableGateways && availableGateways.length == 1) @@ -78,10 +71,21 @@ class DepositModalContent extends DecimalChecker { } } + _intitalState() { + return { + depositAddress: "", + selectedAsset: "", + selectedGateway: null, + fetchingAddress: false, + backingAsset: null, + gatewayStatus: availableGateways + }; + } + _setDepositAsset(asset) { let coinToGatewayMapping = _getCoinToGatewayMapping.call(this); this.setState({coinToGatewayMapping}); - + if (!asset) return; let backedAsset = asset.split("."); @@ -264,7 +268,7 @@ class DepositModalContent extends DecimalChecker { const QR = isAddressValid ? ( ) : ( @@ -287,7 +291,7 @@ class DepositModalContent extends DecimalChecker {
@@ -306,9 +310,9 @@ class DepositModalContent extends DecimalChecker { : null} {!fetchingAddress ? ( - (!usingGateway || - (usingGateway && - selectedGateway && + (!usingGateway || + (usingGateway && + selectedGateway && gatewayStatus[selectedGateway].options .enabled)) && isAddressValid && @@ -323,7 +327,7 @@ class DepositModalContent extends DecimalChecker { ) : (
diff --git a/app/components/Modal/WithdrawModalNew.jsx b/app/components/Modal/WithdrawModalNew.jsx index a6c76c319c..56dc50d4ba 100644 --- a/app/components/Modal/WithdrawModalNew.jsx +++ b/app/components/Modal/WithdrawModalNew.jsx @@ -3,6 +3,7 @@ import BindToChainState from "components/Utility/BindToChainState"; import DepositWithdrawAssetSelector from "../DepositWithdraw/DepositWithdrawAssetSelector"; import Translate from "react-translate-component"; import ExchangeInput from "components/Exchange/ExchangeInput"; +import AssetName from "../Utility/AssetName"; import {extend, debounce} from "lodash-es"; import GatewayStore from "stores/GatewayStore"; import AssetStore from "stores/AssetStore"; @@ -21,7 +22,7 @@ import ChainTypes from "../Utility/ChainTypes"; import FormattedAsset from "../Utility/FormattedAsset"; import BalanceComponent from "../Utility/BalanceComponent"; import QRScanner from "../QRAddressScanner"; -import {Modal, Button} from "bitshares-ui-style-guide"; +import {Modal, Button, Select} from "bitshares-ui-style-guide"; import counterpart from "counterpart"; import { gatewaySelector, @@ -29,22 +30,20 @@ import { _onAssetSelected, _getCoinToGatewayMapping } from "lib/common/assetGatewayMixin"; -import { - updateGatewayBackers, - getGatewayStatusByAsset -} from "common/gatewayUtils"; +import {getGatewayStatusByAsset} from "common/gatewayUtils"; import {availableGateways} from "common/gateways"; import { validateAddress as blocktradesValidateAddress, WithdrawAddresses } from "lib/common/gatewayMethods"; -import AmountSelector from "components/Utility/AmountSelector"; +import AmountSelector from "components/Utility/AmountSelectorStyleGuide"; import {checkFeeStatusAsync, checkBalance} from "common/trxHelper"; import AccountSelector from "components/Account/AccountSelector"; import {ChainStore} from "bitsharesjs"; const gatewayBoolCheck = "withdrawalAllowed"; import {getAssetAndGateway, getIntermediateAccount} from "common/gatewayUtils"; +import { isObject } from "util"; class WithdrawModalNew extends React.Component { constructor(props) { @@ -145,6 +144,10 @@ class WithdrawModalNew extends React.Component { this._updateFee(); } + if(this.state.address != "") { + this.onAddressSelected(this.state.address); + } + if (np.initialSymbol !== this.props.initialSymbol) { let newState = this._getAssetAndGatewayFromInitialSymbol( np.initialSymbol @@ -154,6 +157,8 @@ class WithdrawModalNew extends React.Component { newState.selectedAsset, gatewayBoolCheck ); + newState.address = ""; + newState.quantity = 0; this.setState(newState); } } @@ -521,21 +526,23 @@ class WithdrawModalNew extends React.Component { } onFeeChanged({asset}) { - this.setState( - { - fee_asset_id: asset.get("id") - }, - this._updateFee - ); + // If asset is an object, just extract asset ID + if(isObject(asset)) { + asset = asset.get("id"); + } + + this.setState({ + fee_asset_id: asset, + },this._updateFee); } - onAssetSelected(value, asset) { + onAssetSelected(asset) { let {selectedAsset, selectedGateway} = _onAssetSelected.call( this, - value, + asset.id, gatewayBoolCheck ); - let address = WithdrawAddresses.getLast(value.toLowerCase()); + let address = WithdrawAddresses.getLast(asset.id.toLowerCase()); this.setState( { selectedAsset, @@ -576,8 +583,7 @@ class WithdrawModalNew extends React.Component { this.setState(stateObj); } - onGatewayChanged(e) { - let selectedGateway = e.target.value; + onGatewayChanged(selectedGateway) { this.setState({selectedGateway}, () => { this.setState(this._getAssetPairVariables(), this.updateFee); }); @@ -619,10 +625,15 @@ class WithdrawModalNew extends React.Component { } } - onAddressChanged(e) { - let {value} = e.target; - this.validateAddress(value); - this.setState({address: value}, this._updateFee); + // Don't validate address on change. + // Validation is done when address is selected + onAddressChanged(inputAddress) { + this.setState({address: inputAddress}); + } + + onAddressSelected(inputAddress) { + this.validateAddress(inputAddress); + this.setState({address: inputAddress}, this._updateFee); } _getBackingAssetProps() { @@ -872,6 +883,8 @@ class WithdrawModalNew extends React.Component { address: data.address }); } + + this.onAddressSelected(data.address); } render() { @@ -1102,7 +1115,6 @@ class WithdrawModalNew extends React.Component { className="error-msg" style={{ position: "absolute", - marginTop: -12, right: 0, textTransform: "uppercase", fontSize: 13 @@ -1125,7 +1137,6 @@ class WithdrawModalNew extends React.Component { className="error-msg" style={{ position: "absolute", - marginTop: -12, right: 0, textTransform: "uppercase", fontSize: 13 @@ -1147,7 +1158,6 @@ class WithdrawModalNew extends React.Component { className="error-msg" style={{ position: "absolute", - marginTop: -12, right: 0, textTransform: "uppercase", fontSize: 13 @@ -1188,35 +1198,34 @@ class WithdrawModalNew extends React.Component {
) : null} -
+
- - {storedAddresses.length > 1 ? ( - - ▼ - - ) : null} - + onSearch={this.onAddressChanged.bind(this)} + onSelect={this.onAddressSelected.bind(this)} + > + {address && storedAddresses.indexOf(address) == -1 ? ( + + {address} + + ) : null} + {storedAddresses.map(address => ( + + {address} + + ))} + + + +
-
- {this._renderStoredAddresses.call(this)} -
) : null} @@ -1254,69 +1263,41 @@ class WithdrawModalNew extends React.Component { {/*FEE & GATEWAY FEE*/} {assetAndGateway || isBTS ? ( -
-
-
- {/* Withdraw amount */} - +
+ + +
+
+ +
+ - {/*!this.state.hasBalance ?

: null*/} - {/*!this.state.hasPoolBalance ?

: null*/} -
-
- {/* Gate fee */} - {gateFee ? ( -
- -
- + - -
-
-
- {selectedAsset} -
-
-
-
-
- ) : null} + + } + />
diff --git a/app/components/QRAddressScanner.jsx b/app/components/QRAddressScanner.jsx index b5eb249828..62298614e7 100644 --- a/app/components/QRAddressScanner.jsx +++ b/app/components/QRAddressScanner.jsx @@ -1,9 +1,8 @@ import React from "react"; import QrReader from "react-qr-reader"; -import Icon from "./Icon/Icon"; import counterpart from "counterpart"; import PropTypes from "prop-types"; -import {Modal, Button} from "bitshares-ui-style-guide"; +import {Modal, Button, Icon} from "bitshares-ui-style-guide"; class QRScanner extends React.Component { modalId = "qr_scanner_modal"; @@ -101,12 +100,7 @@ class QRScanner extends React.Component { return (
- + { - if (gatewayStatus[key].options.enabled) - return ( - - ); - }); - let supportLink = !!selectedGateway ? "/help/gateways/" + gatewayStatus[selectedGateway].name.toLowerCase().replace("-", "") @@ -162,10 +151,7 @@ function gatewaySelector(args) { {selectedGateway ? (   - + ) : null} @@ -191,32 +177,32 @@ function gatewaySelector(args) {
- - + {/* + NOTE 1 + If we have a withdraw, it would be very nice to have + the value of each gateway aligned to the right so + the user doesn't have to select a gateway to see the balance + + NOTE 2 + This list should be sorted alphabetically to limit + any possible siding of a gateway. + */} + {Object.keys(gatewayStatus).map((key, i) => { + if (gatewayStatus[key].options.enabled) { + return ( + + {gatewayStatus[key].name} + + ); + } + })} +