Uses timestamps for dates for Claims and Transactions #136

Merged
jessopb merged 1 commit from removeBlockShowForDates into master 2019-05-07 06:19:28 +02:00
7 changed files with 140 additions and 142 deletions

1
flow-typed/Claim.js vendored
View file

@ -31,6 +31,7 @@ declare type GenericClaim = {
decoded_claim: boolean, // claim made in accordance with sdk protobuf types
depth: number, // confirmations since tx
effective_amount: number, // bid amount + supports
timestamp?: number, // date of transaction
has_signature: boolean,
height: number, // block height the tx was confirmed
hex: string, // `value` hex encoded

View file

@ -40,7 +40,6 @@ export const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'
export const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED';
export const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED';
export const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED';
export const FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS';
export const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED';
export const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED';
export const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED';

View file

@ -71,7 +71,6 @@ export {
doUpdateTotalBalance,
doTotalBalanceSubscribe,
doFetchTransactions,
doFetchBlock,
doGetNewAddress,
doCheckAddressIsMine,
doSendDraftTransaction,
@ -111,6 +110,7 @@ export {
makeSelectClaimsInChannelForPage,
makeSelectMetadataForUri,
makeSelectTitleForUri,
makeSelectDateForUri,
makeSelectContentTypeForUri,
makeSelectIsUriResolving,
makeSelectTotalItemsForChannel,
@ -177,7 +177,6 @@ export {
} from 'redux/selectors/search';
export {
makeSelectBlockDate,
selectBalance,
selectTotalBalance,
selectTransactionsById,

View file

@ -80,17 +80,6 @@ export function doFetchTransactions() {
};
}
export function doFetchBlock(height) {
return dispatch => {
Lbry.block_show({ height }).then(block => {
dispatch({
type: ACTIONS.FETCH_BLOCK_SUCCESS,
data: { block },
});
});
};
}
export function doGetNewAddress() {
return dispatch => {
dispatch({

View file

@ -183,18 +183,6 @@ reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = (state: WalletState, action) =>
sendingSupport: false,
});
reducers[ACTIONS.FETCH_BLOCK_SUCCESS] = (state: WalletState, action) => {
const {
block,
block: { height },
} = action.data;
const blocks = Object.assign({}, state.blocks);
blocks[height] = block;
return Object.assign({}, state, { blocks });
};
reducers[ACTIONS.WALLET_STATUS_COMPLETED] = (state: WalletState, action) =>
Object.assign({}, state, {
walletIsEncrypted: action.result,

View file

@ -178,6 +178,19 @@ export const makeSelectTitleForUri = (uri: string) =>
metadata => metadata && metadata.title
);
export const makeSelectDateForUri = (uri: string) =>
createSelector(
makeSelectClaimForUri(uri),
claim => {
const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined;
if (!timestamp) {
return undefined;
}
const dateObj = new Date(timestamp);
return dateObj;
}
);
export const makeSelectContentTypeForUri = (uri: string) =>
createSelector(
makeSelectClaimForUri(uri),

View file

@ -65,112 +65,130 @@ export const selectWalletLockSucceeded = createSelector(
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 selectTotalBalance = createSelector(selectState, state => state.totalBalance);
export const selectTotalBalance = createSelector(
selectState,
state => state.totalBalance
);
export const selectTransactionsById = createSelector(selectState, state => state.transactions);
export const selectTransactionsById = createSelector(
selectState,
state => state.transactions
);
export const selectTransactionItems = createSelector(selectTransactionsById, byId => {
const items = [];
export const selectTransactionItems = createSelector(
selectTransactionsById,
byId => {
const items = [];
Object.keys(byId).forEach(txid => {
const tx = byId[txid];
Object.keys(byId).forEach(txid => {
const tx = byId[txid];
// ignore dust/fees
// it is fee only txn if all infos are also empty
if (
Math.abs(tx.value) === Math.abs(tx.fee) &&
tx.claim_info.length === 0 &&
tx.support_info.length === 0 &&
tx.update_info.length === 0 &&
tx.abandon_info.length === 0
) {
return;
}
// ignore dust/fees
// it is fee only txn if all infos are also empty
if (
Math.abs(tx.value) === Math.abs(tx.fee) &&
tx.claim_info.length === 0 &&
tx.support_info.length === 0 &&
tx.update_info.length === 0 &&
tx.abandon_info.length === 0
) {
return;
}
const append = [];
const append = [];
append.push(
...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 =>
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 }))
);
append.push(
...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON }))
);
if (!append.length) {
append.push(
Object.assign({}, tx, {
type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE,
...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 =>
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 }))
);
append.push(
...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON }))
);
if (!append.length) {
append.push(
Object.assign({}, tx, {
type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE,
})
);
}
items.push(
...append.map(item => {
// value on transaction, amount on outpoint
// amount is always positive, but should match sign of value
const balanceDelta = parseFloat(item.balance_delta);
const value = parseFloat(item.value);
const amount = balanceDelta || value;
const fee = parseFloat(tx.fee);
return {
txid,
timestamp: tx.timestamp,
date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null,
amount,
fee,
claim_id: item.claim_id,
claim_name: item.claim_name,
type: item.type || TRANSACTIONS.SPEND,
nout: item.nout,
confirmations: tx.confirmations,
};
})
);
}
});
items.push(
...append.map(item => {
// value on transaction, amount on outpoint
// amount is always positive, but should match sign of value
const balanceDelta = parseFloat(item.balance_delta);
const value = parseFloat(item.value);
const amount = balanceDelta || value;
const fee = parseFloat(tx.fee);
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 {
txid,
timestamp: tx.timestamp,
date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null,
amount,
fee,
claim_id: item.claim_id,
claim_name: item.claim_name,
type: item.type || TRANSACTIONS.SPEND,
nout: item.nout,
confirmations: tx.confirmations,
};
})
);
});
return tx2.timestamp - tx1.timestamp;
});
}
);
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;
}
export const selectRecentTransactions = createSelector(
selectTransactionItems,
transactions => {
const threshold = new Date();
threshold.setDate(threshold.getDate() - 7);
return transactions.filter(transaction => {
if (!transaction.date) {
return true; // pending transaction
}
return tx2.timestamp - tx1.timestamp;
});
});
export const selectRecentTransactions = createSelector(selectTransactionItems, transactions => {
const threshold = new Date();
threshold.setDate(threshold.getDate() - 7);
return transactions.filter(transaction => {
if (!transaction.date) {
return true; // pending transaction
}
return transaction.date > threshold;
});
});
return transaction.date > threshold;
});
}
);
export const selectHasTransactions = createSelector(
selectTransactionItems,
@ -182,9 +200,15 @@ export const selectIsFetchingTransactions = createSelector(
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,
@ -211,30 +235,15 @@ export const selectDraftTransactionError = createSelector(
draft => draft.error
);
export const selectBlocks = createSelector(selectState, state => state.blocks);
export const selectBlocks = createSelector(
selectState,
state => state.blocks
);
export const selectCurrentHeight = createSelector(selectState, state => state.latestBlock);
export const makeSelectBlockDate = block =>
createSelector(selectBlocks, selectCurrentHeight, (blocks, latestBlock) => {
// If we have the block data, look at the actual date,
// If not, try to simulate it based on 2.5 minute blocks
// Adding this on 11/7/2018 because caling block_show for every claim is causing
// performance issues.
if (blocks && blocks[block]) {
return new Date(blocks[block].time * 1000);
}
// Pending claim
if (block < 1) {
return null;
}
const difference = latestBlock - block;
const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms
const publishDate = Date.now() - msSincePublish;
return new Date(publishDate);
});
export const selectCurrentHeight = createSelector(
selectState,
state => state.latestBlock
);
export const selectTransactionListFilter = createSelector(
selectState,