ViewPastSwaps: limit to 10 entries + other fixes

(1) Due to IAPI/commerce query limit, and also to not pollute the wallet with infinite chargeCodes, we'll only show the last 10 swaps. Beamer mentioned that it's possible to tracked back the past chargeCodes of the user, and potential provide a `list` endpoint to handle disputes.

(2) If a user explicitly removed an entry, don't repopulate that entry even if websocket returned an updated status for it. While it might be useful to handle accidental removals, it looks weird when the list gets repopulated with 'Expired' entries.

(3) Add sanitization when repopulating the chargeCodes from the wallet data (i.e. remove 'null' entries).

(4) Always repopulate the list per wallet data so every instance looks the same.
This commit is contained in:
infinite-persistence 2021-04-11 13:21:19 +08:00 committed by Sean Yesmunt
parent ca40e0287b
commit f94f98e0f3

View file

@ -3,6 +3,17 @@ import * as ACTIONS from 'constants/action_types';
import { ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux'; import { ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
import { handleActions } from 'util/redux-utils'; import { handleActions } from 'util/redux-utils';
const SWAP_HISTORY_LENGTH_LIMIT = 10;
function getBottomEntries(array, count) {
const curCount = array.length;
if (curCount < count) {
return array;
} else {
return array.slice(curCount - count);
}
}
const defaultState: CoinSwapState = { const defaultState: CoinSwapState = {
coinSwaps: [], coinSwaps: [],
}; };
@ -79,19 +90,27 @@ export default handleActions(
}, },
}; };
} else { } else {
newCoinSwaps.push({ // If a pending swap is removed, the websocket will return an update
chargeCode: charge.code, // when it expires, for example, causing the entry to re-appear. This
coins: Object.keys(charge.addresses), // might be a good thing (e.g. to get back accidental removals), but it
sendAddresses: charge.addresses, // actually causes synchronization confusion across multiple instances.
sendAmounts: charge.pricing, const IGNORED_DELETED_SWAPS = true;
lbcAmount: calculateLbcAmount(charge.pricing, exchange, 0),
status: { if (!IGNORED_DELETED_SWAPS) {
status: lastTimeline.status, newCoinSwaps.push({
receiptCurrency: lastTimeline.payment.value.currency, chargeCode: charge.code,
receiptTxid: lastTimeline.payment.transaction_id, coins: Object.keys(charge.addresses),
lbcTxid: exchange.lbc_txid || '', sendAddresses: charge.addresses,
}, sendAmounts: charge.pricing,
}); lbcAmount: calculateLbcAmount(charge.pricing, exchange, 0),
status: {
status: lastTimeline.status,
receiptCurrency: lastTimeline.payment.value.currency,
receiptTxid: lastTimeline.payment.transaction_id,
lbcTxid: exchange.lbc_txid || '',
},
});
}
} }
return { return {
@ -104,27 +123,32 @@ export default handleActions(
action: { data: { coinSwapCodes: ?Array<string> } } action: { data: { coinSwapCodes: ?Array<string> } }
) => { ) => {
const { coinSwapCodes } = action.data; const { coinSwapCodes } = action.data;
const newCoinSwaps = state.coinSwaps.slice(); const newCoinSwaps = [];
if (coinSwapCodes) { if (coinSwapCodes) {
coinSwapCodes.forEach((chargeCode) => { coinSwapCodes.forEach((chargeCode) => {
if (!newCoinSwaps.find((x) => x.chargeCode === chargeCode)) { if (chargeCode && typeof chargeCode === 'string') {
newCoinSwaps.push({ const existingSwap = state.coinSwaps.find((x) => x.chargeCode === chargeCode);
// Just restore the 'chargeCode', and query the other data if (existingSwap) {
// via 'btc/status' later. newCoinSwaps.push({ ...existingSwap });
chargeCode: chargeCode, } else {
coins: [], newCoinSwaps.push({
sendAddresses: {}, // Just restore the 'chargeCode', and query the other data
sendAmounts: {}, // via 'btc/status' later.
lbcAmount: 0, chargeCode: chargeCode,
}); coins: [],
sendAddresses: {},
sendAmounts: {},
lbcAmount: 0,
});
}
} }
}); });
} }
return { return {
...state, ...state,
coinSwaps: newCoinSwaps, coinSwaps: getBottomEntries(newCoinSwaps, SWAP_HISTORY_LENGTH_LIMIT),
}; };
}, },
}, },