Performance Improvements (Pure components, debounced gas slider) (#899)
* PureComponent a ton of non-connected components. * Debounce gas price slider. Keep gas price in state to reflect changes immediately. * PureComponent balance sidebar and swap unconnected components. * Import correct component. * Move debouncing of gas slider to sagas via gasPriceInputIntent action. * Remove console log. * Remove leftover file from merge.
This commit is contained in:
parent
ae8b123cfd
commit
d1a2c885a2
|
@ -6,6 +6,7 @@ import {
|
||||||
SetValueFieldAction,
|
SetValueFieldAction,
|
||||||
InputGasLimitAction,
|
InputGasLimitAction,
|
||||||
InputGasPriceAction,
|
InputGasPriceAction,
|
||||||
|
InputGasPriceIntentAction,
|
||||||
InputDataAction,
|
InputDataAction,
|
||||||
InputNonceAction,
|
InputNonceAction,
|
||||||
ResetAction,
|
ResetAction,
|
||||||
|
@ -25,6 +26,12 @@ const inputGasPrice = (payload: InputGasPriceAction['payload']) => ({
|
||||||
payload
|
payload
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type TInputGasPriceIntent = typeof inputGasPrice;
|
||||||
|
const inputGasPriceIntent = (payload: InputGasPriceIntentAction['payload']) => ({
|
||||||
|
type: TypeKeys.GAS_PRICE_INPUT_INTENT,
|
||||||
|
payload
|
||||||
|
});
|
||||||
|
|
||||||
type TInputNonce = typeof inputNonce;
|
type TInputNonce = typeof inputNonce;
|
||||||
const inputNonce = (payload: InputNonceAction['payload']) => ({
|
const inputNonce = (payload: InputNonceAction['payload']) => ({
|
||||||
type: TypeKeys.NONCE_INPUT,
|
type: TypeKeys.NONCE_INPUT,
|
||||||
|
@ -79,6 +86,7 @@ const reset = (): ResetAction => ({ type: TypeKeys.RESET });
|
||||||
export {
|
export {
|
||||||
TInputGasLimit,
|
TInputGasLimit,
|
||||||
TInputGasPrice,
|
TInputGasPrice,
|
||||||
|
TInputGasPriceIntent,
|
||||||
TInputNonce,
|
TInputNonce,
|
||||||
TInputData,
|
TInputData,
|
||||||
TSetGasLimitField,
|
TSetGasLimitField,
|
||||||
|
@ -90,6 +98,7 @@ export {
|
||||||
TReset,
|
TReset,
|
||||||
inputGasLimit,
|
inputGasLimit,
|
||||||
inputGasPrice,
|
inputGasPrice,
|
||||||
|
inputGasPriceIntent,
|
||||||
inputNonce,
|
inputNonce,
|
||||||
inputData,
|
inputData,
|
||||||
setGasLimitField,
|
setGasLimitField,
|
||||||
|
|
|
@ -10,6 +10,10 @@ interface InputGasPriceAction {
|
||||||
type: TypeKeys.GAS_PRICE_INPUT;
|
type: TypeKeys.GAS_PRICE_INPUT;
|
||||||
payload: string;
|
payload: string;
|
||||||
}
|
}
|
||||||
|
interface InputGasPriceIntentAction {
|
||||||
|
type: TypeKeys.GAS_PRICE_INPUT_INTENT;
|
||||||
|
payload: string;
|
||||||
|
}
|
||||||
interface InputDataAction {
|
interface InputDataAction {
|
||||||
type: TypeKeys.DATA_FIELD_INPUT;
|
type: TypeKeys.DATA_FIELD_INPUT;
|
||||||
payload: string;
|
payload: string;
|
||||||
|
@ -84,6 +88,7 @@ type FieldAction =
|
||||||
export {
|
export {
|
||||||
InputGasLimitAction,
|
InputGasLimitAction,
|
||||||
InputGasPriceAction,
|
InputGasPriceAction,
|
||||||
|
InputGasPriceIntentAction,
|
||||||
InputDataAction,
|
InputDataAction,
|
||||||
InputNonceAction,
|
InputNonceAction,
|
||||||
SetGasLimitFieldAction,
|
SetGasLimitFieldAction,
|
||||||
|
|
|
@ -30,6 +30,7 @@ export enum TypeKeys {
|
||||||
DATA_FIELD_INPUT = 'DATA_FIELD_INPUT',
|
DATA_FIELD_INPUT = 'DATA_FIELD_INPUT',
|
||||||
GAS_LIMIT_INPUT = 'GAS_LIMIT_INPUT',
|
GAS_LIMIT_INPUT = 'GAS_LIMIT_INPUT',
|
||||||
GAS_PRICE_INPUT = 'GAS_PRICE_INPUT',
|
GAS_PRICE_INPUT = 'GAS_PRICE_INPUT',
|
||||||
|
GAS_PRICE_INPUT_INTENT = 'GAS_PRICE_INPUT_INTENT',
|
||||||
NONCE_INPUT = 'NONCE_INPUT',
|
NONCE_INPUT = 'NONCE_INPUT',
|
||||||
|
|
||||||
DATA_FIELD_SET = 'DATA_FIELD_SET',
|
DATA_FIELD_SET = 'DATA_FIELD_SET',
|
||||||
|
|
|
@ -7,7 +7,7 @@ interface State {
|
||||||
isFading: boolean;
|
isFading: boolean;
|
||||||
hasAcknowledged: boolean;
|
hasAcknowledged: boolean;
|
||||||
}
|
}
|
||||||
export default class AlphaAgreement extends React.Component<{}, State> {
|
export default class AlphaAgreement extends React.PureComponent<{}, State> {
|
||||||
public state = {
|
public state = {
|
||||||
hasAcknowledged: !!localStorage.getItem(LS_KEY),
|
hasAcknowledged: !!localStorage.getItem(LS_KEY),
|
||||||
isFading: false
|
isFading: false
|
||||||
|
|
|
@ -23,7 +23,7 @@ interface State {
|
||||||
decimal: string;
|
decimal: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class AddCustomTokenForm extends React.Component<Props, State> {
|
export default class AddCustomTokenForm extends React.PureComponent<Props, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
tokenSymbolLookup: {},
|
tokenSymbolLookup: {},
|
||||||
address: '',
|
address: '',
|
||||||
|
|
|
@ -19,7 +19,7 @@ interface State {
|
||||||
trackedTokens: { [symbol: string]: boolean };
|
trackedTokens: { [symbol: string]: boolean };
|
||||||
showCustomTokenForm: boolean;
|
showCustomTokenForm: boolean;
|
||||||
}
|
}
|
||||||
export default class TokenBalances extends React.Component<Props, State> {
|
export default class TokenBalances extends React.PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
trackedTokens: {},
|
trackedTokens: {},
|
||||||
showCustomTokenForm: false
|
showCustomTokenForm: false
|
||||||
|
|
|
@ -19,7 +19,7 @@ interface State {
|
||||||
showLongBalance: boolean;
|
showLongBalance: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TokenRow extends React.Component<Props, State> {
|
export default class TokenRow extends React.PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
showLongBalance: false
|
showLongBalance: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './PreFooter.scss';
|
import './PreFooter.scss';
|
||||||
|
|
||||||
const PreFooter = () => {
|
const PreFooter: React.SFC<{}> = () => {
|
||||||
return (
|
return (
|
||||||
<section className="pre-footer">
|
<section className="pre-footer">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
|
|
|
@ -108,7 +108,7 @@ interface State {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Footer extends React.Component<Props, State> {
|
export default class Footer extends React.PureComponent<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { isOpen: false };
|
this.state = { isOpen: false };
|
||||||
|
|
|
@ -36,7 +36,7 @@ interface State {
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CustomNodeModal extends React.Component<Props, State> {
|
export default class CustomNodeModal extends React.PureComponent<Props, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
name: '',
|
name: '',
|
||||||
url: '',
|
url: '',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import NavigationLink from './NavigationLink';
|
import NavigationLink from './NavigationLink';
|
||||||
import { knowledgeBaseURL } from 'config';
|
import { knowledgeBaseURL } from 'config';
|
||||||
import './Navigation.scss';
|
import './Navigation.scss';
|
||||||
|
@ -58,7 +58,7 @@ interface BorderStyle {
|
||||||
borderTopColor?: string;
|
borderTopColor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Navigation extends Component<Props, State> {
|
export default class Navigation extends PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
showLeftArrow: false,
|
showLeftArrow: false,
|
||||||
showRightArrow: false
|
showRightArrow: false
|
||||||
|
|
|
@ -10,7 +10,7 @@ interface Props extends RouteComponentProps<{}> {
|
||||||
isHomepage: boolean;
|
isHomepage: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavigationLink extends React.Component<Props, {}> {
|
class NavigationLink extends React.PureComponent<Props, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
const { link, location, isHomepage } = this.props;
|
const { link, location, isHomepage } = this.props;
|
||||||
const isExternalLink = link.to.includes('http');
|
const isExternalLink = link.to.includes('http');
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
} from 'actions/config';
|
} from 'actions/config';
|
||||||
import logo from 'assets/images/logo-myetherwallet.svg';
|
import logo from 'assets/images/logo-myetherwallet.svg';
|
||||||
import { Dropdown, ColorDropdown } from 'components/ui';
|
import { Dropdown, ColorDropdown } from 'components/ui';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { TSetGasPriceField } from 'actions/transaction';
|
import { TSetGasPriceField } from 'actions/transaction';
|
||||||
|
@ -49,7 +49,7 @@ interface State {
|
||||||
isAddingCustomNode: boolean;
|
isAddingCustomNode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Header extends Component<Props, State> {
|
export default class Header extends PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
isAddingCustomNode: false
|
isAddingCustomNode: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface Props {
|
||||||
match: RouteComponentProps<{}>['match'];
|
match: RouteComponentProps<{}>['match'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SubTabs extends React.Component<Props> {
|
export default class SubTabs extends React.PureComponent<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const { tabs, match } = this.props;
|
const { tabs, match } = this.props;
|
||||||
const currentPath = match.url;
|
const currentPath = match.url;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import BN from 'bn.js';
|
||||||
import { translateRaw } from 'translations';
|
import { translateRaw } from 'translations';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
inputGasPrice,
|
inputGasPrice,
|
||||||
TInputGasPrice,
|
TInputGasPrice,
|
||||||
|
inputGasPriceIntent,
|
||||||
|
TInputGasPriceIntent,
|
||||||
getNonceRequested,
|
getNonceRequested,
|
||||||
TGetNonceRequested,
|
TGetNonceRequested,
|
||||||
reset,
|
reset,
|
||||||
|
@ -12,6 +15,7 @@ import {
|
||||||
import { fetchCCRates, TFetchCCRates } from 'actions/rates';
|
import { fetchCCRates, TFetchCCRates } from 'actions/rates';
|
||||||
import { getNetworkConfig, getOffline } from 'selectors/config';
|
import { getNetworkConfig, getOffline } from 'selectors/config';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
|
import { Units } from 'libs/units';
|
||||||
import SimpleGas from './components/SimpleGas';
|
import SimpleGas from './components/SimpleGas';
|
||||||
import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas';
|
import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas';
|
||||||
import './TXMetaDataPanel.scss';
|
import './TXMetaDataPanel.scss';
|
||||||
|
@ -27,6 +31,7 @@ interface StateProps {
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
inputGasPrice: TInputGasPrice;
|
inputGasPrice: TInputGasPrice;
|
||||||
|
inputGasPriceIntent: TInputGasPriceIntent;
|
||||||
fetchCCRates: TFetchCCRates;
|
fetchCCRates: TFetchCCRates;
|
||||||
getNonceRequested: TGetNonceRequested;
|
getNonceRequested: TGetNonceRequested;
|
||||||
reset: TReset;
|
reset: TReset;
|
||||||
|
@ -47,6 +52,7 @@ interface OwnProps {
|
||||||
type Props = DispatchProps & OwnProps & StateProps;
|
type Props = DispatchProps & OwnProps & StateProps;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
gasPrice: AppState['transaction']['fields']['gasPrice'];
|
||||||
sliderState: SliderStates;
|
sliderState: SliderStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +62,7 @@ class TXMetaDataPanel extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
public state: State = {
|
public state: State = {
|
||||||
|
gasPrice: this.props.gasPrice,
|
||||||
sliderState: (this.props as DefaultProps).initialState
|
sliderState: (this.props as DefaultProps).initialState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,10 +78,14 @@ class TXMetaDataPanel extends React.Component<Props, State> {
|
||||||
if (this.props.offline && !nextProps.offline) {
|
if (this.props.offline && !nextProps.offline) {
|
||||||
this.props.fetchCCRates([this.props.network.unit]);
|
this.props.fetchCCRates([this.props.network.unit]);
|
||||||
}
|
}
|
||||||
|
if (this.props.gasPrice !== nextProps.gasPrice) {
|
||||||
|
this.setState({ gasPrice: nextProps.gasPrice });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const { offline, disableToggle, gasPrice, advancedGasOptions, className = '' } = this.props;
|
const { offline, disableToggle, advancedGasOptions, className = '' } = this.props;
|
||||||
|
const { gasPrice } = this.state;
|
||||||
const showAdvanced = this.state.sliderState === 'advanced' || offline;
|
const showAdvanced = this.state.sliderState === 'advanced' || offline;
|
||||||
return (
|
return (
|
||||||
<div className={`Gas col-md-12 ${className}`}>
|
<div className={`Gas col-md-12 ${className}`}>
|
||||||
|
@ -85,7 +96,7 @@ class TXMetaDataPanel extends React.Component<Props, State> {
|
||||||
options={advancedGasOptions}
|
options={advancedGasOptions}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<SimpleGas gasPrice={gasPrice} inputGasPrice={this.props.inputGasPrice} />
|
<SimpleGas gasPrice={gasPrice} inputGasPrice={this.handleGasPriceInput} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!offline &&
|
{!offline &&
|
||||||
|
@ -107,6 +118,15 @@ class TXMetaDataPanel extends React.Component<Props, State> {
|
||||||
private toggleAdvanced = () => {
|
private toggleAdvanced = () => {
|
||||||
this.setState({ sliderState: this.state.sliderState === 'advanced' ? 'simple' : 'advanced' });
|
this.setState({ sliderState: this.state.sliderState === 'advanced' ? 'simple' : 'advanced' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private handleGasPriceInput = (raw: string) => {
|
||||||
|
const gasBn = new BN(raw);
|
||||||
|
const value = gasBn.mul(new BN(Units.gwei));
|
||||||
|
this.setState({
|
||||||
|
gasPrice: { raw, value }
|
||||||
|
});
|
||||||
|
this.props.inputGasPriceIntent(raw);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state: AppState): StateProps {
|
function mapStateToProps(state: AppState): StateProps {
|
||||||
|
@ -119,6 +139,7 @@ function mapStateToProps(state: AppState): StateProps {
|
||||||
|
|
||||||
export default connect(mapStateToProps, {
|
export default connect(mapStateToProps, {
|
||||||
inputGasPrice,
|
inputGasPrice,
|
||||||
|
inputGasPriceIntent,
|
||||||
fetchCCRates,
|
fetchCCRates,
|
||||||
getNonceRequested,
|
getNonceRequested,
|
||||||
reset
|
reset
|
||||||
|
|
|
@ -108,6 +108,7 @@ class AdvancedGas extends React.Component<Props, State> {
|
||||||
{feeSummary && (
|
{feeSummary && (
|
||||||
<div className="AdvancedGas-fee-summary">
|
<div className="AdvancedGas-fee-summary">
|
||||||
<FeeSummary
|
<FeeSummary
|
||||||
|
gasPrice={gasPrice}
|
||||||
render={({ gasPriceWei, gasLimit, fee, usd }) => (
|
render={({ gasPriceWei, gasLimit, fee, usd }) => (
|
||||||
<span>
|
<span>
|
||||||
{gasPriceWei} * {gasLimit} = {fee} {usd && <span>~= ${usd} USD</span>}
|
{gasPriceWei} * {gasLimit} = {fee} {usd && <span>~= ${usd} USD</span>}
|
||||||
|
|
|
@ -14,17 +14,20 @@ interface RenderData {
|
||||||
usd: React.ReactElement<string> | null;
|
usd: React.ReactElement<string> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface ReduxStateProps {
|
||||||
// Redux props
|
|
||||||
gasPrice: AppState['transaction']['fields']['gasPrice'];
|
|
||||||
gasLimit: AppState['transaction']['fields']['gasLimit'];
|
gasLimit: AppState['transaction']['fields']['gasLimit'];
|
||||||
rates: AppState['rates']['rates'];
|
rates: AppState['rates']['rates'];
|
||||||
network: AppState['config']['network'];
|
network: AppState['config']['network'];
|
||||||
isOffline: AppState['config']['offline'];
|
isOffline: AppState['config']['offline'];
|
||||||
// Component props
|
}
|
||||||
|
|
||||||
|
interface OwnProps {
|
||||||
|
gasPrice: AppState['transaction']['fields']['gasPrice'];
|
||||||
render(data: RenderData): React.ReactElement<string> | string;
|
render(data: RenderData): React.ReactElement<string> | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Props = OwnProps & ReduxStateProps;
|
||||||
|
|
||||||
class FeeSummary extends React.Component<Props> {
|
class FeeSummary extends React.Component<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const { gasPrice, gasLimit, rates, network, isOffline } = this.props;
|
const { gasPrice, gasLimit, rates, network, isOffline } = this.props;
|
||||||
|
@ -67,9 +70,8 @@ class FeeSummary extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state: AppState) {
|
function mapStateToProps(state: AppState): ReduxStateProps {
|
||||||
return {
|
return {
|
||||||
gasPrice: state.transaction.fields.gasPrice,
|
|
||||||
gasLimit: state.transaction.fields.gasLimit,
|
gasLimit: state.transaction.fields.gasLimit,
|
||||||
rates: state.rates.rates,
|
rates: state.rates.rates,
|
||||||
network: getNetworkConfig(state),
|
network: getNetworkConfig(state),
|
||||||
|
|
|
@ -3,7 +3,6 @@ import Slider from 'rc-slider';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import { gasPriceDefaults } from 'config';
|
import { gasPriceDefaults } from 'config';
|
||||||
import FeeSummary from './FeeSummary';
|
import FeeSummary from './FeeSummary';
|
||||||
import { TInputGasPrice } from 'actions/transaction';
|
|
||||||
import './SimpleGas.scss';
|
import './SimpleGas.scss';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getGasLimitEstimationTimedOut } from 'selectors/transaction';
|
import { getGasLimitEstimationTimedOut } from 'selectors/transaction';
|
||||||
|
@ -13,7 +12,7 @@ import { getIsWeb3Node } from 'selectors/config';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
gasPrice: AppState['transaction']['fields']['gasPrice'];
|
gasPrice: AppState['transaction']['fields']['gasPrice'];
|
||||||
inputGasPrice: TInputGasPrice;
|
inputGasPrice(rawGas: string);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
|
@ -41,7 +40,7 @@ class SimpleGas extends React.Component<Props> {
|
||||||
<div className="prompt-toggle-gas-limit">
|
<div className="prompt-toggle-gas-limit">
|
||||||
<p className="small">
|
<p className="small">
|
||||||
{isWeb3Node
|
{isWeb3Node
|
||||||
? "Couldn't calculate gas limit, if you know what your doing, try setting manually in Advanced settings"
|
? "Couldn't calculate gas limit, if you know what you're doing, try setting manually in Advanced settings"
|
||||||
: "Couldn't calculate gas limit, try switching nodes"}
|
: "Couldn't calculate gas limit, try switching nodes"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,6 +61,7 @@ class SimpleGas extends React.Component<Props> {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<FeeSummary
|
<FeeSummary
|
||||||
|
gasPrice={gasPrice}
|
||||||
render={({ fee, usd }) => (
|
render={({ fee, usd }) => (
|
||||||
<span>
|
<span>
|
||||||
{fee} {usd && <span>/ ${usd}</span>}
|
{fee} {usd && <span>/ ${usd}</span>}
|
||||||
|
|
|
@ -60,7 +60,7 @@ const customDPath: DPath = {
|
||||||
value: 'custom'
|
value: 'custom'
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeterministicWalletsModalClass extends React.Component<Props, State> {
|
class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
selectedAddress: '',
|
selectedAddress: '',
|
||||||
selectedAddrIndex: 0,
|
selectedAddrIndex: 0,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export class DigitalBitboxDecrypt extends React.Component<{}, {}> {
|
export class DigitalBitboxDecrypt extends React.PureComponent<{}, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
return <strong>Not yet implemented</strong>;
|
return <strong>Not yet implemented</strong>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isKeystorePassRequired } from 'libs/wallet';
|
import { isKeystorePassRequired } from 'libs/wallet';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import Spinner from 'components/ui/Spinner';
|
import Spinner from 'components/ui/Spinner';
|
||||||
import { TShowNotification } from 'actions/notifications';
|
import { TShowNotification } from 'actions/notifications';
|
||||||
|
@ -25,7 +25,7 @@ function isValidFile(rawFile: File): boolean {
|
||||||
return fileType === '' || fileType === 'application/json';
|
return fileType === '' || fileType === 'application/json';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class KeystoreDecrypt extends Component {
|
export class KeystoreDecrypt extends PureComponent {
|
||||||
public props: {
|
public props: {
|
||||||
value: KeystoreValue;
|
value: KeystoreValue;
|
||||||
isWalletPending: boolean;
|
isWalletPending: boolean;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import './LedgerNano.scss';
|
import './LedgerNano.scss';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||||
import { LedgerWallet } from 'libs/wallet';
|
import { LedgerWallet } from 'libs/wallet';
|
||||||
|
@ -31,7 +31,7 @@ interface State {
|
||||||
|
|
||||||
type Props = OwnProps & StateProps;
|
type Props = OwnProps & StateProps;
|
||||||
|
|
||||||
class LedgerNanoSDecryptClass extends Component<Props, State> {
|
class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
publicKey: '',
|
publicKey: '',
|
||||||
chainCode: '',
|
chainCode: '',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { mnemonicToSeed, validateMnemonic } from 'bip39';
|
import { mnemonicToSeed, validateMnemonic } from 'bip39';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||||
import { formatMnemonic } from 'utils/formatters';
|
import { formatMnemonic } from 'utils/formatters';
|
||||||
|
@ -27,7 +27,7 @@ interface State {
|
||||||
dPath: string;
|
dPath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MnemonicDecryptClass extends Component<Props & StateProps, State> {
|
class MnemonicDecryptClass extends PureComponent<Props & StateProps, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
phrase: '',
|
phrase: '',
|
||||||
formattedPhrase: '',
|
formattedPhrase: '',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { isValidEncryptedPrivKey, isValidPrivKey } from 'libs/validators';
|
import { isValidEncryptedPrivKey, isValidPrivKey } from 'libs/validators';
|
||||||
import { stripHexPrefix } from 'libs/values';
|
import { stripHexPrefix } from 'libs/values';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import { TogglablePassword } from 'components';
|
import { TogglablePassword } from 'components';
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ interface Props {
|
||||||
onUnlock(): void;
|
onUnlock(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PrivateKeyDecrypt extends Component<Props> {
|
export class PrivateKeyDecrypt extends PureComponent<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const { key, password } = this.props.value;
|
const { key, password } = this.props.value;
|
||||||
const { isValidPkey, isPassRequired } = validatePkeyAndPass(key, password);
|
const { isValidPkey, isPassRequired } = validatePkeyAndPass(key, password);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { TrezorWallet, TREZOR_MINIMUM_FIRMWARE } from 'libs/wallet';
|
import { TrezorWallet, TREZOR_MINIMUM_FIRMWARE } from 'libs/wallet';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import TrezorConnect from 'vendor/trezor-connect';
|
import TrezorConnect from 'vendor/trezor-connect';
|
||||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||||
|
@ -32,7 +32,7 @@ interface State {
|
||||||
|
|
||||||
type Props = OwnProps & StateProps;
|
type Props = OwnProps & StateProps;
|
||||||
|
|
||||||
class TrezorDecryptClass extends Component<Props, State> {
|
class TrezorDecryptClass extends PureComponent<Props, State> {
|
||||||
public state: State = {
|
public state: State = {
|
||||||
publicKey: '',
|
publicKey: '',
|
||||||
chainCode: '',
|
chainCode: '',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { donationAddressMap } from 'config';
|
import { donationAddressMap } from 'config';
|
||||||
import { isValidETHAddress } from 'libs/validators';
|
import { isValidETHAddress } from 'libs/validators';
|
||||||
|
@ -12,7 +12,7 @@ interface State {
|
||||||
address: string;
|
address: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ViewOnlyDecrypt extends Component<Props, State> {
|
export class ViewOnlyDecrypt extends PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
address: ''
|
address: ''
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { NewTabLink } from 'components/ui';
|
import { NewTabLink } from 'components/ui';
|
||||||
import './Web3.scss';
|
import './Web3.scss';
|
||||||
|
@ -7,15 +7,10 @@ interface Props {
|
||||||
onUnlock(): void;
|
onUnlock(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Web3Decrypt extends Component<Props> {
|
export const Web3Decrypt: React.SFC<Props> = ({ onUnlock }) => (
|
||||||
public render() {
|
|
||||||
return (
|
|
||||||
<div className="Web3Decrypt">
|
<div className="Web3Decrypt">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button className="Web3Decrypt-decrypt btn btn-primary btn-lg btn-block" onClick={onUnlock}>
|
||||||
className="Web3Decrypt-decrypt btn btn-primary btn-lg btn-block"
|
|
||||||
onClick={this.props.onUnlock}
|
|
||||||
>
|
|
||||||
{translate('ADD_MetaMask')}
|
{translate('ADD_MetaMask')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,5 +24,3 @@ export class Web3Decrypt extends Component<Props> {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import DropdownShell from './DropdownShell';
|
import DropdownShell from './DropdownShell';
|
||||||
import removeIcon from 'assets/images/icon-remove.svg';
|
import removeIcon from 'assets/images/icon-remove.svg';
|
||||||
|
@ -25,7 +25,7 @@ interface Props<T> {
|
||||||
onChange(value: T): void;
|
onChange(value: T): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ColorDropdown<T> extends Component<Props<T>, {}> {
|
export default class ColorDropdown<T> extends PureComponent<Props<T>, {}> {
|
||||||
private dropdownShell: DropdownShell | null;
|
private dropdownShell: DropdownShell | null;
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import DropdownShell from './DropdownShell';
|
import DropdownShell from './DropdownShell';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ interface State {
|
||||||
search: string;
|
search: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DropdownComponent<T> extends Component<Props<T>, State> {
|
export default class DropdownComponent<T> extends PureComponent<Props<T>, State> {
|
||||||
public state = {
|
public state = {
|
||||||
search: ''
|
search: ''
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -14,7 +14,7 @@ interface State {
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DropdownComponent extends Component<Props, State> {
|
export default class DropdownComponent extends PureComponent<Props, State> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
color: 'default',
|
color: 'default',
|
||||||
size: 'sm'
|
size: 'sm'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
export type ExpandHandler = (ev: React.FormEvent<HTMLAnchorElement>) => void;
|
export type ExpandHandler = (ev: React.FormEvent<HTMLAnchorElement>) => void;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ interface State {
|
||||||
|
|
||||||
const initialState: State = { expanded: false };
|
const initialState: State = { expanded: false };
|
||||||
|
|
||||||
export class Expandable extends Component<Props, State> {
|
export class Expandable extends PureComponent<Props, State> {
|
||||||
public state: State = initialState;
|
public state: State = initialState;
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import closeIcon from 'assets/images/icon-x.svg';
|
import closeIcon from 'assets/images/icon-x.svg';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import './Modal.scss';
|
import './Modal.scss';
|
||||||
|
|
||||||
export interface IButton {
|
export interface IButton {
|
||||||
|
@ -17,7 +17,7 @@ interface Props {
|
||||||
handleClose?(): void;
|
handleClose?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Modal extends Component<Props, {}> {
|
export default class Modal extends PureComponent<Props, {}> {
|
||||||
private modalContent: HTMLElement | null = null;
|
private modalContent: HTMLElement | null = null;
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface State {
|
||||||
qr?: string;
|
qr?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class QRCode extends React.Component<Props, State> {
|
export default class QRCode extends React.PureComponent<Props, State> {
|
||||||
public state: State = {};
|
public state: State = {};
|
||||||
public componentWillMount() {
|
public componentWillMount() {
|
||||||
// Start generating QR codes immediately
|
// Start generating QR codes immediately
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import Dropdown from './Dropdown';
|
import Dropdown from './Dropdown';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -8,7 +8,7 @@ interface Props {
|
||||||
onChange(value: string): void;
|
onChange(value: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SimpleDropdown extends Component<Props, void> {
|
export default class SimpleDropdown extends PureComponent<Props, void> {
|
||||||
public render() {
|
public render() {
|
||||||
const { options, value, onChange, ariaLabel } = this.props;
|
const { options, value, onChange, ariaLabel } = this.props;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value?: string;
|
value?: string;
|
||||||
|
@ -6,7 +6,7 @@ interface Props {
|
||||||
onChange(event: React.FormEvent<HTMLSpanElement>): void;
|
onChange(event: React.FormEvent<HTMLSpanElement>): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SimpleSelect extends Component<Props, {}> {
|
export default class SimpleSelect extends PureComponent<Props, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import './SwapDropdown.scss';
|
import './SwapDropdown.scss';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ interface Props<T> {
|
||||||
onChange(value: T): void;
|
onChange(value: T): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SwapDropdown<T> extends Component<Props<T>, {}> {
|
class SwapDropdown<T> extends PureComponent<Props<T>, {}> {
|
||||||
public state = {
|
public state = {
|
||||||
open: false
|
open: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ interface State {
|
||||||
isKeystoreModalOpen: boolean;
|
isKeystoreModalOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class WalletInfo extends React.Component<Props, State> {
|
export default class WalletInfo extends React.PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
address: '',
|
address: '',
|
||||||
privateKey: '',
|
privateKey: '',
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import QRCode from 'qrcode.react';
|
import QRCode from 'qrcode.react';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
paymentAddress: string | null;
|
paymentAddress: string | null;
|
||||||
destinationAmount: number;
|
destinationAmount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class BitcoinQR extends Component<Props, {}> {
|
export default class BitcoinQR extends PureComponent<Props, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
const { paymentAddress, destinationAmount } = this.props;
|
const { paymentAddress, destinationAmount } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
} from 'reducers/swap/types';
|
} from 'reducers/swap/types';
|
||||||
import SimpleButton from 'components/ui/SimpleButton';
|
import SimpleButton from 'components/ui/SimpleButton';
|
||||||
import { generateKindMax, generateKindMin, WhitelistedCoins, bityConfig } from 'config/bity';
|
import { generateKindMax, generateKindMin, WhitelistedCoins, bityConfig } from 'config/bity';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { combineAndUpper } from 'utils/formatters';
|
import { combineAndUpper } from 'utils/formatters';
|
||||||
import { SwapDropdown } from 'components/ui';
|
import { SwapDropdown } from 'components/ui';
|
||||||
|
@ -41,7 +41,7 @@ interface State {
|
||||||
|
|
||||||
type Props = StateProps & ActionProps;
|
type Props = StateProps & ActionProps;
|
||||||
|
|
||||||
export default class CurrencySwap extends Component<Props, State> {
|
export default class CurrencySwap extends PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
disabled: true,
|
disabled: true,
|
||||||
origin: {
|
origin: {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import bityLogoWhite from 'assets/images/logo-bity-white.svg';
|
||||||
import shapeshiftLogoWhite from 'assets/images/logo-shapeshift.svg';
|
import shapeshiftLogoWhite from 'assets/images/logo-shapeshift.svg';
|
||||||
import Spinner from 'components/ui/Spinner';
|
import Spinner from 'components/ui/Spinner';
|
||||||
import { bityReferralURL, shapeshiftReferralURL } from 'config';
|
import { bityReferralURL, shapeshiftReferralURL } from 'config';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import './CurrentRates.scss';
|
import './CurrentRates.scss';
|
||||||
import { SHAPESHIFT_WHITELIST } from 'api/shapeshift';
|
import { SHAPESHIFT_WHITELIST } from 'api/shapeshift';
|
||||||
|
@ -22,7 +22,7 @@ interface Props {
|
||||||
shapeshiftRates: NormalizedShapeshiftRates;
|
shapeshiftRates: NormalizedShapeshiftRates;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CurrentRates extends Component<Props> {
|
export default class CurrentRates extends PureComponent<Props> {
|
||||||
private shapeShiftRateCache = null;
|
private shapeShiftRateCache = null;
|
||||||
|
|
||||||
public getRandomSSPairData = (
|
public getRandomSSPairData = (
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
TStopPollShapeshiftOrderStatus
|
TStopPollShapeshiftOrderStatus
|
||||||
} from 'actions/swap';
|
} from 'actions/swap';
|
||||||
import { SwapInput } from 'reducers/swap/types';
|
import { SwapInput } from 'reducers/swap/types';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import BitcoinQR from './BitcoinQR';
|
import BitcoinQR from './BitcoinQR';
|
||||||
import PaymentInfo from './PaymentInfo';
|
import PaymentInfo from './PaymentInfo';
|
||||||
import SwapProgress from './SwapProgress';
|
import SwapProgress from './SwapProgress';
|
||||||
|
@ -39,7 +39,7 @@ interface ReduxActionProps {
|
||||||
showNotification: TShowNotification;
|
showNotification: TShowNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PartThree extends Component<ReduxActionProps & ReduxStateProps, {}> {
|
export default class PartThree extends PureComponent<ReduxActionProps & ReduxStateProps, {}> {
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
const { provider } = this.props;
|
const { provider } = this.props;
|
||||||
if (provider === 'shapeshift') {
|
if (provider === 'shapeshift') {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { SwapInput } from 'reducers/swap/types';
|
import { SwapInput } from 'reducers/swap/types';
|
||||||
import './PaymentInfo.scss';
|
import './PaymentInfo.scss';
|
||||||
|
@ -8,7 +8,7 @@ export interface Props {
|
||||||
paymentAddress: string | null;
|
paymentAddress: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PaymentInfo extends Component<Props, {}> {
|
export default class PaymentInfo extends PureComponent<Props, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
const { origin } = this.props;
|
const { origin } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -10,7 +10,7 @@ import classnames from 'classnames';
|
||||||
import SimpleButton from 'components/ui/SimpleButton';
|
import SimpleButton from 'components/ui/SimpleButton';
|
||||||
import { donationAddressMap } from 'config';
|
import { donationAddressMap } from 'config';
|
||||||
import { isValidBTCAddress, isValidETHAddress } from 'libs/validators';
|
import { isValidBTCAddress, isValidETHAddress } from 'libs/validators';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import { combineAndUpper } from 'utils/formatters';
|
import { combineAndUpper } from 'utils/formatters';
|
||||||
import './ReceivingAddress.scss';
|
import './ReceivingAddress.scss';
|
||||||
|
@ -32,7 +32,7 @@ export interface ActionProps {
|
||||||
shapeshiftOrderCreateRequestedSwap: TShapeshiftOrderCreateRequestedSwap;
|
shapeshiftOrderCreateRequestedSwap: TShapeshiftOrderCreateRequestedSwap;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ReceivingAddress extends Component<StateProps & ActionProps, {}> {
|
export default class ReceivingAddress extends PureComponent<StateProps & ActionProps, {}> {
|
||||||
public onChangeDestinationAddress = (event: React.FormEvent<HTMLInputElement>) => {
|
public onChangeDestinationAddress = (event: React.FormEvent<HTMLInputElement>) => {
|
||||||
const value = event.currentTarget.value;
|
const value = event.currentTarget.value;
|
||||||
this.props.destinationAddressSwap(value);
|
this.props.destinationAddressSwap(value);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import './ShapeshiftBanner.scss';
|
import './ShapeshiftBanner.scss';
|
||||||
import shapeshiftSvg from 'assets/images/logo-shapeshift.svg';
|
import shapeshiftSvg from 'assets/images/logo-shapeshift.svg';
|
||||||
|
|
||||||
export default () => (
|
const ShapeshiftBanner: React.SFC<{}> = () => (
|
||||||
<div className="ShapeshiftBanner">
|
<div className="ShapeshiftBanner">
|
||||||
<div className="ShapeshiftBanner-banner">
|
<div className="ShapeshiftBanner-banner">
|
||||||
<p>
|
<p>
|
||||||
|
@ -13,3 +13,5 @@ export default () => (
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export default ShapeshiftBanner;
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface Props {
|
||||||
bityRates: NormalizedBityRates;
|
bityRates: NormalizedBityRates;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SupportFooter extends React.Component<Props, {}> {
|
class SupportFooter extends React.PureComponent<Props, {}> {
|
||||||
public state = {
|
public state = {
|
||||||
open: false
|
open: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { RestartSwapAction } from 'actions/swap';
|
import { RestartSwapAction } from 'actions/swap';
|
||||||
import { SwapInput } from 'reducers/swap/types';
|
import { SwapInput } from 'reducers/swap/types';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { toFixedIfLarger } from 'utils/formatters';
|
import { toFixedIfLarger } from 'utils/formatters';
|
||||||
|
@ -16,7 +16,7 @@ export interface SwapInfoHeaderProps {
|
||||||
restartSwap(): RestartSwapAction;
|
restartSwap(): RestartSwapAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SwapInfoHeader extends Component<SwapInfoHeaderProps, {}> {
|
export default class SwapInfoHeader extends PureComponent<SwapInfoHeaderProps, {}> {
|
||||||
public computedOriginDestinationRatio = () => {
|
public computedOriginDestinationRatio = () => {
|
||||||
const { origin, destination } = this.props;
|
const { origin, destination } = this.props;
|
||||||
if (!origin.amount || !destination.amount) {
|
if (!origin.amount || !destination.amount) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { RestartSwapAction } from 'actions/swap';
|
||||||
import bityLogo from 'assets/images/logo-bity.svg';
|
import bityLogo from 'assets/images/logo-bity.svg';
|
||||||
import shapeshiftLogo from 'assets/images/shapeshift-dark.svg';
|
import shapeshiftLogo from 'assets/images/shapeshift-dark.svg';
|
||||||
import { bityReferralURL } from 'config';
|
import { bityReferralURL } from 'config';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import './SwapInfoHeader.scss';
|
import './SwapInfoHeader.scss';
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ export interface SwapInfoHeaderTitleProps {
|
||||||
restartSwap(): RestartSwapAction;
|
restartSwap(): RestartSwapAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SwapInfoHeaderTitle extends Component<SwapInfoHeaderTitleProps, {}> {
|
export default class SwapInfoHeaderTitle extends PureComponent<SwapInfoHeaderTitleProps, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
const { provider } = this.props;
|
const { provider } = this.props;
|
||||||
const logoToRender = provider === 'shapeshift' ? shapeshiftLogo : bityLogo;
|
const logoToRender = provider === 'shapeshift' ? shapeshiftLogo : bityLogo;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { TShowNotification } from 'actions/notifications';
|
import { TShowNotification } from 'actions/notifications';
|
||||||
import { bityConfig } from 'config/bity';
|
import { bityConfig } from 'config/bity';
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import translate, { translateRaw } from 'translations';
|
import translate, { translateRaw } from 'translations';
|
||||||
import './SwapProgress.scss';
|
import './SwapProgress.scss';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ export interface Props {
|
||||||
interface State {
|
interface State {
|
||||||
hasShownViewTx: boolean;
|
hasShownViewTx: boolean;
|
||||||
}
|
}
|
||||||
export default class SwapProgress extends Component<Props, State> {
|
export default class SwapProgress extends PureComponent<Props, State> {
|
||||||
public state = {
|
public state = {
|
||||||
hasShownViewTx: false
|
hasShownViewTx: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ type Data = Buffer;
|
||||||
|
|
||||||
export const ETH_DECIMAL = 18;
|
export const ETH_DECIMAL = 18;
|
||||||
|
|
||||||
const Units = {
|
export const Units = {
|
||||||
wei: '1',
|
wei: '1',
|
||||||
kwei: '1000',
|
kwei: '1000',
|
||||||
ada: '1000',
|
ada: '1000',
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
import { State, RequestStatus } from './typings';
|
import { State, RequestStatus } from './typings';
|
||||||
import { TypeKeys as TK, ResetAction, NetworkAction } from 'actions/transaction';
|
import {
|
||||||
|
TypeKeys as TK,
|
||||||
|
ResetAction,
|
||||||
|
NetworkAction,
|
||||||
|
InputGasPriceAction,
|
||||||
|
InputGasPriceIntentAction
|
||||||
|
} from 'actions/transaction';
|
||||||
import { Action } from 'redux';
|
import { Action } from 'redux';
|
||||||
|
|
||||||
const INITIAL_STATE: State = {
|
const INITIAL_STATE: State = {
|
||||||
gasEstimationStatus: null,
|
gasEstimationStatus: null,
|
||||||
getFromStatus: null,
|
getFromStatus: null,
|
||||||
getNonceStatus: null
|
getNonceStatus: null,
|
||||||
|
gasPriceStatus: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPostFix = (str: string) => {
|
const getPostFix = (str: string) => {
|
||||||
|
@ -18,9 +25,17 @@ const nextState = (field: keyof State) => (state: State, action: Action): State
|
||||||
[field]: RequestStatus[getPostFix(action.type)]
|
[field]: RequestStatus[getPostFix(action.type)]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setGasPriceStatus = (state: State, gasPriceStatus: RequestStatus) => ({
|
||||||
|
...state,
|
||||||
|
gasPriceStatus
|
||||||
|
});
|
||||||
|
|
||||||
const reset = () => INITIAL_STATE;
|
const reset = () => INITIAL_STATE;
|
||||||
|
|
||||||
export const network = (state: State = INITIAL_STATE, action: NetworkAction | ResetAction) => {
|
export const network = (
|
||||||
|
state: State = INITIAL_STATE,
|
||||||
|
action: NetworkAction | ResetAction | InputGasPriceAction | InputGasPriceIntentAction
|
||||||
|
) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case TK.ESTIMATE_GAS_REQUESTED:
|
case TK.ESTIMATE_GAS_REQUESTED:
|
||||||
return nextState('gasEstimationStatus')(state, action);
|
return nextState('gasEstimationStatus')(state, action);
|
||||||
|
@ -42,6 +57,14 @@ export const network = (state: State = INITIAL_STATE, action: NetworkAction | Re
|
||||||
return nextState('getNonceStatus')(state, action);
|
return nextState('getNonceStatus')(state, action);
|
||||||
case TK.GET_NONCE_FAILED:
|
case TK.GET_NONCE_FAILED:
|
||||||
return nextState('getNonceStatus')(state, action);
|
return nextState('getNonceStatus')(state, action);
|
||||||
|
|
||||||
|
// Not exactly "network" requests, but we want to show pending while
|
||||||
|
// gas price is subject to change
|
||||||
|
case TK.GAS_PRICE_INPUT_INTENT:
|
||||||
|
return setGasPriceStatus(state, RequestStatus.REQUESTED);
|
||||||
|
case TK.GAS_PRICE_INPUT:
|
||||||
|
return setGasPriceStatus(state, RequestStatus.SUCCEEDED);
|
||||||
|
|
||||||
case TK.RESET:
|
case TK.RESET:
|
||||||
return reset();
|
return reset();
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -8,4 +8,5 @@ export interface State {
|
||||||
gasEstimationStatus: RequestStatus | null;
|
gasEstimationStatus: RequestStatus | null;
|
||||||
getFromStatus: RequestStatus | null;
|
getFromStatus: RequestStatus | null;
|
||||||
getNonceStatus: RequestStatus | null;
|
getNonceStatus: RequestStatus | null;
|
||||||
|
gasPriceStatus: RequestStatus | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { call, put, takeEvery } from 'redux-saga/effects';
|
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects';
|
||||||
import { SagaIterator } from 'redux-saga';
|
import { SagaIterator, delay } from 'redux-saga';
|
||||||
import {
|
import {
|
||||||
|
inputGasPrice,
|
||||||
setDataField,
|
setDataField,
|
||||||
setGasLimitField,
|
setGasLimitField,
|
||||||
setGasPriceField,
|
setGasPriceField,
|
||||||
|
@ -11,6 +12,7 @@ import {
|
||||||
InputDataAction,
|
InputDataAction,
|
||||||
InputGasLimitAction,
|
InputGasLimitAction,
|
||||||
InputGasPriceAction,
|
InputGasPriceAction,
|
||||||
|
InputGasPriceIntentAction,
|
||||||
InputNonceAction,
|
InputNonceAction,
|
||||||
TypeKeys
|
TypeKeys
|
||||||
} from 'actions/transaction';
|
} from 'actions/transaction';
|
||||||
|
@ -38,6 +40,13 @@ export function* handleGasPriceInput({ payload }: InputGasPriceAction): SagaIter
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function* handleGasPriceInputIntent({ payload }: InputGasPriceIntentAction): SagaIterator {
|
||||||
|
yield call(delay, 300);
|
||||||
|
// Important to put and not fork handleGasPriceInput, we want
|
||||||
|
// action to go to reducers.
|
||||||
|
yield put(inputGasPrice(payload));
|
||||||
|
}
|
||||||
|
|
||||||
export function* handleNonceInput({ payload }: InputNonceAction): SagaIterator {
|
export function* handleNonceInput({ payload }: InputNonceAction): SagaIterator {
|
||||||
const validNonce: boolean = yield call(isValidNonce, payload);
|
const validNonce: boolean = yield call(isValidNonce, payload);
|
||||||
yield put(setNonceField({ raw: payload, value: validNonce ? Nonce(payload) : null }));
|
yield put(setNonceField({ raw: payload, value: validNonce ? Nonce(payload) : null }));
|
||||||
|
@ -47,5 +56,6 @@ export const fields = [
|
||||||
takeEvery(TypeKeys.DATA_FIELD_INPUT, handleDataInput),
|
takeEvery(TypeKeys.DATA_FIELD_INPUT, handleDataInput),
|
||||||
takeEvery(TypeKeys.GAS_LIMIT_INPUT, handleGasLimitInput),
|
takeEvery(TypeKeys.GAS_LIMIT_INPUT, handleGasLimitInput),
|
||||||
takeEvery(TypeKeys.GAS_PRICE_INPUT, handleGasPriceInput),
|
takeEvery(TypeKeys.GAS_PRICE_INPUT, handleGasPriceInput),
|
||||||
takeEvery(TypeKeys.NONCE_INPUT, handleNonceInput)
|
takeEvery(TypeKeys.NONCE_INPUT, handleNonceInput),
|
||||||
|
takeLatest(TypeKeys.GAS_PRICE_INPUT_INTENT, handleGasPriceInputIntent)
|
||||||
];
|
];
|
||||||
|
|
|
@ -10,10 +10,12 @@ const getGasLimit = (state: AppState) => getFields(state).gasLimit;
|
||||||
const getGasPrice = (state: AppState) => getFields(state).gasPrice;
|
const getGasPrice = (state: AppState) => getFields(state).gasPrice;
|
||||||
const getValue = (state: AppState) => getFields(state).value;
|
const getValue = (state: AppState) => getFields(state).value;
|
||||||
const getNonce = (state: AppState) => getFields(state).nonce;
|
const getNonce = (state: AppState) => getFields(state).nonce;
|
||||||
|
|
||||||
const getDataExists = (state: AppState) => {
|
const getDataExists = (state: AppState) => {
|
||||||
const { value } = getData(state);
|
const { value } = getData(state);
|
||||||
return !!value && value.length > 0;
|
return !!value && value.length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getValidGasCost = (state: AppState) => {
|
const getValidGasCost = (state: AppState) => {
|
||||||
const gasCost = getGasCost(state);
|
const gasCost = getGasCost(state);
|
||||||
const etherBalance = getEtherBalance(state);
|
const etherBalance = getEtherBalance(state);
|
||||||
|
|
Loading…
Reference in New Issue