From c7021a08ade7b2c6810bf869db703be4c73011e2 Mon Sep 17 00:00:00 2001 From: jessopb <36554050+jessopb@users.noreply.github.com> Date: Wed, 19 Jan 2022 20:46:01 -0500 Subject: [PATCH] Selector refactors (#7424) * Attempt to speed up sidebar menu for mobile (#283) * Exclude default homepage data at compile time The youtuber IDs alone is pretty huge, and is unused in the `CUSTOM_HOMEPAGE=true` configuration. * Remove Desktop items and other cleanup - Moved constants out of the component. - Remove SIMPLE_SITE check. - Remove Desktop-only items * Sidebar: limit subscription and tag section Too slow for huge lists Limit to 10 initially, and load everything on "Show more" * Fix makeSelectThumbnailForUri - Fix memo - Expose function to extract directly from claim if client already have it. * Fix and optimize makeSelectIsSubscribed (#273) - It will not return true if the uri provided is canonical, because the compared subscription uri is in permanent form. This was causing certain elements like the Heart to not appear in claim tiles. - It is super slow for large subscriptions not just because of the array size + being a hot selector, but also because it is looking up the claim twice (not memo'd) and also calling `parseURI` to determine if it's a channel, which is unnecessary if you already have the claim. - Optimize the selector to only look up the claim once, and make operations using already-obtained info. * Simplify makeSelectTitleForUri No need to memo given no transformation. * Simplify makeSelectIsUriResolving - Memo not required. `resolvingUris` is very dynamic and is a short array anyways. - Changeg from using `indexOf` to `includes`, which is more concise. * Cost Info selector fixes - no memo required since they are just directly accessing the store. Co-authored-by: infinite-persistence <64950861+infinite-persistence@users.noreply.github.com> Co-authored-by: infinite-persistence --- extras/lbryinc/index.js | 4 +- extras/lbryinc/redux/selectors/cost_info.js | 23 ++++--- ui/component/channelForm/index.js | 8 +-- .../channelMentionSuggestion/index.js | 6 +- .../channelMentionTopSuggestion/index.js | 4 +- ui/component/channelThumbnail/index.js | 8 +-- ui/component/channelTitle/index.js | 4 +- .../claimInsufficientCredits/index.js | 4 +- ui/component/claimLink/index.js | 4 +- ui/component/claimMenuList/index.js | 4 +- ui/component/claimPreview/index.js | 18 +++--- ui/component/claimPreviewTile/index.js | 20 +++--- ui/component/claimPreviewTitle/index.js | 4 +- ui/component/claimProperties/index.js | 4 +- ui/component/collectionEdit/index.js | 8 +-- .../collectionPreviewOverlay/index.js | 4 +- ui/component/collectionPreviewTile/index.js | 12 ++-- ui/component/comment/index.js | 6 +- ui/component/embedPlayButton/index.js | 8 +-- ui/component/fileActions/index.js | 4 +- ui/component/fileDownloadLink/index.js | 4 +- ui/component/filePrice/index.js | 6 +- ui/component/fileRender/index.js | 4 +- ui/component/fileRenderFloating/index.js | 8 +-- ui/component/fileRenderInitiator/index.js | 16 ++--- ui/component/fileRenderInline/index.js | 4 +- ui/component/fileTitle/index.js | 4 +- ui/component/fileTitleSection/index.js | 10 +-- ui/component/fileViewerEmbeddedTitle/index.js | 4 +- ui/component/invited/index.js | 10 +-- ui/component/previewLink/index.js | 12 ++-- .../previewOverlayProperties/index.js | 4 +- ui/component/repostCreate/index.js | 10 +-- ui/component/router/index.js | 4 +- ui/component/searchTopClaim/index.js | 4 +- ui/component/socialShare/index.js | 4 +- ui/component/subscribeButton/index.js | 4 +- ui/component/uriIndicator/index.js | 4 +- ui/component/viewers/videoViewer/index.js | 4 +- ui/component/walletSendTip/index.js | 4 +- ui/component/wunderbarSuggestion/index.js | 6 +- ui/component/wunderbarTopSuggestion/index.js | 4 +- ui/modal/modalRemoveFile/index.js | 8 +-- ui/page/channel/index.js | 12 ++-- ui/page/collection/index.js | 8 +-- ui/page/file/index.js | 4 +- ui/page/show/index.js | 8 +-- ui/redux/actions/content.js | 4 +- ui/redux/actions/file.js | 2 +- ui/redux/actions/search.js | 2 +- ui/redux/selectors/claims.js | 62 ++++++++++++++----- ui/redux/selectors/content.js | 38 +++++++----- ui/redux/selectors/search.js | 16 ++--- ui/redux/selectors/subscriptions.js | 41 +++++------- ui/util/buildHomepage.js | 53 +++++++++------- 55 files changed, 291 insertions(+), 258 deletions(-) diff --git a/extras/lbryinc/index.js b/extras/lbryinc/index.js index 2d86de5fd..df1b0f823 100644 --- a/extras/lbryinc/index.js +++ b/extras/lbryinc/index.js @@ -38,8 +38,8 @@ export { syncReducer } from './redux/reducers/sync'; // selectors export { selectAuthToken, selectIsAuthenticating } from './redux/selectors/auth'; export { - makeSelectFetchingCostInfoForUri, - makeSelectCostInfoForUri, + selectFetchingCostInfoForUri, + selectCostInfoForUri, selectAllCostInfoByUri, selectFetchingCostInfo, } from './redux/selectors/cost_info'; diff --git a/extras/lbryinc/redux/selectors/cost_info.js b/extras/lbryinc/redux/selectors/cost_info.js index b510c7c84..8d5103715 100644 --- a/extras/lbryinc/redux/selectors/cost_info.js +++ b/extras/lbryinc/redux/selectors/cost_info.js @@ -1,13 +1,16 @@ -import { createSelector } from 'reselect'; +// @flow +type State = { costInfo: any }; -export const selectState = state => state.costInfo || {}; +export const selectState = (state: State) => state.costInfo || {}; +export const selectAllCostInfoByUri = (state: State) => selectState(state).byUri; +export const selectFetchingCostInfo = (state: State) => selectState(state).fetching; -export const selectAllCostInfoByUri = createSelector(selectState, state => state.byUri || {}); +export const selectCostInfoForUri = (state: State, uri: string) => { + const costInfos = selectAllCostInfoByUri(state); + return costInfos && costInfos[uri]; +}; -export const makeSelectCostInfoForUri = uri => - createSelector(selectAllCostInfoByUri, costInfos => costInfos && costInfos[uri]); - -export const selectFetchingCostInfo = createSelector(selectState, state => state.fetching || {}); - -export const makeSelectFetchingCostInfoForUri = uri => - createSelector(selectFetchingCostInfo, fetchingByUri => fetchingByUri && fetchingByUri[uri]); +export const selectFetchingCostInfoForUri = (state: State, uri: string) => { + const fetchingByUri = selectFetchingCostInfo(state); + return fetchingByUri && fetchingByUri[uri]; +}; diff --git a/ui/component/channelForm/index.js b/ui/component/channelForm/index.js index 43e054f7e..9e08c2f93 100644 --- a/ui/component/channelForm/index.js +++ b/ui/component/channelForm/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { - makeSelectTitleForUri, - makeSelectThumbnailForUri, + selectTitleForUri, + selectThumbnailForUri, makeSelectCoverForUri, makeSelectMetadataItemForUri, makeSelectAmountForUri, @@ -21,8 +21,8 @@ import ChannelForm from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), - thumbnailUrl: makeSelectThumbnailForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), + thumbnailUrl: selectThumbnailForUri(state, props.uri), coverUrl: makeSelectCoverForUri(props.uri)(state), description: makeSelectMetadataItemForUri(props.uri, 'description')(state), website: makeSelectMetadataItemForUri(props.uri, 'website_url')(state), diff --git a/ui/component/channelMentionSuggestion/index.js b/ui/component/channelMentionSuggestion/index.js index afc418ce7..787502cc3 100644 --- a/ui/component/channelMentionSuggestion/index.js +++ b/ui/component/channelMentionSuggestion/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; +import { selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims'; import ChannelMentionSuggestion from './view'; const select = (state, props) => ({ - claim: makeSelectClaimForUri(props.uri)(state), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), + claim: selectClaimForUri(state, props.uri), + isResolvingUri: selectIsUriResolving(state, props.uri), }); export default connect(select)(ChannelMentionSuggestion); diff --git a/ui/component/channelMentionTopSuggestion/index.js b/ui/component/channelMentionTopSuggestion/index.js index 54d1f6786..2d21fda09 100644 --- a/ui/component/channelMentionTopSuggestion/index.js +++ b/ui/component/channelMentionTopSuggestion/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectIsUriResolving } from 'redux/selectors/claims'; +import { selectIsUriResolving } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import { makeSelectWinningUriForQuery } from 'redux/selectors/search'; import ChannelMentionTopSuggestion from './view'; @@ -8,7 +8,7 @@ const select = (state, props) => { const uriFromQuery = `lbry://${props.query}`; return { uriFromQuery, - isResolvingUri: makeSelectIsUriResolving(uriFromQuery)(state), + isResolvingUri: selectIsUriResolving(state, uriFromQuery), winningUri: makeSelectWinningUriForQuery(props.query)(state), }; }; diff --git a/ui/component/channelThumbnail/index.js b/ui/component/channelThumbnail/index.js index ebedaff1a..cbe02fc88 100644 --- a/ui/component/channelThumbnail/index.js +++ b/ui/component/channelThumbnail/index.js @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; -import { makeSelectThumbnailForUri, makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; +import { selectThumbnailForUri, selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import ChannelThumbnail from './view'; const select = (state, props) => ({ - thumbnail: makeSelectThumbnailForUri(props.uri)(state), - claim: makeSelectClaimForUri(props.uri)(state), - isResolving: makeSelectIsUriResolving(props.uri)(state), + thumbnail: selectThumbnailForUri(state, props.uri), + claim: selectClaimForUri(state, props.uri), + isResolving: selectIsUriResolving(state, props.uri), }); export default connect(select, { diff --git a/ui/component/channelTitle/index.js b/ui/component/channelTitle/index.js index d98e83683..13322c3f5 100644 --- a/ui/component/channelTitle/index.js +++ b/ui/component/channelTitle/index.js @@ -1,9 +1,9 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims'; import ChannelTitle from './view'; const select = (state, props) => ({ - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), claim: makeSelectClaimForUri(props.uri)(state), }); diff --git a/ui/component/claimInsufficientCredits/index.js b/ui/component/claimInsufficientCredits/index.js index 3a0230ea4..e8326006c 100644 --- a/ui/component/claimInsufficientCredits/index.js +++ b/ui/component/claimInsufficientCredits/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; -import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; +import { selectInsufficientCreditsForUri } from 'redux/selectors/content'; import { makeSelectClaimWasPurchased } from 'redux/selectors/claims'; import ClaimInsufficientCredits from './view'; const select = (state, props) => ({ - isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), + isInsufficientCredits: selectInsufficientCreditsForUri(state, props.uri), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), }); diff --git a/ui/component/claimLink/index.js b/ui/component/claimLink/index.js index ea4ab51b3..21363a527 100644 --- a/ui/component/claimLink/index.js +++ b/ui/component/claimLink/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import { doSetPlayingUri } from 'redux/actions/content'; import { punctuationMarks } from 'util/remark-lbry'; @@ -25,7 +25,7 @@ const select = (state, props) => { uri, claim, fullUri: props.uri, - isResolvingUri: makeSelectIsUriResolving(uri)(state), + isResolvingUri: selectIsUriResolving(state, uri), blackListedOutpoints: selectBlackListedOutpoints(state), playingUri: selectPlayingUri(state), }; diff --git a/ui/component/claimMenuList/index.js b/ui/component/claimMenuList/index.js index 6996729f5..e8dd1c512 100644 --- a/ui/component/claimMenuList/index.js +++ b/ui/component/claimMenuList/index.js @@ -26,7 +26,7 @@ import { } from 'redux/selectors/comments'; import { doToast } from 'redux/actions/notifications'; import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; import { selectListShuffle } from 'redux/selectors/content'; import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content'; import ClaimPreview from './view'; @@ -62,7 +62,7 @@ const select = (state, props) => { channelIsMuted: makeSelectChannelIsMuted(contentChannelUri)(state), channelIsBlocked: makeSelectChannelIsBlocked(contentChannelUri)(state), fileInfo: makeSelectFileInfoForUri(contentPermanentUri)(state), - isSubscribed: makeSelectIsSubscribed(contentChannelUri, true)(state), + isSubscribed: selectIsSubscribedForUri(state, contentChannelUri), channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state), isAdmin: selectHasAdminChannel(state), claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state), diff --git a/ui/component/claimPreview/index.js b/ui/component/claimPreview/index.js index 65efab5d6..4e07f98c3 100644 --- a/ui/component/claimPreview/index.js +++ b/ui/component/claimPreview/index.js @@ -1,13 +1,12 @@ import { connect } from 'react-redux'; import { selectClaimForUri, - makeSelectIsUriResolving, + selectIsUriResolving, selectClaimIsMine, makeSelectClaimIsPending, - makeSelectClaimIsNsfw, makeSelectReflectingClaimForUri, makeSelectClaimWasPurchased, - makeSelectTitleForUri, + selectTitleForUri, selectDateForUri, } from 'redux/selectors/claims'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; @@ -23,7 +22,8 @@ import { doFileGet } from 'redux/actions/file'; import { selectBanStateForUri } from 'lbryinc'; import { selectShowMatureContent } from 'redux/selectors/settings'; import { makeSelectHasVisitedUri } from 'redux/selectors/content'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; +import { isClaimNsfw } from 'util/claim'; import ClaimPreview from './view'; import formatMediaDuration from 'util/formatMediaDuration'; @@ -36,17 +36,17 @@ const select = (state, props) => { claim, mediaDuration, date: props.uri && selectDateForUri(state, props.uri), - title: props.uri && makeSelectTitleForUri(props.uri)(state), + title: props.uri && selectTitleForUri(state, props.uri), pending: props.uri && makeSelectClaimIsPending(props.uri)(state), reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state), obscureNsfw: selectShowMatureContent(state) === false, claimIsMine: props.uri && selectClaimIsMine(state, claim), - isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), - isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state), - nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state), + isResolvingUri: props.uri && selectIsUriResolving(state, props.uri), + isResolvingRepost: props.uri && selectIsUriResolving(state, props.repostUrl), + nsfw: claim ? isClaimNsfw(claim) : false, banState: selectBanStateForUri(state, props.uri), hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state), - isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state), + isSubscribed: props.uri && selectIsSubscribedForUri(state, props.uri), streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state), wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state), isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state), diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js index 7d1e558d4..95b209ff8 100644 --- a/ui/component/claimPreviewTile/index.js +++ b/ui/component/claimPreviewTile/index.js @@ -1,18 +1,16 @@ import { connect } from 'react-redux'; import { makeSelectClaimForUri, - makeSelectIsUriResolving, - makeSelectThumbnailForUri, - makeSelectTitleForUri, - makeSelectChannelForClaimUri, - makeSelectClaimIsNsfw, + selectIsUriResolving, + getThumbnailFromClaim, + selectTitleForUri, selectDateForUri, } from 'redux/selectors/claims'; import { doFileGet } from 'redux/actions/file'; import { doResolveUri } from 'redux/actions/claims'; -import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectViewCountForUri, selectBanStateForUri } from 'lbryinc'; import { selectShowMatureContent } from 'redux/selectors/settings'; +import { isClaimNsfw } from 'util/claim'; import ClaimPreviewTile from './view'; import formatMediaDuration from 'util/formatMediaDuration'; @@ -25,14 +23,12 @@ const select = (state, props) => { claim, mediaDuration, date: props.uri && selectDateForUri(state, props.uri), - channel: props.uri && makeSelectChannelForClaimUri(props.uri)(state), - isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), - thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), - title: props.uri && makeSelectTitleForUri(props.uri)(state), + isResolvingUri: props.uri && selectIsUriResolving(state, props.uri), + thumbnail: getThumbnailFromClaim(claim), + title: props.uri && selectTitleForUri(state, props.uri), banState: selectBanStateForUri(state, props.uri), - blockedChannelUris: selectMutedChannels(state), showMature: selectShowMatureContent(state), - isMature: makeSelectClaimIsNsfw(props.uri)(state), + isMature: claim ? isClaimNsfw(claim) : false, viewCount: selectViewCountForUri(state, props.uri), }; }; diff --git a/ui/component/claimPreviewTitle/index.js b/ui/component/claimPreviewTitle/index.js index 5a36e2b29..43f788207 100644 --- a/ui/component/claimPreviewTitle/index.js +++ b/ui/component/claimPreviewTitle/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims'; import ClaimPreviewTitle from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), }); export default connect(select)(ClaimPreviewTitle); diff --git a/ui/component/claimProperties/index.js b/ui/component/claimProperties/index.js index 3b5f3edf6..475e2b0d7 100644 --- a/ui/component/claimProperties/index.js +++ b/ui/component/claimProperties/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; import ClaimProperties from './view'; const select = (state, props) => { @@ -8,7 +8,7 @@ const select = (state, props) => { return { claim, - isSubscribed: makeSelectIsSubscribed(props.uri)(state), + isSubscribed: selectIsSubscribedForUri(state, props.uri), claimIsMine: selectClaimIsMine(state, claim), }; }; diff --git a/ui/component/collectionEdit/index.js b/ui/component/collectionEdit/index.js index 54cf51ee3..55fe5d51e 100644 --- a/ui/component/collectionEdit/index.js +++ b/ui/component/collectionEdit/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { - makeSelectTitleForUri, - makeSelectThumbnailForUri, + selectTitleForUri, + selectThumbnailForUri, makeSelectMetadataItemForUri, makeSelectAmountForUri, makeSelectClaimForUri, @@ -25,8 +25,8 @@ import { doSetActiveChannel, doSetIncognito } from 'redux/actions/app'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), - thumbnailUrl: makeSelectThumbnailForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), + thumbnailUrl: selectThumbnailForUri(state, props.uri), description: makeSelectMetadataItemForUri(props.uri, 'description')(state), tags: makeSelectMetadataItemForUri(props.uri, 'tags')(state), locations: makeSelectMetadataItemForUri(props.uri, 'locations')(state), diff --git a/ui/component/collectionPreviewOverlay/index.js b/ui/component/collectionPreviewOverlay/index.js index caee0c5c9..233609c5a 100644 --- a/ui/component/collectionPreviewOverlay/index.js +++ b/ui/component/collectionPreviewOverlay/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectIsUriResolving, selectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims'; +import { selectIsUriResolving, selectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims'; import { makeSelectUrlsForCollectionId, makeSelectNameForCollectionId, @@ -22,7 +22,7 @@ const select = (state, props) => { collectionItemUrls: makeSelectUrlsForCollectionId(collectionId)(state), // ForId || ForUri pendingCollection: makeSelectPendingCollectionForId(collectionId)(state), claim, - isResolvingUri: collectionUri && makeSelectIsUriResolving(collectionUri)(state), + isResolvingUri: collectionUri && selectIsUriResolving(state, collectionUri), }; }; diff --git a/ui/component/collectionPreviewTile/index.js b/ui/component/collectionPreviewTile/index.js index 706cd974d..82cdd90b8 100644 --- a/ui/component/collectionPreviewTile/index.js +++ b/ui/component/collectionPreviewTile/index.js @@ -1,8 +1,8 @@ import { connect } from 'react-redux'; import { - makeSelectIsUriResolving, - makeSelectThumbnailForUri, - makeSelectTitleForUri, + selectIsUriResolving, + getThumbnailFromClaim, + selectTitleForUri, makeSelectChannelForClaimUri, makeSelectClaimIsNsfw, selectClaimIdForUri, @@ -39,9 +39,9 @@ const select = (state, props) => { claim, isResolvingCollectionClaims: makeSelectIsResolvingCollectionForId(collectionId)(state), channelClaim: collectionUri && makeSelectChannelForClaimUri(collectionUri)(state), - isResolvingUri: collectionUri && makeSelectIsUriResolving(collectionUri)(state), - thumbnail: collectionUri && makeSelectThumbnailForUri(collectionUri)(state), - title: collectionUri && makeSelectTitleForUri(collectionUri)(state), + isResolvingUri: collectionUri && selectIsUriResolving(state, collectionUri), + thumbnail: getThumbnailFromClaim(claim), + title: collectionUri && selectTitleForUri(state, collectionUri), blackListedOutpoints: selectBlackListedOutpoints(state), filteredOutpoints: selectFilteredOutpoints(state), blockedChannelUris: selectMutedChannels(state), diff --git a/ui/component/comment/index.js b/ui/component/comment/index.js index 81744b65f..743faac8d 100644 --- a/ui/component/comment/index.js +++ b/ui/component/comment/index.js @@ -2,7 +2,8 @@ import { connect } from 'react-redux'; import { selectTotalStakedAmountForChannelUri, makeSelectClaimForUri, - makeSelectThumbnailForUri, + selectThumbnailForUri, + selectHasChannels, selectMyChannelClaims, } from 'redux/selectors/claims'; import { doCommentUpdate, doCommentList } from 'redux/actions/comments'; @@ -25,11 +26,12 @@ const select = (state, props) => { return { claim: makeSelectClaimForUri(props.uri)(state), - thumbnail: props.authorUri && makeSelectThumbnailForUri(props.authorUri)(state), + thumbnail: props.authorUri && selectThumbnailForUri(state, props.authorUri), channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state), commentingEnabled: true, othersReacts: selectOthersReactsForComment(state, reactionKey), activeChannelClaim, + hasChannels: selectHasChannels(state), // myChannels: selectMyChannelClaims(state), playingUri: selectPlayingUri(state), stakedLevel: selectTotalStakedAmountForChannelUri(state, props.authorUri), diff --git a/ui/component/embedPlayButton/index.js b/ui/component/embedPlayButton/index.js index 70847b149..ec8840c8d 100644 --- a/ui/component/embedPlayButton/index.js +++ b/ui/component/embedPlayButton/index.js @@ -1,8 +1,8 @@ import { connect } from 'react-redux'; -import { makeSelectThumbnailForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; +import { selectThumbnailForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import * as SETTINGS from 'constants/settings'; -import { doFetchCostInfoForUri, makeSelectCostInfoForUri } from 'lbryinc'; +import { doFetchCostInfoForUri, selectCostInfoForUri } from 'lbryinc'; import { doPlayUri, doSetPlayingUri } from 'redux/actions/content'; import { doAnaltyicsPurchaseEvent } from 'redux/actions/app'; import { makeSelectClientSetting } from 'redux/selectors/settings'; @@ -11,10 +11,10 @@ import { makeSelectFileRenderModeForUri } from 'redux/selectors/content'; import ChannelThumbnail from './view'; const select = (state, props) => ({ - thumbnail: makeSelectThumbnailForUri(props.uri)(state), + thumbnail: selectThumbnailForUri(state, props.uri), claim: makeSelectClaimForUri(props.uri)(state), floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), renderMode: makeSelectFileRenderModeForUri(props.uri)(state), }); diff --git a/ui/component/fileActions/index.js b/ui/component/fileActions/index.js index 78d76d263..a7dfda1e1 100644 --- a/ui/component/fileActions/index.js +++ b/ui/component/fileActions/index.js @@ -8,7 +8,7 @@ import { import { makeSelectStreamingUrlForUri, makeSelectFileInfoForUri } from 'redux/selectors/file_info'; import { doPrepareEdit } from 'redux/actions/publish'; import { DISABLE_COMMENTS_TAG } from 'constants/tags'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; import { doSetPlayingUri, doPlayUri } from 'redux/actions/content'; import { doToast } from 'redux/actions/notifications'; import { doOpenModal, doSetActiveChannel, doSetIncognito, doAnalyticsView } from 'redux/actions/app'; @@ -24,7 +24,7 @@ const select = (state, props) => { claimIsMine: selectClaimIsMine(state, claim), fileInfo: makeSelectFileInfoForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state), - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), hasChannels: selectHasChannels(state), reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state), streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), diff --git a/ui/component/fileDownloadLink/index.js b/ui/component/fileDownloadLink/index.js index bf4ad34d3..5ae3b0cfa 100644 --- a/ui/component/fileDownloadLink/index.js +++ b/ui/component/fileDownloadLink/index.js @@ -6,7 +6,7 @@ import { makeSelectLoadingForUri, makeSelectStreamingUrlForUri, } from 'redux/selectors/file_info'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; import { doOpenModal, doAnalyticsView } from 'redux/actions/app'; import { doSetPlayingUri, doPlayUri } from 'redux/actions/content'; import FileDownloadLink from './view'; @@ -20,7 +20,7 @@ const select = (state, props) => { loading: makeSelectLoadingForUri(props.uri)(state), claimIsMine: selectClaimIsMine(state, claim), claim, - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), }; diff --git a/ui/component/filePrice/index.js b/ui/component/filePrice/index.js index 560f38b96..3c816eb18 100644 --- a/ui/component/filePrice/index.js +++ b/ui/component/filePrice/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { selectClaimForUri, makeSelectClaimWasPurchased, selectClaimIsMine } from 'redux/selectors/claims'; -import { makeSelectCostInfoForUri, doFetchCostInfoForUri, makeSelectFetchingCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri, doFetchCostInfoForUri, selectFetchingCostInfoForUri } from 'lbryinc'; import FilePrice from './view'; const select = (state, props) => { @@ -10,8 +10,8 @@ const select = (state, props) => { claim, claimIsMine: selectClaimIsMine(state, claim), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), - costInfo: makeSelectCostInfoForUri(props.uri)(state), - fetching: makeSelectFetchingCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), + fetching: selectFetchingCostInfoForUri(state, props.uri), }; }; diff --git a/ui/component/fileRender/index.js b/ui/component/fileRender/index.js index 83a29abc0..6ddfd880f 100644 --- a/ui/component/fileRender/index.js +++ b/ui/component/fileRender/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { makeSelectDownloadPathForUri, makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; -import { makeSelectClaimForUri, makeSelectThumbnailForUri, makeSelectContentTypeForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectThumbnailForUri, makeSelectContentTypeForUri } from 'redux/selectors/claims'; import * as SETTINGS from 'constants/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content'; @@ -11,7 +11,7 @@ const select = (state, props) => { return { currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), claim: makeSelectClaimForUri(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), + thumbnail: selectThumbnailForUri(state, props.uri), contentType: makeSelectContentTypeForUri(props.uri)(state), downloadPath: makeSelectDownloadPathForUri(props.uri)(state), fileExtension: makeSelectFileExtensionForUri(props.uri)(state), diff --git a/ui/component/fileRenderFloating/index.js b/ui/component/fileRenderFloating/index.js index be0e6d4dd..0f54c8f75 100644 --- a/ui/component/fileRenderFloating/index.js +++ b/ui/component/fileRenderFloating/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectTitleForUri, makeSelectClaimIsNsfw, makeSelectClaimWasPurchased } from 'redux/selectors/claims'; +import { selectTitleForUri, makeSelectClaimIsNsfw, makeSelectClaimWasPurchased } from 'redux/selectors/claims'; import { makeSelectFileInfoForUri, makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; import { makeSelectNextUrlForCollectionAndUrl, @@ -13,7 +13,7 @@ import { makeSelectFileRenderModeForUri, } from 'redux/selectors/content'; import { makeSelectClientSetting } from 'redux/selectors/settings'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; import { doPlayUri, doSetPlayingUri } from 'redux/actions/content'; import { doFetchRecommendedContent } from 'redux/actions/search'; import { doAnaltyicsPurchaseEvent } from 'redux/actions/app'; @@ -30,7 +30,7 @@ const select = (state, props) => { uri, primaryUri, playingUri, - title: makeSelectTitleForUri(uri)(state), + title: selectTitleForUri(state, uri), fileInfo: makeSelectFileInfoForUri(uri)(state), mature: makeSelectClaimIsNsfw(uri)(state), isFloating: makeSelectIsPlayerFloating(props.location)(state), @@ -38,7 +38,7 @@ const select = (state, props) => { floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), renderMode: makeSelectFileRenderModeForUri(uri)(state), videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state), - costInfo: makeSelectCostInfoForUri(uri)(state), + costInfo: selectCostInfoForUri(state, uri), claimWasPurchased: makeSelectClaimWasPurchased(uri)(state), nextListUri: collectionId && makeSelectNextUrlForCollectionAndUrl(collectionId, uri)(state), previousListUri: collectionId && makeSelectPreviousUrlForCollectionAndUrl(collectionId, uri)(state), diff --git a/ui/component/fileRenderInitiator/index.js b/ui/component/fileRenderInitiator/index.js index 4808fcb26..8bcb1248e 100644 --- a/ui/component/fileRenderInitiator/index.js +++ b/ui/component/fileRenderInitiator/index.js @@ -1,16 +1,16 @@ import { connect } from 'react-redux'; import { doPlayUri, doSetPlayingUri, doSetPrimaryUri } from 'redux/actions/content'; -import { makeSelectThumbnailForUri, makeSelectClaimForUri, makeSelectClaimWasPurchased } from 'redux/selectors/claims'; +import { selectThumbnailForUri, makeSelectClaimForUri, makeSelectClaimWasPurchased } from 'redux/selectors/claims'; import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; import * as SETTINGS from 'constants/settings'; import * as COLLECTIONS_CONSTS from 'constants/collections'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import { withRouter } from 'react-router'; import { makeSelectIsPlaying, - makeSelectShouldObscurePreview, - makeSelectInsufficientCreditsForUri, + selectShouldObscurePreviewForUri, + selectInsufficientCreditsForUri, makeSelectFileRenderModeForUri, } from 'redux/selectors/content'; import FileRenderInitiator from './view'; @@ -22,13 +22,13 @@ const select = (state, props) => { const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID); return { - claimThumbnail: makeSelectThumbnailForUri(props.uri)(state), + claimThumbnail: selectThumbnailForUri(state, props.uri), fileInfo: makeSelectFileInfoForUri(props.uri)(state), - obscurePreview: makeSelectShouldObscurePreview(props.uri)(state), + obscurePreview: selectShouldObscurePreviewForUri(state, props.uri), isPlaying: makeSelectIsPlaying(props.uri)(state), - insufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), + insufficientCredits: selectInsufficientCreditsForUri(state, props.uri), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY_MEDIA)(state), - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), renderMode: makeSelectFileRenderModeForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), diff --git a/ui/component/fileRenderInline/index.js b/ui/component/fileRenderInline/index.js index f5e7a0db1..a858d3639 100644 --- a/ui/component/fileRenderInline/index.js +++ b/ui/component/fileRenderInline/index.js @@ -6,14 +6,14 @@ import { makeSelectFileRenderModeForUri, selectPrimaryUri } from 'redux/selector import { withRouter } from 'react-router'; import { doAnalyticsView } from 'redux/actions/app'; import FileRenderInline from './view'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; const select = (state, props) => ({ fileInfo: makeSelectFileInfoForUri(props.uri)(state), isPlaying: selectPrimaryUri(state) === props.uri, streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state), - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), }); diff --git a/ui/component/fileTitle/index.js b/ui/component/fileTitle/index.js index f3644c754..bba4441fd 100644 --- a/ui/component/fileTitle/index.js +++ b/ui/component/fileTitle/index.js @@ -1,9 +1,9 @@ import { connect } from 'react-redux'; -import { makeSelectTitleForUri } from 'redux/selectors/claims'; +import { selectTitleForUri } from 'redux/selectors/claims'; import FileTitleSection from './view'; const select = (state, props) => ({ - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), }); export default connect(select)(FileTitleSection); diff --git a/ui/component/fileTitleSection/index.js b/ui/component/fileTitleSection/index.js index b012111f5..1fbbe0b08 100644 --- a/ui/component/fileTitleSection/index.js +++ b/ui/component/fileTitleSection/index.js @@ -1,18 +1,18 @@ import { connect } from 'react-redux'; import { doFetchSubCount, selectSubCountForUri } from 'lbryinc'; -import { makeSelectTitleForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; -import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; +import { selectTitleForUri, selectClaimForUri } from 'redux/selectors/claims'; +import { selectInsufficientCreditsForUri } from 'redux/selectors/content'; import FileTitleSection from './view'; const select = (state, props) => { - const claim = makeSelectClaimForUri(props.uri)(state); + const claim = selectClaimForUri(state, props.uri); const channelClaimId = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined; const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined; const subCount = channelUri && selectSubCountForUri(state, channelUri); return { - isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), + isInsufficientCredits: selectInsufficientCreditsForUri(state, props.uri), + title: selectTitleForUri(state, props.uri), channelClaimId, subCount, }; diff --git a/ui/component/fileViewerEmbeddedTitle/index.js b/ui/component/fileViewerEmbeddedTitle/index.js index 4e7dda364..80b5087b5 100644 --- a/ui/component/fileViewerEmbeddedTitle/index.js +++ b/ui/component/fileViewerEmbeddedTitle/index.js @@ -1,11 +1,11 @@ import { connect } from 'react-redux'; import fileViewerEmbeddedTitle from './view'; -import { makeSelectTagInClaimOrChannelForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; +import { makeSelectTagInClaimOrChannelForUri, selectTitleForUri } from 'redux/selectors/claims'; import { PREFERENCE_EMBED } from 'constants/tags'; export default connect((state, props) => { return { - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), preferEmbed: makeSelectTagInClaimOrChannelForUri(props.uri, PREFERENCE_EMBED)(state), }; })(fileViewerEmbeddedTitle); diff --git a/ui/component/invited/index.js b/ui/component/invited/index.js index 7d76abf08..d91178095 100644 --- a/ui/component/invited/index.js +++ b/ui/component/invited/index.js @@ -5,7 +5,7 @@ import { selectUser, selectSetReferrerPending, selectSetReferrerError } from 're import { doClaimRewardType } from 'redux/actions/rewards'; import { selectUnclaimedRewards } from 'redux/selectors/rewards'; import { doUserSetReferrer } from 'redux/actions/user'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; import { doChannelSubscribe } from 'redux/actions/subscriptions'; import Invited from './view'; @@ -15,16 +15,16 @@ const select = (state, props) => { referrerSetPending: selectSetReferrerPending(state), referrerSetError: selectSetReferrerError(state), rewards: selectUnclaimedRewards(state), - isSubscribed: makeSelectIsSubscribed(props.fullUri)(state), + isSubscribed: selectIsSubscribedForUri(state, props.fullUri), fullUri: props.fullUri, referrer: props.referrer, }; }; -const perform = dispatch => ({ +const perform = (dispatch) => ({ claimReward: () => dispatch(doClaimRewardType(REWARDS.TYPE_REFEREE)), - setReferrer: referrer => dispatch(doUserSetReferrer(referrer)), - channelSubscribe: uri => dispatch(doChannelSubscribe(uri)), + setReferrer: (referrer) => dispatch(doUserSetReferrer(referrer)), + channelSubscribe: (uri) => dispatch(doChannelSubscribe(uri)), }); export default withRouter(connect(select, perform)(Invited)); diff --git a/ui/component/previewLink/index.js b/ui/component/previewLink/index.js index 9d93d2c63..1df8f7807 100644 --- a/ui/component/previewLink/index.js +++ b/ui/component/previewLink/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; import { selectClaimIsMine, - makeSelectTitleForUri, - makeSelectThumbnailForUri, + selectTitleForUri, + getThumbnailFromClaim, selectClaimForUri, - makeSelectIsUriResolving, + selectIsUriResolving, makeSelectMetadataItemForUri, } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; @@ -17,11 +17,11 @@ const select = (state, props) => { return { uri: props.uri, claim, - title: makeSelectTitleForUri(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), + thumbnail: getThumbnailFromClaim(claim), description: makeSelectMetadataItemForUri(props.uri, 'description')(state), channelIsMine: selectClaimIsMine(state, claim), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), + isResolvingUri: selectIsUriResolving(state, props.uri), blackListedOutpoints: selectBlackListedOutpoints(state), }; }; diff --git a/ui/component/previewOverlayProperties/index.js b/ui/component/previewOverlayProperties/index.js index aa0938a0c..2b3d7b9bd 100644 --- a/ui/component/previewOverlayProperties/index.js +++ b/ui/component/previewOverlayProperties/index.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims'; import { makeSelectFilePartlyDownloaded } from 'redux/selectors/file_info'; import { makeSelectEditedCollectionForId } from 'redux/selectors/collections'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; import PreviewOverlayProperties from './view'; const select = (state, props) => { @@ -13,7 +13,7 @@ const select = (state, props) => { claim, editedCollection: makeSelectEditedCollectionForId(claimId)(state), downloaded: makeSelectFilePartlyDownloaded(props.uri)(state), - isSubscribed: makeSelectIsSubscribed(props.uri)(state), + isSubscribed: selectIsSubscribedForUri(state, props.uri), claimIsMine: selectClaimIsMine(state, claim), }; }; diff --git a/ui/component/repostCreate/index.js b/ui/component/repostCreate/index.js index da2d21455..81ae4bdb2 100644 --- a/ui/component/repostCreate/index.js +++ b/ui/component/repostCreate/index.js @@ -2,13 +2,13 @@ import { connect } from 'react-redux'; import { doHideModal } from 'redux/actions/app'; import { makeSelectClaimForUri, - makeSelectTitleForUri, + selectTitleForUri, selectMyChannelClaims, selectRepostError, selectRepostLoading, selectMyClaimsWithoutChannels, makeSelectEffectiveAmountForUri, - makeSelectIsUriResolving, + selectIsUriResolving, selectFetchingMyChannels, } from 'redux/selectors/claims'; @@ -31,13 +31,13 @@ const select = (state, props) => ({ enteredContentClaim: makeSelectClaimForUri(props.contentUri)(state), enteredRepostClaim: makeSelectClaimForUri(props.repostUri, false)(state), enteredRepostAmount: makeSelectEffectiveAmountForUri(props.repostUri)(state), - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), balance: selectBalance(state), error: selectRepostError(state), reposting: selectRepostLoading(state), myClaims: selectMyClaimsWithoutChannels(state), - isResolvingPassedRepost: props.name && makeSelectIsUriResolving(`lbry://${props.name}`)(state), - isResolvingEnteredRepost: props.repostUri && makeSelectIsUriResolving(`lbry://${props.repostUri}`)(state), + isResolvingPassedRepost: props.name && selectIsUriResolving(state, `lbry://${props.name}`), + isResolvingEnteredRepost: props.repostUri && selectIsUriResolving(state, `lbry://${props.repostUri}`), activeChannelClaim: selectActiveChannelClaim(state), fetchingMyChannels: selectFetchingMyChannels(state), incognito: selectIncognito(state), diff --git a/ui/component/router/index.js b/ui/component/router/index.js index 48b648cd2..dc059c665 100644 --- a/ui/component/router/index.js +++ b/ui/component/router/index.js @@ -4,7 +4,7 @@ import { selectHasNavigated, selectScrollStartingPosition, selectWelcomeVersion import { selectHomepageData } from 'redux/selectors/settings'; import Router from './view'; import { normalizeURI } from 'util/lbryURI'; -import { makeSelectTitleForUri } from 'redux/selectors/claims'; +import { selectTitleForUri } from 'redux/selectors/claims'; import { doSetHasNavigated } from 'redux/actions/app'; import { doUserSetReferrer } from 'redux/actions/user'; import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards'; @@ -28,7 +28,7 @@ const select = (state) => { return { uri, - title: makeSelectTitleForUri(uri)(state), + title: selectTitleForUri(state, uri), currentScroll: selectScrollStartingPosition(state), isAuthenticated: selectUserVerifiedEmail(state), welcomeVersion: selectWelcomeVersion(state), diff --git a/ui/component/searchTopClaim/index.js b/ui/component/searchTopClaim/index.js index 74f7b9cbf..df59e36a0 100644 --- a/ui/component/searchTopClaim/index.js +++ b/ui/component/searchTopClaim/index.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { doClearPublish, doPrepareEdit } from 'redux/actions/publish'; import { doResolveUris } from 'redux/actions/claims'; import { selectPendingIds, makeSelectClaimForUri } from 'redux/selectors/claims'; -import { makeSelectWinningUriForQuery, makeSelectIsResolvingWinningUri } from 'redux/selectors/search'; +import { makeSelectWinningUriForQuery, selectIsResolvingWinningUri } from 'redux/selectors/search'; import SearchTopClaim from './view'; import { push } from 'connected-react-router'; import * as PAGES from 'constants/pages'; @@ -13,7 +13,7 @@ const select = (state, props) => { return { winningUri, winningClaim: winningUri ? makeSelectClaimForUri(winningUri)(state) : undefined, - isResolvingWinningUri: props.query ? makeSelectIsResolvingWinningUri(props.query)(state) : false, + isResolvingWinningUri: props.query ? selectIsResolvingWinningUri(state, props.query) : false, pendingIds: selectPendingIds(state), }; }; diff --git a/ui/component/socialShare/index.js b/ui/component/socialShare/index.js index 71382702f..ffb119638 100644 --- a/ui/component/socialShare/index.js +++ b/ui/component/socialShare/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims'; import SocialShare from './view'; import { makeSelectContentPositionForUri } from 'redux/selectors/content'; import { makeSelectClientSetting } from 'redux/selectors/settings'; @@ -7,7 +7,7 @@ import * as SETTINGS from 'constants/settings'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), position: makeSelectContentPositionForUri(props.uri)(state), customShareUrlEnabled: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL_ENABLED)(state), customShareUrl: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL)(state), diff --git a/ui/component/subscribeButton/index.js b/ui/component/subscribeButton/index.js index f6331c809..7d9ae272f 100644 --- a/ui/component/subscribeButton/index.js +++ b/ui/component/subscribeButton/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions'; import { - makeSelectIsSubscribed, + selectIsSubscribedForUri, selectFirstRunCompleted, makeSelectNotificationsDisabled, } from 'redux/selectors/subscriptions'; @@ -11,7 +11,7 @@ import { doToast } from 'redux/actions/notifications'; import SubscribeButton from './view'; const select = (state, props) => ({ - isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), + isSubscribed: selectIsSubscribedForUri(state, props.uri), firstRunCompleted: selectFirstRunCompleted(state), permanentUrl: makeSelectPermanentUrlForUri(props.uri)(state), notificationsDisabled: makeSelectNotificationsDisabled(props.uri)(state), diff --git a/ui/component/uriIndicator/index.js b/ui/component/uriIndicator/index.js index e18fbf192..d1c2b4807 100644 --- a/ui/component/uriIndicator/index.js +++ b/ui/component/uriIndicator/index.js @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; import { normalizeURI } from 'util/lbryURI'; import { doResolveUri } from 'redux/actions/claims'; -import { makeSelectIsUriResolving, makeSelectClaimForUri } from 'redux/selectors/claims'; +import { selectIsUriResolving, makeSelectClaimForUri } from 'redux/selectors/claims'; import UriIndicator from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), + isResolvingUri: selectIsUriResolving(state, props.uri), uri: normalizeURI(props.uri), }); diff --git a/ui/component/viewers/videoViewer/index.js b/ui/component/viewers/videoViewer/index.js index e8907c907..a71b7970c 100644 --- a/ui/component/viewers/videoViewer/index.js +++ b/ui/component/viewers/videoViewer/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectThumbnailForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectThumbnailForUri } from 'redux/selectors/claims'; import { makeSelectNextUrlForCollectionAndUrl, makeSelectPreviousUrlForCollectionAndUrl, @@ -56,7 +56,7 @@ const select = (state, props) => { volume: selectVolume(state), muted: selectMute(state), videoPlaybackRate: makeSelectClientSetting(SETTINGS.VIDEO_PLAYBACK_RATE)(state), - thumbnail: makeSelectThumbnailForUri(uri)(state), + thumbnail: selectThumbnailForUri(state, uri), claim: makeSelectClaimForUri(uri)(state), homepageData: selectHomepageData(state), shareTelemetry: selectDaemonSettings(state).share_usage_data, diff --git a/ui/component/walletSendTip/index.js b/ui/component/walletSendTip/index.js index 5cf567057..16d967d33 100644 --- a/ui/component/walletSendTip/index.js +++ b/ui/component/walletSendTip/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { - makeSelectTitleForUri, + selectTitleForUri, makeSelectClaimForUri, makeSelectClaimIsMine, selectFetchingMyChannels, @@ -18,7 +18,7 @@ import { selectUserVerifiedEmail } from 'redux/selectors/user'; const select = (state, props) => ({ isPending: selectIsSendingSupport(state), - title: makeSelectTitleForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), claim: makeSelectClaimForUri(props.uri, false)(state), balance: selectBalance(state), instantTipEnabled: makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state), diff --git a/ui/component/wunderbarSuggestion/index.js b/ui/component/wunderbarSuggestion/index.js index 6b5b1fd19..f5cdcb73a 100644 --- a/ui/component/wunderbarSuggestion/index.js +++ b/ui/component/wunderbarSuggestion/index.js @@ -1,10 +1,10 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; +import { selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims'; import WunderbarSuggestion from './view'; const select = (state, props) => ({ - claim: makeSelectClaimForUri(props.uri)(state), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), + claim: selectClaimForUri(state, props.uri), + isResolvingUri: selectIsUriResolving(state, props.uri), }); export default connect(select)(WunderbarSuggestion); diff --git a/ui/component/wunderbarTopSuggestion/index.js b/ui/component/wunderbarTopSuggestion/index.js index 8dd77e369..a76ba73c3 100644 --- a/ui/component/wunderbarTopSuggestion/index.js +++ b/ui/component/wunderbarTopSuggestion/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { makeSelectClaimForUri, - makeSelectIsUriResolving, + selectIsUriResolving, makeSelectTagInClaimOrChannelForUri, } from 'redux/selectors/claims'; import { doResolveUris } from 'redux/actions/claims'; @@ -23,7 +23,7 @@ const select = (state, props) => { } } catch (e) {} - const resolvingUris = uris.some((uri) => makeSelectIsUriResolving(uri)(state)); + const resolvingUris = uris.some((uri) => selectIsUriResolving(state, uri)); const winningUri = makeSelectWinningUriForQuery(props.query)(state); const winningClaim = winningUri ? makeSelectClaimForUri(winningUri)(state) : undefined; const preferEmbed = makeSelectTagInClaimOrChannelForUri(winningUri, PREFERENCE_EMBED)(state); diff --git a/ui/modal/modalRemoveFile/index.js b/ui/modal/modalRemoveFile/index.js index 2a9228f39..ee27b76b3 100644 --- a/ui/modal/modalRemoveFile/index.js +++ b/ui/modal/modalRemoveFile/index.js @@ -1,18 +1,18 @@ import { connect } from 'react-redux'; import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file'; import { - makeSelectTitleForUri, + selectTitleForUri, selectClaimForUri, makeSelectIsAbandoningClaimForUri, - makeSelectClaimIsMine, + selectClaimIsMineForUri, } from 'redux/selectors/claims'; import { doResolveUri } from 'redux/actions/claims'; import { doHideModal } from 'redux/actions/app'; import ModalRemoveFile from './view'; const select = (state, props) => ({ - claimIsMine: makeSelectClaimIsMine(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), + claimIsMine: selectClaimIsMineForUri(state, props.uri), + title: selectTitleForUri(state, props.uri), claim: selectClaimForUri(state, props.uri), isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state), }); diff --git a/ui/page/channel/index.js b/ui/page/channel/index.js index 4576586d3..5e537a3d2 100644 --- a/ui/page/channel/index.js +++ b/ui/page/channel/index.js @@ -1,8 +1,8 @@ import { connect } from 'react-redux'; import { selectClaimIsMine, - makeSelectTitleForUri, - makeSelectThumbnailForUri, + selectTitleForUri, + getThumbnailFromClaim, makeSelectCoverForUri, selectCurrentChannelPage, selectClaimForUri, @@ -11,7 +11,7 @@ import { import { selectMyUnpublishedCollections } from 'redux/selectors/collections'; import { selectBlackListedOutpoints, doFetchSubCount, selectSubCountForUri } from 'lbryinc'; // ban state import { selectYoutubeChannels } from 'redux/selectors/user'; -import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; +import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; import { selectModerationBlockList } from 'redux/selectors/comments'; import { selectMutedChannels } from 'redux/selectors/blocked'; import { doOpenModal } from 'redux/actions/app'; @@ -21,13 +21,13 @@ const select = (state, props) => { const claim = selectClaimForUri(state, props.uri); return { - title: makeSelectTitleForUri(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), + title: selectTitleForUri(state, props.uri), + thumbnail: getThumbnailFromClaim(claim), cover: makeSelectCoverForUri(props.uri)(state), channelIsMine: selectClaimIsMine(state, claim), page: selectCurrentChannelPage(state), claim, - isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), + isSubscribed: selectIsSubscribedForUri(state, props.uri), blackListedOutpoints: selectBlackListedOutpoints(state), subCount: selectSubCountForUri(state, props.uri), pending: makeSelectClaimIsPending(props.uri)(state), diff --git a/ui/page/collection/index.js b/ui/page/collection/index.js index 62585eafe..04ef4b8a5 100644 --- a/ui/page/collection/index.js +++ b/ui/page/collection/index.js @@ -3,8 +3,8 @@ import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; import CollectionPage from './view'; import { - makeSelectTitleForUri, - makeSelectThumbnailForUri, + selectTitleForUri, + getThumbnailFromClaim, selectClaimIsMine, makeSelectClaimIsPending, makeSelectClaimForClaimId, @@ -38,8 +38,8 @@ const select = (state, props) => { collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state), collectionCount: makeSelectCountForCollectionId(collectionId)(state), isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state), - title: makeSelectTitleForUri(uri)(state), - thumbnail: makeSelectThumbnailForUri(uri)(state), + title: selectTitleForUri(state, uri), + thumbnail: getThumbnailFromClaim(claim), isMyClaim: selectClaimIsMine(state, claim), // or collection is mine? isMyCollection: makeSelectCollectionIsMine(collectionId)(state), claimIsPending: makeSelectClaimIsPending(uri)(state), diff --git a/ui/page/file/index.js b/ui/page/file/index.js index 0395c634f..989077ade 100644 --- a/ui/page/file/index.js +++ b/ui/page/file/index.js @@ -11,7 +11,7 @@ import { doFetchFileInfo } from 'redux/actions/file_info'; import { makeSelectCollectionForId } from 'redux/selectors/collections'; import * as COLLECTIONS_CONSTS from 'constants/collections'; import * as SETTINGS from 'constants/settings'; -import { makeSelectCostInfoForUri, doFetchCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri, doFetchCostInfoForUri } from 'lbryinc'; import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectFileRenderModeForUri, makeSelectContentPositionForUri } from 'redux/selectors/content'; import { DISABLE_COMMENTS_TAG } from 'constants/tags'; @@ -25,7 +25,7 @@ const select = (state, props) => { return { linkedCommentId: urlParams.get('lc'), - costInfo: makeSelectCostInfoForUri(props.uri)(state), + costInfo: selectCostInfoForUri(state, props.uri), metadata: makeSelectMetadataForUri(props.uri)(state), obscureNsfw: !selectShowMatureContent(state), isMature: makeSelectClaimIsNsfw(props.uri)(state), diff --git a/ui/page/show/index.js b/ui/page/show/index.js index 8c174e058..974af2a7b 100644 --- a/ui/page/show/index.js +++ b/ui/page/show/index.js @@ -4,10 +4,10 @@ import { connect } from 'react-redux'; import { withRouter } from 'react-router'; import { PAGE_SIZE } from 'constants/claim'; import { + selectIsUriResolving, selectClaimForUri, - makeSelectIsUriResolving, makeSelectTotalPagesForChannel, - makeSelectTitleForUri, + selectTitleForUri, selectClaimIsMine, makeSelectClaimIsPending, } from 'redux/selectors/claims'; @@ -71,11 +71,11 @@ const select = (state, props) => { return { uri, claim, - isResolvingUri: makeSelectIsUriResolving(uri)(state), + isResolvingUri: selectIsUriResolving(state, uri), blackListedOutpoints: selectBlackListedOutpoints(state), totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state), isSubscribed: makeSelectChannelInSubscriptions(uri)(state), - title: makeSelectTitleForUri(uri)(state), + title: selectTitleForUri(state, uri), claimIsMine: selectClaimIsMine(state, claim), claimIsPending: makeSelectClaimIsPending(uri)(state), collection: makeSelectCollectionForId(collectionId)(state), diff --git a/ui/redux/actions/content.js b/ui/redux/actions/content.js index d625071a7..c0f9a4c07 100644 --- a/ui/redux/actions/content.js +++ b/ui/redux/actions/content.js @@ -22,7 +22,7 @@ import { doToast } from 'redux/actions/notifications'; import { doPurchaseUri } from 'redux/actions/file'; import Lbry from 'lbry'; import * as SETTINGS from 'constants/settings'; -import { makeSelectCostInfoForUri, Lbryio } from 'lbryinc'; +import { selectCostInfoForUri, Lbryio } from 'lbryinc'; import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings'; const DOWNLOAD_POLL_INTERVAL = 1000; @@ -169,7 +169,7 @@ export function doPlayUri( } const daemonSettings = selectDaemonSettings(state); - const costInfo = makeSelectCostInfoForUri(uri)(state); + const costInfo = selectCostInfoForUri(state, uri); const cost = (costInfo && Number(costInfo.cost)) || 0; const saveFile = !uriIsStreamable ? true : daemonSettings.save_files || saveFileOverride || cost > 0; const instantPurchaseEnabled = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state); diff --git a/ui/redux/actions/file.js b/ui/redux/actions/file.js index e73177e35..677e0ff89 100644 --- a/ui/redux/actions/file.js +++ b/ui/redux/actions/file.js @@ -22,7 +22,7 @@ import { } from 'redux/selectors/file_info'; type Dispatch = (action: any) => any; -type GetState = () => { file: FileState }; +type GetState = () => { claims: any, file: FileState, content: any }; export function doOpenFileInFolder(path: string) { return () => { shell.showItemInFolder(path); diff --git a/ui/redux/actions/search.js b/ui/redux/actions/search.js index dfd9c724a..1c9a8ddef 100644 --- a/ui/redux/actions/search.js +++ b/ui/redux/actions/search.js @@ -12,7 +12,7 @@ import { getRecommendationSearchOptions } from 'util/search'; import { SEARCH_SERVER_API } from 'config'; type Dispatch = (action: any) => any; -type GetState = () => { search: SearchState }; +type GetState = () => { claims: any, search: SearchState }; type SearchOptions = { size?: number, diff --git a/ui/redux/selectors/claims.js b/ui/redux/selectors/claims.js index fb986fe1f..677476415 100644 --- a/ui/redux/selectors/claims.js +++ b/ui/redux/selectors/claims.js @@ -332,10 +332,11 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) => return byChannel['pageCount']; }); -export const selectMetadataForUri = createCachedSelector(selectClaimForUri, (claim, uri) => { +export const selectMetadataForUri = (state: State, uri: string) => { + const claim = selectClaimForUri(state, uri); const metadata = claim && claim.value; return metadata || (claim === undefined ? undefined : null); -})((state, uri) => String(uri)); +}; export const makeSelectMetadataForUri = (uri: string) => createSelector(makeSelectClaimForUri(uri), (claim) => { @@ -348,8 +349,10 @@ export const makeSelectMetadataItemForUri = (uri: string, key: string) => return metadata ? metadata[key] : undefined; }); -export const makeSelectTitleForUri = (uri: string) => - createSelector(makeSelectMetadataForUri(uri), (metadata) => metadata && metadata.title); +export const selectTitleForUri = (state: State, uri: string) => { + const metadata = selectMetadataForUri(state, uri); + return metadata && metadata.title; +}; export const selectDateForUri = createCachedSelector( selectClaimForUri, // input: (state, uri, ?returnRepost) @@ -388,11 +391,14 @@ export const makeSelectContentTypeForUri = (uri: string) => return source ? source.media_type : undefined; }); -export const makeSelectThumbnailForUri = (uri: string) => - createSelector(makeSelectClaimForUri(uri), (claim) => { - const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; - }); +export const getThumbnailFromClaim = (claim: Claim) => { + const thumbnail = claim && claim.value && claim.value.thumbnail; + return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; +}; + +export const selectThumbnailForUri = createCachedSelector(selectClaimForUri, (claim) => { + return getThumbnailFromClaim(claim); +})((state, uri) => String(uri)); export const makeSelectCoverForUri = (uri: string) => createSelector(makeSelectClaimForUri(uri), (claim) => { @@ -513,8 +519,10 @@ export const selectResolvingUris = createSelector(selectState, (state) => state. export const selectChannelImportPending = (state: State) => selectState(state).pendingChannelImport; -export const makeSelectIsUriResolving = (uri: string) => - createSelector(selectResolvingUris, (resolvingUris) => resolvingUris && resolvingUris.indexOf(uri) !== -1); +export const selectIsUriResolving = (state: State, uri: string) => { + const resolvingUris = selectResolvingUris(state); + return resolvingUris && resolvingUris.includes(uri); +}; export const selectPlayingUri = (state: State) => selectState(state).playingUri; @@ -567,6 +575,17 @@ export const makeSelectOmittedCountForChannel = (uri: string) => } ); +export const selectClaimIsNsfwForUri = createCachedSelector( + selectClaimForUri, + // Eventually these will come from some list of tags that are considered adult + // Or possibly come from users settings of what tags they want to hide + // For now, there is just a hard coded list of tags inside `isClaimNsfw` + // selectNaughtyTags(), + (claim: Claim) => { + return claim ? isClaimNsfw(claim) : false; + } +)((state, uri) => String(uri)); + export const makeSelectClaimIsNsfw = (uri: string) => createSelector( makeSelectClaimForUri(uri), @@ -582,7 +601,6 @@ export const makeSelectClaimIsNsfw = (uri: string) => return isClaimNsfw(claim); } ); - // Returns the associated channel uri for a given claim uri // accepts a regular claim uri lbry://something // returns the channel uri that created this claim lbry://@channel @@ -644,15 +662,31 @@ export const selectClaimSearchByQueryLastPageReached = createSelector( (state) => state.claimSearchByQueryLastPageReached || {} ); +// Deprecated export const makeSelectShortUrlForUri = (uri: string) => createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.short_url); - +// Deprecated export const makeSelectCanonicalUrlForUri = (uri: string) => createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.canonical_url); - +// Deprecated export const makeSelectPermanentUrlForUri = (uri: string) => createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.permanent_url); +export const selectShortUrlForUri = (state: State, uri: string) => { + const claim = selectClaimForUri(state, uri); + return claim && claim.short_url; +}; + +export const selectCanonicalUrlForUri = (state: State, uri: string) => { + const claim = selectClaimForUri(state, uri); + return claim && claim.canonical_url; +}; + +export const selectPermanentUrlForUri = (state: State, uri: string) => { + const claim = selectClaimForUri(state, uri); + return claim && claim.permanent_url; +}; + export const makeSelectSupportsForUri = (uri: string) => createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim: ?StreamClaim) => { if (!claim || !claim.is_my_output) { diff --git a/ui/redux/selectors/content.js b/ui/redux/selectors/content.js index 44305be42..f3d4e9784 100644 --- a/ui/redux/selectors/content.js +++ b/ui/redux/selectors/content.js @@ -3,13 +3,14 @@ import { createSelector } from 'reselect'; import { makeSelectClaimForUri, selectClaimsByUri, + selectClaimIsNsfwForUri, + selectClaimIsMineForUri, makeSelectClaimIsNsfw, - makeSelectClaimIsMine, makeSelectContentTypeForUri, } from 'redux/selectors/claims'; import { makeSelectMediaTypeForUri, makeSelectFileNameForUri } from 'redux/selectors/file_info'; import { selectBalance } from 'redux/selectors/wallet'; -import { makeSelectCostInfoForUri } from 'lbryinc'; +import { selectCostInfoForUri } from 'lbryinc'; import { selectShowMatureContent } from 'redux/selectors/settings'; import * as RENDER_MODES from 'constants/file_render_modes'; import path from 'path'; @@ -18,13 +19,14 @@ import { FORCE_CONTENT_TYPE_PLAYER, FORCE_CONTENT_TYPE_COMIC } from 'constants/c const RECENT_HISTORY_AMOUNT = 10; const HISTORY_ITEMS_PER_PAGE = 50; -export const selectState = (state: any) => state.content || {}; +type State = { claims: any, content: any }; -export const selectPlayingUri = createSelector(selectState, (state) => state.playingUri); -export const selectPrimaryUri = createSelector(selectState, (state) => state.primaryUri); +export const selectState = (state: State) => state.content || {}; -export const selectListLoop = createSelector(selectState, (state) => state.loopList); -export const selectListShuffle = createSelector(selectState, (state) => state.shuffleList); +export const selectPlayingUri = (state: State) => selectState(state).playingUri; +export const selectPrimaryUri = (state: State) => selectState(state).primaryUri; +export const selectListLoop = (state: State) => selectState(state).loopList; +export const selectListShuffle = (state: State) => selectState(state).shuffleList; export const makeSelectIsPlaying = (uri: string) => createSelector(selectPrimaryUri, (primaryUri) => primaryUri === uri); @@ -84,6 +86,13 @@ export const selectRecentHistory = createSelector(selectHistory, (history) => { return history.slice(0, RECENT_HISTORY_AMOUNT); }); +export const selectShouldObscurePreviewForUri = (state: State, uri: string) => { + const showMatureContent = selectShowMatureContent(state); + const isClaimMature = selectClaimIsNsfwForUri(state, uri); + return isClaimMature && !showMatureContent; +}; + +// deprecated export const makeSelectShouldObscurePreview = (uri: string) => createSelector(selectShowMatureContent, makeSelectClaimIsNsfw(uri), (showMatureContent, isClaimMature) => { return isClaimMature && !showMatureContent; @@ -155,12 +164,9 @@ export const makeSelectFileRenderModeForUri = (uri: string) => } ); -export const makeSelectInsufficientCreditsForUri = (uri: string) => - createSelector( - makeSelectClaimIsMine(uri), - makeSelectCostInfoForUri(uri), - selectBalance, - (isMine, costInfo, balance) => { - return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance; - } - ); +export const selectInsufficientCreditsForUri = (state: State, uri: string) => { + const isMine = selectClaimIsMineForUri(state, uri); + const costInfo = selectCostInfoForUri(state, uri); + const balance = selectBalance(state); + return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance; +}; diff --git a/ui/redux/selectors/search.js b/ui/redux/selectors/search.js index 6ef2b0047..8a76cca0c 100644 --- a/ui/redux/selectors/search.js +++ b/ui/redux/selectors/search.js @@ -8,7 +8,7 @@ import { makeSelectClaimForClaimId, makeSelectClaimIsNsfw, makeSelectPendingClaimForUri, - makeSelectIsUriResolving, + selectIsUriResolving, } from 'redux/selectors/claims'; import { parseURI } from 'util/lbryURI'; import { isClaimNsfw } from 'util/claim'; @@ -18,7 +18,7 @@ import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectHistory } from 'redux/selectors/content'; import { selectAllCostInfoByUri } from 'lbryinc'; -type State = { search: SearchState }; +type State = { claims: any, search: SearchState }; export const selectState = (state: State): SearchState => state.search; @@ -238,7 +238,7 @@ export const makeSelectWinningUriForQuery = (query: string) => { ); }; -export const makeSelectIsResolvingWinningUri = (query: string = '') => { +export const selectIsResolvingWinningUri = (state: State, query: string = '') => { const uriFromQuery = `lbry://${query}`; let channelUriFromQuery; try { @@ -248,13 +248,9 @@ export const makeSelectIsResolvingWinningUri = (query: string = '') => { } } catch (e) {} - return createSelector( - makeSelectIsUriResolving(uriFromQuery), - channelUriFromQuery ? makeSelectIsUriResolving(channelUriFromQuery) : () => {}, - (claim1IsResolving, claim2IsResolving) => { - return claim1IsResolving || claim2IsResolving; - } - ); + const claim1IsResolving = selectIsUriResolving(state, uriFromQuery); + const claim2IsResolving = channelUriFromQuery ? selectIsUriResolving(state, channelUriFromQuery) : false; + return claim1IsResolving || claim2IsResolving; }; export const makeSelectUrlForClaimId = (claimId: string) => diff --git a/ui/redux/selectors/subscriptions.js b/ui/redux/selectors/subscriptions.js index ec0b339c8..364fa8988 100644 --- a/ui/redux/selectors/subscriptions.js +++ b/ui/redux/selectors/subscriptions.js @@ -1,12 +1,15 @@ import { SUGGESTED_FEATURED, SUGGESTED_TOP_SUBSCRIBED } from 'constants/subscriptions'; import { createSelector } from 'reselect'; +import { createCachedSelector } from 're-reselect'; import { parseURI, isURIEqual } from 'util/lbryURI'; import { selectAllFetchingChannelClaims, makeSelectChannelForClaimUri, makeSelectClaimForUri, + selectClaimForUri, } from 'redux/selectors/claims'; import { swapKeyAndValue } from 'util/swap-json'; +import { getChannelFromClaim } from 'util/claim'; // Returns the entire subscriptions state const selectState = (state) => state.subscriptions || {}; @@ -105,34 +108,18 @@ export const selectSubscriptionsBeingFetched = createSelector( export const makeSelectChannelInSubscriptions = (uri) => createSelector(selectSubscriptions, (subscriptions) => subscriptions.some((sub) => sub.uri === uri)); -export const makeSelectIsSubscribed = (uri) => - createSelector( - selectSubscriptions, - makeSelectChannelForClaimUri(uri, true), - makeSelectClaimForUri(uri), - (subscriptions, channelUri, claim) => { - if (channelUri) { - return subscriptions.some((sub) => isURIEqual(sub.uri, channelUri)); - } - - // If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already - let isChannel; - try { - ({ isChannel } = parseURI(uri)); - } catch (e) {} - - if (isChannel && claim) { - const uri = claim.permanent_url; - return subscriptions.some((sub) => isURIEqual(sub.uri, uri)); - } - - if (isChannel && !claim) { - return subscriptions.some((sub) => isURIEqual(sub.uri, uri)); - } - - return false; +export const selectIsSubscribedForUri = createCachedSelector( + selectClaimForUri, + selectSubscriptions, + (claim, subscriptions) => { + const channelClaim = getChannelFromClaim(claim); + if (channelClaim) { + const uri = channelClaim.permanent_url; + return subscriptions.some((sub) => isURIEqual(sub.uri, uri)); } - ); + return false; + } +)((state, uri) => String(uri)); export const makeSelectNotificationsDisabled = (uri) => createSelector( diff --git a/ui/util/buildHomepage.js b/ui/util/buildHomepage.js index 6c192889b..f5cb70d1f 100644 --- a/ui/util/buildHomepage.js +++ b/ui/util/buildHomepage.js @@ -144,6 +144,32 @@ export function GetLinksData( let rowData: Array = []; const individualTagDataItems: Array = []; + if (isHomepage && showPersonalizedChannels && subscribedChannels) { + const RECENT_FROM_FOLLOWING = { + title: __('Recent From Following'), + link: `/$/${PAGES.CHANNELS_FOLLOWING}`, + icon: ICONS.SUBSCRIBE, + options: { + orderBy: CS.ORDER_BY_NEW_VALUE, + releaseTime: + subscribedChannels.length > 20 + ? `>${Math.floor(moment().subtract(9, 'months').startOf('week').unix())}` + : `>${Math.floor(moment().subtract(1, 'year').startOf('week').unix())}`, + pageSize: getPageSize(subscribedChannels.length > 3 ? (subscribedChannels.length > 6 ? 16 : 8) : 4), + streamTypes: null, + channelIds: subscribedChannels.map((subscription: Subscription) => { + const { channelClaimId } = parseURI(subscription.uri); + if (channelClaimId) return channelClaimId; + }), + }, + }; + // $FlowFixMe flow thinks this might not be Array + rowData.push(RECENT_FROM_FOLLOWING); + } + + // ************************************************************************** + // @if CUSTOM_HOMEPAGE='false' + const YOUTUBER_CHANNEL_IDS = [ 'fb364ef587872515f545a5b4b3182b58073f230f', '589276465a23c589801d874f484cc39f307d7ec7', @@ -274,28 +300,6 @@ export function GetLinksData( }, }; - if (isHomepage && showPersonalizedChannels && subscribedChannels) { - const RECENT_FROM_FOLLOWING = { - title: __('Recent From Following'), - link: `/$/${PAGES.CHANNELS_FOLLOWING}`, - icon: ICONS.SUBSCRIBE, - options: { - orderBy: CS.ORDER_BY_NEW_VALUE, - releaseTime: - subscribedChannels.length > 20 - ? `>${Math.floor(moment().subtract(9, 'months').startOf('week').unix())}` - : `>${Math.floor(moment().subtract(1, 'year').startOf('week').unix())}`, - pageSize: getPageSize(subscribedChannels.length > 3 ? (subscribedChannels.length > 6 ? 16 : 8) : 4), - streamTypes: null, - channelIds: subscribedChannels.map((subscription: Subscription) => { - const { channelClaimId } = parseURI(subscription.uri); - if (channelClaimId) return channelClaimId; - }), - }, - }; - // $FlowFixMe flow thinks this might not be Array - rowData.push(RECENT_FROM_FOLLOWING); - } if (isHomepage && !CUSTOM_HOMEPAGE) { if (followedTags) { const TRENDING_FOR_TAGS = { @@ -330,6 +334,7 @@ export function GetLinksData( } } } + if (!CUSTOM_HOMEPAGE) { if (!authenticated) { rowData.push(YOUTUBE_CREATOR_ROW); @@ -338,6 +343,10 @@ export function GetLinksData( rowData.push(LATEST_FROM_LBRY); if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS); } + + // @endif + // ************************************************************************** + // TODO: provide better method for exempting from homepage (Object.values(all): any) .filter((row) => !(isHomepage && row.name === 'news'))