support pending channels

This commit is contained in:
jessop 2020-06-16 21:56:51 -04:00
parent 72f9d57134
commit b32f6d0ddc
9 changed files with 469 additions and 483 deletions

588
dist/bundle.es.js vendored

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ declare type GenericClaim = {
timestamp?: number, // date of last transaction timestamp?: number, // date of last transaction
height: number, // block height the tx was confirmed height: number, // block height the tx was confirmed
is_channel_signature_valid?: boolean, is_channel_signature_valid?: boolean,
is_my_output: true, is_my_output: boolean,
name: string, name: string,
normalized_name: string, // `name` normalized via unicode NFD spec, normalized_name: string, // `name` normalized via unicode NFD spec,
nout: number, // index number for an output of a tx nout: number, // index number for an output of a tx

2
flow-typed/Claim.js vendored
View file

@ -22,7 +22,7 @@ declare type GenericClaim = {
timestamp?: number, // date of last transaction timestamp?: number, // date of last transaction
height: number, // block height the tx was confirmed height: number, // block height the tx was confirmed
is_channel_signature_valid?: boolean, is_channel_signature_valid?: boolean,
is_my_output: true, is_my_output: boolean,
name: string, name: string,
normalized_name: string, // `name` normalized via unicode NFD spec, normalized_name: string, // `name` normalized via unicode NFD spec,
nout: number, // index number for an output of a tx nout: number, // index number for an output of a tx

View file

@ -76,6 +76,7 @@ export {
doClearRepostError, doClearRepostError,
doCheckPublishNameAvailability, doCheckPublishNameAvailability,
doPurchaseList, doPurchaseList,
doCheckPendingClaims,
} from 'redux/actions/claims'; } from 'redux/actions/claims';
export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file'; export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file';
@ -94,7 +95,6 @@ export {
doUploadThumbnail, doUploadThumbnail,
doPrepareEdit, doPrepareEdit,
doPublish, doPublish,
doCheckPendingPublishes,
doCheckReflectingFiles, doCheckReflectingFiles,
} from 'redux/actions/publish'; } from 'redux/actions/publish';
@ -198,7 +198,6 @@ export {
makeSelectFirstRecommendedFileForUri, makeSelectFirstRecommendedFileForUri,
makeSelectChannelForClaimUri, makeSelectChannelForClaimUri,
makeSelectClaimIsPending, makeSelectClaimIsPending,
makeSelectPendingByUri,
makeSelectReflectingClaimForUri, makeSelectReflectingClaimForUri,
makeSelectClaimsInChannelForCurrentPageState, makeSelectClaimsInChannelForCurrentPageState,
makeSelectShortUrlForUri, makeSelectShortUrlForUri,
@ -207,7 +206,6 @@ export {
makeSelectSupportsForUri, makeSelectSupportsForUri,
makeSelectMyPurchasesForPage, makeSelectMyPurchasesForPage,
makeSelectClaimWasPurchased, makeSelectClaimWasPurchased,
selectPendingById,
selectReflectingById, selectReflectingById,
selectClaimsById, selectClaimsById,
selectClaimsByUri, selectClaimsByUri,
@ -217,9 +215,9 @@ export {
selectMyActiveClaims, selectMyActiveClaims,
selectAllFetchingChannelClaims, selectAllFetchingChannelClaims,
selectIsFetchingClaimListMine, selectIsFetchingClaimListMine,
selectPendingClaims,
selectMyClaims, selectMyClaims,
selectMyClaimsWithoutChannels, selectMyClaimsWithoutChannels,
selectMyChannelUrls,
selectMyClaimUrisWithoutChannels, selectMyClaimUrisWithoutChannels,
selectAllMyClaimsByOutpoint, selectAllMyClaimsByOutpoint,
selectMyClaimsOutpoints, selectMyClaimsOutpoints,

View file

@ -9,6 +9,7 @@ import {
selectResolvingUris, selectResolvingUris,
selectClaimsByUri, selectClaimsByUri,
selectMyChannelClaims, selectMyChannelClaims,
selectPendingIds,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doFetchTxoPage } from 'redux/actions/wallet'; import { doFetchTxoPage } from 'redux/actions/wallet';
import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
@ -338,7 +339,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) {
}; };
} }
export function doCreateChannel(name: string, amount: number, optionalParams: any) { export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) {
return (dispatch: Dispatch) => { return (dispatch: Dispatch) => {
dispatch({ dispatch({
type: ACTIONS.CREATE_CHANNEL_STARTED, type: ACTIONS.CREATE_CHANNEL_STARTED,
@ -395,6 +396,11 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an
type: ACTIONS.CREATE_CHANNEL_COMPLETED, type: ACTIONS.CREATE_CHANNEL_COMPLETED,
data: { channelClaim }, data: { channelClaim },
}); });
dispatch({
type: ACTIONS.UPDATE_PENDING_CLAIMS,
data: [channelClaim],
});
dispatch(doCheckPendingClaims(cb));
return channelClaim; return channelClaim;
}) })
.catch(error => { .catch(error => {
@ -408,7 +414,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an
}; };
} }
export function doUpdateChannel(params: any) { export function doUpdateChannel(params: any, cb: any) {
return (dispatch: Dispatch, getState: GetState) => { return (dispatch: Dispatch, getState: GetState) => {
dispatch({ dispatch({
type: ACTIONS.UPDATE_CHANNEL_STARTED, type: ACTIONS.UPDATE_CHANNEL_STARTED,
@ -454,7 +460,15 @@ export function doUpdateChannel(params: any) {
type: ACTIONS.UPDATE_CHANNEL_COMPLETED, type: ACTIONS.UPDATE_CHANNEL_COMPLETED,
data: { channelClaim }, data: { channelClaim },
}); });
dispatch({
type: ACTIONS.UPDATE_PENDING_CLAIMS,
data: {
claims: [channelClaim],
},
});
dispatch(doCheckPendingClaims(cb));
}) })
.then()
.catch(error => { .catch(error => {
dispatch({ dispatch({
type: ACTIONS.UPDATE_CHANNEL_FAILED, type: ACTIONS.UPDATE_CHANNEL_FAILED,
@ -669,3 +683,48 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) {
}).then(success, failure); }).then(success, failure);
}; };
} }
export const doCheckPendingClaims = (onConfirmed: Function) => (
dispatch: Dispatch,
getState: GetState
) => {
let claimCheckInterval;
const checkClaimList = () => {
const state = getState();
const pendingIdSet = new Set(selectPendingIds(state));
Lbry.claim_list({ page: 1, page_size: 10 })
.then(result => {
const claims = result.items;
const claimsToConfirm = [];
claims.forEach(claim => {
const { claim_id: claimId } = claim;
if (claim.confirmations > 0 && pendingIdSet.has(claimId)) {
pendingIdSet.delete(claimId);
claimsToConfirm.push(claim);
if (onConfirmed) {
onConfirmed(claim);
}
}
});
if (claimsToConfirm.length) {
dispatch({
type: ACTIONS.UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claimsToConfirm,
},
});
}
return pendingIdSet.size;
})
.then(len => {
if (!len) {
clearInterval(claimCheckInterval);
}
});
};
claimCheckInterval = setInterval(() => {
checkClaimList();
}, 30000);
};

View file

@ -10,7 +10,6 @@ import { doError } from 'redux/actions/notifications';
import { isClaimNsfw } from 'util/claim'; import { isClaimNsfw } from 'util/claim';
import { import {
selectMyChannelClaims, selectMyChannelClaims,
selectPendingById,
selectMyClaimsWithoutChannels, selectMyClaimsWithoutChannels,
selectReflectingById, selectReflectingById,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
@ -427,46 +426,3 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt
}, 5000); }, 5000);
} }
}; };
export const doCheckPendingPublishes = (onConfirmed: Function) => (
dispatch: Dispatch,
getState: GetState
) => {
let publishCheckInterval;
const checkFileList = () => {
const state = getState();
const pendingById = selectPendingById(state);
Lbry.claim_list({ page: 1, page_size: 10 })
.then(result => {
const claims = result.items;
const claimsToConfirm = [];
claims.forEach(claim => {
if (claim.confirmations > 0 && pendingById[claim.claim_id]) {
delete pendingById[claim.claim_id];
claimsToConfirm.push(claim);
if (onConfirmed) {
onConfirmed(claim);
}
}
});
if (claimsToConfirm.length) {
dispatch({
type: ACTIONS.UPDATE_CONFIRMED_CLAIMS,
data: {
claims: claimsToConfirm,
},
});
}
return Object.keys(pendingById).length;
})
.then(len => {
if (!len) {
clearInterval(publishCheckInterval);
}
});
};
publishCheckInterval = setInterval(() => {
checkFileList();
}, 30000);
};

View file

@ -9,7 +9,7 @@
// - Sean // - Sean
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import { buildURI, parseURI } from 'lbryURI'; import mergeClaim from 'util/merge-claim';
type State = { type State = {
createChannelError: ?string, createChannelError: ?string,
@ -17,10 +17,11 @@ type State = {
claimsByUri: { [string]: string }, claimsByUri: { [string]: string },
byId: { [string]: Claim }, byId: { [string]: Claim },
resolvingUris: Array<string>, resolvingUris: Array<string>,
pendingById: { [string]: Claim }, pendingIds: Array<string>,
reflectingById: { [string]: ReflectingUpdate }, reflectingById: { [string]: ReflectingUpdate },
myClaims: ?Array<string>, myClaims: ?Array<string>,
myChannelClaims: ?Array<string>, myChannelClaims: ?Array<string>,
myChannelUrls: ?Array<string>,
abandoningById: { [string]: boolean }, abandoningById: { [string]: boolean },
fetchingChannelClaims: { [string]: number }, fetchingChannelClaims: { [string]: number },
fetchingMyChannels: boolean, fetchingMyChannels: boolean,
@ -66,6 +67,7 @@ const defaultState = {
fetchingChannelClaims: {}, fetchingChannelClaims: {},
resolvingUris: [], resolvingUris: [],
myChannelClaims: undefined, myChannelClaims: undefined,
myChannelUrls: undefined,
myClaims: undefined, myClaims: undefined,
myPurchases: undefined, myPurchases: undefined,
myPurchasesPageNumber: undefined, myPurchasesPageNumber: undefined,
@ -75,7 +77,7 @@ const defaultState = {
fetchingMyPurchasesError: undefined, fetchingMyPurchasesError: undefined,
fetchingMyChannels: false, fetchingMyChannels: false,
abandoningById: {}, abandoningById: {},
pendingById: {}, pendingIds: [],
reflectingById: {}, reflectingById: {},
claimSearchError: false, claimSearchError: false,
claimSearchByQuery: {}, claimSearchByQuery: {},
@ -112,18 +114,19 @@ function handleClaimAction(state: State, action: any): State {
const byUri = Object.assign({}, state.claimsByUri); const byUri = Object.assign({}, state.claimsByUri);
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const channelClaimCounts = Object.assign({}, state.channelClaimCounts); const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
const pendingIds = state.pendingIds;
let newResolvingUrls = new Set(state.resolvingUris); let newResolvingUrls = new Set(state.resolvingUris);
Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => {
// $FlowFixMe // $FlowFixMe
const { claimsInChannel, stream, channel } = resolveResponse; const { claimsInChannel, stream, channel } = resolveResponse;
if (claimsInChannel) {
channelClaimCounts[url] = claimsInChannel;
channelClaimCounts[channel.canonical_url] = claimsInChannel;
}
if (stream) { if (stream) {
byId[stream.claim_id] = stream; if (pendingIds.includes(stream.claim_id)) {
byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]);// merge them
} else {
byId[stream.claim_id] = stream;
}
byUri[url] = stream.claim_id; byUri[url] = stream.claim_id;
// If url isn't a canonical_url, make sure that is added too // If url isn't a canonical_url, make sure that is added too
@ -135,12 +138,18 @@ function handleClaimAction(state: State, action: any): State {
newResolvingUrls.delete(stream.permanent_url); newResolvingUrls.delete(stream.permanent_url);
} }
if (channel) { if (channel && channel.claim_id) {
if (!stream) { if (claimsInChannel) {
byUri[url] = channel.claim_id; channelClaimCounts[url] = claimsInChannel;
channelClaimCounts[channel.canonical_url] = claimsInChannel;
} }
byUri[url] = channel.claim_id;
byId[channel.claim_id] = channel; if (pendingIds.includes(channel.claim_id)) {
byId[channel.claim_id] = mergeClaim(channel, byId[channel.claim_id]);
} else {
byId[channel.claim_id] = channel;
}
// Also add the permanent_url here until lighthouse returns canonical_url for search results // Also add the permanent_url here until lighthouse returns canonical_url for search results
byUri[channel.permanent_url] = channel.claim_id; byUri[channel.permanent_url] = channel.claim_id;
byUri[channel.canonical_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id;
@ -198,47 +207,37 @@ 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 pendingIds = state.pendingIds || [];
let myClaimIds = new Set(state.myClaims); let myClaimIds = new Set(state.myClaims);
let urlsForCurrentPage = []; let urlsForCurrentPage = [];
const pendingIdSet = new Set(pendingIds);
claims.forEach((claim: Claim) => { claims.forEach((claim: Claim) => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { permanent_url: permanentUri, claim_id: claimId } = claim;
const { claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) { if (claim.type && claim.type.match(/claim|update/)) {
urlsForCurrentPage.push(uri); urlsForCurrentPage.push(permanentUri);
if (claim.confirmations < 1) { if (claim.confirmations < 1) {
pendingById[claimId] = claim; pendingIdSet.add(claimId);
delete byId[claimId]; } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) {
delete byUri[claimId]; pendingIdSet.delete(claimId);
}
if (pendingIds.includes(claimId)) {
byId[claimId] = mergeClaim(claim, byId[claimId]);
} else { } else {
byId[claimId] = claim; byId[claimId] = claim;// just add
byUri[uri] = claimId;
} }
byUri[permanentUri] = claimId;
myClaimIds.add(claimId); myClaimIds.add(claimId);
if (!resolve && pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
}
} }
}); });
// Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0)
if (!resolve) {
Object.values(pendingById)
// $FlowFixMe
.filter(pendingClaim => byId[pendingClaim.claim_id])
.forEach(pendingClaim => {
// $FlowFixMe
delete pendingById[pendingClaim.claim_id];
});
}
return Object.assign({}, state, { return Object.assign({}, state, {
isFetchingClaimListMine: false, isFetchingClaimListMine: false,
myClaims: Array.from(myClaimIds), myClaims: Array.from(myClaimIds),
byId, byId,
pendingIds: Array.from(pendingIdSet),
claimsByUri: byUri, claimsByUri: byUri,
pendingById,
myClaimsPageResults: urlsForCurrentPage, myClaimsPageResults: urlsForCurrentPage,
myClaimsPageNumber: page, myClaimsPageNumber: page,
myClaimsPageTotalResults: totalItems, myClaimsPageTotalResults: totalItems,
@ -252,8 +251,9 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
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); let myClaimIds = new Set(state.myClaims);
const pendingById = Object.assign(state.pendingById); const pendingIds = state.pendingIds || [];
let myChannelClaims; let myChannelClaims;
let myChannelUrls = [];
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 channelClaimCounts = Object.assign({}, state.channelClaimCounts); const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
@ -261,8 +261,10 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
if (!claims.length) { if (!claims.length) {
// $FlowFixMe // $FlowFixMe
myChannelClaims = null; myChannelClaims = null;
myChannelUrls = null;
} else { } else {
myChannelClaims = new Set(state.myChannelClaims); myChannelClaims = new Set(state.myChannelClaims);
myChannelUrls = [];
claims.forEach(claim => { claims.forEach(claim => {
const { meta } = claim; const { meta } = claim;
const { claims_in_channel: claimsInChannel } = claim.meta; const { claims_in_channel: claimsInChannel } = claim.meta;
@ -275,18 +277,11 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
// $FlowFixMe // $FlowFixMe
myChannelClaims.add(claimId); myChannelClaims.add(claimId);
if (!byId[claimId]) { if (!pendingIds.some(c => c === claimId)) {
byId[claimId] = claim; byId[claimId] = claim;
} }
myChannelUrls.push(permanentUrl);
myClaimIds.add(claimId); myClaimIds.add(claimId);
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
}
if (pendingById[claimId] && claim.confirmations > 0) {
delete pendingById[claimId];
}
}); });
} }
@ -296,7 +291,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St
channelClaimCounts, channelClaimCounts,
fetchingMyChannels: false, fetchingMyChannels: false,
myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null,
myClaims: Array.from(myClaimIds), myClaims: myClaimIds ? Array.from(myClaimIds) : null,
myChannelUrls,
}); });
}; };
@ -385,19 +381,31 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State =>
}; };
reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => {
const { claims }: { claims: Array<Claim> } = action.data; const { claims: pendingClaims }: { claims: Array<Claim> } = action.data;
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 pendingIds = state.pendingIds;
const pendingIdSet = new Set(pendingIds);
let myClaimIds = new Set(state.myClaims); let myClaimIds = new Set(state.myClaims);
const myChannelClaims = new Set(state.myChannelClaims);
// $FlowFixMe // $FlowFixMe
claims.forEach((claim: Claim) => { pendingClaims.forEach((claim: Claim) => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); let newClaim;
const { claim_id: claimId } = claim; const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim;
if (claim.type && claim.type.match(/claim|update/)) { pendingIdSet.add(claimId);
pendingById[claimId] = claim; const oldClaim = byId[claimId];
delete byId[claimId]; if (oldClaim && oldClaim.canonical_url) {
newClaim = mergeClaim(oldClaim, claim);
} else {
newClaim = claim;
}
if (valueType === 'channel') {
myChannelClaims.add(claimId);
}
if (type && type.match(/claim|update/)) {
byId[claimId] = newClaim;
byUri[uri] = claimId; byUri[uri] = claimId;
} }
myClaimIds.add(claimId); myClaimIds.add(claimId);
@ -405,32 +413,35 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State =>
return Object.assign({}, state, { return Object.assign({}, state, {
myClaims: Array.from(myClaimIds), myClaims: Array.from(myClaimIds),
byId, byId,
myChannelClaims: Array.from(myChannelClaims),
claimsByUri: byUri, claimsByUri: byUri,
pendingById, pendingIds: Array.from(pendingIdSet),
}); });
}; };
reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => {
const { claims }: { claims: Array<Claim> } = action.data; const { claims: confirmedClaims }: { claims: Array<Claim> } = action.data;
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 pendingIds = state.pendingIds;
let myClaimIds = new Set(state.myClaims); const pendingIdSet = new Set(pendingIds);
claims.forEach((claim: GenericClaim) => { confirmedClaims.forEach((claim: GenericClaim) => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { permanent_url: permanentUri, claim_id: claimId, type } = claim;
const { claim_id: claimId } = claim; let newClaim = claim;
if (claim.type && claim.type.match(/claim|update/)) { const oldClaim = byId[claimId];
delete pendingById[claimId]; if (oldClaim && oldClaim.canonical_url) {
byId[claimId] = claim; newClaim = mergeClaim(oldClaim, claim);
}
if (type && type.match(/claim|update|channel/)) {
byId[claimId] = newClaim;
pendingIdSet.delete(claimId);
} }
myClaimIds.add(claimId);
}); });
return Object.assign({}, state, { return Object.assign({}, state, {
myClaims: Array.from(myClaimIds), pendingIds: Array.from(pendingIdSet),
byId, byId,
claimsByUri: byUri, claimsByUri: byUri,
pendingById,
}); });
}; };
@ -466,19 +477,7 @@ reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({
}); });
reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => {
const channelClaim: ChannelClaim = action.data.channelClaim;
const byId = Object.assign({}, state.byId);
const pendingById = Object.assign({}, state.pendingById);
const myChannelClaims = new Set(state.myChannelClaims);
byId[channelClaim.claim_id] = channelClaim;
pendingById[channelClaim.claim_id] = channelClaim;
myChannelClaims.add(channelClaim.claim_id);
return Object.assign({}, state, { return Object.assign({}, state, {
byId,
pendingById,
myChannelClaims: Array.from(myChannelClaims),
creatingChannel: false, creatingChannel: false,
}); });
}; };
@ -498,13 +497,7 @@ reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State =>
}; };
reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => {
const channelClaim: ChannelClaim = action.data.channelClaim;
const byId = Object.assign({}, state.byId);
byId[channelClaim.claim_id] = channelClaim;
return Object.assign({}, state, { return Object.assign({}, state, {
byId,
updateChannelError: '', updateChannelError: '',
updatingChannel: false, updatingChannel: false,
}); });

View file

@ -6,7 +6,7 @@ import {
} from 'redux/selectors/search'; } from 'redux/selectors/search';
import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { isClaimNsfw, createNormalizedClaimSearchKey, filterClaims } from 'util/claim'; import { isClaimNsfw, filterClaims } from 'util/claim';
import { getSearchQueryString } from 'util/query-params'; import { getSearchQueryString } from 'util/query-params';
import { PAGE_SIZE } from 'constants/claim'; import { PAGE_SIZE } from 'constants/claim';
@ -48,10 +48,9 @@ export const selectRepostError = createSelector(
); );
export const selectClaimsByUri = createSelector( export const selectClaimsByUri = createSelector(
selectState, selectClaimIdsByUri,
selectClaimsById, selectClaimsById,
(state, byId) => { (byUri, byId) => {
const byUri = state.claimsByUri || {};
const claims = {}; const claims = {};
Object.keys(byUri).forEach(uri => { Object.keys(byUri).forEach(uri => {
@ -76,42 +75,25 @@ export const selectAllClaimsByChannel = createSelector(
state => state.paginatedClaimsByChannel || {} state => state.paginatedClaimsByChannel || {}
); );
export const selectPendingById = createSelector( export const selectPendingIds = createSelector(
selectState, selectState,
state => state.pendingById || {} state => state.pendingIds || []
);
export const selectPendingClaims = createSelector(
selectState,
state => Object.values(state.pendingById || [])
); );
export const makeSelectClaimIsPending = (uri: string) => export const makeSelectClaimIsPending = (uri: string) =>
createSelector( createSelector(
selectPendingById, selectClaimIdsByUri,
pendingById => { selectPendingIds,
let claimId; (idsByUri, pendingIds) => {
const claimId = idsByUri(normalizeURI(uri));
try {
const { isChannel, channelClaimId, streamClaimId } = parseURI(uri);
claimId = isChannel ? channelClaimId : streamClaimId;
} catch (e) {}
if (claimId) { if (claimId) {
return Boolean(pendingById[claimId]); return pendingIds.some(i => i === claimId);
} }
return false;
} }
); );
export const makeSelectPendingByUri = (uri: string) =>
createSelector(
selectPendingById,
pendingById => {
const { isChannel, channelClaimId, streamClaimId } = parseURI(uri);
const claimId = isChannel ? channelClaimId : streamClaimId;
return pendingById[claimId];
}
);
export const selectReflectingById = createSelector( export const selectReflectingById = createSelector(
selectState, selectState,
state => state.reflectingById state => state.reflectingById
@ -119,30 +101,21 @@ export const selectReflectingById = createSelector(
export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) =>
createSelector( createSelector(
selectClaimsByUri, selectClaimIdsByUri,
selectPendingById, selectClaimsById,
(byUri, pendingById) => { (byUri, byId) => {
// Check if a claim is pending first let validUri;
// It won't be in claimsByUri because resolving it will return nothing
let valid;
let channelClaimId; let channelClaimId;
let streamClaimId; let streamClaimId;
let isChannel; let isChannel;
try { try {
({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri));
valid = true; validUri = true;
} catch (e) {} } catch (e) {}
if (valid && byUri) { if (validUri && byUri) {
const claimId = isChannel ? channelClaimId : streamClaimId; const claimId = uri && byUri[normalizeURI(uri)];
const pendingClaim = pendingById[claimId]; const claim = byId[claimId];
if (pendingClaim) {
return pendingClaim;
}
const claim = byUri[normalizeURI(uri)];
if (claim === undefined || claim === null) { if (claim === undefined || claim === null) {
// Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined)
return claim; return claim;
@ -456,8 +429,7 @@ export const selectMyClaims = createSelector(
selectMyActiveClaims, selectMyActiveClaims,
selectClaimsById, selectClaimsById,
selectAbandoningIds, selectAbandoningIds,
selectPendingClaims, (myClaimIds, byId, abandoningIds) => {
(myClaimIds, byId, abandoningIds, pendingClaims) => {
const claims = []; const claims = [];
myClaimIds.forEach(id => { myClaimIds.forEach(id => {
@ -466,7 +438,7 @@ export const selectMyClaims = createSelector(
if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim);
}); });
return [...claims, ...pendingClaims]; return [...claims];
} }
); );
@ -495,6 +467,11 @@ export const selectMyClaimUrisWithoutChannels = createSelector(
} }
); );
export const selectMyChannelUrls = createSelector(
selectState,
state => state.myChannelUrls
);
export const selectAllMyClaimsByOutpoint = createSelector( export const selectAllMyClaimsByOutpoint = createSelector(
selectMyClaimsRaw, selectMyClaimsRaw,
claims => claims =>

7
src/util/merge-claim.js Normal file
View file

@ -0,0 +1,7 @@
/*
new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] }
*/
export default function mergeClaims(maybeResolved, pending){
return { ...maybeResolved, ...pending, meta: maybeResolved.meta };
}