diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b477130..6ed46ed 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -7,6 +7,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau require('proxy-polyfill'); var uuid = require('uuid'); var reselect = require('reselect'); +var reReselect = require('re-reselect'); var fromEntries = _interopDefault(require('@ungap/from-entries')); const MINIMUM_PUBLISH_BID = 0.00000001; @@ -2405,15 +2406,14 @@ var _extends$3 = Object.assign || function (target) { for (var i = 1; i < argume const selectState$1 = state => state.claims || {}; -const selectById = reselect.createSelector(selectState$1, state => state.byId || {}); - -const selectPendingClaimsById = reselect.createSelector(selectState$1, state => state.pendingById || {}); +const selectById = state => selectState$1(state).byId || {}; +const selectPendingClaimsById = state => selectState$1(state).pendingById || {}; const selectClaimsById = reselect.createSelector(selectById, selectPendingClaimsById, (byId, pendingById) => { return Object.assign(byId, pendingById); // do I need merged to keep metadata? }); -const selectClaimIdsByUri = reselect.createSelector(selectState$1, state => state.claimsByUri || {}); +const selectClaimIdsByUri = state => selectState$1(state).claimsByUri || {}; const selectCurrentChannelPage = reselect.createSelector(selectState$1, state => state.currentChannelPage || 1); @@ -2469,6 +2469,45 @@ const selectReflectingById = reselect.createSelector(selectState$1, state => sta const makeSelectClaimForClaimId = claimId => reselect.createSelector(selectClaimsById, byId => byId[claimId]); +// Compare with makeSelectClaimForUri just down below +const selectClaimForUri = reReselect.createCachedSelector(selectClaimIdsByUri, selectClaimsById, (state, uri) => uri, (state, uri, returnRepost = true) => returnRepost, (byUri, byId, uri, returnRepost) => { + console.log(' selectClaimForUri'); + + let validUri; + let channelClaimId; + let streamClaimId; + let isChannel; + try { + ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); + validUri = true; + } catch (e) {} + + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; + + // 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) + if (claimId === null) { + return null; + } else if (claimId === undefined) { + return undefined; + } + + const repostedClaim = claim && claim.reposted_claim; + if (repostedClaim && returnRepost) { + const channelUrl = claim.signing_channel && (claim.signing_channel.canonical_url || claim.signing_channel.permanent_url); + + return _extends$3({}, repostedClaim, { + repost_url: normalizeURI(uri), + repost_channel_url: channelUrl, + repost_bid_amount: claim && claim.meta && claim.meta.effective_amount + }); + } else { + return claim; + } + } +})((state, uri, returnRepost = true) => `${uri}:${returnRepost ? '1' : '0'}`); + const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { let validUri; let channelClaimId; @@ -2605,6 +2644,11 @@ const makeSelectTotalPagesInChannelSearch = uri => reselect.createSelector(selec return byChannel['pageCount']; }); +const selectMetadataForUri = reReselect.createCachedSelector(selectClaimForUri, (claim, uri) => { + const metadata = claim && claim.value; + return metadata || (claim === undefined ? undefined : null); +})((state, uri) => uri); + const makeSelectMetadataForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const metadata = claim && claim.value; return metadata || (claim === undefined ? undefined : null); @@ -2616,6 +2660,18 @@ const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeS const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); +// Compare with makeSelectDateForUri just down below +const selectDateForUri = reReselect.createCachedSelector(selectClaimForUri, // (state, uri, ?returnRepost) +claim => { + console.log(' selectDateForUri'); + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null); + if (!timestamp) { + return undefined; + } + const dateObj = new Date(timestamp); + return dateObj; +})((state, uri) => uri); + const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null); if (!timestamp) { @@ -2809,6 +2865,10 @@ const makeSelectMyChannelPermUrlForName = name => reselect.createSelector(select return matchingClaim ? matchingClaim.permanent_url : null; }); +const selectTagsForUri = reReselect.createCachedSelector(selectMetadataForUri, metadata => { + return metadata && metadata.tags || []; +})((state, uri) => uri); + const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => { return metadata && metadata.tags || []; }); @@ -8147,6 +8207,7 @@ exports.selectBlocks = selectBlocks; exports.selectBuiltinCollections = selectBuiltinCollections; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelImportPending = selectChannelImportPending; +exports.selectClaimForUri = selectClaimForUri; exports.selectClaimIdsByUri = selectClaimIdsByUri; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; @@ -8158,6 +8219,7 @@ exports.selectCreateCollectionError = selectCreateCollectionError; exports.selectCreatingChannel = selectCreatingChannel; exports.selectCreatingCollection = selectCreatingCollection; exports.selectCurrentChannelPage = selectCurrentChannelPage; +exports.selectDateForUri = selectDateForUri; exports.selectDownloadUrlsCount = selectDownloadUrlsCount; exports.selectDownloadedUris = selectDownloadedUris; exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; @@ -8195,6 +8257,7 @@ exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; exports.selectIsSendingSupport = selectIsSendingSupport; exports.selectIsStillEditing = selectIsStillEditing; exports.selectIsWalletReconnecting = selectIsWalletReconnecting; +exports.selectMetadataForUri = selectMetadataForUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; exports.selectMyChannelUrls = selectMyChannelUrls; @@ -8236,6 +8299,7 @@ exports.selectResolvingUris = selectResolvingUris; exports.selectSavedCollectionIds = selectSavedCollectionIds; exports.selectSupportsBalance = selectSupportsBalance; exports.selectSupportsByOutpoint = selectSupportsByOutpoint; +exports.selectTagsForUri = selectTagsForUri; exports.selectTakeOverAmount = selectTakeOverAmount; exports.selectTipsBalance = selectTipsBalance; exports.selectToast = selectToast; diff --git a/dist/flow-typed/rereselect.js b/dist/flow-typed/rereselect.js new file mode 100644 index 0000000..31b8179 --- /dev/null +++ b/dist/flow-typed/rereselect.js @@ -0,0 +1,6 @@ +// @flow +// We should be using the `reselect` that comes with flow-typed but it's going to take a ton of work to get that working +// without any errors. For now it's any type +declare module 're-reselect' { + declare module.exports: any; +} diff --git a/flow-typed/rereselect.js b/flow-typed/rereselect.js new file mode 100644 index 0000000..31b8179 --- /dev/null +++ b/flow-typed/rereselect.js @@ -0,0 +1,6 @@ +// @flow +// We should be using the `reselect` that comes with flow-typed but it's going to take a ton of work to get that working +// without any errors. For now it's any type +declare module 're-reselect' { + declare module.exports: any; +} diff --git a/package.json b/package.json index dc6bc25..a74596a 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dependencies": { "@ungap/from-entries": "^0.2.1", "proxy-polyfill": "0.1.6", + "re-reselect": "^4.0.0", "reselect": "^3.0.0", "uuid": "^8.3.1" }, diff --git a/src/index.js b/src/index.js index 079665f..d812678 100644 --- a/src/index.js +++ b/src/index.js @@ -189,20 +189,24 @@ export { } from 'redux/selectors/collections'; export { + selectClaimForUri, makeSelectClaimForUri, makeSelectClaimIsMine, makeSelectFetchingChannelClaims, makeSelectClaimsInChannelForPage, makeSelectTotalPagesInChannelSearch, makeSelectTotalClaimsInChannelSearch, + selectMetadataForUri, makeSelectMetadataForUri, makeSelectMetadataItemForUri, makeSelectThumbnailForUri, makeSelectCoverForUri, makeSelectTitleForUri, + selectDateForUri, makeSelectDateForUri, makeSelectAmountForUri, makeSelectEffectiveAmountForUri, + selectTagsForUri, makeSelectTagsForUri, makeSelectTagInClaimOrChannelForUri, makeSelectTotalStakedAmountForChannelUri, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index f5a03ed..f439663 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -2,20 +2,16 @@ import { normalizeURI, parseURI } from 'lbryURI'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; +import { createCachedSelector } from 're-reselect'; import { isClaimNsfw, filterClaims } from 'util/claim'; import * as CLAIM from 'constants/claim'; +type State = { claims: any }; + const selectState = state => state.claims || {}; -export const selectById = createSelector( - selectState, - state => state.byId || {} -); - -export const selectPendingClaimsById = createSelector( - selectState, - state => state.pendingById || {} -); +export const selectById = (state: State) => selectState(state).byId || {}; +export const selectPendingClaimsById = (state: State) => selectState(state).pendingById || {}; export const selectClaimsById = createSelector( selectById, @@ -25,10 +21,7 @@ export const selectClaimsById = createSelector( } ); -export const selectClaimIdsByUri = createSelector( - selectState, - state => state.claimsByUri || {} -); +export const selectClaimIdsByUri = (state: State) => selectState(state).claimsByUri || {}; export const selectCurrentChannelPage = createSelector( selectState, @@ -132,6 +125,54 @@ export const makeSelectClaimForClaimId = (claimId: string) => byId => byId[claimId] ); +// Compare with makeSelectClaimForUri just down below +export const selectClaimForUri = createCachedSelector( + selectClaimIdsByUri, + selectClaimsById, + (state, uri) => uri, + (state, uri, returnRepost = true) => returnRepost, + (byUri, byId, uri, returnRepost) => { + console.log(' selectClaimForUri'); + + let validUri; + let channelClaimId; + let streamClaimId; + let isChannel; + try { + ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); + validUri = true; + } catch (e) {} + + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; + + // 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) + if (claimId === null) { + return null; + } else if (claimId === undefined) { + return undefined; + } + + const repostedClaim = claim && claim.reposted_claim; + if (repostedClaim && returnRepost) { + const channelUrl = + claim.signing_channel && + (claim.signing_channel.canonical_url || claim.signing_channel.permanent_url); + + return { + ...repostedClaim, + repost_url: normalizeURI(uri), + repost_channel_url: channelUrl, + repost_bid_amount: claim && claim.meta && claim.meta.effective_amount, + }; + } else { + return claim; + } + } + } +)((state, uri, returnRepost = true) => `${uri}:${returnRepost ? '1' : '0'}`); + export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( selectClaimIdsByUri, @@ -299,8 +340,8 @@ export const makeSelectMyPurchasesForPage = (query: ?string, page: number = 1) = const end = Number(page) * Number(CLAIM.PAGE_SIZE); return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos - .slice(start, end) - .map(fileInfo => fileInfo.canonical_url || fileInfo.permanent_url) + .slice(start, end) + .map(fileInfo => fileInfo.canonical_url || fileInfo.permanent_url) : []; } ); @@ -360,6 +401,11 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) => } ); +export const selectMetadataForUri = createCachedSelector(selectClaimForUri, (claim, uri) => { + const metadata = claim && claim.value; + return metadata || (claim === undefined ? undefined : null); +})((state, uri) => uri); + export const makeSelectMetadataForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), @@ -383,6 +429,27 @@ export const makeSelectTitleForUri = (uri: string) => metadata => metadata && metadata.title ); +// Compare with makeSelectDateForUri just down below +export const selectDateForUri = createCachedSelector( + selectClaimForUri, // (state, uri, ?returnRepost) + claim => { + console.log(' selectDateForUri'); + const timestamp = + claim && + claim.value && + (claim.value.release_time + ? claim.value.release_time * 1000 + : claim.meta && claim.meta.creation_timestamp + ? claim.meta.creation_timestamp * 1000 + : null); + if (!timestamp) { + return undefined; + } + const dateObj = new Date(timestamp); + return dateObj; + } +)((state, uri) => uri); + export const makeSelectDateForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), @@ -393,8 +460,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -723,6 +790,13 @@ export const makeSelectMyChannelPermUrlForName = (name: string) => } ); +export const selectTagsForUri = createCachedSelector( + selectMetadataForUri, + (metadata: ?GenericMetadata) => { + return (metadata && metadata.tags) || []; + } +)((state, uri) => uri); + export const makeSelectTagsForUri = (uri: string) => createSelector( makeSelectMetadataForUri(uri), diff --git a/yarn.lock b/yarn.lock index af93714..018e6a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6755,6 +6755,11 @@ randomatic@^3.0.0: kind-of "^6.0.0" math-random "^1.0.1" +re-reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/re-reselect/-/re-reselect-4.0.0.tgz#9ddec4c72c4d952f68caa5aa4b76a9ed38b75cac" + integrity sha512-wuygyq8TXUlSdVXv2kigXxQNOgdb9m7LbIjwfTNGSpaY1riLd5e+VeQjlQMyUtrk0oiyhi1AqIVynworl3qxHA== + react-is@^16.12.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"