2021-02-04 19:15:23 +01:00
|
|
|
import React, { PureComponent } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import classnames from 'classnames';
|
2021-03-04 19:16:33 +01:00
|
|
|
|
2021-05-19 16:51:47 +02:00
|
|
|
import { getBlockExplorerLink } from '@metamask/etherscan-link';
|
2020-11-03 00:41:28 +01:00
|
|
|
import {
|
|
|
|
getEthConversionFromWeiHex,
|
|
|
|
getValueFromWeiHex,
|
2021-02-04 19:15:23 +01:00
|
|
|
} from '../../../helpers/utils/conversions.util';
|
2021-08-25 00:28:16 +02:00
|
|
|
import { formatDate, getURLHostName } from '../../../helpers/utils/util';
|
2021-02-04 19:15:23 +01:00
|
|
|
import TransactionActivityLogIcon from './transaction-activity-log-icon';
|
|
|
|
import { CONFIRMED_STATUS } from './transaction-activity-log.constants';
|
2018-08-26 03:00:38 +02:00
|
|
|
|
|
|
|
export default class TransactionActivityLog extends PureComponent {
|
|
|
|
static contextTypes = {
|
|
|
|
t: PropTypes.func,
|
2021-05-19 16:51:47 +02:00
|
|
|
trackEvent: PropTypes.func,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2018-08-26 03:00:38 +02:00
|
|
|
|
|
|
|
static propTypes = {
|
2018-12-09 21:48:06 +01:00
|
|
|
activities: PropTypes.array,
|
2018-08-31 21:34:22 +02:00
|
|
|
className: PropTypes.string,
|
|
|
|
conversionRate: PropTypes.number,
|
2018-12-09 21:48:06 +01:00
|
|
|
inlineRetryIndex: PropTypes.number,
|
|
|
|
inlineCancelIndex: PropTypes.number,
|
2018-10-26 10:26:43 +02:00
|
|
|
nativeCurrency: PropTypes.string,
|
2018-12-09 21:48:06 +01:00
|
|
|
onCancel: PropTypes.func,
|
|
|
|
onRetry: PropTypes.func,
|
|
|
|
primaryTransaction: PropTypes.object,
|
2019-09-09 21:59:00 +02:00
|
|
|
isEarliestNonce: PropTypes.bool,
|
2021-03-09 22:37:19 +01:00
|
|
|
rpcPrefs: PropTypes.object,
|
2021-02-04 19:15:23 +01:00
|
|
|
};
|
2018-08-26 03:00:38 +02:00
|
|
|
|
2021-03-09 22:37:19 +01:00
|
|
|
handleActivityClick = (activity) => {
|
2021-05-19 16:51:47 +02:00
|
|
|
const { rpcPrefs } = this.props;
|
|
|
|
const etherscanUrl = getBlockExplorerLink(activity, rpcPrefs);
|
|
|
|
|
|
|
|
this.context.trackEvent({
|
|
|
|
category: 'Transactions',
|
|
|
|
event: 'Clicked Block Explorer Link',
|
|
|
|
properties: {
|
|
|
|
link_type: 'Transaction Block Explorer',
|
|
|
|
action: 'Activity Details',
|
2021-08-25 00:28:16 +02:00
|
|
|
block_explorer_domain: getURLHostName(etherscanUrl),
|
2021-05-19 16:51:47 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
global.platform.openTab({ url: etherscanUrl });
|
|
|
|
};
|
2018-08-26 03:00:38 +02:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderInlineRetry(index) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const { t } = this.context;
|
2020-11-03 00:41:28 +01:00
|
|
|
const {
|
|
|
|
inlineRetryIndex,
|
|
|
|
primaryTransaction = {},
|
|
|
|
onRetry,
|
|
|
|
isEarliestNonce,
|
2021-02-04 19:15:23 +01:00
|
|
|
} = this.props;
|
|
|
|
const { status } = primaryTransaction;
|
2018-10-23 13:59:04 +02:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
return isEarliestNonce &&
|
|
|
|
status !== CONFIRMED_STATUS &&
|
|
|
|
index === inlineRetryIndex ? (
|
|
|
|
<div className="transaction-activity-log__action-link" onClick={onRetry}>
|
|
|
|
{t('speedUpTransaction')}
|
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
) : null;
|
2018-08-26 03:00:38 +02:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderInlineCancel(index) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const { t } = this.context;
|
2020-11-03 00:41:28 +01:00
|
|
|
const {
|
|
|
|
inlineCancelIndex,
|
|
|
|
primaryTransaction = {},
|
|
|
|
onCancel,
|
|
|
|
isEarliestNonce,
|
2021-02-04 19:15:23 +01:00
|
|
|
} = this.props;
|
|
|
|
const { status } = primaryTransaction;
|
2018-12-09 21:48:06 +01:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
return isEarliestNonce &&
|
|
|
|
status !== CONFIRMED_STATUS &&
|
|
|
|
index === inlineCancelIndex ? (
|
|
|
|
<div className="transaction-activity-log__action-link" onClick={onCancel}>
|
|
|
|
{t('speedUpCancellation')}
|
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
) : null;
|
2018-08-26 03:00:38 +02:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
renderActivity(activity, index) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const { conversionRate, nativeCurrency } = this.props;
|
2021-03-09 22:37:19 +01:00
|
|
|
const { eventKey, value, timestamp } = activity;
|
2020-11-03 00:41:28 +01:00
|
|
|
const ethValue =
|
|
|
|
index === 0
|
|
|
|
? `${getValueFromWeiHex({
|
|
|
|
value,
|
|
|
|
fromCurrency: 'ETH',
|
|
|
|
toCurrency: 'ETH',
|
|
|
|
conversionRate,
|
|
|
|
numberOfDecimals: 6,
|
|
|
|
})} ${nativeCurrency}`
|
|
|
|
: getEthConversionFromWeiHex({
|
|
|
|
value,
|
|
|
|
fromCurrency: 'ETH',
|
|
|
|
conversionRate,
|
|
|
|
numberOfDecimals: 3,
|
2021-02-04 19:15:23 +01:00
|
|
|
});
|
|
|
|
const formattedTimestamp = formatDate(timestamp, "T 'on' M/d/y");
|
2020-11-03 00:41:28 +01:00
|
|
|
const activityText = this.context.t(eventKey, [
|
|
|
|
ethValue,
|
|
|
|
formattedTimestamp,
|
2021-02-04 19:15:23 +01:00
|
|
|
]);
|
2018-08-31 21:34:22 +02:00
|
|
|
|
2018-08-26 03:00:38 +02:00
|
|
|
return (
|
2020-11-03 00:41:28 +01:00
|
|
|
<div key={index} className="transaction-activity-log__activity">
|
2018-12-09 21:48:06 +01:00
|
|
|
<TransactionActivityLogIcon
|
|
|
|
className="transaction-activity-log__activity-icon"
|
|
|
|
eventKey={eventKey}
|
|
|
|
/>
|
|
|
|
<div className="transaction-activity-log__entry-container">
|
|
|
|
<div
|
|
|
|
className="transaction-activity-log__activity-text"
|
|
|
|
title={activityText}
|
2021-03-09 22:37:19 +01:00
|
|
|
onClick={() => this.handleActivityClick(activity)}
|
2018-12-09 21:48:06 +01:00
|
|
|
>
|
2020-11-03 00:41:28 +01:00
|
|
|
{activityText}
|
2018-12-09 21:48:06 +01:00
|
|
|
</div>
|
2020-11-03 00:41:28 +01:00
|
|
|
{this.renderInlineRetry(index)}
|
|
|
|
{this.renderInlineCancel(index)}
|
2018-08-31 21:34:22 +02:00
|
|
|
</div>
|
2018-08-26 03:00:38 +02:00
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2018-08-26 03:00:38 +02:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
render() {
|
2021-02-04 19:15:23 +01:00
|
|
|
const { t } = this.context;
|
|
|
|
const { className, activities } = this.props;
|
2018-08-26 03:00:38 +02:00
|
|
|
|
2020-05-28 20:00:51 +02:00
|
|
|
if (activities.length === 0) {
|
2021-02-04 19:15:23 +01:00
|
|
|
return null;
|
2020-05-28 20:00:51 +02:00
|
|
|
}
|
|
|
|
|
2018-08-26 03:00:38 +02:00
|
|
|
return (
|
2018-08-31 21:34:22 +02:00
|
|
|
<div className={classnames('transaction-activity-log', className)}>
|
2018-12-09 21:48:06 +01:00
|
|
|
<div className="transaction-activity-log__title">
|
2020-11-03 00:41:28 +01:00
|
|
|
{t('activityLog')}
|
2018-12-09 21:48:06 +01:00
|
|
|
</div>
|
|
|
|
<div className="transaction-activity-log__activities-container">
|
2020-11-03 00:41:28 +01:00
|
|
|
{activities.map((activity, index) =>
|
|
|
|
this.renderActivity(activity, index),
|
|
|
|
)}
|
2018-12-09 21:48:06 +01:00
|
|
|
</div>
|
2018-08-26 03:00:38 +02:00
|
|
|
</div>
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2018-08-26 03:00:38 +02:00
|
|
|
}
|
|
|
|
}
|