2018-04-05 03:57:29 +01:00
|
|
|
import { normalizeURI } from 'lbryURI';
|
|
|
|
import { makeSelectCurrentParam } from 'redux/selectors/navigation';
|
2018-08-01 23:31:51 -04:00
|
|
|
import { selectSearchUrisByQuery } from 'redux/selectors/search';
|
2018-01-11 13:12:37 +01:00
|
|
|
import { createSelector } from 'reselect';
|
2018-07-10 19:15:39 -04:00
|
|
|
import { isClaimNsfw } from 'util/claim';
|
2018-01-11 13:12:37 +01:00
|
|
|
|
|
|
|
const selectState = state => state.claims || {};
|
|
|
|
|
|
|
|
export const selectClaimsById = createSelector(selectState, state => state.byId || {});
|
|
|
|
|
|
|
|
export const selectClaimsByUri = createSelector(selectState, selectClaimsById, (state, byId) => {
|
|
|
|
const byUri = state.claimsByUri || {};
|
|
|
|
const claims = {};
|
|
|
|
|
|
|
|
Object.keys(byUri).forEach(uri => {
|
|
|
|
const claimId = byUri[uri];
|
|
|
|
|
|
|
|
// NOTE returning a null claim allows us to differentiate between an
|
|
|
|
// undefined (never fetched claim) and one which just doesn't exist. Not
|
|
|
|
// the cleanest solution but couldn't think of anything better right now
|
|
|
|
if (claimId === null) {
|
|
|
|
claims[uri] = null;
|
|
|
|
} else {
|
|
|
|
claims[uri] = byId[claimId];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return claims;
|
2018-04-05 03:57:29 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
export const selectAllClaimsByChannel = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.claimsByChannel || {}
|
|
|
|
);
|
|
|
|
|
|
|
|
export const makeSelectClaimForUri = uri =>
|
|
|
|
createSelector(selectClaimsByUri, claims => claims && claims[normalizeURI(uri)]);
|
|
|
|
|
|
|
|
export const selectMyClaimsRaw = createSelector(selectState, state => state.myClaims);
|
|
|
|
|
|
|
|
export const selectAbandoningIds = createSelector(selectState, state =>
|
|
|
|
Object.keys(state.abandoningById || {})
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectMyActiveClaims = createSelector(
|
|
|
|
selectMyClaimsRaw,
|
|
|
|
selectAbandoningIds,
|
|
|
|
(claims, abandoningIds) =>
|
|
|
|
new Set(
|
|
|
|
claims &&
|
|
|
|
claims
|
|
|
|
.map(claim => claim.claim_id)
|
|
|
|
.filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
export const makeSelectClaimIsMine = rawUri => {
|
|
|
|
const uri = normalizeURI(rawUri);
|
|
|
|
return createSelector(
|
|
|
|
selectClaimsByUri,
|
|
|
|
selectMyActiveClaims,
|
|
|
|
(claims, myClaims) =>
|
|
|
|
claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const selectAllFetchingChannelClaims = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.fetchingChannelClaims || {}
|
|
|
|
);
|
|
|
|
|
|
|
|
export const makeSelectFetchingChannelClaims = uri =>
|
|
|
|
createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]);
|
|
|
|
|
2018-05-25 12:34:12 +01:00
|
|
|
export const makeSelectClaimsInChannelForPage = (uri, page) =>
|
|
|
|
createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => {
|
|
|
|
const byChannel = allClaims[uri] || {};
|
|
|
|
const claimIds = byChannel[page || 1];
|
|
|
|
|
|
|
|
if (!claimIds) return claimIds;
|
|
|
|
|
|
|
|
return claimIds.map(claimId => byId[claimId]);
|
|
|
|
});
|
|
|
|
|
2018-04-05 03:57:29 +01:00
|
|
|
export const makeSelectClaimsInChannelForCurrentPage = uri => {
|
|
|
|
const pageSelector = makeSelectCurrentParam('page');
|
|
|
|
|
|
|
|
return createSelector(
|
|
|
|
selectClaimsById,
|
|
|
|
selectAllClaimsByChannel,
|
|
|
|
pageSelector,
|
|
|
|
(byId, allClaims, page) => {
|
|
|
|
const byChannel = allClaims[uri] || {};
|
|
|
|
const claimIds = byChannel[page || 1];
|
|
|
|
|
|
|
|
if (!claimIds) return claimIds;
|
|
|
|
|
|
|
|
return claimIds.map(claimId => byId[claimId]);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const makeSelectMetadataForUri = uri =>
|
|
|
|
createSelector(makeSelectClaimForUri(uri), claim => {
|
|
|
|
const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata;
|
|
|
|
|
|
|
|
return metadata || (claim === undefined ? undefined : null);
|
|
|
|
});
|
|
|
|
|
|
|
|
export const makeSelectTitleForUri = uri =>
|
|
|
|
createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title);
|
|
|
|
|
|
|
|
export const makeSelectContentTypeForUri = uri =>
|
|
|
|
createSelector(makeSelectClaimForUri(uri), claim => {
|
|
|
|
const source = claim && claim.value && claim.value.stream && claim.value.stream.source;
|
|
|
|
return source ? source.contentType : undefined;
|
|
|
|
});
|
|
|
|
|
|
|
|
export const selectIsFetchingClaimListMine = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.isFetchingClaimListMine
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectPendingClaims = createSelector(selectState, state =>
|
|
|
|
Object.values(state.pendingById || {})
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectMyClaims = createSelector(
|
|
|
|
selectMyActiveClaims,
|
|
|
|
selectClaimsById,
|
|
|
|
selectAbandoningIds,
|
|
|
|
selectPendingClaims,
|
|
|
|
(myClaimIds, byId, abandoningIds, pendingClaims) => {
|
|
|
|
const claims = [];
|
|
|
|
|
|
|
|
myClaimIds.forEach(id => {
|
|
|
|
const claim = byId[id];
|
|
|
|
|
|
|
|
if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim);
|
|
|
|
});
|
|
|
|
|
|
|
|
return [...claims, ...pendingClaims];
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectMyClaimsWithoutChannels = createSelector(selectMyClaims, myClaims =>
|
|
|
|
myClaims.filter(claim => !claim.name.match(/^@/))
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectAllMyClaimsByOutpoint = createSelector(
|
|
|
|
selectMyClaimsRaw,
|
|
|
|
claims =>
|
|
|
|
new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectMyClaimsOutpoints = createSelector(selectMyClaims, myClaims => {
|
|
|
|
const outpoints = [];
|
|
|
|
|
|
|
|
myClaims.forEach(claim => outpoints.push(`${claim.txid}:${claim.nout}`));
|
|
|
|
|
|
|
|
return outpoints;
|
|
|
|
});
|
|
|
|
|
|
|
|
export const selectFetchingMyChannels = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.fetchingMyChannels
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectMyChannelClaims = createSelector(
|
|
|
|
selectState,
|
|
|
|
selectClaimsById,
|
|
|
|
(state, byId) => {
|
|
|
|
const ids = state.myChannelClaims || [];
|
|
|
|
const claims = [];
|
|
|
|
|
|
|
|
ids.forEach(id => {
|
|
|
|
if (byId[id]) {
|
2018-07-12 16:42:08 -04:00
|
|
|
// 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
|
2018-04-05 03:57:29 +01:00
|
|
|
claims.push(byId[id]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return claims;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectResolvingUris = createSelector(selectState, state => state.resolvingUris || []);
|
|
|
|
|
|
|
|
export const makeSelectIsUriResolving = uri =>
|
|
|
|
createSelector(
|
|
|
|
selectResolvingUris,
|
|
|
|
resolvingUris => resolvingUris && resolvingUris.indexOf(uri) !== -1
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectFeaturedUris = createSelector(selectState, state => state.featuredUris);
|
|
|
|
|
|
|
|
export const selectFetchingFeaturedUris = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.fetchingFeaturedContent
|
|
|
|
);
|
|
|
|
|
2018-06-06 01:24:01 +01:00
|
|
|
export const selectTrendingUris = createSelector(selectState, state => state.trendingUris);
|
|
|
|
|
|
|
|
export const selectFetchingTrendingUris = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.fetchingTrendingContent
|
|
|
|
);
|
|
|
|
|
2018-04-05 03:57:29 +01:00
|
|
|
export const selectPlayingUri = createSelector(selectState, state => state.playingUri);
|
|
|
|
|
|
|
|
export const selectChannelClaimCounts = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.channelClaimCounts || {}
|
|
|
|
);
|
|
|
|
|
|
|
|
export const makeSelectTotalItemsForChannel = uri =>
|
|
|
|
createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]);
|
|
|
|
|
|
|
|
export const makeSelectTotalPagesForChannel = uri =>
|
|
|
|
createSelector(
|
|
|
|
selectChannelClaimCounts,
|
|
|
|
byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / 10)
|
|
|
|
);
|
|
|
|
|
|
|
|
export const selectRewardContentClaimIds = createSelector(
|
|
|
|
selectState,
|
|
|
|
state => state.rewardedContentClaimIds
|
|
|
|
);
|
2018-07-10 19:15:39 -04:00
|
|
|
|
|
|
|
export const makeSelectNsfwCountFromUris = uris =>
|
|
|
|
createSelector(selectClaimsByUri, claims =>
|
|
|
|
uris.reduce((acc, uri) => {
|
|
|
|
const claim = claims[uri];
|
|
|
|
if (isClaimNsfw(claim)) {
|
|
|
|
return acc + 1;
|
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, 0)
|
|
|
|
);
|
|
|
|
|
|
|
|
export const makeSelectNsfwCountForChannel = uri => {
|
|
|
|
const pageSelector = makeSelectCurrentParam('page');
|
|
|
|
|
|
|
|
return createSelector(
|
|
|
|
selectClaimsById,
|
|
|
|
selectAllClaimsByChannel,
|
|
|
|
pageSelector,
|
|
|
|
(byId, allClaims, page) => {
|
|
|
|
const byChannel = allClaims[uri] || {};
|
|
|
|
const claimIds = byChannel[page || 1];
|
|
|
|
|
|
|
|
if (!claimIds) return 0;
|
|
|
|
|
|
|
|
return claimIds.reduce((acc, claimId) => {
|
|
|
|
const claim = byId[claimId];
|
|
|
|
if (isClaimNsfw(claim)) {
|
|
|
|
return acc + 1;
|
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
2018-08-01 23:31:51 -04:00
|
|
|
|
|
|
|
export const makeSelectRecommendedContentForUri = uri =>
|
|
|
|
createSelector(
|
|
|
|
makeSelectClaimForUri(uri),
|
|
|
|
selectSearchUrisByQuery,
|
|
|
|
(claim, searchUrisByQuery) => {
|
|
|
|
let recommendedContent;
|
|
|
|
|
|
|
|
if (claim) {
|
|
|
|
const {
|
|
|
|
value: {
|
|
|
|
stream: {
|
|
|
|
metadata: { title },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
} = claim;
|
2018-08-22 16:02:20 -04:00
|
|
|
let searchUris = searchUrisByQuery[title.replace(/\//, ' ')];
|
2018-08-01 23:31:51 -04:00
|
|
|
if (searchUris) {
|
|
|
|
searchUris = searchUris.filter(searchUri => searchUri !== uri);
|
|
|
|
recommendedContent = searchUris;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return recommendedContent;
|
|
|
|
}
|
|
|
|
);
|