Merge pull request #293 from lbryio/feat-unlockTips

tip management on claim
This commit is contained in:
jessopb 2020-04-01 07:57:46 -04:00 committed by GitHub
commit 07adf4aab3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 342 additions and 44 deletions

191
dist/bundle.es.js vendored
View file

@ -62,6 +62,10 @@ const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED';
const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED';
const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED';
const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED';
const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED';
const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED';
const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED';
const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED';
const UPDATE_BALANCE = 'UPDATE_BALANCE'; const UPDATE_BALANCE = 'UPDATE_BALANCE';
const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE';
const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED';
@ -327,6 +331,10 @@ var action_types = /*#__PURE__*/Object.freeze({
FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED,
ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED,
ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED, ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED,
ABANDON_CLAIM_SUPPORT_STARTED: ABANDON_CLAIM_SUPPORT_STARTED,
ABANDON_CLAIM_SUPPORT_COMPLETED: ABANDON_CLAIM_SUPPORT_COMPLETED,
ABANDON_CLAIM_SUPPORT_FAILED: ABANDON_CLAIM_SUPPORT_FAILED,
PENDING_SUPPORTS_UPDATED: PENDING_SUPPORTS_UPDATED,
UPDATE_BALANCE: UPDATE_BALANCE, UPDATE_BALANCE: UPDATE_BALANCE,
UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE,
CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED,
@ -1791,6 +1799,15 @@ const selectWalletEncryptPending = reselect.createSelector(selectState$1, state
const selectWalletEncryptSucceeded = reselect.createSelector(selectState$1, state => state.walletEncryptSucceded); const selectWalletEncryptSucceeded = reselect.createSelector(selectState$1, state => state.walletEncryptSucceded);
const selectPendingSupportTransactions = reselect.createSelector(selectState$1, state => state.pendingSupportTransactions);
const makeSelectPendingAmountByUri = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingSupportTransactions, (claimIdsByUri, pendingSupports) => {
const uriEntry = Object.entries(claimIdsByUri).find(([u, cid]) => u === uri);
const claimId = uriEntry && uriEntry[1];
const pendingSupport = claimId && pendingSupports[claimId];
return pendingSupport ? pendingSupport.effective : undefined;
});
const selectWalletEncryptResult = reselect.createSelector(selectState$1, state => state.walletEncryptResult); const selectWalletEncryptResult = reselect.createSelector(selectState$1, state => state.walletEncryptResult);
const selectWalletDecryptPending = reselect.createSelector(selectState$1, state => state.walletDecryptPending); const selectWalletDecryptPending = reselect.createSelector(selectState$1, state => state.walletDecryptPending);
@ -1993,29 +2010,13 @@ function createNormalizedClaimSearchKey(options) {
return query; return query;
} }
function concatClaims(claimList = [], concatClaimList = []) {
if (!claimList || claimList.length === 0) {
if (!concatClaimList) {
return [];
}
return concatClaimList.slice();
}
const claims = claimList.slice();
concatClaimList.forEach(claim => {
if (!claims.some(item => item.claim_id === claim.claim_id)) {
claims.push(claim);
}
});
return claims;
}
var _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
const selectState$2 = state => state.claims || {}; const selectState$2 = state => state.claims || {};
const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {});
const selectClaimIdsByUri = reselect.createSelector(selectState$2, state => state.claimsByUri || {});
const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => state.currentChannelPage || 1); const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => state.currentChannelPage || 1);
const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel); const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel);
@ -2112,7 +2113,21 @@ const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelec
} }
}); });
const selectMyClaimsRaw = reselect.createSelector(selectState$2, state => state.myClaims); const selectMyClaimsRaw = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => {
const ids = state.myClaims;
if (!ids) {
return ids;
}
const claims = [];
ids.forEach(id => {
if (byId[id]) {
// I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544
claims.push(byId[id]);
}
});
return claims;
});
const selectAbandoningIds = reselect.createSelector(selectState$2, state => Object.keys(state.abandoningById || {})); const selectAbandoningIds = reselect.createSelector(selectState$2, state => Object.keys(state.abandoningById || {}));
@ -2799,6 +2814,34 @@ function doWalletUnlock(password) {
}; };
} }
function doSupportAbandonForClaim(claimId, claimType, keep, preview) {
return dispatch => {
if (!preview) {
dispatch({
type: ABANDON_CLAIM_SUPPORT_STARTED
});
}
const params = { claim_id: claimId };
if (preview) params['preview'] = true;
if (keep) params['keep'] = keep;
return lbryProxy.support_abandon(params).then(res => {
if (!preview) {
dispatch({
type: ABANDON_CLAIM_SUPPORT_COMPLETED,
data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType } // add to pendingSupportTransactions,
});
dispatch(doCheckPendingTxs());
}
return res;
}).catch(e => {
dispatch({
type: ABANDON_CLAIM_SUPPORT_FAILED,
data: e.message
});
});
};
}
function doWalletReconnect() { function doWalletReconnect() {
return dispatch => { return dispatch => {
dispatch({ dispatch({
@ -2868,6 +2911,62 @@ function doUpdateBlockHeight() {
}); });
} }
// Calls transaction_show on txes until any pending txes are confirmed
const doCheckPendingTxs = () => (dispatch, getState) => {
const state = getState();
const pendingTxsById = selectPendingSupportTransactions(state); // {}
if (!Object.keys(pendingTxsById).length) {
return;
}
let txCheckInterval;
const checkTxList = () => {
const state = getState();
const pendingTxs = selectPendingSupportTransactions(state); // {}
const promises = [];
const newPendingTxes = {};
const types = new Set([]);
let changed = false;
Object.entries(pendingTxs).forEach(([claim, data]) => {
promises.push(lbryProxy.transaction_show({ txid: data.txid }));
types.add(data.type);
});
Promise.all(promises).then(txShows => {
txShows.forEach(result => {
if (result.height <= 0) {
const entries = Object.entries(pendingTxs);
const match = entries.find(entry => entry[1].txid === result.txid);
newPendingTxes[match[0]] = match[1];
} else {
changed = true;
}
});
}).then(() => {
if (changed) {
dispatch({
type: PENDING_SUPPORTS_UPDATED,
data: newPendingTxes
});
if (types.has('channel')) {
dispatch(doFetchChannelListMine());
}
if (types.has('stream')) {
dispatch(doFetchClaimListMine());
}
}
if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval);
});
if (!Object.keys(pendingTxsById).length) {
clearInterval(txCheckInterval);
}
};
txCheckInterval = setInterval(() => {
checkTxList();
}, 30000);
};
// https://github.com/reactjs/redux/issues/911 // https://github.com/reactjs/redux/issues/911
function batchActions(...actions) { function batchActions(...actions) {
return { return {
@ -4681,19 +4780,23 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri); const byUri = Object.assign({}, state.claimsByUri);
const pendingById = Object.assign({}, state.pendingById); const pendingById = Object.assign({}, state.pendingById);
const myClaims = state.myClaims ? state.myClaims.slice() : []; let myClaimIds = new Set(state.myClaims);
claims.forEach(claim => { claims.forEach(claim => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id });
const { claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) { if (claim.type && claim.type.match(/claim|update/)) {
if (claim.confirmations < 1) { if (claim.confirmations < 1) {
pendingById[claim.claim_id] = claim; pendingById[claimId] = claim;
delete byId[claim.claim_id]; delete byId[claimId];
delete byUri[claim.claim_id]; delete byUri[claimId];
} else { } else {
byId[claim.claim_id] = claim; byId[claimId] = claim;
byUri[uri] = claim.claim_id; byUri[uri] = claimId;
}
myClaimIds.add(claimId);
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
} }
} }
}); });
@ -4708,7 +4811,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
return Object.assign({}, state, { return Object.assign({}, state, {
isFetchingClaimListMine: false, isFetchingClaimListMine: false,
myClaims: concatClaims(myClaims, claims), myClaims: myClaimIds,
byId, byId,
claimsByUri: byUri, claimsByUri: byUri,
pendingById pendingById
@ -4720,8 +4823,8 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch
reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
const { claims } = action.data; const { claims } = action.data;
const myClaims = state.myClaims || []; const myClaims = state.myClaims || [];
let myClaimIds = new Set(state.myClaims);
const pendingById = Object.assign(state.pendingById); const pendingById = Object.assign(state.pendingById);
let myChannelClaims; let myChannelClaims;
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri); const byUri = Object.assign({}, state.claimsByUri);
@ -4747,6 +4850,11 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
byId[claimId] = claim; byId[claimId] = claim;
} }
myClaimIds.add(claimId);
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
}
if (pendingById[claimId] && claim.confirmations > 0) { if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId]; delete pendingById[claimId];
} }
@ -4759,7 +4867,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => {
channelClaimCounts, channelClaimCounts,
fetchingMyChannels: false, fetchingMyChannels: false,
myChannelClaims, myChannelClaims,
myClaims: concatClaims(myClaims, claims) myClaims: myClaimIds
}); });
}; };
@ -5805,7 +5913,8 @@ const defaultState$a = {
walletLockSucceded: null, walletLockSucceded: null,
walletLockResult: null, walletLockResult: null,
transactionListFilter: 'all', transactionListFilter: 'all',
walletReconnecting: false walletReconnecting: false,
pendingSupportTransactions: {}
}; };
const walletReducer = handleActions({ const walletReducer = handleActions({
@ -5868,6 +5977,24 @@ const walletReducer = handleActions({
}); });
}, },
[ABANDON_CLAIM_SUPPORT_COMPLETED]: (state, action) => {
const { claimId, type, txid, effective } = action.data;
const pendingtxs = Object.assign({}, state.pendingSupportTransactions);
pendingtxs[claimId] = { txid, type, effective };
return _extends$i({}, state, {
pendingSupportTransactions: pendingtxs
});
},
[PENDING_SUPPORTS_UPDATED]: (state, action) => {
return _extends$i({}, state, {
pendingSupportTransactions: action.data
});
},
[GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, {
gettingNewAddress: true gettingNewAddress: true
}), }),
@ -6245,6 +6372,7 @@ exports.doSetDraftTransactionAddress = doSetDraftTransactionAddress;
exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount;
exports.doSetFileListSort = doSetFileListSort; exports.doSetFileListSort = doSetFileListSort;
exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doSetTransactionListFilter = doSetTransactionListFilter;
exports.doSupportAbandonForClaim = doSupportAbandonForClaim;
exports.doToast = doToast; exports.doToast = doToast;
exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleBlockChannel = doToggleBlockChannel;
exports.doToggleTagFollow = doToggleTagFollow; exports.doToggleTagFollow = doToggleTagFollow;
@ -6301,6 +6429,7 @@ exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage;
exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel;
exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris;
exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel;
exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri;
exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPendingByUri = makeSelectPendingByUri;
exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri;
exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
@ -6343,6 +6472,7 @@ exports.selectBlocks = selectBlocks;
exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelClaimCounts = selectChannelClaimCounts;
exports.selectChannelImportPending = selectChannelImportPending; exports.selectChannelImportPending = selectChannelImportPending;
exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectChannelIsBlocked = selectChannelIsBlocked;
exports.selectClaimIdsByUri = selectClaimIdsByUri;
exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQuery = selectClaimSearchByQuery;
exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached;
exports.selectClaimsBalance = selectClaimsBalance; exports.selectClaimsBalance = selectClaimsBalance;
@ -6395,6 +6525,7 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels;
exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount;
exports.selectPendingById = selectPendingById; exports.selectPendingById = selectPendingById;
exports.selectPendingClaims = selectPendingClaims; exports.selectPendingClaims = selectPendingClaims;
exports.selectPendingSupportTransactions = selectPendingSupportTransactions;
exports.selectPlayingUri = selectPlayingUri; exports.selectPlayingUri = selectPlayingUri;
exports.selectPublishFormValues = selectPublishFormValues; exports.selectPublishFormValues = selectPublishFormValues;
exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage;

View file

@ -39,6 +39,10 @@ export const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED';
export const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; export const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED';
export const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; export const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED';
export const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; export const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED';
export const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED';
export const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED';
export const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED';
export const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED';
export const UPDATE_BALANCE = 'UPDATE_BALANCE'; export const UPDATE_BALANCE = 'UPDATE_BALANCE';
export const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; export const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE';
export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED';

View file

@ -120,6 +120,7 @@ export {
doSetTransactionListFilter, doSetTransactionListFilter,
doUpdateBlockHeight, doUpdateBlockHeight,
doClearSupport, doClearSupport,
doSupportAbandonForClaim,
} from 'redux/actions/wallet'; } from 'redux/actions/wallet';
export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags';
@ -236,6 +237,7 @@ export {
selectMyStreamUrlsCount, selectMyStreamUrlsCount,
selectRepostError, selectRepostError,
selectRepostLoading, selectRepostLoading,
selectClaimIdsByUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
export { makeSelectCommentsForUri } from 'redux/selectors/comments'; export { makeSelectCommentsForUri } from 'redux/selectors/comments';
@ -329,6 +331,8 @@ export {
makeSelectFilteredTransactionsForPage, makeSelectFilteredTransactionsForPage,
selectFilteredTransactionCount, selectFilteredTransactionCount,
selectIsWalletReconnecting, selectIsWalletReconnecting,
selectPendingSupportTransactions,
makeSelectPendingAmountByUri,
} from 'redux/selectors/wallet'; } from 'redux/selectors/wallet';
export { export {

View file

@ -1,9 +1,10 @@
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import Lbry from 'lbry'; import Lbry from 'lbry';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { selectBalance } from 'redux/selectors/wallet'; import { selectBalance, selectPendingSupportTransactions } from 'redux/selectors/wallet';
import { creditsToString } from 'util/format-credits'; import { creditsToString } from 'util/format-credits';
import { selectMyClaimsRaw } from 'redux/selectors/claims'; import { selectMyClaimsRaw } from 'redux/selectors/claims';
import { doFetchChannelListMine, doFetchClaimListMine } from 'redux/actions/claims';
let walletBalancePromise = null; let walletBalancePromise = null;
export function doUpdateBalance() { export function doUpdateBalance() {
@ -342,6 +343,37 @@ export function doWalletLock() {
}; };
} }
export function doSupportAbandonForClaim(claimId, claimType, keep, preview) {
return dispatch => {
if (!preview) {
dispatch({
type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED,
});
}
const params = {claim_id: claimId};
if (preview) params['preview'] = true;
if (keep) params['keep'] = keep;
return (
Lbry.support_abandon(params)
.then((res) => {
if (!preview) {
dispatch({
type: ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED,
data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType}, // add to pendingSupportTransactions,
});
dispatch(doCheckPendingTxs());
}
return res;
})
.catch(e => {
dispatch({
type: ACTIONS.ABANDON_CLAIM_SUPPORT_FAILED,
data: e.message,
});
}));
};
}
export function doWalletReconnect() { export function doWalletReconnect() {
return dispatch => { return dispatch => {
dispatch({ dispatch({
@ -413,3 +445,62 @@ export function doUpdateBlockHeight() {
} }
}); });
} }
// Calls transaction_show on txes until any pending txes are confirmed
export const doCheckPendingTxs = () => (
dispatch,
getState
) => {
const state = getState();
const pendingTxsById = selectPendingSupportTransactions(state); // {}
if (!Object.keys(pendingTxsById).length) {
return;
}
let txCheckInterval;
const checkTxList = () => {
const state = getState();
const pendingTxs = selectPendingSupportTransactions(state); // {}
const promises = [];
const newPendingTxes = {};
const types = new Set([]);
let changed = false;
Object.entries(pendingTxs).forEach(([claim, data]) => {
promises.push(Lbry.transaction_show({txid: data.txid}));
types.add(data.type);
});
Promise.all(promises).then(txShows => {
txShows.forEach(result => {
if (result.height <= 0) {
const entries = Object.entries(pendingTxs);
const match = entries.find((entry) => entry[1].txid === result.txid);
newPendingTxes[match[0]] = match[1];
} else {
changed = true;
}
});
}).then(() => {
if (changed) {
dispatch({
type: ACTIONS.PENDING_SUPPORTS_UPDATED,
data: newPendingTxes,
});
if (types.has('channel')) {
dispatch(doFetchChannelListMine());
}
if (types.has('stream')) {
dispatch(doFetchClaimListMine());
}
}
if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval);
});
if (!Object.keys(pendingTxsById).length) {
clearInterval(txCheckInterval);
}
};
txCheckInterval = setInterval(() => {
checkTxList();
}, 30000);
};

View file

@ -10,7 +10,6 @@
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import { buildURI, parseURI } from 'lbryURI'; import { buildURI, parseURI } from 'lbryURI';
import { concatClaims } from 'util/claim';
type State = { type State = {
createChannelError: ?string, createChannelError: ?string,
@ -167,19 +166,23 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any):
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri); const byUri = Object.assign({}, state.claimsByUri);
const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById);
const myClaims = state.myClaims ? state.myClaims.slice() : []; let myClaimIds = new Set(state.myClaims);
claims.forEach((claim: Claim) => { claims.forEach((claim: Claim) => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id });
const { claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) { if (claim.type && claim.type.match(/claim|update/)) {
if (claim.confirmations < 1) { if (claim.confirmations < 1) {
pendingById[claim.claim_id] = claim; pendingById[claimId] = claim;
delete byId[claim.claim_id]; delete byId[claimId];
delete byUri[claim.claim_id]; delete byUri[claimId];
} else { } else {
byId[claim.claim_id] = claim; byId[claimId] = claim;
byUri[uri] = claim.claim_id; byUri[uri] = claimId;
}
myClaimIds.add(claimId);
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
} }
} }
}); });
@ -195,7 +198,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any):
return Object.assign({}, state, { return Object.assign({}, state, {
isFetchingClaimListMine: false, isFetchingClaimListMine: false,
myClaims: concatClaims(myClaims, claims), myClaims: myClaimIds,
byId, byId,
claimsByUri: byUri, claimsByUri: byUri,
pendingById, pendingById,
@ -208,8 +211,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State =>
reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => { reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => {
const { claims }: { claims: Array<ChannelClaim> } = action.data; const { claims }: { claims: Array<ChannelClaim> } = action.data;
const myClaims = state.myClaims || []; const myClaims = state.myClaims || [];
let myClaimIds = new Set(state.myClaims);
const pendingById = Object.assign(state.pendingById); const pendingById = Object.assign(state.pendingById);
let myChannelClaims; let myChannelClaims;
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri); const byUri = Object.assign({}, state.claimsByUri);
@ -236,6 +239,11 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
byId[claimId] = claim; byId[claimId] = claim;
} }
myClaimIds.add(claimId);
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
}
if (pendingById[claimId] && claim.confirmations > 0) { if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId]; delete pendingById[claimId];
} }
@ -248,7 +256,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
channelClaimCounts, channelClaimCounts,
fetchingMyChannels: false, fetchingMyChannels: false,
myChannelClaims, myChannelClaims,
myClaims: concatClaims(myClaims, claims), myClaims: myClaimIds,
}); });
}; };

View file

@ -14,6 +14,8 @@ type ActionResult = {
result: any, result: any,
}; };
type WalletState = { type WalletState = {
balance: any, balance: any,
totalBalance: any, totalBalance: any,
@ -43,6 +45,7 @@ type WalletState = {
walletLockSucceded: ?boolean, walletLockSucceded: ?boolean,
walletLockResult: ?boolean, walletLockResult: ?boolean,
walletReconnecting: boolean, walletReconnecting: boolean,
pendingSupportTransactions: {}, // { claimId: {txid: 123, amount 12.3}, }
}; };
const defaultState = { const defaultState = {
@ -76,6 +79,7 @@ const defaultState = {
walletLockResult: null, walletLockResult: null,
transactionListFilter: 'all', transactionListFilter: 'all',
walletReconnecting: false, walletReconnecting: false,
pendingSupportTransactions: {},
}; };
export const walletReducer = handleActions( export const walletReducer = handleActions(
@ -144,6 +148,26 @@ export const walletReducer = handleActions(
}; };
}, },
[ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => {
const { claimId, type, txid, effective }: { claimId: string, type: string, txid: string, effective: string } = action.data;
const pendingtxs = Object.assign({}, state.pendingSupportTransactions);
pendingtxs[claimId] = {txid, type, effective};
return {
...state,
pendingSupportTransactions: pendingtxs,
};
},
[ACTIONS.PENDING_SUPPORTS_UPDATED]: (state: WalletState, action: any): WalletState => {
return {
...state,
pendingSupportTransactions: action.data,
};
},
[ACTIONS.GET_NEW_ADDRESS_STARTED]: (state: WalletState) => ({ [ACTIONS.GET_NEW_ADDRESS_STARTED]: (state: WalletState) => ({
...state, ...state,
gettingNewAddress: true, gettingNewAddress: true,

View file

@ -16,6 +16,11 @@ export const selectClaimsById = createSelector(
state => state.byId || {} state => state.byId || {}
); );
export const selectClaimIdsByUri = createSelector(
selectState,
state => state.claimsByUri || {}
);
export const selectCurrentChannelPage = createSelector( export const selectCurrentChannelPage = createSelector(
selectState, selectState,
state => state.currentChannelPage || 1 state => state.currentChannelPage || 1
@ -156,7 +161,22 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true)
export const selectMyClaimsRaw = createSelector( export const selectMyClaimsRaw = createSelector(
selectState, selectState,
state => state.myClaims selectClaimsById,
(state, byId) => {
const ids = state.myClaims;
if (!ids) {
return ids;
}
const claims = [];
ids.forEach(id => {
if (byId[id]) {
// I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544
claims.push(byId[id]);
}
});
return claims;
}
); );
export const selectAbandoningIds = createSelector( export const selectAbandoningIds = createSelector(

View file

@ -1,7 +1,7 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import * as TRANSACTIONS from 'constants/transaction_types'; import * as TRANSACTIONS from 'constants/transaction_types';
import { PAGE_SIZE, LATEST_PAGE_SIZE } from 'constants/transaction_list'; import { PAGE_SIZE, LATEST_PAGE_SIZE } from 'constants/transaction_list';
import { selectClaimIdsByUri } from 'redux/selectors/claims';
export const selectState = state => state.wallet || {}; export const selectState = state => state.wallet || {};
export const selectWalletState = selectState; export const selectWalletState = selectState;
@ -21,6 +21,22 @@ export const selectWalletEncryptSucceeded = createSelector(
state => state.walletEncryptSucceded state => state.walletEncryptSucceded
); );
export const selectPendingSupportTransactions = createSelector(
selectState,
state => state.pendingSupportTransactions
);
export const makeSelectPendingAmountByUri = (uri) => createSelector(
selectClaimIdsByUri,
selectPendingSupportTransactions,
(claimIdsByUri, pendingSupports) => {
const uriEntry = Object.entries(claimIdsByUri).find(([u, cid]) => u === uri);
const claimId = uriEntry && uriEntry[1];
const pendingSupport = claimId && pendingSupports[claimId];
return pendingSupport ? pendingSupport.effective : undefined;
}
);
export const selectWalletEncryptResult = createSelector( export const selectWalletEncryptResult = createSelector(
selectState, selectState,
state => state.walletEncryptResult state => state.walletEncryptResult