diff options
author | Steve Klebanoff <steve.klebanoff@gmail.com> | 2018-10-19 05:51:45 +0800 |
---|---|---|
committer | Steve Klebanoff <steve.klebanoff@gmail.com> | 2018-10-19 06:32:32 +0800 |
commit | 8a6e0776640a7bec7eab1f91b3b611dc4cadd2f7 (patch) | |
tree | 6cb3708c465f1c75783f763ecfd360e19d0b9a3b | |
parent | b4af27dd4462a001904ac6d69e43aac9fd7bb69a (diff) | |
download | dexon-0x-contracts-8a6e0776640a7bec7eab1f91b3b611dc4cadd2f7.tar.gz dexon-0x-contracts-8a6e0776640a7bec7eab1f91b3b611dc4cadd2f7.tar.zst dexon-0x-contracts-8a6e0776640a7bec7eab1f91b3b611dc4cadd2f7.zip |
feat(instant): Indicate that order details section is loading by having pulsing placeholder
4 files changed, 47 insertions, 16 deletions
diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx index 54639effb..23a00895a 100644 --- a/packages/instant/src/components/amount_placeholder.tsx +++ b/packages/instant/src/components/amount_placeholder.tsx @@ -6,24 +6,27 @@ import { Pulse } from './animations/pulse'; import { Text } from './ui'; -export interface AmountPlaceholderProps { - pulsating: boolean; +export interface PlainPlaceholder { + color: ColorOption; } - -const PlainPlaceholder = () => ( - <Text fontWeight="bold" fontColor={ColorOption.white}> +export const PlainPlaceholder: React.StatelessComponent<PlainPlaceholder> = props => ( + <Text fontWeight="bold" fontColor={props.color}> — </Text> ); +export interface AmountPlaceholderProps { + color: ColorOption; + pulsating: boolean; +} export const AmountPlaceholder: React.StatelessComponent<AmountPlaceholderProps> = props => { if (props.pulsating) { return ( <Pulse> - <PlainPlaceholder /> + <PlainPlaceholder color={props.color} /> </Pulse> ); } else { - return <PlainPlaceholder />; + return <PlainPlaceholder color={props.color} />; } }; diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 9ca4ce598..6a4c850f2 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -17,6 +17,7 @@ export interface InstantHeadingProps { quoteRequestState: AsyncProcessState; } +const placeholderColor = ColorOption.white; export class InstantHeading extends React.Component<InstantHeadingProps, {}> { public render(): React.ReactNode { const placeholderAmountToAlwaysShow = this._placeholderAmountToAlwaysShow(); @@ -52,10 +53,10 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { private _placeholderAmountToAlwaysShow(): React.ReactNode | undefined { if (this.props.quoteRequestState === AsyncProcessState.PENDING) { - return <AmountPlaceholder pulsating={true} />; + return <AmountPlaceholder pulsating={true} color={placeholderColor} />; } if (_.isUndefined(this.props.selectedAssetAmount)) { - return <AmountPlaceholder pulsating={false} />; + return <AmountPlaceholder pulsating={false} color={placeholderColor} />; } return undefined; } @@ -63,7 +64,11 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { private _ethAmount(): React.ReactNode { return ( <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}> - {format.ethBaseAmount(this.props.totalEthBaseAmount, 4, <AmountPlaceholder pulsating={false} />)} + {format.ethBaseAmount( + this.props.totalEthBaseAmount, + 4, + <AmountPlaceholder pulsating={false} color={placeholderColor} />, + )} </Text> ); } @@ -75,7 +80,7 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { this.props.totalEthBaseAmount, this.props.ethUsdPrice, 2, - <AmountPlaceholder pulsating={false} />, + <AmountPlaceholder pulsating={false} color={ColorOption.white} />, )} </Text> ); diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index ad4a87714..f48f27edb 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -7,11 +7,13 @@ import { oc } from 'ts-optchain'; import { ColorOption } from '../style/theme'; import { format } from '../util/format'; +import { AmountPlaceholder } from './amount_placeholder'; import { Container, Flex, Text } from './ui'; export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; ethUsdPrice?: BigNumber; + isLoading: boolean; } export class OrderDetails extends React.Component<OrderDetailsProps> { @@ -39,13 +41,20 @@ export class OrderDetails extends React.Component<OrderDetailsProps> { ethAmount={ethAssetPrice} ethUsdPrice={ethUsdPrice} isEthAmountInBaseUnits={false} + isLoading={this.props.isLoading} + /> + <EthAmountRow + rowLabel="Fee" + ethAmount={ethTokenFee} + ethUsdPrice={ethUsdPrice} + isLoading={this.props.isLoading} /> - <EthAmountRow rowLabel="Fee" ethAmount={ethTokenFee} ethUsdPrice={ethUsdPrice} /> <EthAmountRow rowLabel="Total Cost" ethAmount={totalEthAmount} ethUsdPrice={ethUsdPrice} shouldEmphasize={true} + isLoading={this.props.isLoading} /> </Container> ); @@ -58,6 +67,7 @@ export interface EthAmountRowProps { isEthAmountInBaseUnits?: boolean; ethUsdPrice?: BigNumber; shouldEmphasize?: boolean; + isLoading: boolean; } export const EthAmountRow: React.StatelessComponent<EthAmountRowProps> = ({ @@ -66,15 +76,19 @@ export const EthAmountRow: React.StatelessComponent<EthAmountRowProps> = ({ isEthAmountInBaseUnits, ethUsdPrice, shouldEmphasize, + isLoading, }) => { - const fontWeight = shouldEmphasize ? 700 : 400; + // TODO: put in private function const usdFormatter = isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; - const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; - const usdPriceSection = _.isUndefined(ethUsdPrice) ? null : ( + const shouldHideUsdPriceSection = _.isUndefined(ethUsdPrice) || _.isUndefined(ethAmount); + const usdPriceSection = shouldHideUsdPriceSection ? null : ( <Container marginRight="3px" display="inline-block"> <Text fontColor={ColorOption.lightGrey}>({usdFormatter(ethAmount, ethUsdPrice)})</Text> </Container> ); + + const fontWeight = shouldEmphasize ? 700 : 400; + const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; return ( <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}> <Flex justify="space-between"> @@ -84,7 +98,13 @@ export const EthAmountRow: React.StatelessComponent<EthAmountRowProps> = ({ <Container> {usdPriceSection} <Text fontWeight={fontWeight} fontColor={ColorOption.grey}> - {ethFormatter(ethAmount)} + {ethFormatter( + ethAmount, + 4, + <Container opacity={0.5}> + <AmountPlaceholder color={ColorOption.lightGrey} pulsating={isLoading} /> + </Container>, + )} </Text> </Container> </Flex> diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts index 597bf3088..092aaaf20 100644 --- a/packages/instant/src/containers/latest_buy_quote_order_details.ts +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -8,18 +8,21 @@ import { oc } from 'ts-optchain'; import { State } from '../redux/reducer'; import { OrderDetails } from '../components/order_details'; +import { AsyncProcessState } from '../types'; export interface LatestBuyQuoteOrderDetailsProps {} interface ConnectedState { buyQuoteInfo?: BuyQuoteInfo; ethUsdPrice?: BigNumber; + isLoading: boolean; } const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({ // use the worst case quote info buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(), ethUsdPrice: state.ethUsdPrice, + isLoading: state.quoteRequestState === AsyncProcessState.PENDING, }); export const LatestBuyQuoteOrderDetails: React.ComponentClass<LatestBuyQuoteOrderDetailsProps> = connect( |