refactor: notifications middleware

This commit is contained in:
fernandomg 2020-05-22 16:50:10 -03:00
parent c9a01f6892
commit 376af39f3c
3 changed files with 32 additions and 54 deletions

View File

@ -1,33 +1,18 @@
import { Map } from 'immutable'
import { List } from 'immutable'
export const getAwaitingTransactions = (allTransactions, cancellationTransactionsByNonce, userAccount) => {
if (!allTransactions) {
return Map({})
}
import { isPendingTransaction } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers'
const allAwaitingTransactions = allTransactions.map((safeTransactions) => {
const nonCancelledTransactions = safeTransactions.filter((transaction) => {
// If transactions are not executed, but there's a transaction with the same nonce EXECUTED later
// it means that the transaction was cancelled (Replaced) and shouldn't get executed
let isTransactionCancelled = false
if (!transaction.isExecuted) {
if (cancellationTransactionsByNonce.get(transaction.nonce)) {
// eslint-disable-next-line no-param-reassign
isTransactionCancelled = true
}
}
// The transaction is not executed and is not cancelled, so it's still waiting confirmations
if (!transaction.executionTxHash && !isTransactionCancelled) {
// Then we check if the waiting confirmations are not from the current user, otherwise, filters this
// transaction
const transactionWaitingUser = transaction.confirmations.filter(({ owner }) => owner !== userAccount)
export const getAwaitingTransactions = (allTransactions = List([]), cancellationTxs, userAccount: string) => {
return allTransactions.filter((tx) => {
const cancelTx = !!tx.nonce && !isNaN(Number(tx.nonce)) ? cancellationTxs.get(`${tx.nonce}`) : null
// The transaction is not executed and is not cancelled, nor pending, so it's still waiting confirmations
if (!tx.executionTxHash && !tx.cancelled && !isPendingTransaction(tx, cancelTx)) {
// Then we check if the waiting confirmations are not from the current user, otherwise, filters this transaction
const transactionWaitingUser = tx.confirmations.filter(({ owner }) => owner !== userAccount)
return transactionWaitingUser.size > 0
}
return false
})
return nonCancelledTransactions
})
return allAwaitingTransactions
}

View File

@ -1,5 +1,4 @@
import { push } from 'connected-react-router'
import { List, Map } from 'immutable'
import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications'
import closeSnackbarAction from 'src/logic/notifications/store/actions/closeSnackbar'
@ -12,13 +11,14 @@ import { getIncomingTxAmount } from 'src/routes/safe/components/Transactions/Txs
import { grantedSelector } from 'src/routes/safe/container/selector'
import { ADD_INCOMING_TRANSACTIONS } from 'src/routes/safe/store/actions/addIncomingTransactions'
import { ADD_SAFE } from 'src/routes/safe/store/actions/addSafe'
import { ADD_TRANSACTIONS } from 'src/routes/safe/store/actions/addTransactions'
import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions'
import updateSafe from 'src/routes/safe/store/actions/updateSafe'
import { CANCELLATION_TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/cancellationTransactions'
import { safeParamAddressFromStateSelector, safesMapSelector } from 'src/routes/safe/store/selectors'
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
const watchedActions = [ADD_TRANSACTIONS, ADD_INCOMING_TRANSACTIONS, ADD_SAFE]
const watchedActions = [ADD_OR_UPDATE_TRANSACTIONS, ADD_INCOMING_TRANSACTIONS, ADD_SAFE]
const sendAwaitingTransactionNotification = async (
dispatch,
@ -59,48 +59,41 @@ const sendAwaitingTransactionNotification = async (
await saveToStorage(LAST_TIME_USED_LOGGED_IN_ID, lastTimeUserLoggedInForSafes)
}
const onNotificationClicked = (dispatch, notificationKey, safeAddress) => () => {
dispatch(closeSnackbarAction({ key: notificationKey }))
dispatch(push(`/safes/${safeAddress}/transactions`))
}
const notificationsMiddleware = (store) => (next) => async (action) => {
const handledAction = next(action)
const { dispatch } = store
if (watchedActions.includes(action.type)) {
const state = store.getState()
switch (action.type) {
case ADD_TRANSACTIONS: {
const transactionsList = action.payload
const userAddress = userAccountSelector(state)
const safeAddress = action.payload.keySeq().get(0)
const cancellationTransactions = state.cancellationTransactions.get(safeAddress)
const cancellationTransactionsByNonce = cancellationTransactions
? cancellationTransactions.reduce((acc, tx) => acc.set(tx.nonce, tx), Map())
: Map()
const awaitingTransactions = getAwaitingTransactions(
transactionsList,
cancellationTransactionsByNonce,
userAddress,
)
const awaitingTxsSubmissionDateList = awaitingTransactions
.get(safeAddress, List([]))
.map((tx) => tx.submissionDate)
case ADD_OR_UPDATE_TRANSACTIONS: {
const { safeAddress, transactions } = action.payload
const userAddress: string = userAccountSelector(state)
const cancellationTransactions = state[CANCELLATION_TRANSACTIONS_REDUCER_ID].get(safeAddress)
const awaitingTransactions = getAwaitingTransactions(transactions, cancellationTransactions, userAddress)
const awaitingTxsSubmissionDateList = awaitingTransactions.map((tx) => tx.submissionDate)
const safes = safesMapSelector(state)
const currentSafe = safes.get(safeAddress)
if (!isUserOwner(currentSafe, userAddress) || awaitingTxsSubmissionDateList.size === 0) {
if (!isUserOwner(currentSafe, userAddress) || awaitingTransactions.size === 0) {
break
}
const notificationKey = `${safeAddress}-awaiting`
const onNotificationClicked = () => {
dispatch(closeSnackbarAction({ key: notificationKey }))
dispatch(push(`/safes/${safeAddress}/transactions`))
}
await sendAwaitingTransactionNotification(
dispatch,
safeAddress,
awaitingTxsSubmissionDateList,
notificationKey,
onNotificationClicked,
onNotificationClicked(dispatch, notificationKey, safeAddress),
)
break

View File

@ -38,9 +38,9 @@ const finalCreateStore = composeEnhancers(
applyMiddleware(
thunk,
routerMiddleware(history),
notificationsMiddleware,
safeStorage,
providerWatcher,
notificationsMiddleware,
addressBookMiddleware,
currencyValuesStorageMiddleware,
),