aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/ts/components/inputs/allowance_state_toggle.tsx102
-rw-r--r--packages/website/ts/components/ui/allowance_state_view.tsx2
-rw-r--r--packages/website/ts/components/wallet/wallet.tsx10
-rw-r--r--packages/website/ts/containers/inputs/allowance_state_toggle.ts20
4 files changed, 118 insertions, 16 deletions
diff --git a/packages/website/ts/components/inputs/allowance_state_toggle.tsx b/packages/website/ts/components/inputs/allowance_state_toggle.tsx
index bf661dee8..495efd806 100644
--- a/packages/website/ts/components/inputs/allowance_state_toggle.tsx
+++ b/packages/website/ts/components/inputs/allowance_state_toggle.tsx
@@ -1,36 +1,82 @@
-import { colors } from '@0xproject/react-shared';
+import { BigNumber, logUtils } from '@0xproject/utils';
+import * as _ from 'lodash';
import * as React from 'react';
-import { AllowanceStateView, AllowanceState } from 'ts/components/ui/allowance_state_view';
-import { Token, TokenState } from 'ts/types';
-import { Container } from 'ts/components/ui/container';
import ReactTooltip = require('react-tooltip');
+import { Blockchain } from 'ts/blockchain';
+import { AllowanceState, AllowanceStateView } from 'ts/components/ui/allowance_state_view';
+import { Container } from 'ts/components/ui/container';
+import { Dispatcher } from 'ts/redux/dispatcher';
+import { BalanceErrs, Token, TokenState } from 'ts/types';
+import { analytics } from 'ts/utils/analytics';
+import { errorReporter } from 'ts/utils/error_reporter';
+import { utils } from 'ts/utils/utils';
export interface AllowanceStateToggleProps {
+ networkId: number;
+ blockchain: Blockchain;
+ dispatcher: Dispatcher;
token: Token;
tokenState: TokenState;
+ userAddress: string;
+ onErrorOccurred?: (errType: BalanceErrs) => void;
+ refetchTokenStateAsync: () => Promise<void>;
}
export interface AllowanceStateToggleState {
allowanceState: AllowanceState;
+ prevAllowance: BigNumber;
}
-const flip = () => Math.random() < 0.5;
+const DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS = new BigNumber(2).pow(256).minus(1);
export class AllowanceStateToggle extends React.Component<AllowanceStateToggleProps, AllowanceStateToggleState> {
- public state = {
- allowanceState: flip() ? AllowanceState.Loading : AllowanceState.Locked,
+ public static defaultProps = {
+ onErrorOccurred: _.noop.bind(_),
};
+ private static _getAllowanceStateFromAllowance(allowance?: BigNumber): AllowanceState {
+ if (_.isUndefined(allowance)) {
+ return AllowanceState.Loading;
+ }
+ if (allowance.gt(0)) {
+ return AllowanceState.Unlocked;
+ }
+ return AllowanceState.Locked;
+ }
+ constructor(props: AllowanceStateToggleProps) {
+ super(props);
+ const allowance = props.tokenState.allowance;
+ this.state = {
+ allowanceState: AllowanceState.Loading,
+ prevAllowance: allowance,
+ };
+ }
+
public render(): React.ReactNode {
const tooltipId = `tooltip-id-${this.props.token.symbol}`;
return (
<Container cursor="pointer">
<ReactTooltip id={tooltipId}>{this._getTooltipContent()}</ReactTooltip>
- <div data-tip={true} data-for={tooltipId} data-place="right" data-effect="solid">
+ <div
+ data-tip={true}
+ data-for={tooltipId}
+ data-place="right"
+ data-effect="solid"
+ onClick={this._onToggleAllowanceAsync.bind(this)}
+ >
<AllowanceStateView allowanceState={this.state.allowanceState} />
</div>
</Container>
);
}
+ public componentWillReceiveProps(nextProps: AllowanceStateToggleProps): void {
+ if (!nextProps.tokenState.allowance.eq(this.state.prevAllowance)) {
+ const allowance = nextProps.tokenState.allowance;
+ this.setState({
+ prevAllowance: allowance,
+ allowanceState: AllowanceStateToggle._getAllowanceStateFromAllowance(allowance),
+ });
+ }
+ }
private _getTooltipContent(): React.ReactNode {
const symbol = this.props.token.symbol;
switch (this.state.allowanceState) {
@@ -53,4 +99,44 @@ export class AllowanceStateToggle extends React.Component<AllowanceStateTogglePr
return null;
}
}
+ private async _onToggleAllowanceAsync(): Promise<void> {
+ if (this.props.userAddress === '') {
+ this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
+ return;
+ }
+
+ this.setState({
+ allowanceState: AllowanceState.Loading,
+ });
+
+ let newAllowanceAmountInBaseUnits = new BigNumber(0);
+ if (!this._isAllowanceSet()) {
+ newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
+ }
+ const logData = {
+ tokenSymbol: this.props.token.symbol,
+ newAllowance: newAllowanceAmountInBaseUnits.toNumber(),
+ };
+ try {
+ await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
+ analytics.track('Set Allowances Success', logData);
+ await this.props.refetchTokenStateAsync();
+ } catch (err) {
+ analytics.track('Set Allowance Failure', logData);
+ this.setState({
+ allowanceState: AllowanceStateToggle._getAllowanceStateFromAllowance(this.state.prevAllowance),
+ });
+ const errMsg = `${err}`;
+ if (utils.didUserDenyWeb3Request(errMsg)) {
+ return;
+ }
+ logUtils.log(`Unexpected error encountered: ${err}`);
+ logUtils.log(err.stack);
+ this.props.onErrorOccurred(BalanceErrs.allowanceSettingFailed);
+ errorReporter.report(err);
+ }
+ }
+ private _isAllowanceSet(): boolean {
+ return !this.props.tokenState.allowance.eq(0);
+ }
}
diff --git a/packages/website/ts/components/ui/allowance_state_view.tsx b/packages/website/ts/components/ui/allowance_state_view.tsx
index eecf88c34..6b20d37eb 100644
--- a/packages/website/ts/components/ui/allowance_state_view.tsx
+++ b/packages/website/ts/components/ui/allowance_state_view.tsx
@@ -1,7 +1,5 @@
-import { colors } from '@0xproject/react-shared';
import CircularProgress from 'material-ui/CircularProgress';
import * as React from 'react';
-import { styled } from 'ts/style/theme';
export enum AllowanceState {
Locked,
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index 32c56ef14..2cba993c4 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -28,7 +28,6 @@ import { NullTokenRow } from 'ts/components/wallet/null_token_row';
import { PlaceHolder } from 'ts/components/wallet/placeholder';
import { StandardIconRow } from 'ts/components/wallet/standard_icon_row';
import { WrapEtherItem } from 'ts/components/wallet/wrap_ether_item';
-import { AllowanceToggle } from 'ts/containers/inputs/allowance_toggle';
import { AllowanceStateToggle } from 'ts/containers/inputs/allowance_state_toggle';
import { Dispatcher } from 'ts/redux/dispatcher';
import { colors } from 'ts/style/colors';
@@ -422,7 +421,14 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
// refetchTokenStateAsync={async () => this.props.refetchTokenStateAsync(config.token.address)}
// />
// );
- return <AllowanceStateToggle token={config.token} tokenState={config.tokenState} />;
+ return (
+ <AllowanceStateToggle
+ blockchain={this.props.blockchain}
+ token={config.token}
+ tokenState={config.tokenState}
+ refetchTokenStateAsync={async () => this.props.refetchTokenStateAsync(config.token.address)}
+ />
+ );
}
private _renderAmount(
amount: BigNumber,
diff --git a/packages/website/ts/containers/inputs/allowance_state_toggle.ts b/packages/website/ts/containers/inputs/allowance_state_toggle.ts
index cdda5ecf0..d6ff11f84 100644
--- a/packages/website/ts/containers/inputs/allowance_state_toggle.ts
+++ b/packages/website/ts/containers/inputs/allowance_state_toggle.ts
@@ -9,21 +9,33 @@ import { AllowanceStateToggle as AllowanceStateToggleComponent } from 'ts/compon
import { Dispatcher } from 'ts/redux/dispatcher';
interface AllowanceStateToggleProps {
+ blockchain: Blockchain;
+ onErrorOccurred?: (errType: BalanceErrs) => void;
token: Token;
tokenState: TokenState;
+ isDisabled?: boolean;
+ refetchTokenStateAsync: () => Promise<void>;
}
-interface ConnectedState {}
+interface ConnectedState {
+ networkId: number;
+ userAddress: string;
+}
interface ConnectedDispatch {
dispatcher: Dispatcher;
}
-const mapStateToProps = (state: State, _ownProps: AllowanceStateToggleProps): ConnectedState => ({});
+const mapStateToProps = (state: State, _ownProps: AllowanceStateToggleProps): ConnectedState => ({
+ networkId: state.networkId,
+ userAddress: state.userAddress,
+});
-// const mapDispatchTopProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({});
+const mapDispatchTopProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
+ dispatcher: new Dispatcher(dispatch),
+});
export const AllowanceStateToggle: React.ComponentClass<AllowanceStateToggleProps> = connect(
mapStateToProps,
- // mapDispatchTopProps,
+ mapDispatchTopProps,
)(AllowanceStateToggleComponent);