From f9eba65aee8e71de609801e640de4101af9645e6 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 29 Oct 2018 20:06:31 -0700 Subject: return estimated state --- packages/instant/src/components/buy_button.tsx | 4 ++-- packages/instant/src/components/zero_ex_instant.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 93bd8e635..36cc32dbc 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -57,9 +57,9 @@ export class BuyButton extends React.Component { } let txHash: string | undefined; - const gasPrice = await gasPriceEstimator.getFastAmountInWeiAsync(); + const gasInfo = await gasPriceEstimator.getGasInfoAsync(); try { - txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress, gasPrice }); + txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress, gasPrice: gasInfo.gasPriceInWei }); } catch (e) { if (e instanceof Error) { if (e.message === AssetBuyerError.SignatureRequestDenied) { diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index d54dfc153..365c1610f 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -83,7 +83,7 @@ export class ZeroExInstant extends React.Component { // warm up the gas price estimator cache just in case we can't // grab the gas price estimate when submitting the transaction // tslint:disable-next-line:no-floating-promises - gasPriceEstimator.getFastAmountInWeiAsync(); + gasPriceEstimator.getGasInfoAsync(); // tslint:disable-next-line:no-floating-promises this._flashErrorIfWrongNetwork(); -- cgit v1.2.3 From 728f70f51b2fe4c5037e7b74a5dfb29f1f8ca4c9 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 29 Oct 2018 20:08:46 -0700 Subject: store estimated time in Ms on state --- packages/instant/src/components/buy_button.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 36cc32dbc..ec1010fe9 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -19,7 +19,7 @@ export interface BuyButtonProps { onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; - onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; + onBuyProcessing: (buyQuote: BuyQuote, txHash: string, estimatedTimeMs?: number) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; } @@ -73,7 +73,7 @@ export class BuyButton extends React.Component { throw e; } - this.props.onBuyProcessing(buyQuote, txHash); + this.props.onBuyProcessing(buyQuote, txHash, gasInfo.estimatedTimeMs); try { await web3Wrapper.awaitTransactionSuccessAsync(txHash); } catch (e) { -- cgit v1.2.3 From 05b74ba1c8b10c356d396ce9a4834d053cd791b1 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 13:27:28 -0700 Subject: Dispatching progress --- packages/instant/src/components/progress_bar.tsx | 17 +++++++++++++++++ .../src/components/zero_ex_instant_container.tsx | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 packages/instant/src/components/progress_bar.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/progress_bar.tsx b/packages/instant/src/components/progress_bar.tsx new file mode 100644 index 000000000..b89c56ed5 --- /dev/null +++ b/packages/instant/src/components/progress_bar.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Container } from './ui/container'; +import { Text } from './ui/text'; + +export interface ProgressBarProps { + percentageDone: number; +} +export const ProgressBar: React.StatelessComponent = props => ( + + + {props.percentageDone}% + + +); diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index ff19351ff..b9f8d0d92 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -4,11 +4,11 @@ import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order import { LatestError } from '../containers/latest_error'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; +import { SelectedAssetProgressBar } from '../containers/selected_asset_progress_bar'; import { ColorOption } from '../style/theme'; import { Container, Flex } from './ui'; - export interface ZeroExInstantContainerProps {} export const ZeroExInstantContainer: React.StatelessComponent = props => ( @@ -25,6 +25,7 @@ export const ZeroExInstantContainer: React.StatelessComponent + -- cgit v1.2.3 From bcb633e5cbcbfdfdfe8c91170abfca7dbb003417 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 13:34:47 -0700 Subject: Making prettier --- packages/instant/src/components/progress_bar.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/progress_bar.tsx b/packages/instant/src/components/progress_bar.tsx index b89c56ed5..5b5968703 100644 --- a/packages/instant/src/components/progress_bar.tsx +++ b/packages/instant/src/components/progress_bar.tsx @@ -3,15 +3,19 @@ import * as React from 'react'; import { ColorOption } from '../style/theme'; import { Container } from './ui/container'; -import { Text } from './ui/text'; export interface ProgressBarProps { percentageDone: number; } export const ProgressBar: React.StatelessComponent = props => ( - - - {props.percentageDone}% + + + ); -- cgit v1.2.3 From 13b41c976b42983f5869813715313c2da22abcbc Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 13:51:18 -0700 Subject: Placeholder for estimated time --- packages/instant/src/components/progress_bar.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/progress_bar.tsx b/packages/instant/src/components/progress_bar.tsx index 5b5968703..d5d1f3ded 100644 --- a/packages/instant/src/components/progress_bar.tsx +++ b/packages/instant/src/components/progress_bar.tsx @@ -3,18 +3,31 @@ import * as React from 'react'; import { ColorOption } from '../style/theme'; import { Container } from './ui/container'; +import { Flex } from './ui/flex'; +import { Text } from './ui/text'; export interface ProgressBarProps { percentageDone: number; + estTimeMs: number; + elapsedTimeMs: number; } + +// TODO: Est time to minutes with suffix +// TODO: time in minutes export const ProgressBar: React.StatelessComponent = props => ( + + + Est. Time ({props.estTimeMs / 1000} seconds) + {props.elapsedTimeMs / 1000} + + -- cgit v1.2.3 From 05f059492bbc86d61946562ac8c116259ded3487 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 14:48:09 -0700 Subject: WIP: beginning of simulated progress bar component --- .../src/components/simulated_progress_bar.tsx | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 packages/instant/src/components/simulated_progress_bar.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx new file mode 100644 index 000000000..3a957aca6 --- /dev/null +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -0,0 +1,136 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { Dispatch } from 'redux'; + +import { PROGRESS_STALL_AT_PERCENTAGE, PROGRESS_TICK_INTERVAL_MS } from '../constants'; +import { Action, actions } from '../redux/actions'; + +import { ColorOption } from '../style/theme'; + +import { Container } from './ui/container'; +import { Flex } from './ui/flex'; +import { Text } from './ui/text'; + +const TICKS_PER_SECOND = 1000 / PROGRESS_TICK_INTERVAL_MS; + +const curTimeUnix = () => { + return new Date().getTime(); +}; + +export interface SimulatedProgressBarProps { + startTimeUnix: number; + expectedEndTimeUnix: number; + ended: boolean; +} +enum TickingRunState { + None, + Running, + Finishing, +} +interface TickingNoneStatus { + runState: TickingRunState.None; +} +interface TickingRunningStatus { + runState: TickingRunState.Running; +} +interface TickingFinishingStatus { + runState: TickingRunState.Finishing; + increasePercentageEveryTick: number; +} +type TickingStatus = TickingNoneStatus | TickingRunningStatus | TickingFinishingStatus; + +export interface SimulatedProgressState { + percentageDone: number; + intervalId?: number; + tickingStatus: TickingStatus; +} +export class SimulatedProgressBar extends React.Component { + public constructor(props: SimulatedProgressBarProps) { + super(props); + + // TODO: look into using assert library here? + if (props.expectedEndTimeUnix <= props.startTimeUnix) { + throw new Error('End time before start time'); + } + + const intervalId = window.setInterval(this._tick.bind(this), PROGRESS_TICK_INTERVAL_MS); + this.state = { + percentageDone: 0, + intervalId, + tickingStatus: { runState: TickingRunState.Running }, + }; + } + + public componentDidUpdate(prevProps: SimulatedProgressBarProps, prevState: SimulatedProgressState): void { + const percentLeft = 100 - this.state.percentageDone; + const increasePercentageEveryTick = percentLeft / TICKS_PER_SECOND; + + if (prevProps.ended === false && this.props.ended === true) { + this.setState({ + tickingStatus: { + runState: TickingRunState.Finishing, + increasePercentageEveryTick, + }, + }); + } + } + + public componentWillUnmount(): void { + this._clearTimer(); + } + + public render(): React.ReactNode { + // TODO: Consider moving to seperate component + return ( + + + + + + ); + } + + private _tick(): void { + const rawPercentageDone = + this.state.tickingStatus.runState === TickingRunState.Finishing + ? this._getNewPercentageFinishing(this.state.tickingStatus) + : this._getNewPercentageNormal(); + + const maxPercentage = + this.state.tickingStatus.runState === TickingRunState.Finishing ? 100 : PROGRESS_STALL_AT_PERCENTAGE; + const percentageDone = Math.floor(Math.min(rawPercentageDone, maxPercentage)); + + this.setState({ + percentageDone, + }); + + if (percentageDone >= 100) { + this._clearTimer(); + } + } + + private _clearTimer(): void { + if (this.state.intervalId) { + window.clearTimeout(this.state.intervalId); + } + } + + // TODO: consider not taking in a parameter here, might be confusing + private _getNewPercentageFinishing(tickingStatus: TickingFinishingStatus): number { + return this.state.percentageDone + tickingStatus.increasePercentageEveryTick; + } + + private _getNewPercentageNormal(): number { + const elapsedTimeMs = curTimeUnix() - this.props.startTimeUnix; + const safeElapsedTimeMs = Math.max(elapsedTimeMs, 1); + + const expectedAmountOfTimeMs = this.props.expectedEndTimeUnix - this.props.startTimeUnix; + const percentageDone = safeElapsedTimeMs / expectedAmountOfTimeMs * 100; + return percentageDone; + } +} -- cgit v1.2.3 From abaa39a5e24daa8a1a7ff5617a14d2f3088cb0e3 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 15:39:58 -0700 Subject: Simulated Progress component working --- .../src/components/simulated_progress_bar.tsx | 34 ++++++++++++++++++---- .../src/components/zero_ex_instant_container.tsx | 4 +++ 2 files changed, 33 insertions(+), 5 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx index 3a957aca6..1fd76ead7 100644 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -23,9 +23,9 @@ export interface SimulatedProgressBarProps { ended: boolean; } enum TickingRunState { - None, - Running, - Finishing, + None = 'None', + Running = 'Running', + Finishing = 'Finishing', } interface TickingNoneStatus { runState: TickingRunState.None; @@ -53,6 +53,7 @@ export class SimulatedProgressBar extends React.Component + -- cgit v1.2.3 From dc9013652914333bfdc3c067d9b83a71f28c7382 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 15:43:38 -0700 Subject: Remove old files --- packages/instant/src/components/progress_bar.tsx | 34 ---------------------- .../src/components/zero_ex_instant_container.tsx | 3 -- 2 files changed, 37 deletions(-) delete mode 100644 packages/instant/src/components/progress_bar.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/progress_bar.tsx b/packages/instant/src/components/progress_bar.tsx deleted file mode 100644 index d5d1f3ded..000000000 --- a/packages/instant/src/components/progress_bar.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import * as React from 'react'; - -import { ColorOption } from '../style/theme'; - -import { Container } from './ui/container'; -import { Flex } from './ui/flex'; -import { Text } from './ui/text'; - -export interface ProgressBarProps { - percentageDone: number; - estTimeMs: number; - elapsedTimeMs: number; -} - -// TODO: Est time to minutes with suffix -// TODO: time in minutes -export const ProgressBar: React.StatelessComponent = props => ( - - - - Est. Time ({props.estTimeMs / 1000} seconds) - {props.elapsedTimeMs / 1000} - - - - - - -); diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index ae315da47..6b1042668 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -5,8 +5,6 @@ import { LatestError } from '../containers/latest_error'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; -// TODO: delete this import and this actual file -import { SelectedAssetProgressBar } from '../containers/selected_asset_progress_bar'; import { SelectedAssetSimulatedProgressBar } from '../containers/selected_asset_simulated_progress_bar'; import { ColorOption } from '../style/theme'; @@ -29,7 +27,6 @@ export const ZeroExInstantContainer: React.StatelessComponent - -- cgit v1.2.3 From d21487d0c07de307bbe9de459f8d3b00e15dc8dc Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 15:47:35 -0700 Subject: Show estimated time --- packages/instant/src/components/simulated_progress_bar.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx index 1fd76ead7..5742cd474 100644 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -96,8 +96,17 @@ export class SimulatedProgressBar extends React.Component + + {/* TODO: consider moving to separate component */} + + Est. Time ({estimatedTimeSeconds} seconds) + x + + Date: Tue, 30 Oct 2018 15:55:53 -0700 Subject: Showing time --- packages/instant/src/components/simulated_progress_bar.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx index 5742cd474..e9e547cbe 100644 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -43,6 +43,7 @@ export interface SimulatedProgressState { percentageDone: number; intervalId?: number; tickingStatus: TickingStatus; + elapsedTimeMs: number; } export class SimulatedProgressBar extends React.Component { public constructor(props: SimulatedProgressBarProps) { @@ -59,6 +60,7 @@ export class SimulatedProgressBar extends React.Component {/* TODO: consider moving to separate component */} + {/* TODO: should do nice display of these (i.e. 'minutes' and 00:xx) */} Est. Time ({estimatedTimeSeconds} seconds) - x + Time: {elapsedTimeSeconds} @@ -126,6 +130,7 @@ export class SimulatedProgressBar extends React.Component= 100) { -- cgit v1.2.3 From 1c0569cfc61d7b166d79d2d73e9bbc6d11a5b4e8 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 16:40:51 -0700 Subject: Use simulated progress bar for txn --- packages/instant/src/components/buy_button.tsx | 14 ++++---- .../src/components/buy_order_state_buttons.tsx | 39 ++++++++++++++-------- 2 files changed, 34 insertions(+), 19 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index ec1010fe9..d10936d05 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -19,9 +19,9 @@ export interface BuyButtonProps { onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; - onBuyProcessing: (buyQuote: BuyQuote, txHash: string, estimatedTimeMs?: number) => void; - onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; - onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; + onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuySuccess: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuyFailure: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; } export class BuyButton extends React.Component { @@ -73,16 +73,18 @@ export class BuyButton extends React.Component { throw e; } - this.props.onBuyProcessing(buyQuote, txHash, gasInfo.estimatedTimeMs); + const startTimeUnix = new Date().getTime(); + const expectedEndTimeUnix = startTimeUnix + gasInfo.estimatedTimeMs; + this.props.onBuyProcessing(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); try { await web3Wrapper.awaitTransactionSuccessAsync(txHash); } catch (e) { if (e instanceof Error && e.message.startsWith(WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX)) { - this.props.onBuyFailure(buyQuote, txHash); + this.props.onBuyFailure(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); return; } throw e; } - this.props.onBuySuccess(buyQuote, txHash); + this.props.onBuySuccess(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); }; } diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index d01e9ff57..6f197a772 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -6,6 +6,7 @@ import { SecondaryButton } from '../components/secondary_button'; import { Flex } from '../components/ui/flex'; import { PlacingOrderButton } from '../components/placing_order_button'; +import { SimulatedProgressBar } from '../components/simulated_progress_bar'; import { ColorOption } from '../style/theme'; import { OrderProcessState, ZeroExInstantError } from '../types'; @@ -20,10 +21,13 @@ export interface BuyOrderStateButtonProps { onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; - onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; - onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; - onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; + onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuySuccess: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuyFailure: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; onRetry: () => void; + + // TODO: dont commit! + secondaryProgressDemo: () => void; } // TODO: rename to buttons @@ -50,16 +54,25 @@ export const BuyOrderStateButtons: React.StatelessComponent; } + const curTime = new Date().getTime(); + const expectedEndTime = curTime + 5000; return ( - +
+ {/*
+ +
*/} + + New progress bar demo + +
); }; -- cgit v1.2.3 From 9787d1085da225ac3180983065f63d26a6bab3e6 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 16:43:58 -0700 Subject: Get rid of old demo --- packages/instant/src/components/buy_order_state_buttons.tsx | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index 6f197a772..df1664cd9 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -25,12 +25,8 @@ export interface BuyOrderStateButtonProps { onBuySuccess: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; onRetry: () => void; - - // TODO: dont commit! - secondaryProgressDemo: () => void; } -// TODO: rename to buttons export const BuyOrderStateButtons: React.StatelessComponent = props => { if (props.buyOrderProcessingState === OrderProcessState.FAILURE) { return ( @@ -54,15 +50,8 @@ export const BuyOrderStateButtons: React.StatelessComponent; } - const curTime = new Date().getTime(); - const expectedEndTime = curTime + 5000; return (
- {/*
- -
*/} - - New progress bar demo Date: Tue, 30 Oct 2018 16:45:04 -0700 Subject: Takeout unneeded div --- .../src/components/buy_order_state_buttons.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index df1664cd9..4a6b467d2 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -51,17 +51,15 @@ export const BuyOrderStateButtons: React.StatelessComponent - -
+ ); }; -- cgit v1.2.3 From 229f11f164ce5109b771295d9aee8ebb74314181 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 30 Oct 2018 20:18:21 -0700 Subject: Nice formatting of displayed time --- packages/instant/src/components/simulated_progress_bar.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx index e9e547cbe..e4b08db8c 100644 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -1,11 +1,9 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { Dispatch } from 'redux'; import { PROGRESS_STALL_AT_PERCENTAGE, PROGRESS_TICK_INTERVAL_MS } from '../constants'; -import { Action, actions } from '../redux/actions'; - import { ColorOption } from '../style/theme'; +import { timeUtil } from '../util/time'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; @@ -106,9 +104,8 @@ export class SimulatedProgressBar extends React.Component {/* TODO: consider moving to separate component */} - {/* TODO: should do nice display of these (i.e. 'minutes' and 00:xx) */} - Est. Time ({estimatedTimeSeconds} seconds) - Time: {elapsedTimeSeconds} + Est. Time ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) + Time: {timeUtil.secondsToStopwatchTime(elapsedTimeSeconds)}
-- cgit v1.2.3 From 9a5b52036b8765a6de464d8c6294b46ebcfd604e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 31 Oct 2018 08:14:44 -0700 Subject: Tick less often, and let CSS style the transition --- .../src/components/simulated_progress_bar.tsx | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx index e4b08db8c..067f4093e 100644 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ b/packages/instant/src/components/simulated_progress_bar.tsx @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import { PROGRESS_STALL_AT_PERCENTAGE, PROGRESS_TICK_INTERVAL_MS } from '../constants'; -import { ColorOption } from '../style/theme'; +import { ColorOption, styled } from '../style/theme'; import { timeUtil } from '../util/time'; import { Container } from './ui/container'; @@ -109,11 +109,12 @@ export class SimulatedProgressBar extends React.Component - @@ -172,3 +173,22 @@ export class SimulatedProgressBar extends React.Component + ` + width: ${props => props.percentageDone}%; + background-color: ${props => props.theme[props.backgroundColor]}; + border-radius: ${props => props.borderRadius}; + height: ${props => props.height}; + transition: width ${props => props.transitionTimeMs}ms ease-in-out; + `; -- cgit v1.2.3 From d6755472087af76982779728db7424b1171a1b47 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 31 Oct 2018 09:14:50 -0700 Subject: Explicit actions for setting different order states This allows us to dispatch updates with less syntax, and allows us to not have to send in progress info when setting failure and success --- packages/instant/src/components/buy_button.tsx | 9 +++++---- packages/instant/src/components/buy_order_state_buttons.tsx | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index d10936d05..c00b1678d 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -20,8 +20,8 @@ export interface BuyButtonProps { onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; - onBuySuccess: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; - onBuyFailure: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; + onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; } export class BuyButton extends React.Component { @@ -80,11 +80,12 @@ export class BuyButton extends React.Component { await web3Wrapper.awaitTransactionSuccessAsync(txHash); } catch (e) { if (e instanceof Error && e.message.startsWith(WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX)) { - this.props.onBuyFailure(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); + this.props.onBuyFailure(buyQuote, txHash); return; } throw e; } - this.props.onBuySuccess(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); + + this.props.onBuySuccess(buyQuote, txHash); }; } diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index 4a6b467d2..3f0764062 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -6,7 +6,6 @@ import { SecondaryButton } from '../components/secondary_button'; import { Flex } from '../components/ui/flex'; import { PlacingOrderButton } from '../components/placing_order_button'; -import { SimulatedProgressBar } from '../components/simulated_progress_bar'; import { ColorOption } from '../style/theme'; import { OrderProcessState, ZeroExInstantError } from '../types'; @@ -22,8 +21,8 @@ export interface BuyOrderStateButtonProps { onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; - onBuySuccess: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; - onBuyFailure: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void; + onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; + onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; } -- cgit v1.2.3 From ae84dac46382258e9a59b194f8aed7184d283e6f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 31 Oct 2018 16:46:24 -0700 Subject: WIP of new timedprogressbar using CSS animations --- packages/instant/src/components/time_counter.tsx | 64 +++++++++++++ .../instant/src/components/timed_progress_bar.tsx | 101 +++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 packages/instant/src/components/time_counter.tsx create mode 100644 packages/instant/src/components/timed_progress_bar.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx new file mode 100644 index 000000000..26deb82bd --- /dev/null +++ b/packages/instant/src/components/time_counter.tsx @@ -0,0 +1,64 @@ +import * as React from 'react'; + +import { timeUtil } from '../util/time'; + +import { Flex } from './ui/flex'; +import { Text } from './ui/text'; + +export interface TimeCounterProps { + estimatedTimeMs: number; + ended: boolean; +} +interface TimeCounterState { + elapsedSeconds: number; +} + +export class TimeCounter extends React.Component { + public state = { + elapsedSeconds: 0, + }; + private _timerId?: number; + + public componentDidMount(): void { + this._setupTimerBasedOnProps(); + } + + public componentWillUnmount(): void { + this._clearTimer(); + } + + public componentDidUpdate(prevProps: TimeCounterProps): void { + if (prevProps.ended !== this.props.ended) { + this._setupTimerBasedOnProps(); + } + } + + public render(): React.ReactNode { + const estimatedTimeSeconds = this.props.estimatedTimeMs / 1000; + return ( + + Est. Time ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) + Time: {timeUtil.secondsToStopwatchTime(this.state.elapsedSeconds)} + + ); + } + + private _setupTimerBasedOnProps(): void { + this.props.ended ? this._clearTimer() : this._newTimer(); + } + + private _newTimer(): void { + this._clearTimer(); + this._timerId = window.setInterval(() => { + this.setState({ + elapsedSeconds: this.state.elapsedSeconds + 1, + }); + }, 1000); + } + + private _clearTimer(): void { + if (this._timerId) { + window.clearInterval(this._timerId); + } + } +} diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx new file mode 100644 index 000000000..7fdfe1a25 --- /dev/null +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -0,0 +1,101 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { Keyframes } from 'styled-components'; + +import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_PERCENTAGE } from '../constants'; +import { ColorOption, keyframes, styled } from '../style/theme'; +import { timeUtil } from '../util/time'; + +import { Container } from './ui/container'; +import { Flex } from './ui/flex'; +import { Text } from './ui/text'; + +export interface TimedProgressBarProps { + expectedTimeMs: number; + ended: boolean; +} + +interface TimedProgressBarState { + animationTimeMs: number; + animationStartingWidth: string; + maxWidthPercent: number; +} + +export const beginningState = (props: TimedProgressBarProps): TimedProgressBarState => { + return { + animationTimeMs: props.expectedTimeMs, + animationStartingWidth: '0%', + maxWidthPercent: PROGRESS_STALL_AT_PERCENTAGE, + }; +}; + +export class TimedProgressBar extends React.Component { + private readonly _barRef = React.createRef(); + + public constructor(props: TimedProgressBarProps) { + super(props); + this.state = beginningState(props); + } + + public componentDidUpdate(prevProps: TimedProgressBarProps, prevState: TimedProgressBarState): void { + if (prevProps.ended === false && this.props.ended === true) { + // Show nice animation going to end + // barRef current should always exist, but checking for typesafety + if (this._barRef.current) { + const curProgressWidth = this._barRef.current.offsetWidth; + this.setState({ + animationTimeMs: PROGRESS_FINISH_ANIMATION_TIME_MS, + animationStartingWidth: `${curProgressWidth}px`, + maxWidthPercent: 100, + }); + } + return; + } + + if (prevProps.expectedTimeMs !== this.props.expectedTimeMs || prevProps.ended !== this.props.ended) { + // things changed, get fresh state + this.setState(beginningState(this.props)); + } + } + + public render(): React.ReactNode { + return ( + + + + ); + } +} + +const expandingWidthKeyframes = (fromWidth: string, maxWidthPercent: number) => { + return keyframes` + from { + width: ${fromWidth} + } + to { + width: ${maxWidthPercent}%; + } + `; +}; + +interface TimedProgressProps { + timeMs: number; + fromWidth: string; + maxWidthPercent: number; +} +// TODO use PrimaryColor instead of black +export const TimedProgress = + styled.div < + TimedProgressProps > + ` + background-color: black; + border-radius: 6px; + height: 6px; + animation: ${props => expandingWidthKeyframes(props.fromWidth, props.maxWidthPercent)} + ${props => props.timeMs}ms linear 1 forwards; + `; -- cgit v1.2.3 From 096f9deceedabff7fe90a7781271f55dfa059e1f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 31 Oct 2018 16:49:41 -0700 Subject: Removing old simulated progress bar, and adding documentation to TimedProgressBar --- .../src/components/simulated_progress_bar.tsx | 194 --------------------- .../instant/src/components/timed_progress_bar.tsx | 9 +- 2 files changed, 5 insertions(+), 198 deletions(-) delete mode 100644 packages/instant/src/components/simulated_progress_bar.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/simulated_progress_bar.tsx b/packages/instant/src/components/simulated_progress_bar.tsx deleted file mode 100644 index 067f4093e..000000000 --- a/packages/instant/src/components/simulated_progress_bar.tsx +++ /dev/null @@ -1,194 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; - -import { PROGRESS_STALL_AT_PERCENTAGE, PROGRESS_TICK_INTERVAL_MS } from '../constants'; -import { ColorOption, styled } from '../style/theme'; -import { timeUtil } from '../util/time'; - -import { Container } from './ui/container'; -import { Flex } from './ui/flex'; -import { Text } from './ui/text'; - -const TICKS_PER_SECOND = 1000 / PROGRESS_TICK_INTERVAL_MS; - -const curTimeUnix = () => { - return new Date().getTime(); -}; - -export interface SimulatedProgressBarProps { - startTimeUnix: number; - expectedEndTimeUnix: number; - ended: boolean; -} -enum TickingRunState { - None = 'None', - Running = 'Running', - Finishing = 'Finishing', -} -interface TickingNoneStatus { - runState: TickingRunState.None; -} -interface TickingRunningStatus { - runState: TickingRunState.Running; -} -interface TickingFinishingStatus { - runState: TickingRunState.Finishing; - increasePercentageEveryTick: number; -} -type TickingStatus = TickingNoneStatus | TickingRunningStatus | TickingFinishingStatus; - -export interface SimulatedProgressState { - percentageDone: number; - intervalId?: number; - tickingStatus: TickingStatus; - elapsedTimeMs: number; -} -export class SimulatedProgressBar extends React.Component { - public constructor(props: SimulatedProgressBarProps) { - super(props); - - // TODO: look into using assert library here? - if (props.expectedEndTimeUnix <= props.startTimeUnix) { - throw new Error('End time before start time'); - } - - // TODO: use getFreshState here - const intervalId = window.setInterval(this._tick.bind(this), PROGRESS_TICK_INTERVAL_MS); - this.state = { - percentageDone: 0, - intervalId, - tickingStatus: { runState: TickingRunState.Running }, - elapsedTimeMs: 0, - }; - } - - public componentDidUpdate(prevProps: SimulatedProgressBarProps, prevState: SimulatedProgressState): void { - const percentLeft = 100 - this.state.percentageDone; - const increasePercentageEveryTick = percentLeft / TICKS_PER_SECOND; - - // if we just switched to ending, having animate to end - if (prevProps.ended === false && this.props.ended === true) { - this.setState({ - tickingStatus: { - runState: TickingRunState.Finishing, - increasePercentageEveryTick, - }, - }); - return; - } - - // later TODO: the new state could be for the wrong order, attach to order state or add concurrency checking - - // if anything else changes, reset internal state - if ( - prevProps.startTimeUnix !== this.props.startTimeUnix || - prevProps.expectedEndTimeUnix !== this.props.expectedEndTimeUnix || - prevProps.ended !== this.props.ended - ) { - this.setState(this._getFreshState()); - } - } - - public componentWillUnmount(): void { - console.log('unmount'); - this._clearTimer(); - } - - public render(): React.ReactNode { - // TODO: Consider moving to seperate component - - const estimatedTimeSeconds = Math.ceil((this.props.expectedEndTimeUnix - this.props.startTimeUnix) / 1000); - const elapsedTimeSeconds = Math.floor(this.state.elapsedTimeMs / 1000); - return ( - - - {/* TODO: consider moving to separate component */} - - Est. Time ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) - Time: {timeUtil.secondsToStopwatchTime(elapsedTimeSeconds)} - - - - - - - ); - } - - private _getFreshState(): SimulatedProgressState { - this._clearTimer(); - const intervalId = window.setInterval(this._tick.bind(this), PROGRESS_TICK_INTERVAL_MS); - return { - percentageDone: 0, - intervalId, - tickingStatus: { runState: TickingRunState.Running }, - elapsedTimeMs: 0, - }; - } - - private _tick(): void { - const rawPercentageDone = - this.state.tickingStatus.runState === TickingRunState.Finishing - ? this._getNewPercentageFinishing(this.state.tickingStatus) - : this._getNewPercentageNormal(); - const maxPercentage = - this.state.tickingStatus.runState === TickingRunState.Finishing ? 100 : PROGRESS_STALL_AT_PERCENTAGE; - const percentageDone = Math.min(rawPercentageDone, maxPercentage); - - const elapsedTimeMs = Math.max(curTimeUnix() - this.props.startTimeUnix, 0); - - this.setState({ - percentageDone, - elapsedTimeMs, - }); - - if (percentageDone >= 100) { - this._clearTimer(); - } - } - - private _clearTimer(): void { - if (this.state.intervalId) { - window.clearTimeout(this.state.intervalId); - } - } - - // TODO: consider not taking in a parameter here, might be confusing - private _getNewPercentageFinishing(tickingStatus: TickingFinishingStatus): number { - return this.state.percentageDone + tickingStatus.increasePercentageEveryTick; - } - - private _getNewPercentageNormal(): number { - const elapsedTimeMs = curTimeUnix() - this.props.startTimeUnix; - const safeElapsedTimeMs = Math.max(elapsedTimeMs, 1); - - const expectedAmountOfTimeMs = this.props.expectedEndTimeUnix - this.props.startTimeUnix; - const percentageDone = safeElapsedTimeMs / expectedAmountOfTimeMs * 100; - return percentageDone; - } -} - -interface InnerProgressBarElementProps { - percentageDone: number; - backgroundColor: ColorOption; - borderRadius: string; - height: string; - transitionTimeMs: number; -} - -export const InnerProgressBarElement = - styled.div < - InnerProgressBarElementProps > - ` - width: ${props => props.percentageDone}%; - background-color: ${props => props.theme[props.backgroundColor]}; - border-radius: ${props => props.borderRadius}; - height: ${props => props.height}; - transition: width ${props => props.transitionTimeMs}ms ease-in-out; - `; diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index 7fdfe1a25..a4bb2eabd 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -1,14 +1,10 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { Keyframes } from 'styled-components'; import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_PERCENTAGE } from '../constants'; import { ColorOption, keyframes, styled } from '../style/theme'; -import { timeUtil } from '../util/time'; import { Container } from './ui/container'; -import { Flex } from './ui/flex'; -import { Text } from './ui/text'; export interface TimedProgressBarProps { expectedTimeMs: number; @@ -29,6 +25,11 @@ export const beginningState = (props: TimedProgressBarProps): TimedProgressBarSt }; }; +/** + * Timed Progress Bar + * Goes from 0% -> PROGRESS_STALL_AT_PERCENTAGE% over time of expectedTimeMs + * When ended set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length + */ export class TimedProgressBar extends React.Component { private readonly _barRef = React.createRef(); -- cgit v1.2.3 From 906909e33fe97d49196696c528c131c1a1c66f14 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 31 Oct 2018 16:54:52 -0700 Subject: Rename to SelectedAssetProgress --- packages/instant/src/components/zero_ex_instant_container.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 6b1042668..87a7cee88 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -5,7 +5,7 @@ import { LatestError } from '../containers/latest_error'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; -import { SelectedAssetSimulatedProgressBar } from '../containers/selected_asset_simulated_progress_bar'; +import { SelectedAssetProgress } from '../containers/selected_asset_progress'; import { ColorOption } from '../style/theme'; @@ -26,7 +26,7 @@ export const ZeroExInstantContainer: React.StatelessComponent - + -- cgit v1.2.3 From f9a38fcb32ee4e755c7f271a1c5a116c29985a10 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 09:51:27 -0700 Subject: ended -> hasEnded --- packages/instant/src/components/time_counter.tsx | 6 +++--- packages/instant/src/components/timed_progress_bar.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx index 26deb82bd..7d9245b5d 100644 --- a/packages/instant/src/components/time_counter.tsx +++ b/packages/instant/src/components/time_counter.tsx @@ -7,7 +7,7 @@ import { Text } from './ui/text'; export interface TimeCounterProps { estimatedTimeMs: number; - ended: boolean; + hasEnded: boolean; } interface TimeCounterState { elapsedSeconds: number; @@ -28,7 +28,7 @@ export class TimeCounter extends React.Component Date: Thu, 1 Nov 2018 10:04:04 -0700 Subject: Minor cleanup Don't export beginningState, and updating prop name in comment --- packages/instant/src/components/timed_progress_bar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index 16781b9d7..8dc95808b 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -17,7 +17,7 @@ interface TimedProgressBarState { maxWidthPercent: number; } -export const beginningState = (props: TimedProgressBarProps): TimedProgressBarState => { +const beginningState = (props: TimedProgressBarProps): TimedProgressBarState => { return { animationTimeMs: props.expectedTimeMs, animationStartingWidth: '0%', @@ -28,7 +28,7 @@ export const beginningState = (props: TimedProgressBarProps): TimedProgressBarSt /** * Timed Progress Bar * Goes from 0% -> PROGRESS_STALL_AT_PERCENTAGE% over time of expectedTimeMs - * When ended set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length + * When hasEnded set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length */ export class TimedProgressBar extends React.Component { private readonly _barRef = React.createRef(); -- cgit v1.2.3 From 544ddd44a00fe7432d6d8cef44c75f9bfbc78150 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 10:46:34 -0700 Subject: Getting rid of TimedProgress state --- .../instant/src/components/timed_progress_bar.tsx | 70 +++++++--------------- 1 file changed, 23 insertions(+), 47 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index 8dc95808b..694ae7e2f 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -11,66 +11,42 @@ export interface TimedProgressBarProps { hasEnded: boolean; } -interface TimedProgressBarState { - animationTimeMs: number; - animationStartingWidth: string; - maxWidthPercent: number; -} - -const beginningState = (props: TimedProgressBarProps): TimedProgressBarState => { - return { - animationTimeMs: props.expectedTimeMs, - animationStartingWidth: '0%', - maxWidthPercent: PROGRESS_STALL_AT_PERCENTAGE, - }; -}; - /** * Timed Progress Bar * Goes from 0% -> PROGRESS_STALL_AT_PERCENTAGE% over time of expectedTimeMs * When hasEnded set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length */ -export class TimedProgressBar extends React.Component { +export class TimedProgressBar extends React.Component { private readonly _barRef = React.createRef(); - public constructor(props: TimedProgressBarProps) { - super(props); - this.state = beginningState(props); - } - - public componentDidUpdate(prevProps: TimedProgressBarProps, prevState: TimedProgressBarState): void { - if (prevProps.hasEnded === false && this.props.hasEnded === true) { - // Show nice animation going to end - // barRef current should always exist, but checking for typesafety - if (this._barRef.current) { - const curProgressWidth = this._barRef.current.offsetWidth; - this.setState({ - animationTimeMs: PROGRESS_FINISH_ANIMATION_TIME_MS, - animationStartingWidth: `${curProgressWidth}px`, - maxWidthPercent: 100, - }); - } - return; - } - - if (prevProps.expectedTimeMs !== this.props.expectedTimeMs || prevProps.hasEnded !== this.props.hasEnded) { - // things changed, get fresh state - this.setState(beginningState(this.props)); - } - } - public render(): React.ReactNode { + const timedProgressProps = this._calculateTimedProgressProps(); return ( - + ); } + + private _calculateTimedProgressProps(): TimedProgressProps { + if (this.props.hasEnded) { + if (!this._barRef.current) { + throw new Error('ended but no reference'); + } + const fromWidth = `${this._barRef.current.offsetWidth}px`; + return { + timeMs: PROGRESS_FINISH_ANIMATION_TIME_MS, + fromWidth, + maxWidthPercent: 100, + }; + } + + return { + timeMs: this.props.expectedTimeMs, + fromWidth: '0px', + maxWidthPercent: PROGRESS_STALL_AT_PERCENTAGE, + }; + } } const expandingWidthKeyframes = (fromWidth: string, maxWidthPercent: number) => { -- cgit v1.2.3 From 9990f8720cbc04bc7a5074d6668f22af80b2a476 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 10:50:37 -0700 Subject: maxWidth -> toWidth, and make from and to width consistent units --- .../instant/src/components/timed_progress_bar.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index 694ae7e2f..78c7ee849 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -1,7 +1,7 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_PERCENTAGE } from '../constants'; +import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_WIDTH } from '../constants'; import { ColorOption, keyframes, styled } from '../style/theme'; import { Container } from './ui/container'; @@ -13,8 +13,8 @@ export interface TimedProgressBarProps { /** * Timed Progress Bar - * Goes from 0% -> PROGRESS_STALL_AT_PERCENTAGE% over time of expectedTimeMs - * When hasEnded set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length + * Goes from 0% -> PROGRESS_STALL_AT_WIDTH over time of expectedTimeMs + * When hasEnded set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length of time */ export class TimedProgressBar extends React.Component { private readonly _barRef = React.createRef(); @@ -37,25 +37,25 @@ export class TimedProgressBar extends React.Component return { timeMs: PROGRESS_FINISH_ANIMATION_TIME_MS, fromWidth, - maxWidthPercent: 100, + toWidth: '100%', }; } return { timeMs: this.props.expectedTimeMs, fromWidth: '0px', - maxWidthPercent: PROGRESS_STALL_AT_PERCENTAGE, + toWidth: PROGRESS_STALL_AT_WIDTH, }; } } -const expandingWidthKeyframes = (fromWidth: string, maxWidthPercent: number) => { +const expandingWidthKeyframes = (fromWidth: string, toWidth: string) => { return keyframes` from { - width: ${fromWidth} + width: ${fromWidth}; } to { - width: ${maxWidthPercent}%; + width: ${toWidth}; } `; }; @@ -63,7 +63,7 @@ const expandingWidthKeyframes = (fromWidth: string, maxWidthPercent: number) => interface TimedProgressProps { timeMs: number; fromWidth: string; - maxWidthPercent: number; + toWidth: string; } // TODO use PrimaryColor instead of black export const TimedProgress = @@ -73,6 +73,6 @@ export const TimedProgress = background-color: black; border-radius: 6px; height: 6px; - animation: ${props => expandingWidthKeyframes(props.fromWidth, props.maxWidthPercent)} + animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)} ${props => props.timeMs}ms linear 1 forwards; `; -- cgit v1.2.3 From f82d16a5b06a47f3ede917165ba75dfd73f48137 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 11:15:07 -0700 Subject: Use primary color instead of black --- packages/instant/src/components/timed_progress_bar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index 78c7ee849..c6ba4ac19 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -70,7 +70,7 @@ export const TimedProgress = styled.div < TimedProgressProps > ` - background-color: black; + background-color: ${props => props.theme[ColorOption.primaryColor]}; border-radius: 6px; height: 6px; animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)} -- cgit v1.2.3 From cd79a2fad1babd1d421c693208cd7de5ae980630 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 11:15:34 -0700 Subject: Use new constants --- packages/instant/src/components/time_counter.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx index 7d9245b5d..c98fd2550 100644 --- a/packages/instant/src/components/time_counter.tsx +++ b/packages/instant/src/components/time_counter.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; +import { ONE_SECOND_MS } from '../constants'; import { timeUtil } from '../util/time'; import { Flex } from './ui/flex'; @@ -34,7 +35,7 @@ export class TimeCounter extends React.Component Est. Time ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) @@ -53,7 +54,7 @@ export class TimeCounter extends React.Component Date: Thu, 1 Nov 2018 11:17:41 -0700 Subject: Remove old TODO --- packages/instant/src/components/timed_progress_bar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index c6ba4ac19..f2a6f5745 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -65,7 +65,7 @@ interface TimedProgressProps { fromWidth: string; toWidth: string; } -// TODO use PrimaryColor instead of black + export const TimedProgress = styled.div < TimedProgressProps > -- cgit v1.2.3 From 61a1a0be974c8610623f2bcb9a43797532cc78d9 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 11:29:33 -0700 Subject: Move BuyOrderProgress to its own component --- .../instant/src/components/buy_order_progress.tsx | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/instant/src/components/buy_order_progress.tsx (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_order_progress.tsx b/packages/instant/src/components/buy_order_progress.tsx new file mode 100644 index 000000000..e259e5606 --- /dev/null +++ b/packages/instant/src/components/buy_order_progress.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; + +import { TimedProgressBar } from '../components/timed_progress_bar'; + +import { TimeCounter } from '../components/time_counter'; +import { Container } from '../components/ui'; +import { OrderProcessState, OrderState } from '../types'; + +export interface BuyOrderProgressProps { + buyOrderState: OrderState; +} + +export const BuyOrderProgress: React.StatelessComponent = props => { + const { buyOrderState } = props; + + if ( + buyOrderState.processState === OrderProcessState.PROCESSING || + buyOrderState.processState === OrderProcessState.SUCCESS || + buyOrderState.processState === OrderProcessState.FAILURE + ) { + const progress = buyOrderState.progress; + const hasEnded = buyOrderState.processState !== OrderProcessState.PROCESSING; + const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix; + return ( + + + + + + + ); + } + + return null; +}; -- cgit v1.2.3 From 771e01162d2c1f8543d5561872fb82af9e8e7b62 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 11:30:13 -0700 Subject: Rename export --- packages/instant/src/components/zero_ex_instant_container.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 87a7cee88..efebf264c 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -5,7 +5,7 @@ import { LatestError } from '../containers/latest_error'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; -import { SelectedAssetProgress } from '../containers/selected_asset_progress'; +import { SelectedAssetBuyOrderProgress } from '../containers/selected_asset_progress'; import { ColorOption } from '../style/theme'; @@ -26,7 +26,7 @@ export const ZeroExInstantContainer: React.StatelessComponent - + -- cgit v1.2.3 From f9d13cd43ae43c05558538ac3d108552c7854fee Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 11:32:18 -0700 Subject: Move file to new file to reflect the new export name --- packages/instant/src/components/zero_ex_instant_container.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index efebf264c..c47f3af73 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -5,7 +5,7 @@ import { LatestError } from '../containers/latest_error'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; -import { SelectedAssetBuyOrderProgress } from '../containers/selected_asset_progress'; +import { SelectedAssetBuyOrderProgress } from '../containers/selected_asset_buy_order_progress'; import { ColorOption } from '../style/theme'; -- cgit v1.2.3 From dc655fd903c5b35ea9280c5afd10b78b25fa7ca3 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 12:08:48 -0700 Subject: Better styling of estimated time --- packages/instant/src/components/time_counter.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx index c98fd2550..22dc634d9 100644 --- a/packages/instant/src/components/time_counter.tsx +++ b/packages/instant/src/components/time_counter.tsx @@ -3,8 +3,10 @@ import * as React from 'react'; import { ONE_SECOND_MS } from '../constants'; import { timeUtil } from '../util/time'; +import { Container } from './ui/container'; import { Flex } from './ui/flex'; import { Text } from './ui/text'; +import { ColorOption } from '../style/theme'; export interface TimeCounterProps { estimatedTimeMs: number; @@ -38,8 +40,19 @@ export class TimeCounter extends React.Component - Est. Time ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) - Time: {timeUtil.secondsToStopwatchTime(this.state.elapsedSeconds)} + + + + Est. Time + + + + ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)}) + + + + Time: {timeUtil.secondsToStopwatchTime(this.state.elapsedSeconds)} + ); } -- cgit v1.2.3 From 7858dafce4c9441c8205fa6ed607ca50851cc4ba Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 1 Nov 2018 14:14:00 -0700 Subject: linting: moving order of imports --- packages/instant/src/components/time_counter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx index 22dc634d9..f9b68163c 100644 --- a/packages/instant/src/components/time_counter.tsx +++ b/packages/instant/src/components/time_counter.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import { ONE_SECOND_MS } from '../constants'; +import { ColorOption } from '../style/theme'; import { timeUtil } from '../util/time'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; import { Text } from './ui/text'; -import { ColorOption } from '../style/theme'; export interface TimeCounterProps { estimatedTimeMs: number; -- cgit v1.2.3 From 5e66cc8a40759658a8763f85996163e5ae013fcd Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 1 Nov 2018 18:24:32 -0700 Subject: feat(instant): implement affiliateFeeInfo prop --- packages/instant/src/components/buy_button.tsx | 13 ++++++++++--- packages/instant/src/components/buy_order_state_buttons.tsx | 4 +++- .../instant/src/components/zero_ex_instant_provider.tsx | 6 ++++-- 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'packages/instant/src/components') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index c00b1678d..12ac62601 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -1,10 +1,11 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as _ from 'lodash'; import * as React from 'react'; +import { oc } from 'ts-optchain'; import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; -import { ZeroExInstantError } from '../types'; +import { AffiliateInfo, ZeroExInstantError } from '../types'; import { getBestAddress } from '../util/address'; import { balanceUtil } from '../util/balance'; import { gasPriceEstimator } from '../util/gas_price_estimator'; @@ -16,6 +17,7 @@ import { Button, Text } from './ui'; export interface BuyButtonProps { buyQuote?: BuyQuote; assetBuyer?: AssetBuyer; + affiliateInfo?: AffiliateInfo; onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote) => void; @@ -42,7 +44,7 @@ export class BuyButton extends React.Component { } private readonly _handleClick = async () => { // The button is disabled when there is no buy quote anyway. - const { buyQuote, assetBuyer } = this.props; + const { buyQuote, assetBuyer, affiliateInfo } = this.props; if (_.isUndefined(buyQuote) || _.isUndefined(assetBuyer)) { return; } @@ -58,8 +60,13 @@ export class BuyButton extends React.Component { let txHash: string | undefined; const gasInfo = await gasPriceEstimator.getGasInfoAsync(); + const feeRecipient = oc(affiliateInfo).feeRecipient(); try { - txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress, gasPrice: gasInfo.gasPriceInWei }); + txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { + feeRecipient, + takerAddress, + gasPrice: gasInfo.gasPriceInWei, + }); } catch (e) { if (e instanceof Error) { if (e.message === AssetBuyerError.SignatureRequestDenied) { diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index 1d02f8cd9..5c074a67a 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -2,7 +2,7 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as React from 'react'; import { ColorOption } from '../style/theme'; -import { OrderProcessState, ZeroExInstantError } from '../types'; +import { AffiliateInfo, OrderProcessState, ZeroExInstantError } from '../types'; import { BuyButton } from './buy_button'; import { PlacingOrderButton } from './placing_order_button'; @@ -13,6 +13,7 @@ export interface BuyOrderStateButtonProps { buyQuote?: BuyQuote; buyOrderProcessingState: OrderProcessState; assetBuyer?: AssetBuyer; + affiliateInfo?: AffiliateInfo; onViewTransaction: () => void; onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; @@ -50,6 +51,7 @@ export const BuyOrderStateButtons: React.StatelessComponent; networkId: Network; + affiliateInfo: AffiliateInfo; } export class ZeroExInstantProvider extends React.Component { @@ -66,6 +67,7 @@ export class ZeroExInstantProvider extends React.Component