From 08f5ad0f03a66ccf3d37de76b4636c6a269a74c4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 30 Oct 2018 16:31:47 -0400 Subject: [PATCH] fix: make sure pending transactions are always displayed first --- dist/bundle.js | 21 ++++++- src/redux/reducers/wallet.js | 2 +- src/redux/selectors/wallet.js | 100 +++++++++++++++++++++------------- 3 files changed, 81 insertions(+), 42 deletions(-) diff --git a/dist/bundle.js b/dist/bundle.js index 43031f9..e8d1feb 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -4994,23 +4994,40 @@ var selectTransactionItems = exports.selectTransactionItems = (0, _reselect.crea return { txid: txid, + timestamp: tx.timestamp, date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, amount: amount, fee: amount < 0 ? -1 * tx.fee / append.length : 0, claim_id: item.claim_id, claim_name: item.claim_name, type: item.type || TRANSACTIONS.SPEND, - nout: item.nout + nout: item.nout, + confirmations: tx.confirmations }; }))); }); - return items; + + return items.sort(function (tx1, tx2) { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } + + return tx2.timestamp - tx1.timestamp; + }); }); var selectRecentTransactions = exports.selectRecentTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) { var threshold = new Date(); threshold.setDate(threshold.getDate() - 7); return transactions.filter(function (transaction) { + if (!transaction.date) { + return true; // pending transaction + } + return transaction.date > threshold; }); }); diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 1ab9d40..ed9ae3c 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -71,7 +71,7 @@ reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = (state: WalletState, action) => const { transactions } = action.data; - transactions.forEach(transaction => { + transactions.forEach((transaction) => { byId[transaction.txid] = transaction; }); diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 2c75897..3db2bdd 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -1,80 +1,83 @@ import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; -export const selectState = state => state.wallet || {}; +export const selectState = (state) => state.wallet || {}; export const selectWalletState = selectState; export const selectWalletIsEncrypted = createSelector( selectState, - state => state.walletIsEncrypted + (state) => state.walletIsEncrypted ); export const selectWalletEncryptPending = createSelector( selectState, - state => state.walletEncryptPending + (state) => state.walletEncryptPending ); export const selectWalletEncryptSucceeded = createSelector( selectState, - state => state.walletEncryptSucceded + (state) => state.walletEncryptSucceded ); export const selectWalletEncryptResult = createSelector( selectState, - state => state.walletEncryptResult + (state) => state.walletEncryptResult ); export const selectWalletDecryptPending = createSelector( selectState, - state => state.walletDecryptPending + (state) => state.walletDecryptPending ); export const selectWalletDecryptSucceeded = createSelector( selectState, - state => state.walletDecryptSucceded + (state) => state.walletDecryptSucceded ); export const selectWalletDecryptResult = createSelector( selectState, - state => state.walletDecryptResult + (state) => state.walletDecryptResult ); export const selectWalletUnlockPending = createSelector( selectState, - state => state.walletUnlockPending + (state) => state.walletUnlockPending ); export const selectWalletUnlockSucceeded = createSelector( selectState, - state => state.walletUnlockSucceded + (state) => state.walletUnlockSucceded ); export const selectWalletUnlockResult = createSelector( selectState, - state => state.walletUnlockResult + (state) => state.walletUnlockResult ); export const selectWalletLockPending = createSelector( selectState, - state => state.walletLockPending + (state) => state.walletLockPending ); export const selectWalletLockSucceeded = createSelector( selectState, - state => state.walletLockSucceded + (state) => state.walletLockSucceded ); -export const selectWalletLockResult = createSelector(selectState, state => state.walletLockResult); +export const selectWalletLockResult = createSelector( + selectState, + (state) => state.walletLockResult +); -export const selectBalance = createSelector(selectState, state => state.balance); +export const selectBalance = createSelector(selectState, (state) => state.balance); -export const selectTransactionsById = createSelector(selectState, state => state.transactions); +export const selectTransactionsById = createSelector(selectState, (state) => state.transactions); -export const selectTransactionItems = createSelector(selectTransactionsById, byId => { +export const selectTransactionItems = createSelector(selectTransactionsById, (byId) => { const items = []; - Object.keys(byId).forEach(txid => { + Object.keys(byId).forEach((txid) => { const tx = byId[txid]; // ignore dust/fees @@ -92,24 +95,24 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI const append = []; append.push( - ...tx.claim_info.map(item => + ...tx.claim_info.map((item) => Object.assign({}, tx, item, { type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, }) ) ); append.push( - ...tx.support_info.map(item => + ...tx.support_info.map((item) => Object.assign({}, tx, item, { type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, }) ) ); append.push( - ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) + ...tx.update_info.map((item) => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) ); append.push( - ...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) + ...tx.abandon_info.map((item) => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) ); if (!append.length) { @@ -121,13 +124,14 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI } items.push( - ...append.map(item => { + ...append.map((item) => { // value on transaction, amount on outpoint // amount is always positive, but should match sign of value const amount = parseFloat(item.balance_delta ? item.balance_delta : item.value); return { txid, + timestamp: tx.timestamp, date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, amount, fee: amount < 0 ? -1 * tx.fee / append.length : 0, @@ -135,67 +139,85 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI claim_name: item.claim_name, type: item.type || TRANSACTIONS.SPEND, nout: item.nout, + confirmations: tx.confirmations, }; }) ); }); - return items; + + return items.sort((tx1, tx2) => { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } + + return tx2.timestamp - tx1.timestamp; + }); }); -export const selectRecentTransactions = createSelector(selectTransactionItems, transactions => { +export const selectRecentTransactions = createSelector(selectTransactionItems, (transactions) => { const threshold = new Date(); threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => transaction.date > threshold); + return transactions.filter((transaction) => { + if (!transaction.date) { + return true; // pending transaction + } + + return transaction.date > threshold; + }); }); export const selectHasTransactions = createSelector( selectTransactionItems, - transactions => transactions && transactions.length > 0 + (transactions) => transactions && transactions.length > 0 ); export const selectIsFetchingTransactions = createSelector( selectState, - state => state.fetchingTransactions + (state) => state.fetchingTransactions ); -export const selectIsSendingSupport = createSelector(selectState, state => state.sendingSupport); +export const selectIsSendingSupport = createSelector(selectState, (state) => state.sendingSupport); -export const selectReceiveAddress = createSelector(selectState, state => state.receiveAddress); +export const selectReceiveAddress = createSelector(selectState, (state) => state.receiveAddress); export const selectGettingNewAddress = createSelector( selectState, - state => state.gettingNewAddress + (state) => state.gettingNewAddress ); export const selectDraftTransaction = createSelector( selectState, - state => state.draftTransaction || {} + (state) => state.draftTransaction || {} ); export const selectDraftTransactionAmount = createSelector( selectDraftTransaction, - draft => draft.amount + (draft) => draft.amount ); export const selectDraftTransactionAddress = createSelector( selectDraftTransaction, - draft => draft.address + (draft) => draft.address ); export const selectDraftTransactionError = createSelector( selectDraftTransaction, - draft => draft.error + (draft) => draft.error ); -export const selectBlocks = createSelector(selectState, state => state.blocks); +export const selectBlocks = createSelector(selectState, (state) => state.blocks); -export const makeSelectBlockDate = block => +export const makeSelectBlockDate = (block) => createSelector( selectBlocks, - blocks => (blocks && blocks[block] ? new Date(blocks[block].time * 1000) : undefined) + (blocks) => (blocks && blocks[block] ? new Date(blocks[block].time * 1000) : undefined) ); export const selectTransactionListFilter = createSelector( selectState, - state => state.transactionListFilter || '' + (state) => state.transactionListFilter || '' );