Merge pull request #1480 from 0xProject/feature/instant/performance-boost
[instant] No more laggy input
This commit is contained in:
@@ -30,3 +30,5 @@ export const AmountPlaceholder: React.StatelessComponent<AmountPlaceholderProps>
|
|||||||
return <PlainPlaceholder color={props.color} />;
|
return <PlainPlaceholder color={props.color} />;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AmountPlaceholder.displayName = 'AmountPlaceholder';
|
||||||
|
@@ -11,6 +11,7 @@ export interface SlideAnimationProps {
|
|||||||
slideOutSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
|
slideOutSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
|
||||||
zIndex?: OptionallyScreenSpecific<number>;
|
zIndex?: OptionallyScreenSpecific<number>;
|
||||||
height?: string;
|
height?: string;
|
||||||
|
onAnimationEnd?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => {
|
export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => {
|
||||||
@@ -19,8 +20,15 @@ export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = pro
|
|||||||
}
|
}
|
||||||
const positionSettings = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings;
|
const positionSettings = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings;
|
||||||
return (
|
return (
|
||||||
<PositionAnimation height={props.height} positionSettings={positionSettings} zIndex={props.zIndex}>
|
<PositionAnimation
|
||||||
|
onAnimationEnd={props.onAnimationEnd}
|
||||||
|
height={props.height}
|
||||||
|
positionSettings={positionSettings}
|
||||||
|
zIndex={props.zIndex}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</PositionAnimation>
|
</PositionAnimation>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SlideAnimation.displayName = 'SlideAnimation';
|
||||||
|
@@ -32,7 +32,7 @@ export interface BuyButtonProps {
|
|||||||
onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
|
onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BuyButton extends React.Component<BuyButtonProps> {
|
export class BuyButton extends React.PureComponent<BuyButtonProps> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
onClick: util.boundNoop,
|
onClick: util.boundNoop,
|
||||||
onBuySuccess: util.boundNoop,
|
onBuySuccess: util.boundNoop,
|
||||||
|
@@ -31,3 +31,5 @@ export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> =
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BuyOrderProgress.displayName = 'BuyOrderProgress';
|
||||||
|
@@ -71,3 +71,5 @@ export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonP
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BuyOrderStateButtons.displayName = 'BuyOrderStateButtons';
|
||||||
|
@@ -31,7 +31,7 @@ export interface ERC20AssetAmountInputState {
|
|||||||
currentFontSizePx: number;
|
currentFontSizePx: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInputProps, ERC20AssetAmountInputState> {
|
export class ERC20AssetAmountInput extends React.PureComponent<ERC20AssetAmountInputProps, ERC20AssetAmountInputState> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
onChange: util.boundNoop,
|
onChange: util.boundNoop,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
|
@@ -21,12 +21,12 @@ export interface ERC20TokenSelectorState {
|
|||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps> {
|
export class ERC20TokenSelector extends React.PureComponent<ERC20TokenSelectorProps> {
|
||||||
public state: ERC20TokenSelectorState = {
|
public state: ERC20TokenSelectorState = {
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
};
|
};
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const { tokens, onTokenSelect } = this.props;
|
const { tokens } = this.props;
|
||||||
return (
|
return (
|
||||||
<Container height="100%">
|
<Container height="100%">
|
||||||
<Container marginBottom="10px">
|
<Container marginBottom="10px">
|
||||||
@@ -42,12 +42,11 @@ export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps>
|
|||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
/>
|
/>
|
||||||
<Container overflow="scroll" height="calc(100% - 90px)" marginTop="10px">
|
<Container overflow="scroll" height="calc(100% - 90px)" marginTop="10px">
|
||||||
{_.map(tokens, token => {
|
<TokenRowFilter
|
||||||
if (!this._isTokenQueryMatch(token)) {
|
tokens={tokens}
|
||||||
return null;
|
onClick={this._handleTokenClick}
|
||||||
}
|
searchQuery={this.state.searchQuery}
|
||||||
return <TokenSelectorRow key={token.assetData} token={token} onClick={onTokenSelect} />;
|
/>
|
||||||
})}
|
|
||||||
</Container>
|
</Container>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
@@ -59,8 +58,32 @@ export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps>
|
|||||||
});
|
});
|
||||||
analytics.trackTokenSelectorSearched(searchQuery);
|
analytics.trackTokenSelectorSearched(searchQuery);
|
||||||
};
|
};
|
||||||
|
private readonly _handleTokenClick = (token: ERC20Asset): void => {
|
||||||
|
this.props.onTokenSelect(token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TokenRowFilterProps {
|
||||||
|
tokens: ERC20Asset[];
|
||||||
|
onClick: (token: ERC20Asset) => void;
|
||||||
|
searchQuery: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TokenRowFilter extends React.Component<TokenRowFilterProps> {
|
||||||
|
public render(): React.ReactNode {
|
||||||
|
return _.map(this.props.tokens, token => {
|
||||||
|
if (!this._isTokenQueryMatch(token)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return <TokenSelectorRow key={token.assetData} token={token} onClick={this.props.onClick} />;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public shouldComponentUpdate(nextProps: TokenRowFilterProps): boolean {
|
||||||
|
const arePropsDeeplyEqual = _.isEqual(nextProps, this.props);
|
||||||
|
return !arePropsDeeplyEqual;
|
||||||
|
}
|
||||||
private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
|
private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
|
||||||
const { searchQuery } = this.state;
|
const { searchQuery } = this.props;
|
||||||
const searchQueryLowerCase = searchQuery.toLowerCase().trim();
|
const searchQueryLowerCase = searchQuery.toLowerCase().trim();
|
||||||
if (searchQueryLowerCase === '') {
|
if (searchQueryLowerCase === '') {
|
||||||
return true;
|
return true;
|
||||||
@@ -76,7 +99,7 @@ interface TokenSelectorRowProps {
|
|||||||
onClick: (token: ERC20Asset) => void;
|
onClick: (token: ERC20Asset) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TokenSelectorRow extends React.Component<TokenSelectorRowProps> {
|
class TokenSelectorRow extends React.PureComponent<TokenSelectorRowProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const { token } = this.props;
|
const { token } = this.props;
|
||||||
const circleColor = token.metaData.primaryColor || 'black';
|
const circleColor = token.metaData.primaryColor || 'black';
|
||||||
@@ -131,8 +154,9 @@ const getTokenIcon = (symbol: string): React.StatelessComponent | undefined => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const TokenSelectorRowIcon: React.StatelessComponent<TokenSelectorRowIconProps> = props => {
|
class TokenSelectorRowIcon extends React.PureComponent<TokenSelectorRowIconProps> {
|
||||||
const { token } = props;
|
public render(): React.ReactNode {
|
||||||
|
const { token } = this.props;
|
||||||
const iconUrlIfExists = token.metaData.iconUrl;
|
const iconUrlIfExists = token.metaData.iconUrl;
|
||||||
|
|
||||||
const TokenIcon = getTokenIcon(token.metaData.symbol);
|
const TokenIcon = getTokenIcon(token.metaData.symbol);
|
||||||
@@ -148,4 +172,5 @@ const TokenSelectorRowIcon: React.StatelessComponent<TokenSelectorRowIconProps>
|
|||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
@@ -18,7 +18,7 @@ import { Button } from './ui/button';
|
|||||||
|
|
||||||
export interface InstallWalletPanelContentProps {}
|
export interface InstallWalletPanelContentProps {}
|
||||||
|
|
||||||
export class InstallWalletPanelContent extends React.Component<InstallWalletPanelContentProps> {
|
export class InstallWalletPanelContent extends React.PureComponent<InstallWalletPanelContentProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const panelProps = this._getStandardPanelContentProps();
|
const panelProps = this._getStandardPanelContentProps();
|
||||||
return <StandardPanelContent {...panelProps} />;
|
return <StandardPanelContent {...panelProps} />;
|
||||||
|
@@ -28,7 +28,7 @@ const ICON_WIDTH = 34;
|
|||||||
const ICON_HEIGHT = 34;
|
const ICON_HEIGHT = 34;
|
||||||
const ICON_COLOR = ColorOption.white;
|
const ICON_COLOR = ColorOption.white;
|
||||||
|
|
||||||
export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
|
export class InstantHeading extends React.PureComponent<InstantHeadingProps, {}> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
|
const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
|
||||||
return (
|
return (
|
||||||
|
@@ -26,7 +26,7 @@ export interface OrderDetailsProps {
|
|||||||
onBaseCurrencySwitchEth: () => void;
|
onBaseCurrencySwitchEth: () => void;
|
||||||
onBaseCurrencySwitchUsd: () => void;
|
onBaseCurrencySwitchUsd: () => void;
|
||||||
}
|
}
|
||||||
export class OrderDetails extends React.Component<OrderDetailsProps> {
|
export class OrderDetails extends React.PureComponent<OrderDetailsProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const shouldShowUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice();
|
const shouldShowUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice();
|
||||||
return (
|
return (
|
||||||
@@ -200,7 +200,7 @@ export interface OrderDetailsRowProps {
|
|||||||
primaryValue: React.ReactNode;
|
primaryValue: React.ReactNode;
|
||||||
secondaryValue?: React.ReactNode;
|
secondaryValue?: React.ReactNode;
|
||||||
}
|
}
|
||||||
export class OrderDetailsRow extends React.Component<OrderDetailsRowProps, {}> {
|
export class OrderDetailsRow extends React.PureComponent<OrderDetailsRowProps, {}> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
|
<Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
|
||||||
|
@@ -24,7 +24,7 @@ export interface PaymentMethodProps {
|
|||||||
onUnlockWalletClick: () => void;
|
onUnlockWalletClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PaymentMethod extends React.Component<PaymentMethodProps> {
|
export class PaymentMethod extends React.PureComponent<PaymentMethodProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<Container width="100%" height="120px" padding="20px 20px 0px 20px">
|
<Container width="100%" height="120px" padding="20px 20px 0px 20px">
|
||||||
|
@@ -16,7 +16,7 @@ export interface PaymentMethodDropdownProps {
|
|||||||
network: Network;
|
network: Network;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PaymentMethodDropdown extends React.Component<PaymentMethodDropdownProps> {
|
export class PaymentMethodDropdown extends React.PureComponent<PaymentMethodDropdownProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const { accountAddress, accountEthBalanceInWei } = this.props;
|
const { accountAddress, accountEthBalanceInWei } = this.props;
|
||||||
const value = format.ethAddress(accountAddress);
|
const value = format.ethAddress(accountAddress);
|
||||||
|
@@ -14,3 +14,5 @@ export const PlacingOrderButton: React.StatelessComponent<{}> = props => (
|
|||||||
Placing Order…
|
Placing Order…
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PlacingOrderButton.displayName = 'PlacingOrderButton';
|
||||||
|
@@ -26,7 +26,7 @@ interface ScalingAmountInputState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { stringToMaybeBigNumber, areMaybeBigNumbersEqual } = maybeBigNumberUtil;
|
const { stringToMaybeBigNumber, areMaybeBigNumbersEqual } = maybeBigNumberUtil;
|
||||||
export class ScalingAmountInput extends React.Component<ScalingAmountInputProps, ScalingAmountInputState> {
|
export class ScalingAmountInput extends React.PureComponent<ScalingAmountInputProps, ScalingAmountInputState> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
onAmountChange: util.boundNoop,
|
onAmountChange: util.boundNoop,
|
||||||
onFontSizeChange: util.boundNoop,
|
onFontSizeChange: util.boundNoop,
|
||||||
|
@@ -51,7 +51,7 @@ const defaultScalingSettings: ScalingSettings = {
|
|||||||
additionalInputSpaceInCh: 0.4,
|
additionalInputSpaceInCh: 0.4,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ScalingInput extends React.Component<ScalingInputProps> {
|
export class ScalingInput extends React.PureComponent<ScalingInputProps> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
onChange: util.boundNoop,
|
onChange: util.boundNoop,
|
||||||
onFontSizeChange: util.boundNoop,
|
onFontSizeChange: util.boundNoop,
|
||||||
|
@@ -24,3 +24,4 @@ export const SecondaryButton: React.StatelessComponent<SecondaryButtonProps> = p
|
|||||||
SecondaryButton.defaultProps = {
|
SecondaryButton.defaultProps = {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
};
|
};
|
||||||
|
SecondaryButton.displayName = 'SecondaryButton';
|
||||||
|
@@ -18,3 +18,4 @@ export const SectionHeader: React.StatelessComponent<SectionHeaderProps> = props
|
|||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
SectionHeader.displayName = 'SectionHeader';
|
||||||
|
@@ -38,6 +38,8 @@ export const Error: React.StatelessComponent<ErrorProps> = props => (
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Error.displayName = 'Error';
|
||||||
|
|
||||||
export interface SlidingErrorProps extends ErrorProps {
|
export interface SlidingErrorProps extends ErrorProps {
|
||||||
animationState: SlideAnimationState;
|
animationState: SlideAnimationState;
|
||||||
}
|
}
|
||||||
@@ -94,3 +96,5 @@ export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props =
|
|||||||
</SlideAnimation>
|
</SlideAnimation>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SlidingError.displayName = 'SlidingError';
|
||||||
|
@@ -26,15 +26,19 @@ export const Panel: React.StatelessComponent<PanelProps> = ({ children, onClose
|
|||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Panel.displayName = 'Panel';
|
||||||
|
|
||||||
export interface SlidingPanelProps extends PanelProps {
|
export interface SlidingPanelProps extends PanelProps {
|
||||||
animationState: SlideAnimationState;
|
animationState: SlideAnimationState;
|
||||||
|
onAnimationEnd?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SlidingPanel: React.StatelessComponent<SlidingPanelProps> = props => {
|
export class SlidingPanel extends React.PureComponent<SlidingPanelProps> {
|
||||||
if (props.animationState === 'none') {
|
public render(): React.ReactNode {
|
||||||
|
if (this.props.animationState === 'none') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { animationState, ...rest } = props;
|
const { animationState, onAnimationEnd, ...rest } = this.props;
|
||||||
const slideAmount = '100%';
|
const slideAmount = '100%';
|
||||||
const slideUpSettings: PositionAnimationSettings = {
|
const slideUpSettings: PositionAnimationSettings = {
|
||||||
duration: '0.3s',
|
duration: '0.3s',
|
||||||
@@ -60,8 +64,10 @@ export const SlidingPanel: React.StatelessComponent<SlidingPanelProps> = props =
|
|||||||
slideOutSettings={slideDownSettings}
|
slideOutSettings={slideDownSettings}
|
||||||
animationState={animationState}
|
animationState={animationState}
|
||||||
height="100%"
|
height="100%"
|
||||||
|
onAnimationEnd={onAnimationEnd}
|
||||||
>
|
>
|
||||||
<Panel {...rest} />
|
<Panel {...rest} />
|
||||||
</SlideAnimation>
|
</SlideAnimation>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
@@ -71,3 +71,5 @@ export const StandardPanelContent: React.StatelessComponent<StandardPanelContent
|
|||||||
<Container>{action}</Container>
|
<Container>{action}</Container>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
StandardPanelContent.displayName = 'StandardPanelContent';
|
||||||
|
@@ -9,7 +9,7 @@ export interface StandardSlidingPanelProps extends StandardSlidingPanelSettings
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StandardSlidingPanel extends React.Component<StandardSlidingPanelProps> {
|
export class StandardSlidingPanel extends React.PureComponent<StandardSlidingPanelProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const { animationState, content, onClose } = this.props;
|
const { animationState, content, onClose } = this.props;
|
||||||
return (
|
return (
|
||||||
|
@@ -16,7 +16,7 @@ interface TimeCounterState {
|
|||||||
elapsedSeconds: number;
|
elapsedSeconds: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TimeCounter extends React.Component<TimeCounterProps, TimeCounterState> {
|
export class TimeCounter extends React.PureComponent<TimeCounterProps, TimeCounterState> {
|
||||||
public state = {
|
public state = {
|
||||||
elapsedSeconds: 0,
|
elapsedSeconds: 0,
|
||||||
};
|
};
|
||||||
|
@@ -17,7 +17,7 @@ export interface TimedProgressBarProps {
|
|||||||
* Goes from 0% -> PROGRESS_STALL_AT_WIDTH over time of expectedTimeMs
|
* 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
|
* 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<TimedProgressBarProps, {}> {
|
export class TimedProgressBar extends React.PureComponent<TimedProgressBarProps, {}> {
|
||||||
private readonly _barRef = React.createRef<HTMLDivElement>();
|
private readonly _barRef = React.createRef<HTMLDivElement>();
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
|
@@ -26,7 +26,7 @@ export interface DropdownState {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
export class Dropdown extends React.PureComponent<DropdownProps, DropdownState> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
items: [],
|
items: [],
|
||||||
};
|
};
|
||||||
@@ -138,3 +138,5 @@ export const DropdownItem: React.StatelessComponent<DropdownItemProps> = ({ text
|
|||||||
</Text>
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DropdownItem.displayName = 'DropdownItem';
|
||||||
|
@@ -45,3 +45,5 @@ WalletPrompt.defaultProps = {
|
|||||||
primaryColor: ColorOption.darkOrange,
|
primaryColor: ColorOption.darkOrange,
|
||||||
secondaryColor: ColorOption.lightOrange,
|
secondaryColor: ColorOption.lightOrange,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WalletPrompt.displayName = 'WalletPrompt';
|
||||||
|
@@ -17,3 +17,5 @@ export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZeroExInstant.displayName = 'ZeroExInstant';
|
||||||
|
@@ -24,7 +24,10 @@ export interface ZeroExInstantContainerState {
|
|||||||
tokenSelectionPanelAnimationState: SlideAnimationState;
|
tokenSelectionPanelAnimationState: SlideAnimationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ZeroExInstantContainer extends React.Component<ZeroExInstantContainerProps, ZeroExInstantContainerState> {
|
export class ZeroExInstantContainer extends React.PureComponent<
|
||||||
|
ZeroExInstantContainerProps,
|
||||||
|
ZeroExInstantContainerState
|
||||||
|
> {
|
||||||
public state = {
|
public state = {
|
||||||
tokenSelectionPanelAnimationState: 'none' as SlideAnimationState,
|
tokenSelectionPanelAnimationState: 'none' as SlideAnimationState,
|
||||||
};
|
};
|
||||||
@@ -60,6 +63,7 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
|
|||||||
<SlidingPanel
|
<SlidingPanel
|
||||||
animationState={this.state.tokenSelectionPanelAnimationState}
|
animationState={this.state.tokenSelectionPanelAnimationState}
|
||||||
onClose={this._handlePanelCloseClickedX}
|
onClose={this._handlePanelCloseClickedX}
|
||||||
|
onAnimationEnd={this._handleSlidingPanelAnimationEnd}
|
||||||
>
|
>
|
||||||
<AvailableERC20TokenSelector onTokenSelect={this._handlePanelCloseAfterChose} />
|
<AvailableERC20TokenSelector onTokenSelect={this._handlePanelCloseAfterChose} />
|
||||||
</SlidingPanel>
|
</SlidingPanel>
|
||||||
@@ -98,4 +102,11 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
|
|||||||
tokenSelectionPanelAnimationState: 'slidOut',
|
tokenSelectionPanelAnimationState: 'slidOut',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
private readonly _handleSlidingPanelAnimationEnd = (): void => {
|
||||||
|
if (this.state.tokenSelectionPanelAnimationState === 'slidOut') {
|
||||||
|
// When the slidOut animation completes, don't keep the panel mounted.
|
||||||
|
// Performance optimization
|
||||||
|
this.setState({ tokenSelectionPanelAnimationState: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -49,3 +49,5 @@ export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlay
|
|||||||
</ZeroExInstantProvider>
|
</ZeroExInstantProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZeroExInstantOverlay.displayName = 'ZeroExInstantOverlay';
|
||||||
|
@@ -21,7 +21,7 @@ import { providerStateFactory } from '../util/provider_state_factory';
|
|||||||
|
|
||||||
export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig;
|
export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig;
|
||||||
|
|
||||||
export class ZeroExInstantProvider extends React.Component<ZeroExInstantProviderProps> {
|
export class ZeroExInstantProvider extends React.PureComponent<ZeroExInstantProviderProps> {
|
||||||
private readonly _store: Store;
|
private readonly _store: Store;
|
||||||
private _accountUpdateHeartbeat?: Heartbeater;
|
private _accountUpdateHeartbeat?: Heartbeater;
|
||||||
private _buyQuoteHeartbeat?: Heartbeater;
|
private _buyQuoteHeartbeat?: Heartbeater;
|
||||||
|
@@ -14,7 +14,7 @@ import { zIndex } from '../style/z_index';
|
|||||||
import { Asset, DisplayStatus, Omit, SlideAnimationState } from '../types';
|
import { Asset, DisplayStatus, Omit, SlideAnimationState } from '../types';
|
||||||
import { errorFlasher } from '../util/error_flasher';
|
import { errorFlasher } from '../util/error_flasher';
|
||||||
|
|
||||||
export interface LatestErrorComponentProps {
|
interface LatestErrorComponentProps {
|
||||||
asset?: Asset;
|
asset?: Asset;
|
||||||
latestErrorMessage?: string;
|
latestErrorMessage?: string;
|
||||||
animationState: SlideAnimationState;
|
animationState: SlideAnimationState;
|
||||||
@@ -22,7 +22,7 @@ export interface LatestErrorComponentProps {
|
|||||||
onOverlayClick: () => void;
|
onOverlayClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LatestErrorComponent: React.StatelessComponent<LatestErrorComponentProps> = props => {
|
const LatestErrorComponent: React.StatelessComponent<LatestErrorComponentProps> = props => {
|
||||||
if (!props.latestErrorMessage) {
|
if (!props.latestErrorMessage) {
|
||||||
// Render a hidden SlidingError such that instant does not move when a real error is rendered.
|
// Render a hidden SlidingError such that instant does not move when a real error is rendered.
|
||||||
return (
|
return (
|
||||||
|
Reference in New Issue
Block a user