fix: make sure pending transactions are always displayed first

This commit is contained in:
Sean Yesmunt 2018-10-30 16:31:47 -04:00
parent 5ddcb60d31
commit 08f5ad0f03
3 changed files with 81 additions and 42 deletions

21
dist/bundle.js vendored
View file

@ -4994,23 +4994,40 @@ var selectTransactionItems = exports.selectTransactionItems = (0, _reselect.crea
return { return {
txid: txid, txid: txid,
timestamp: tx.timestamp,
date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null,
amount: amount, amount: amount,
fee: amount < 0 ? -1 * tx.fee / append.length : 0, fee: amount < 0 ? -1 * tx.fee / append.length : 0,
claim_id: item.claim_id, claim_id: item.claim_id,
claim_name: item.claim_name, claim_name: item.claim_name,
type: item.type || TRANSACTIONS.SPEND, 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 selectRecentTransactions = exports.selectRecentTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) {
var threshold = new Date(); var threshold = new Date();
threshold.setDate(threshold.getDate() - 7); threshold.setDate(threshold.getDate() - 7);
return transactions.filter(function (transaction) { return transactions.filter(function (transaction) {
if (!transaction.date) {
return true; // pending transaction
}
return transaction.date > threshold; return transaction.date > threshold;
}); });
}); });

View file

@ -71,7 +71,7 @@ reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = (state: WalletState, action) =>
const { transactions } = action.data; const { transactions } = action.data;
transactions.forEach(transaction => { transactions.forEach((transaction) => {
byId[transaction.txid] = transaction; byId[transaction.txid] = transaction;
}); });

View file

@ -1,80 +1,83 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import * as TRANSACTIONS from 'constants/transaction_types'; 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 selectWalletState = selectState;
export const selectWalletIsEncrypted = createSelector( export const selectWalletIsEncrypted = createSelector(
selectState, selectState,
state => state.walletIsEncrypted (state) => state.walletIsEncrypted
); );
export const selectWalletEncryptPending = createSelector( export const selectWalletEncryptPending = createSelector(
selectState, selectState,
state => state.walletEncryptPending (state) => state.walletEncryptPending
); );
export const selectWalletEncryptSucceeded = createSelector( export const selectWalletEncryptSucceeded = createSelector(
selectState, selectState,
state => state.walletEncryptSucceded (state) => state.walletEncryptSucceded
); );
export const selectWalletEncryptResult = createSelector( export const selectWalletEncryptResult = createSelector(
selectState, selectState,
state => state.walletEncryptResult (state) => state.walletEncryptResult
); );
export const selectWalletDecryptPending = createSelector( export const selectWalletDecryptPending = createSelector(
selectState, selectState,
state => state.walletDecryptPending (state) => state.walletDecryptPending
); );
export const selectWalletDecryptSucceeded = createSelector( export const selectWalletDecryptSucceeded = createSelector(
selectState, selectState,
state => state.walletDecryptSucceded (state) => state.walletDecryptSucceded
); );
export const selectWalletDecryptResult = createSelector( export const selectWalletDecryptResult = createSelector(
selectState, selectState,
state => state.walletDecryptResult (state) => state.walletDecryptResult
); );
export const selectWalletUnlockPending = createSelector( export const selectWalletUnlockPending = createSelector(
selectState, selectState,
state => state.walletUnlockPending (state) => state.walletUnlockPending
); );
export const selectWalletUnlockSucceeded = createSelector( export const selectWalletUnlockSucceeded = createSelector(
selectState, selectState,
state => state.walletUnlockSucceded (state) => state.walletUnlockSucceded
); );
export const selectWalletUnlockResult = createSelector( export const selectWalletUnlockResult = createSelector(
selectState, selectState,
state => state.walletUnlockResult (state) => state.walletUnlockResult
); );
export const selectWalletLockPending = createSelector( export const selectWalletLockPending = createSelector(
selectState, selectState,
state => state.walletLockPending (state) => state.walletLockPending
); );
export const selectWalletLockSucceeded = createSelector( export const selectWalletLockSucceeded = createSelector(
selectState, 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 = []; const items = [];
Object.keys(byId).forEach(txid => { Object.keys(byId).forEach((txid) => {
const tx = byId[txid]; const tx = byId[txid];
// ignore dust/fees // ignore dust/fees
@ -92,24 +95,24 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI
const append = []; const append = [];
append.push( append.push(
...tx.claim_info.map(item => ...tx.claim_info.map((item) =>
Object.assign({}, tx, item, { Object.assign({}, tx, item, {
type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH,
}) })
) )
); );
append.push( append.push(
...tx.support_info.map(item => ...tx.support_info.map((item) =>
Object.assign({}, tx, item, { Object.assign({}, tx, item, {
type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP,
}) })
) )
); );
append.push( 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( 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) { if (!append.length) {
@ -121,13 +124,14 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI
} }
items.push( items.push(
...append.map(item => { ...append.map((item) => {
// value on transaction, amount on outpoint // value on transaction, amount on outpoint
// amount is always positive, but should match sign of value // amount is always positive, but should match sign of value
const amount = parseFloat(item.balance_delta ? item.balance_delta : item.value); const amount = parseFloat(item.balance_delta ? item.balance_delta : item.value);
return { return {
txid, txid,
timestamp: tx.timestamp,
date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null,
amount, amount,
fee: amount < 0 ? -1 * tx.fee / append.length : 0, fee: amount < 0 ? -1 * tx.fee / append.length : 0,
@ -135,67 +139,85 @@ export const selectTransactionItems = createSelector(selectTransactionsById, byI
claim_name: item.claim_name, claim_name: item.claim_name,
type: item.type || TRANSACTIONS.SPEND, type: item.type || TRANSACTIONS.SPEND,
nout: item.nout, 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(); const threshold = new Date();
threshold.setDate(threshold.getDate() - 7); 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( export const selectHasTransactions = createSelector(
selectTransactionItems, selectTransactionItems,
transactions => transactions && transactions.length > 0 (transactions) => transactions && transactions.length > 0
); );
export const selectIsFetchingTransactions = createSelector( export const selectIsFetchingTransactions = createSelector(
selectState, 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( export const selectGettingNewAddress = createSelector(
selectState, selectState,
state => state.gettingNewAddress (state) => state.gettingNewAddress
); );
export const selectDraftTransaction = createSelector( export const selectDraftTransaction = createSelector(
selectState, selectState,
state => state.draftTransaction || {} (state) => state.draftTransaction || {}
); );
export const selectDraftTransactionAmount = createSelector( export const selectDraftTransactionAmount = createSelector(
selectDraftTransaction, selectDraftTransaction,
draft => draft.amount (draft) => draft.amount
); );
export const selectDraftTransactionAddress = createSelector( export const selectDraftTransactionAddress = createSelector(
selectDraftTransaction, selectDraftTransaction,
draft => draft.address (draft) => draft.address
); );
export const selectDraftTransactionError = createSelector( export const selectDraftTransactionError = createSelector(
selectDraftTransaction, 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( createSelector(
selectBlocks, 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( export const selectTransactionListFilter = createSelector(
selectState, selectState,
state => state.transactionListFilter || '' (state) => state.transactionListFilter || ''
); );