mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Token transfers will now be hidden on the ETH asset page. Arguably token transfers are still relevant to show on the ETH asset page because the gas for token transfers is paid in ETH, but they weren't being displayed in a way that highlighted this (only the token amount was shown inline - not the gas price). We will likely restore token transfers to the ETH asset page at a later date, after designs have been updated to highlight their relevance to this page.
140 lines
5.5 KiB
JavaScript
140 lines
5.5 KiB
JavaScript
import React, { useMemo, useEffect, useRef, useState, useCallback } from 'react'
|
|
import PropTypes from 'prop-types'
|
|
import { useSelector, useDispatch } from 'react-redux'
|
|
import {
|
|
nonceSortedCompletedTransactionsSelector,
|
|
nonceSortedPendingTransactionsSelector,
|
|
} from '../../../selectors/transactions'
|
|
import {
|
|
getFeatureFlags,
|
|
} from '../../../selectors/selectors'
|
|
import * as actions from '../../../ducks/gas/gas.duck'
|
|
import { useI18nContext } from '../../../hooks/useI18nContext'
|
|
import TransactionListItem from '../transaction-list-item'
|
|
import Button from '../../ui/button'
|
|
import { TOKEN_CATEGORY_HASH } from '../../../helpers/constants/transactions'
|
|
|
|
const PAGE_INCREMENT = 10
|
|
|
|
const getTransactionGroupRecipientAddressFilter = (recipientAddress) => {
|
|
return ({ initialTransaction: { txParams } }) => txParams && txParams.to === recipientAddress
|
|
}
|
|
|
|
const tokenTransactionFilter = ({
|
|
initialTransaction: {
|
|
transactionCategory,
|
|
},
|
|
}) => !TOKEN_CATEGORY_HASH[transactionCategory]
|
|
|
|
|
|
const getFilteredTransactionGroups = (transactionGroups, hideTokenTransactions, tokenAddress) => {
|
|
if (hideTokenTransactions) {
|
|
return transactionGroups.filter(tokenTransactionFilter)
|
|
} else if (tokenAddress) {
|
|
return transactionGroups.filter(getTransactionGroupRecipientAddressFilter(tokenAddress))
|
|
}
|
|
return transactionGroups
|
|
}
|
|
|
|
export default function TransactionList ({ hideTokenTransactions, tokenAddress }) {
|
|
const [limit, setLimit] = useState(PAGE_INCREMENT)
|
|
const t = useI18nContext()
|
|
|
|
const dispatch = useDispatch()
|
|
const unfilteredPendingTransactions = useSelector(nonceSortedPendingTransactionsSelector)
|
|
const unfilteredCompletedTransactions = useSelector(nonceSortedCompletedTransactionsSelector)
|
|
const { transactionTime: transactionTimeFeatureActive } = useSelector(getFeatureFlags)
|
|
|
|
const pendingTransactions = useMemo(
|
|
() => getFilteredTransactionGroups(unfilteredPendingTransactions, hideTokenTransactions, tokenAddress),
|
|
[hideTokenTransactions, tokenAddress, unfilteredPendingTransactions]
|
|
)
|
|
const completedTransactions = useMemo(
|
|
() => getFilteredTransactionGroups(unfilteredCompletedTransactions, hideTokenTransactions, tokenAddress),
|
|
[hideTokenTransactions, tokenAddress, unfilteredCompletedTransactions]
|
|
)
|
|
|
|
const { fetchGasEstimates, fetchBasicGasAndTimeEstimates } = useMemo(() => ({
|
|
fetchGasEstimates: (blockTime) => dispatch(actions.fetchGasEstimates(blockTime)),
|
|
fetchBasicGasAndTimeEstimates: () => dispatch(actions.fetchBasicGasAndTimeEstimates()),
|
|
}), [dispatch])
|
|
|
|
// keep track of previous values from state.
|
|
// loaded is used here to determine if our effect has ran at least once.
|
|
const prevState = useRef({ loaded: false, pendingTransactions, transactionTimeFeatureActive })
|
|
|
|
useEffect(() => {
|
|
const { loaded } = prevState.current
|
|
const pendingTransactionAdded = pendingTransactions.length > 0 && prevState.current.pendingTransactions.length === 0
|
|
const transactionTimeFeatureWasActivated = !prevState.current.transactionTimeFeatureActive && transactionTimeFeatureActive
|
|
if (transactionTimeFeatureActive && pendingTransactions.length > 0 && (loaded === false || transactionTimeFeatureWasActivated || pendingTransactionAdded)) {
|
|
fetchBasicGasAndTimeEstimates()
|
|
.then(({ blockTime }) => fetchGasEstimates(blockTime))
|
|
}
|
|
prevState.current = { loaded: true, pendingTransactions, transactionTimeFeatureActive }
|
|
}, [fetchGasEstimates, fetchBasicGasAndTimeEstimates, transactionTimeFeatureActive, pendingTransactions ])
|
|
|
|
const viewMore = useCallback(() => setLimit((prev) => prev + PAGE_INCREMENT), [])
|
|
|
|
|
|
const pendingLength = pendingTransactions.length
|
|
|
|
return (
|
|
<div className="transaction-list">
|
|
<div className="transaction-list__transactions">
|
|
{
|
|
pendingLength > 0 && (
|
|
<div className="transaction-list__pending-transactions">
|
|
<div className="transaction-list__header">
|
|
{ `${t('queue')} (${pendingTransactions.length})` }
|
|
</div>
|
|
{
|
|
pendingTransactions.map((transactionGroup, index) => (
|
|
<TransactionListItem isEarliestNonce={index === 0} transactionGroup={transactionGroup} key={`${transactionGroup.nonce}:${index}`} />
|
|
))
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
<div className="transaction-list__completed-transactions">
|
|
{
|
|
pendingLength > 0
|
|
? (
|
|
<div className="transaction-list__header">
|
|
{ t('history') }
|
|
</div>
|
|
)
|
|
: null
|
|
}
|
|
{
|
|
completedTransactions.length > 0
|
|
? completedTransactions.slice(0, limit).map((transactionGroup, index) => (
|
|
<TransactionListItem transactionGroup={transactionGroup} key={`${transactionGroup.nonce}:${limit + index - 10}`} />
|
|
))
|
|
: (
|
|
<div className="transaction-list__empty">
|
|
<div className="transaction-list__empty-text">
|
|
{ t('noTransactions') }
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
{completedTransactions.length > limit && (
|
|
<Button className="transaction-list__view-more" type="secondary" rounded onClick={viewMore}>View More</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
TransactionList.propTypes = {
|
|
hideTokenTransactions: PropTypes.bool,
|
|
tokenAddress: PropTypes.string,
|
|
}
|
|
|
|
TransactionList.defaultProps = {
|
|
hideTokenTransactions: false,
|
|
tokenAddress: undefined,
|
|
}
|