feat: refactor progress bar code to expose static progress bar

This commit is contained in:
fragosti 2018-11-09 13:19:59 -08:00
parent daa011f7cb
commit fa7bd072d0
5 changed files with 73 additions and 26 deletions

View File

@ -1,6 +1,7 @@
import * as _ from 'lodash';
import * as React from 'react';
import { TimedProgressBar } from '../components/timed_progress_bar';
import { ProgressBar, TimedProgressBar } from '../components/timed_progress_bar';
import { TimeCounter } from '../components/time_counter';
import { Container } from '../components/ui/container';
@ -12,7 +13,7 @@ export interface BuyOrderProgressProps {
export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = props => {
const { buyOrderState } = props;
let content: React.ReactNode = null;
if (
buyOrderState.processState === OrderProcessState.Processing ||
buyOrderState.processState === OrderProcessState.Success ||
@ -21,15 +22,25 @@ export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> =
const progress = buyOrderState.progress;
const hasEnded = buyOrderState.processState !== OrderProcessState.Processing;
const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix;
return (
<Container padding="20px 20px 0px 20px" width="100%">
content = (
<React.Fragment>
<Container marginBottom="5px">
<TimeCounter estimatedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
</Container>
<TimedProgressBar expectedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
</React.Fragment>
);
} else {
// Just show a static progress bar if we aren't processing or in an end state
content = (
<Container marginTop="10px">
<ProgressBar width="0px" />
</Container>
);
}
return null;
return (
<Container padding="20px 20px 0px 20px" width="100%">
{content}
</Container>
);
};

View File

@ -2,7 +2,7 @@ import * as _ from 'lodash';
import * as React from 'react';
import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_WIDTH } from '../constants';
import { ColorOption, keyframes, styled } from '../style/theme';
import { ColorOption, css, keyframes, styled } from '../style/theme';
import { Container } from './ui/container';
@ -20,15 +20,11 @@ export class TimedProgressBar extends React.Component<TimedProgressBarProps, {}>
private readonly _barRef = React.createRef<HTMLDivElement>();
public render(): React.ReactNode {
const timedProgressProps = this._calculateTimedProgressProps();
return (
<Container width="100%" backgroundColor={ColorOption.lightGrey} borderRadius="6px">
<TimedProgress {...timedProgressProps} ref={this._barRef as any} />
</Container>
);
const widthAnimationSettings = this._calculateWidthAnimationSettings();
return <ProgressBar animationSettings={widthAnimationSettings} ref={this._barRef} />;
}
private _calculateTimedProgressProps(): TimedProgressProps {
private _calculateWidthAnimationSettings(): WidthAnimationSettings {
if (this.props.hasEnded) {
if (!this._barRef.current) {
throw new Error('ended but no reference');
@ -60,21 +56,45 @@ const expandingWidthKeyframes = (fromWidth: string, toWidth: string) => {
`;
};
interface TimedProgressProps {
export interface WidthAnimationSettings {
timeMs: number;
fromWidth: string;
toWidth: string;
}
export const TimedProgress =
interface ProgressProps {
width?: string;
animationSettings?: WidthAnimationSettings;
}
export const Progress =
styled.div <
TimedProgressProps >
ProgressProps >
`
&& {
background-color: ${props => props.theme[ColorOption.primaryColor]};
border-radius: 6px;
height: 6px;
animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)}
${props => props.timeMs}ms linear 1 forwards;
${props => (props.width ? `width: ${props.width};` : '')}
${props =>
props.animationSettings
? css`
animation: ${expandingWidthKeyframes(
props.animationSettings.fromWidth,
props.animationSettings.toWidth,
)}
${props.animationSettings.timeMs}ms linear 1 forwards;
`
: ''}
}
`;
export interface ProgressBarProps extends ProgressProps {}
export const ProgressBar: React.ComponentType<ProgressBarProps & React.ClassAttributes<{}>> = React.forwardRef(
(props, ref) => (
<Container width="100%" backgroundColor={ColorOption.lightGrey} borderRadius="6px">
<Progress {...props} ref={ref as any} />
</Container>
),
);

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import { INJECTED_DIV_CLASS } from '../constants';
import { ConnectedZeroExInstantContainer } from '../containers/connected_zero_ex_instant_container';
import { ZeroExInstantContainer } from './zero_ex_instant_container';
import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
export type ZeroExInstantProps = ZeroExInstantProviderProps;
@ -11,7 +11,7 @@ export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props
return (
<div className={INJECTED_DIV_CLASS}>
<ZeroExInstantProvider {...props}>
<ZeroExInstantContainer />
<ConnectedZeroExInstantContainer />
</ZeroExInstantProvider>
</div>
);

View File

@ -9,14 +9,16 @@ import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_
import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
import { ColorOption } from '../style/theme';
import { zIndex } from '../style/z_index';
import { SlideAnimationState } from '../types';
import { OrderProcessState, SlideAnimationState } from '../types';
import { CSSReset } from './css_reset';
import { SlidingPanel } from './sliding_panel';
import { Container } from './ui/container';
import { Flex } from './ui/flex';
export interface ZeroExInstantContainerProps {}
export interface ZeroExInstantContainerProps {
orderProcessState: OrderProcessState;
}
export interface ZeroExInstantContainerState {
tokenSelectionPanelAnimationState: SlideAnimationState;
}
@ -48,7 +50,7 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
>
<Flex direction="column" justify="flex-start" height="100%">
<SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} />
<SelectedAssetBuyOrderProgress />
{this._renderPaymentMethodOrBuyOrderProgress()}
<LatestBuyQuoteOrderDetails />
<Container padding="20px" width="100%">
<SelectedAssetBuyOrderStateButtons />
@ -76,4 +78,18 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
tokenSelectionPanelAnimationState: 'slidOut',
});
};
private readonly _renderPaymentMethodOrBuyOrderProgress = (): React.ReactNode => {
const { orderProcessState } = this.props;
if (
orderProcessState === OrderProcessState.Processing ||
orderProcessState === OrderProcessState.Success ||
orderProcessState === OrderProcessState.Failure
) {
return <SelectedAssetBuyOrderProgress />;
}
if (orderProcessState === OrderProcessState.None) {
return <SelectedAssetBuyOrderProgress />;
}
return null;
};
}

View File

@ -1,12 +1,12 @@
import * as React from 'react';
import { ConnectedZeroExInstantContainer } from '../containers/connected_zero_ex_instant_container';
import { ColorOption } from '../style/theme';
import { Container } from './ui/container';
import { Flex } from './ui/flex';
import { Icon } from './ui/icon';
import { Overlay } from './ui/overlay';
import { ZeroExInstantContainer } from './zero_ex_instant_container';
import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps {
@ -31,7 +31,7 @@ export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlay
/>
</Container>
<Container width={{ default: 'auto', sm: '100%' }} height={{ default: 'auto', sm: '100%' }}>
<ZeroExInstantContainer />
<ConnectedZeroExInstantContainer />
</Container>
</Flex>
</Overlay>