1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-29 23:58:06 +01:00
metamask-extension/ui/pages/confirm-transaction/confirm-transaction.component.js
Alex Donesky d359429f04
Stop GasFeeController polling when pop closes (#11746)
* Stop GasFeeController polling when pop closes

* Stop estimate gas polling on window unload

* lint + comments

* Improve client closed logic

* lint

* Add back _beforeUnload on unmount in gas-modal-page-container

* Add full check and call onClientClosed method for notifcation environment

* Add gas pollingToken tracking to appStateController and use to disconnect polling for each environment type

* remove unused method

* move controller manipulation logic from background.js to metamask-controller, disaggregate methods

* add beforeunload handling to reset gas polling tokens from root of send page

* cleanup, lint and address feedback

* clear appState gasPollingTokens when all instances of all env types are closed, fix pollingTokenType arg from onEnvironmentTypeClosed call in metamask-controller

* mock new methods to fix tests

* final bit of cleanup + comments

Co-authored-by: Dan Miller <danjm.com@gmail.com>
2021-08-04 16:53:13 -05:00

216 lines
6.5 KiB
JavaScript

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Switch, Route } from 'react-router-dom';
import Loading from '../../components/ui/loading-screen';
import ConfirmTransactionSwitch from '../confirm-transaction-switch';
import ConfirmTransactionBase from '../confirm-transaction-base';
import ConfirmSendEther from '../confirm-send-ether';
import ConfirmSendToken from '../confirm-send-token';
import ConfirmDeployContract from '../confirm-deploy-contract';
import ConfirmApprove from '../confirm-approve';
import ConfirmTokenTransactionBaseContainer from '../confirm-token-transaction-base';
import ConfirmDecryptMessage from '../confirm-decrypt-message';
import ConfirmEncryptionPublicKey from '../confirm-encryption-public-key';
import {
CONFIRM_TRANSACTION_ROUTE,
CONFIRM_DEPLOY_CONTRACT_PATH,
CONFIRM_SEND_ETHER_PATH,
CONFIRM_SEND_TOKEN_PATH,
CONFIRM_APPROVE_PATH,
CONFIRM_TRANSFER_FROM_PATH,
CONFIRM_TOKEN_METHOD_PATH,
SIGNATURE_REQUEST_PATH,
DECRYPT_MESSAGE_REQUEST_PATH,
ENCRYPTION_PUBLIC_KEY_REQUEST_PATH,
DEFAULT_ROUTE,
} from '../../helpers/constants/routes';
import {
disconnectGasFeeEstimatePoller,
getGasFeeEstimatesAndStartPolling,
addPollingTokenToAppState,
removePollingTokenFromAppState,
} from '../../store/actions';
import ConfTx from './conf-tx';
export default class ConfirmTransaction extends Component {
static contextTypes = {
metricsEvent: PropTypes.func,
};
static propTypes = {
history: PropTypes.object.isRequired,
totalUnapprovedCount: PropTypes.number.isRequired,
sendTo: PropTypes.string,
setTransactionToConfirm: PropTypes.func,
clearConfirmTransaction: PropTypes.func,
mostRecentOverviewPage: PropTypes.string.isRequired,
transaction: PropTypes.object,
getContractMethodData: PropTypes.func,
transactionId: PropTypes.string,
paramsTransactionId: PropTypes.string,
getTokenParams: PropTypes.func,
isTokenMethodAction: PropTypes.bool,
setDefaultHomeActiveTabName: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {};
}
_beforeUnload = () => {
this._isMounted = false;
if (this.state.pollingToken) {
disconnectGasFeeEstimatePoller(this.state.pollingToken);
removePollingTokenFromAppState(this.state.pollingToken);
}
};
componentDidMount() {
this._isMounted = true;
const {
totalUnapprovedCount = 0,
sendTo,
history,
mostRecentOverviewPage,
transaction: { txParams: { data, to } = {} } = {},
getContractMethodData,
transactionId,
paramsTransactionId,
getTokenParams,
isTokenMethodAction,
} = this.props;
getGasFeeEstimatesAndStartPolling().then((pollingToken) => {
if (this._isMounted) {
this.setState({ pollingToken });
addPollingTokenToAppState(pollingToken);
} else {
disconnectGasFeeEstimatePoller(pollingToken);
removePollingTokenFromAppState(pollingToken);
}
});
window.addEventListener('beforeunload', this._beforeUnload);
if (!totalUnapprovedCount && !sendTo) {
history.replace(mostRecentOverviewPage);
return;
}
getContractMethodData(data);
if (isTokenMethodAction) {
getTokenParams(to);
}
const txId = transactionId || paramsTransactionId;
if (txId) {
this.props.setTransactionToConfirm(txId);
}
}
componentWillUnmount() {
this._beforeUnload();
window.removeEventListener('beforeunload', this._beforeUnload);
}
componentDidUpdate(prevProps) {
const {
setTransactionToConfirm,
transaction: { txData: { txParams: { data } = {} } = {} },
clearConfirmTransaction,
getContractMethodData,
paramsTransactionId,
transactionId,
history,
mostRecentOverviewPage,
totalUnapprovedCount,
setDefaultHomeActiveTabName,
} = this.props;
if (
paramsTransactionId &&
transactionId &&
prevProps.paramsTransactionId !== paramsTransactionId
) {
clearConfirmTransaction();
getContractMethodData(data);
setTransactionToConfirm(paramsTransactionId);
} else if (
prevProps.transactionId &&
!transactionId &&
!totalUnapprovedCount
) {
setDefaultHomeActiveTabName('Activity').then(() => {
history.replace(DEFAULT_ROUTE);
});
} else if (
prevProps.transactionId &&
transactionId &&
prevProps.transactionId !== transactionId
) {
history.replace(mostRecentOverviewPage);
}
}
render() {
const { transactionId, paramsTransactionId } = this.props;
// Show routes when state.confirmTransaction has been set and when either the ID in the params
// isn't specified or is specified and matches the ID in state.confirmTransaction in order to
// support URLs of /confirm-transaction or /confirm-transaction/<transactionId>
return transactionId &&
(!paramsTransactionId || paramsTransactionId === transactionId) ? (
<Switch>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_DEPLOY_CONTRACT_PATH}`}
component={ConfirmDeployContract}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_TOKEN_METHOD_PATH}`}
component={ConfirmTransactionBase}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_SEND_ETHER_PATH}`}
component={ConfirmSendEther}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_SEND_TOKEN_PATH}`}
component={ConfirmSendToken}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_APPROVE_PATH}`}
component={ConfirmApprove}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${CONFIRM_TRANSFER_FROM_PATH}`}
component={ConfirmTokenTransactionBaseContainer}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${SIGNATURE_REQUEST_PATH}`}
component={ConfTx}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${DECRYPT_MESSAGE_REQUEST_PATH}`}
component={ConfirmDecryptMessage}
/>
<Route
exact
path={`${CONFIRM_TRANSACTION_ROUTE}/:id?${ENCRYPTION_PUBLIC_KEY_REQUEST_PATH}`}
component={ConfirmEncryptionPublicKey}
/>
<Route path="*" component={ConfirmTransactionSwitch} />
</Switch>
) : (
<Loading />
);
}
}