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 <inf.persistence@gmail.com>
This commit is contained in:
jessopb 2022-01-19 20:46:01 -05:00 committed by GitHub
parent ea072febae
commit c7021a08ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 291 additions and 258 deletions

View file

@ -38,8 +38,8 @@ export { syncReducer } from './redux/reducers/sync';
// selectors // selectors
export { selectAuthToken, selectIsAuthenticating } from './redux/selectors/auth'; export { selectAuthToken, selectIsAuthenticating } from './redux/selectors/auth';
export { export {
makeSelectFetchingCostInfoForUri, selectFetchingCostInfoForUri,
makeSelectCostInfoForUri, selectCostInfoForUri,
selectAllCostInfoByUri, selectAllCostInfoByUri,
selectFetchingCostInfo, selectFetchingCostInfo,
} from './redux/selectors/cost_info'; } from './redux/selectors/cost_info';

View file

@ -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 => export const selectFetchingCostInfoForUri = (state: State, uri: string) => {
createSelector(selectAllCostInfoByUri, costInfos => costInfos && costInfos[uri]); const fetchingByUri = selectFetchingCostInfo(state);
return fetchingByUri && fetchingByUri[uri];
export const selectFetchingCostInfo = createSelector(selectState, state => state.fetching || {}); };
export const makeSelectFetchingCostInfoForUri = uri =>
createSelector(selectFetchingCostInfo, fetchingByUri => fetchingByUri && fetchingByUri[uri]);

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectTitleForUri, selectTitleForUri,
makeSelectThumbnailForUri, selectThumbnailForUri,
makeSelectCoverForUri, makeSelectCoverForUri,
makeSelectMetadataItemForUri, makeSelectMetadataItemForUri,
makeSelectAmountForUri, makeSelectAmountForUri,
@ -21,8 +21,8 @@ import ChannelForm from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
thumbnailUrl: makeSelectThumbnailForUri(props.uri)(state), thumbnailUrl: selectThumbnailForUri(state, props.uri),
coverUrl: makeSelectCoverForUri(props.uri)(state), coverUrl: makeSelectCoverForUri(props.uri)(state),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state), description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
website: makeSelectMetadataItemForUri(props.uri, 'website_url')(state), website: makeSelectMetadataItemForUri(props.uri, 'website_url')(state),

View file

@ -1,10 +1,10 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; import { selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims';
import ChannelMentionSuggestion from './view'; import ChannelMentionSuggestion from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: selectClaimForUri(state, props.uri),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state), isResolvingUri: selectIsUriResolving(state, props.uri),
}); });
export default connect(select)(ChannelMentionSuggestion); export default connect(select)(ChannelMentionSuggestion);

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectIsUriResolving } from 'redux/selectors/claims'; import { selectIsUriResolving } from 'redux/selectors/claims';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { makeSelectWinningUriForQuery } from 'redux/selectors/search'; import { makeSelectWinningUriForQuery } from 'redux/selectors/search';
import ChannelMentionTopSuggestion from './view'; import ChannelMentionTopSuggestion from './view';
@ -8,7 +8,7 @@ const select = (state, props) => {
const uriFromQuery = `lbry://${props.query}`; const uriFromQuery = `lbry://${props.query}`;
return { return {
uriFromQuery, uriFromQuery,
isResolvingUri: makeSelectIsUriResolving(uriFromQuery)(state), isResolvingUri: selectIsUriResolving(state, uriFromQuery),
winningUri: makeSelectWinningUriForQuery(props.query)(state), winningUri: makeSelectWinningUriForQuery(props.query)(state),
}; };
}; };

View file

@ -1,12 +1,12 @@
import { connect } from 'react-redux'; 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 { doResolveUri } from 'redux/actions/claims';
import ChannelThumbnail from './view'; import ChannelThumbnail from './view';
const select = (state, props) => ({ const select = (state, props) => ({
thumbnail: makeSelectThumbnailForUri(props.uri)(state), thumbnail: selectThumbnailForUri(state, props.uri),
claim: makeSelectClaimForUri(props.uri)(state), claim: selectClaimForUri(state, props.uri),
isResolving: makeSelectIsUriResolving(props.uri)(state), isResolving: selectIsUriResolving(state, props.uri),
}); });
export default connect(select, { export default connect(select, {

View file

@ -1,9 +1,9 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
import ChannelTitle from './view'; import ChannelTitle from './view';
const select = (state, props) => ({ const select = (state, props) => ({
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
}); });

View file

@ -1,10 +1,10 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; import { selectInsufficientCreditsForUri } from 'redux/selectors/content';
import { makeSelectClaimWasPurchased } from 'redux/selectors/claims'; import { makeSelectClaimWasPurchased } from 'redux/selectors/claims';
import ClaimInsufficientCredits from './view'; import ClaimInsufficientCredits from './view';
const select = (state, props) => ({ const select = (state, props) => ({
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), isInsufficientCredits: selectInsufficientCreditsForUri(state, props.uri),
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
}); });

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; 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 { doResolveUri } from 'redux/actions/claims';
import { doSetPlayingUri } from 'redux/actions/content'; import { doSetPlayingUri } from 'redux/actions/content';
import { punctuationMarks } from 'util/remark-lbry'; import { punctuationMarks } from 'util/remark-lbry';
@ -25,7 +25,7 @@ const select = (state, props) => {
uri, uri,
claim, claim,
fullUri: props.uri, fullUri: props.uri,
isResolvingUri: makeSelectIsUriResolving(uri)(state), isResolvingUri: selectIsUriResolving(state, uri),
blackListedOutpoints: selectBlackListedOutpoints(state), blackListedOutpoints: selectBlackListedOutpoints(state),
playingUri: selectPlayingUri(state), playingUri: selectPlayingUri(state),
}; };

View file

@ -26,7 +26,7 @@ import {
} from 'redux/selectors/comments'; } from 'redux/selectors/comments';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions'; 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 { selectListShuffle } from 'redux/selectors/content';
import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content'; import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
import ClaimPreview from './view'; import ClaimPreview from './view';
@ -62,7 +62,7 @@ const select = (state, props) => {
channelIsMuted: makeSelectChannelIsMuted(contentChannelUri)(state), channelIsMuted: makeSelectChannelIsMuted(contentChannelUri)(state),
channelIsBlocked: makeSelectChannelIsBlocked(contentChannelUri)(state), channelIsBlocked: makeSelectChannelIsBlocked(contentChannelUri)(state),
fileInfo: makeSelectFileInfoForUri(contentPermanentUri)(state), fileInfo: makeSelectFileInfoForUri(contentPermanentUri)(state),
isSubscribed: makeSelectIsSubscribed(contentChannelUri, true)(state), isSubscribed: selectIsSubscribedForUri(state, contentChannelUri),
channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state), channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state),
isAdmin: selectHasAdminChannel(state), isAdmin: selectHasAdminChannel(state),
claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state), claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state),

View file

@ -1,13 +1,12 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
selectClaimForUri, selectClaimForUri,
makeSelectIsUriResolving, selectIsUriResolving,
selectClaimIsMine, selectClaimIsMine,
makeSelectClaimIsPending, makeSelectClaimIsPending,
makeSelectClaimIsNsfw,
makeSelectReflectingClaimForUri, makeSelectReflectingClaimForUri,
makeSelectClaimWasPurchased, makeSelectClaimWasPurchased,
makeSelectTitleForUri, selectTitleForUri,
selectDateForUri, selectDateForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info';
@ -23,7 +22,8 @@ import { doFileGet } from 'redux/actions/file';
import { selectBanStateForUri } from 'lbryinc'; import { selectBanStateForUri } from 'lbryinc';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import { makeSelectHasVisitedUri } from 'redux/selectors/content'; 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 ClaimPreview from './view';
import formatMediaDuration from 'util/formatMediaDuration'; import formatMediaDuration from 'util/formatMediaDuration';
@ -36,17 +36,17 @@ const select = (state, props) => {
claim, claim,
mediaDuration, mediaDuration,
date: props.uri && selectDateForUri(state, props.uri), 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), pending: props.uri && makeSelectClaimIsPending(props.uri)(state),
reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state), reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state),
obscureNsfw: selectShowMatureContent(state) === false, obscureNsfw: selectShowMatureContent(state) === false,
claimIsMine: props.uri && selectClaimIsMine(state, claim), claimIsMine: props.uri && selectClaimIsMine(state, claim),
isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), isResolvingUri: props.uri && selectIsUriResolving(state, props.uri),
isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state), isResolvingRepost: props.uri && selectIsUriResolving(state, props.repostUrl),
nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state), nsfw: claim ? isClaimNsfw(claim) : false,
banState: selectBanStateForUri(state, props.uri), banState: selectBanStateForUri(state, props.uri),
hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state), 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), streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state),
wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state), wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state), isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state),

View file

@ -1,18 +1,16 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectIsUriResolving, selectIsUriResolving,
makeSelectThumbnailForUri, getThumbnailFromClaim,
makeSelectTitleForUri, selectTitleForUri,
makeSelectChannelForClaimUri,
makeSelectClaimIsNsfw,
selectDateForUri, selectDateForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doFileGet } from 'redux/actions/file'; import { doFileGet } from 'redux/actions/file';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { selectMutedChannels } from 'redux/selectors/blocked';
import { selectViewCountForUri, selectBanStateForUri } from 'lbryinc'; import { selectViewCountForUri, selectBanStateForUri } from 'lbryinc';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import { isClaimNsfw } from 'util/claim';
import ClaimPreviewTile from './view'; import ClaimPreviewTile from './view';
import formatMediaDuration from 'util/formatMediaDuration'; import formatMediaDuration from 'util/formatMediaDuration';
@ -25,14 +23,12 @@ const select = (state, props) => {
claim, claim,
mediaDuration, mediaDuration,
date: props.uri && selectDateForUri(state, props.uri), date: props.uri && selectDateForUri(state, props.uri),
channel: props.uri && makeSelectChannelForClaimUri(props.uri)(state), isResolvingUri: props.uri && selectIsUriResolving(state, props.uri),
isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), thumbnail: getThumbnailFromClaim(claim),
thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), title: props.uri && selectTitleForUri(state, props.uri),
title: props.uri && makeSelectTitleForUri(props.uri)(state),
banState: selectBanStateForUri(state, props.uri), banState: selectBanStateForUri(state, props.uri),
blockedChannelUris: selectMutedChannels(state),
showMature: selectShowMatureContent(state), showMature: selectShowMatureContent(state),
isMature: makeSelectClaimIsNsfw(props.uri)(state), isMature: claim ? isClaimNsfw(claim) : false,
viewCount: selectViewCountForUri(state, props.uri), viewCount: selectViewCountForUri(state, props.uri),
}; };
}; };

View file

@ -1,10 +1,10 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
import ClaimPreviewTitle from './view'; import ClaimPreviewTitle from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
}); });
export default connect(select)(ClaimPreviewTitle); export default connect(select)(ClaimPreviewTitle);

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims'; import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions';
import ClaimProperties from './view'; import ClaimProperties from './view';
const select = (state, props) => { const select = (state, props) => {
@ -8,7 +8,7 @@ const select = (state, props) => {
return { return {
claim, claim,
isSubscribed: makeSelectIsSubscribed(props.uri)(state), isSubscribed: selectIsSubscribedForUri(state, props.uri),
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
}; };
}; };

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectTitleForUri, selectTitleForUri,
makeSelectThumbnailForUri, selectThumbnailForUri,
makeSelectMetadataItemForUri, makeSelectMetadataItemForUri,
makeSelectAmountForUri, makeSelectAmountForUri,
makeSelectClaimForUri, makeSelectClaimForUri,
@ -25,8 +25,8 @@ import { doSetActiveChannel, doSetIncognito } from 'redux/actions/app';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
thumbnailUrl: makeSelectThumbnailForUri(props.uri)(state), thumbnailUrl: selectThumbnailForUri(state, props.uri),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state), description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
tags: makeSelectMetadataItemForUri(props.uri, 'tags')(state), tags: makeSelectMetadataItemForUri(props.uri, 'tags')(state),
locations: makeSelectMetadataItemForUri(props.uri, 'locations')(state), locations: makeSelectMetadataItemForUri(props.uri, 'locations')(state),

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectIsUriResolving, selectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims'; import { selectIsUriResolving, selectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims';
import { import {
makeSelectUrlsForCollectionId, makeSelectUrlsForCollectionId,
makeSelectNameForCollectionId, makeSelectNameForCollectionId,
@ -22,7 +22,7 @@ const select = (state, props) => {
collectionItemUrls: makeSelectUrlsForCollectionId(collectionId)(state), // ForId || ForUri collectionItemUrls: makeSelectUrlsForCollectionId(collectionId)(state), // ForId || ForUri
pendingCollection: makeSelectPendingCollectionForId(collectionId)(state), pendingCollection: makeSelectPendingCollectionForId(collectionId)(state),
claim, claim,
isResolvingUri: collectionUri && makeSelectIsUriResolving(collectionUri)(state), isResolvingUri: collectionUri && selectIsUriResolving(state, collectionUri),
}; };
}; };

View file

@ -1,8 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectIsUriResolving, selectIsUriResolving,
makeSelectThumbnailForUri, getThumbnailFromClaim,
makeSelectTitleForUri, selectTitleForUri,
makeSelectChannelForClaimUri, makeSelectChannelForClaimUri,
makeSelectClaimIsNsfw, makeSelectClaimIsNsfw,
selectClaimIdForUri, selectClaimIdForUri,
@ -39,9 +39,9 @@ const select = (state, props) => {
claim, claim,
isResolvingCollectionClaims: makeSelectIsResolvingCollectionForId(collectionId)(state), isResolvingCollectionClaims: makeSelectIsResolvingCollectionForId(collectionId)(state),
channelClaim: collectionUri && makeSelectChannelForClaimUri(collectionUri)(state), channelClaim: collectionUri && makeSelectChannelForClaimUri(collectionUri)(state),
isResolvingUri: collectionUri && makeSelectIsUriResolving(collectionUri)(state), isResolvingUri: collectionUri && selectIsUriResolving(state, collectionUri),
thumbnail: collectionUri && makeSelectThumbnailForUri(collectionUri)(state), thumbnail: getThumbnailFromClaim(claim),
title: collectionUri && makeSelectTitleForUri(collectionUri)(state), title: collectionUri && selectTitleForUri(state, collectionUri),
blackListedOutpoints: selectBlackListedOutpoints(state), blackListedOutpoints: selectBlackListedOutpoints(state),
filteredOutpoints: selectFilteredOutpoints(state), filteredOutpoints: selectFilteredOutpoints(state),
blockedChannelUris: selectMutedChannels(state), blockedChannelUris: selectMutedChannels(state),

View file

@ -2,7 +2,8 @@ import { connect } from 'react-redux';
import { import {
selectTotalStakedAmountForChannelUri, selectTotalStakedAmountForChannelUri,
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectThumbnailForUri, selectThumbnailForUri,
selectHasChannels,
selectMyChannelClaims, selectMyChannelClaims,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doCommentUpdate, doCommentList } from 'redux/actions/comments'; import { doCommentUpdate, doCommentList } from 'redux/actions/comments';
@ -25,11 +26,12 @@ const select = (state, props) => {
return { return {
claim: makeSelectClaimForUri(props.uri)(state), 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), channelIsBlocked: props.authorUri && makeSelectChannelIsMuted(props.authorUri)(state),
commentingEnabled: true, commentingEnabled: true,
othersReacts: selectOthersReactsForComment(state, reactionKey), othersReacts: selectOthersReactsForComment(state, reactionKey),
activeChannelClaim, activeChannelClaim,
hasChannels: selectHasChannels(state), //
myChannels: selectMyChannelClaims(state), myChannels: selectMyChannelClaims(state),
playingUri: selectPlayingUri(state), playingUri: selectPlayingUri(state),
stakedLevel: selectTotalStakedAmountForChannelUri(state, props.authorUri), stakedLevel: selectTotalStakedAmountForChannelUri(state, props.authorUri),

View file

@ -1,8 +1,8 @@
import { connect } from 'react-redux'; 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 { doResolveUri } from 'redux/actions/claims';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import { doFetchCostInfoForUri, makeSelectCostInfoForUri } from 'lbryinc'; import { doFetchCostInfoForUri, selectCostInfoForUri } from 'lbryinc';
import { doPlayUri, doSetPlayingUri } from 'redux/actions/content'; import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
import { doAnaltyicsPurchaseEvent } from 'redux/actions/app'; import { doAnaltyicsPurchaseEvent } from 'redux/actions/app';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
@ -11,10 +11,10 @@ import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
import ChannelThumbnail from './view'; import ChannelThumbnail from './view';
const select = (state, props) => ({ const select = (state, props) => ({
thumbnail: makeSelectThumbnailForUri(props.uri)(state), thumbnail: selectThumbnailForUri(state, props.uri),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
renderMode: makeSelectFileRenderModeForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
}); });

View file

@ -8,7 +8,7 @@ import {
import { makeSelectStreamingUrlForUri, makeSelectFileInfoForUri } from 'redux/selectors/file_info'; import { makeSelectStreamingUrlForUri, makeSelectFileInfoForUri } from 'redux/selectors/file_info';
import { doPrepareEdit } from 'redux/actions/publish'; import { doPrepareEdit } from 'redux/actions/publish';
import { DISABLE_COMMENTS_TAG } from 'constants/tags'; import { DISABLE_COMMENTS_TAG } from 'constants/tags';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { doSetPlayingUri, doPlayUri } from 'redux/actions/content'; import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { doOpenModal, doSetActiveChannel, doSetIncognito, doAnalyticsView } from 'redux/actions/app'; import { doOpenModal, doSetActiveChannel, doSetIncognito, doAnalyticsView } from 'redux/actions/app';
@ -24,7 +24,7 @@ const select = (state, props) => {
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
renderMode: makeSelectFileRenderModeForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
hasChannels: selectHasChannels(state), hasChannels: selectHasChannels(state),
reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state), reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),

View file

@ -6,7 +6,7 @@ import {
makeSelectLoadingForUri, makeSelectLoadingForUri,
makeSelectStreamingUrlForUri, makeSelectStreamingUrlForUri,
} from 'redux/selectors/file_info'; } from 'redux/selectors/file_info';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { doOpenModal, doAnalyticsView } from 'redux/actions/app'; import { doOpenModal, doAnalyticsView } from 'redux/actions/app';
import { doSetPlayingUri, doPlayUri } from 'redux/actions/content'; import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
import FileDownloadLink from './view'; import FileDownloadLink from './view';
@ -20,7 +20,7 @@ const select = (state, props) => {
loading: makeSelectLoadingForUri(props.uri)(state), loading: makeSelectLoadingForUri(props.uri)(state),
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
claim, claim,
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
}; };

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectClaimForUri, makeSelectClaimWasPurchased, selectClaimIsMine } from 'redux/selectors/claims'; import { selectClaimForUri, makeSelectClaimWasPurchased, selectClaimIsMine } from 'redux/selectors/claims';
import { makeSelectCostInfoForUri, doFetchCostInfoForUri, makeSelectFetchingCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri, doFetchCostInfoForUri, selectFetchingCostInfoForUri } from 'lbryinc';
import FilePrice from './view'; import FilePrice from './view';
const select = (state, props) => { const select = (state, props) => {
@ -10,8 +10,8 @@ const select = (state, props) => {
claim, claim,
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
fetching: makeSelectFetchingCostInfoForUri(props.uri)(state), fetching: selectFetchingCostInfoForUri(state, props.uri),
}; };
}; };

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectDownloadPathForUri, makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; 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 * as SETTINGS from 'constants/settings';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content'; import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content';
@ -11,7 +11,7 @@ const select = (state, props) => {
return { return {
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
thumbnail: makeSelectThumbnailForUri(props.uri)(state), thumbnail: selectThumbnailForUri(state, props.uri),
contentType: makeSelectContentTypeForUri(props.uri)(state), contentType: makeSelectContentTypeForUri(props.uri)(state),
downloadPath: makeSelectDownloadPathForUri(props.uri)(state), downloadPath: makeSelectDownloadPathForUri(props.uri)(state),
fileExtension: makeSelectFileExtensionForUri(props.uri)(state), fileExtension: makeSelectFileExtensionForUri(props.uri)(state),

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; 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 { makeSelectFileInfoForUri, makeSelectStreamingUrlForUri } from 'redux/selectors/file_info';
import { import {
makeSelectNextUrlForCollectionAndUrl, makeSelectNextUrlForCollectionAndUrl,
@ -13,7 +13,7 @@ import {
makeSelectFileRenderModeForUri, makeSelectFileRenderModeForUri,
} from 'redux/selectors/content'; } from 'redux/selectors/content';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { doPlayUri, doSetPlayingUri } from 'redux/actions/content'; import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
import { doFetchRecommendedContent } from 'redux/actions/search'; import { doFetchRecommendedContent } from 'redux/actions/search';
import { doAnaltyicsPurchaseEvent } from 'redux/actions/app'; import { doAnaltyicsPurchaseEvent } from 'redux/actions/app';
@ -30,7 +30,7 @@ const select = (state, props) => {
uri, uri,
primaryUri, primaryUri,
playingUri, playingUri,
title: makeSelectTitleForUri(uri)(state), title: selectTitleForUri(state, uri),
fileInfo: makeSelectFileInfoForUri(uri)(state), fileInfo: makeSelectFileInfoForUri(uri)(state),
mature: makeSelectClaimIsNsfw(uri)(state), mature: makeSelectClaimIsNsfw(uri)(state),
isFloating: makeSelectIsPlayerFloating(props.location)(state), isFloating: makeSelectIsPlayerFloating(props.location)(state),
@ -38,7 +38,7 @@ const select = (state, props) => {
floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), floatingPlayerEnabled: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
renderMode: makeSelectFileRenderModeForUri(uri)(state), renderMode: makeSelectFileRenderModeForUri(uri)(state),
videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state), videoTheaterMode: makeSelectClientSetting(SETTINGS.VIDEO_THEATER_MODE)(state),
costInfo: makeSelectCostInfoForUri(uri)(state), costInfo: selectCostInfoForUri(state, uri),
claimWasPurchased: makeSelectClaimWasPurchased(uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(uri)(state),
nextListUri: collectionId && makeSelectNextUrlForCollectionAndUrl(collectionId, uri)(state), nextListUri: collectionId && makeSelectNextUrlForCollectionAndUrl(collectionId, uri)(state),
previousListUri: collectionId && makeSelectPreviousUrlForCollectionAndUrl(collectionId, uri)(state), previousListUri: collectionId && makeSelectPreviousUrlForCollectionAndUrl(collectionId, uri)(state),

View file

@ -1,16 +1,16 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doPlayUri, doSetPlayingUri, doSetPrimaryUri } from 'redux/actions/content'; 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 { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import * as COLLECTIONS_CONSTS from 'constants/collections'; import * as COLLECTIONS_CONSTS from 'constants/collections';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { import {
makeSelectIsPlaying, makeSelectIsPlaying,
makeSelectShouldObscurePreview, selectShouldObscurePreviewForUri,
makeSelectInsufficientCreditsForUri, selectInsufficientCreditsForUri,
makeSelectFileRenderModeForUri, makeSelectFileRenderModeForUri,
} from 'redux/selectors/content'; } from 'redux/selectors/content';
import FileRenderInitiator from './view'; import FileRenderInitiator from './view';
@ -22,13 +22,13 @@ const select = (state, props) => {
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID); const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
return { return {
claimThumbnail: makeSelectThumbnailForUri(props.uri)(state), claimThumbnail: selectThumbnailForUri(state, props.uri),
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
obscurePreview: makeSelectShouldObscurePreview(props.uri)(state), obscurePreview: selectShouldObscurePreviewForUri(state, props.uri),
isPlaying: makeSelectIsPlaying(props.uri)(state), isPlaying: makeSelectIsPlaying(props.uri)(state),
insufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), insufficientCredits: selectInsufficientCreditsForUri(state, props.uri),
autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY_MEDIA)(state), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY_MEDIA)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
renderMode: makeSelectFileRenderModeForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),

View file

@ -6,14 +6,14 @@ import { makeSelectFileRenderModeForUri, selectPrimaryUri } from 'redux/selector
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { doAnalyticsView } from 'redux/actions/app'; import { doAnalyticsView } from 'redux/actions/app';
import FileRenderInline from './view'; import FileRenderInline from './view';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
const select = (state, props) => ({ const select = (state, props) => ({
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
isPlaying: selectPrimaryUri(state) === props.uri, isPlaying: selectPrimaryUri(state) === props.uri,
streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state), streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
renderMode: makeSelectFileRenderModeForUri(props.uri)(state), renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
}); });

View file

@ -1,9 +1,9 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectTitleForUri } from 'redux/selectors/claims'; import { selectTitleForUri } from 'redux/selectors/claims';
import FileTitleSection from './view'; import FileTitleSection from './view';
const select = (state, props) => ({ const select = (state, props) => ({
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
}); });
export default connect(select)(FileTitleSection); export default connect(select)(FileTitleSection);

View file

@ -1,18 +1,18 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchSubCount, selectSubCountForUri } from 'lbryinc'; import { doFetchSubCount, selectSubCountForUri } from 'lbryinc';
import { makeSelectTitleForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; import { selectTitleForUri, selectClaimForUri } from 'redux/selectors/claims';
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; import { selectInsufficientCreditsForUri } from 'redux/selectors/content';
import FileTitleSection from './view'; import FileTitleSection from './view';
const select = (state, props) => { 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 channelClaimId = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined;
const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined; const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined;
const subCount = channelUri && selectSubCountForUri(state, channelUri); const subCount = channelUri && selectSubCountForUri(state, channelUri);
return { return {
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), isInsufficientCredits: selectInsufficientCreditsForUri(state, props.uri),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
channelClaimId, channelClaimId,
subCount, subCount,
}; };

View file

@ -1,11 +1,11 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import fileViewerEmbeddedTitle from './view'; import fileViewerEmbeddedTitle from './view';
import { makeSelectTagInClaimOrChannelForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; import { makeSelectTagInClaimOrChannelForUri, selectTitleForUri } from 'redux/selectors/claims';
import { PREFERENCE_EMBED } from 'constants/tags'; import { PREFERENCE_EMBED } from 'constants/tags';
export default connect((state, props) => { export default connect((state, props) => {
return { return {
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
preferEmbed: makeSelectTagInClaimOrChannelForUri(props.uri, PREFERENCE_EMBED)(state), preferEmbed: makeSelectTagInClaimOrChannelForUri(props.uri, PREFERENCE_EMBED)(state),
}; };
})(fileViewerEmbeddedTitle); })(fileViewerEmbeddedTitle);

View file

@ -5,7 +5,7 @@ import { selectUser, selectSetReferrerPending, selectSetReferrerError } from 're
import { doClaimRewardType } from 'redux/actions/rewards'; import { doClaimRewardType } from 'redux/actions/rewards';
import { selectUnclaimedRewards } from 'redux/selectors/rewards'; import { selectUnclaimedRewards } from 'redux/selectors/rewards';
import { doUserSetReferrer } from 'redux/actions/user'; 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 { doChannelSubscribe } from 'redux/actions/subscriptions';
import Invited from './view'; import Invited from './view';
@ -15,16 +15,16 @@ const select = (state, props) => {
referrerSetPending: selectSetReferrerPending(state), referrerSetPending: selectSetReferrerPending(state),
referrerSetError: selectSetReferrerError(state), referrerSetError: selectSetReferrerError(state),
rewards: selectUnclaimedRewards(state), rewards: selectUnclaimedRewards(state),
isSubscribed: makeSelectIsSubscribed(props.fullUri)(state), isSubscribed: selectIsSubscribedForUri(state, props.fullUri),
fullUri: props.fullUri, fullUri: props.fullUri,
referrer: props.referrer, referrer: props.referrer,
}; };
}; };
const perform = dispatch => ({ const perform = (dispatch) => ({
claimReward: () => dispatch(doClaimRewardType(REWARDS.TYPE_REFEREE)), claimReward: () => dispatch(doClaimRewardType(REWARDS.TYPE_REFEREE)),
setReferrer: referrer => dispatch(doUserSetReferrer(referrer)), setReferrer: (referrer) => dispatch(doUserSetReferrer(referrer)),
channelSubscribe: uri => dispatch(doChannelSubscribe(uri)), channelSubscribe: (uri) => dispatch(doChannelSubscribe(uri)),
}); });
export default withRouter(connect(select, perform)(Invited)); export default withRouter(connect(select, perform)(Invited));

View file

@ -1,10 +1,10 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
selectClaimIsMine, selectClaimIsMine,
makeSelectTitleForUri, selectTitleForUri,
makeSelectThumbnailForUri, getThumbnailFromClaim,
selectClaimForUri, selectClaimForUri,
makeSelectIsUriResolving, selectIsUriResolving,
makeSelectMetadataItemForUri, makeSelectMetadataItemForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
@ -17,11 +17,11 @@ const select = (state, props) => {
return { return {
uri: props.uri, uri: props.uri,
claim, claim,
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
thumbnail: makeSelectThumbnailForUri(props.uri)(state), thumbnail: getThumbnailFromClaim(claim),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state), description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
channelIsMine: selectClaimIsMine(state, claim), channelIsMine: selectClaimIsMine(state, claim),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state), isResolvingUri: selectIsUriResolving(state, props.uri),
blackListedOutpoints: selectBlackListedOutpoints(state), blackListedOutpoints: selectBlackListedOutpoints(state),
}; };
}; };

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims'; import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
import { makeSelectFilePartlyDownloaded } from 'redux/selectors/file_info'; import { makeSelectFilePartlyDownloaded } from 'redux/selectors/file_info';
import { makeSelectEditedCollectionForId } from 'redux/selectors/collections'; import { makeSelectEditedCollectionForId } from 'redux/selectors/collections';
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions';
import PreviewOverlayProperties from './view'; import PreviewOverlayProperties from './view';
const select = (state, props) => { const select = (state, props) => {
@ -13,7 +13,7 @@ const select = (state, props) => {
claim, claim,
editedCollection: makeSelectEditedCollectionForId(claimId)(state), editedCollection: makeSelectEditedCollectionForId(claimId)(state),
downloaded: makeSelectFilePartlyDownloaded(props.uri)(state), downloaded: makeSelectFilePartlyDownloaded(props.uri)(state),
isSubscribed: makeSelectIsSubscribed(props.uri)(state), isSubscribed: selectIsSubscribedForUri(state, props.uri),
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
}; };
}; };

View file

@ -2,13 +2,13 @@ import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app'; import { doHideModal } from 'redux/actions/app';
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectTitleForUri, selectTitleForUri,
selectMyChannelClaims, selectMyChannelClaims,
selectRepostError, selectRepostError,
selectRepostLoading, selectRepostLoading,
selectMyClaimsWithoutChannels, selectMyClaimsWithoutChannels,
makeSelectEffectiveAmountForUri, makeSelectEffectiveAmountForUri,
makeSelectIsUriResolving, selectIsUriResolving,
selectFetchingMyChannels, selectFetchingMyChannels,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
@ -31,13 +31,13 @@ const select = (state, props) => ({
enteredContentClaim: makeSelectClaimForUri(props.contentUri)(state), enteredContentClaim: makeSelectClaimForUri(props.contentUri)(state),
enteredRepostClaim: makeSelectClaimForUri(props.repostUri, false)(state), enteredRepostClaim: makeSelectClaimForUri(props.repostUri, false)(state),
enteredRepostAmount: makeSelectEffectiveAmountForUri(props.repostUri)(state), enteredRepostAmount: makeSelectEffectiveAmountForUri(props.repostUri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
balance: selectBalance(state), balance: selectBalance(state),
error: selectRepostError(state), error: selectRepostError(state),
reposting: selectRepostLoading(state), reposting: selectRepostLoading(state),
myClaims: selectMyClaimsWithoutChannels(state), myClaims: selectMyClaimsWithoutChannels(state),
isResolvingPassedRepost: props.name && makeSelectIsUriResolving(`lbry://${props.name}`)(state), isResolvingPassedRepost: props.name && selectIsUriResolving(state, `lbry://${props.name}`),
isResolvingEnteredRepost: props.repostUri && makeSelectIsUriResolving(`lbry://${props.repostUri}`)(state), isResolvingEnteredRepost: props.repostUri && selectIsUriResolving(state, `lbry://${props.repostUri}`),
activeChannelClaim: selectActiveChannelClaim(state), activeChannelClaim: selectActiveChannelClaim(state),
fetchingMyChannels: selectFetchingMyChannels(state), fetchingMyChannels: selectFetchingMyChannels(state),
incognito: selectIncognito(state), incognito: selectIncognito(state),

View file

@ -4,7 +4,7 @@ import { selectHasNavigated, selectScrollStartingPosition, selectWelcomeVersion
import { selectHomepageData } from 'redux/selectors/settings'; import { selectHomepageData } from 'redux/selectors/settings';
import Router from './view'; import Router from './view';
import { normalizeURI } from 'util/lbryURI'; import { normalizeURI } from 'util/lbryURI';
import { makeSelectTitleForUri } from 'redux/selectors/claims'; import { selectTitleForUri } from 'redux/selectors/claims';
import { doSetHasNavigated } from 'redux/actions/app'; import { doSetHasNavigated } from 'redux/actions/app';
import { doUserSetReferrer } from 'redux/actions/user'; import { doUserSetReferrer } from 'redux/actions/user';
import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards'; import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
@ -28,7 +28,7 @@ const select = (state) => {
return { return {
uri, uri,
title: makeSelectTitleForUri(uri)(state), title: selectTitleForUri(state, uri),
currentScroll: selectScrollStartingPosition(state), currentScroll: selectScrollStartingPosition(state),
isAuthenticated: selectUserVerifiedEmail(state), isAuthenticated: selectUserVerifiedEmail(state),
welcomeVersion: selectWelcomeVersion(state), welcomeVersion: selectWelcomeVersion(state),

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import { doClearPublish, doPrepareEdit } from 'redux/actions/publish'; import { doClearPublish, doPrepareEdit } from 'redux/actions/publish';
import { doResolveUris } from 'redux/actions/claims'; import { doResolveUris } from 'redux/actions/claims';
import { selectPendingIds, makeSelectClaimForUri } from 'redux/selectors/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 SearchTopClaim from './view';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
@ -13,7 +13,7 @@ const select = (state, props) => {
return { return {
winningUri, winningUri,
winningClaim: winningUri ? makeSelectClaimForUri(winningUri)(state) : undefined, 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), pendingIds: selectPendingIds(state),
}; };
}; };

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectTitleForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims';
import SocialShare from './view'; import SocialShare from './view';
import { makeSelectContentPositionForUri } from 'redux/selectors/content'; import { makeSelectContentPositionForUri } from 'redux/selectors/content';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
@ -7,7 +7,7 @@ import * as SETTINGS from 'constants/settings';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
position: makeSelectContentPositionForUri(props.uri)(state), position: makeSelectContentPositionForUri(props.uri)(state),
customShareUrlEnabled: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL_ENABLED)(state), customShareUrlEnabled: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL_ENABLED)(state),
customShareUrl: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL)(state), customShareUrl: makeSelectClientSetting(SETTINGS.CUSTOM_SHARE_URL)(state),

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions'; import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
import { import {
makeSelectIsSubscribed, selectIsSubscribedForUri,
selectFirstRunCompleted, selectFirstRunCompleted,
makeSelectNotificationsDisabled, makeSelectNotificationsDisabled,
} from 'redux/selectors/subscriptions'; } from 'redux/selectors/subscriptions';
@ -11,7 +11,7 @@ import { doToast } from 'redux/actions/notifications';
import SubscribeButton from './view'; import SubscribeButton from './view';
const select = (state, props) => ({ const select = (state, props) => ({
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), isSubscribed: selectIsSubscribedForUri(state, props.uri),
firstRunCompleted: selectFirstRunCompleted(state), firstRunCompleted: selectFirstRunCompleted(state),
permanentUrl: makeSelectPermanentUrlForUri(props.uri)(state), permanentUrl: makeSelectPermanentUrlForUri(props.uri)(state),
notificationsDisabled: makeSelectNotificationsDisabled(props.uri)(state), notificationsDisabled: makeSelectNotificationsDisabled(props.uri)(state),

View file

@ -1,12 +1,12 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { normalizeURI } from 'util/lbryURI'; import { normalizeURI } from 'util/lbryURI';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { makeSelectIsUriResolving, makeSelectClaimForUri } from 'redux/selectors/claims'; import { selectIsUriResolving, makeSelectClaimForUri } from 'redux/selectors/claims';
import UriIndicator from './view'; import UriIndicator from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state), isResolvingUri: selectIsUriResolving(state, props.uri),
uri: normalizeURI(props.uri), uri: normalizeURI(props.uri),
}); });

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectThumbnailForUri } from 'redux/selectors/claims'; import { makeSelectClaimForUri, selectThumbnailForUri } from 'redux/selectors/claims';
import { import {
makeSelectNextUrlForCollectionAndUrl, makeSelectNextUrlForCollectionAndUrl,
makeSelectPreviousUrlForCollectionAndUrl, makeSelectPreviousUrlForCollectionAndUrl,
@ -56,7 +56,7 @@ const select = (state, props) => {
volume: selectVolume(state), volume: selectVolume(state),
muted: selectMute(state), muted: selectMute(state),
videoPlaybackRate: makeSelectClientSetting(SETTINGS.VIDEO_PLAYBACK_RATE)(state), videoPlaybackRate: makeSelectClientSetting(SETTINGS.VIDEO_PLAYBACK_RATE)(state),
thumbnail: makeSelectThumbnailForUri(uri)(state), thumbnail: selectThumbnailForUri(state, uri),
claim: makeSelectClaimForUri(uri)(state), claim: makeSelectClaimForUri(uri)(state),
homepageData: selectHomepageData(state), homepageData: selectHomepageData(state),
shareTelemetry: selectDaemonSettings(state).share_usage_data, shareTelemetry: selectDaemonSettings(state).share_usage_data,

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectTitleForUri, selectTitleForUri,
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectClaimIsMine, makeSelectClaimIsMine,
selectFetchingMyChannels, selectFetchingMyChannels,
@ -18,7 +18,7 @@ import { selectUserVerifiedEmail } from 'redux/selectors/user';
const select = (state, props) => ({ const select = (state, props) => ({
isPending: selectIsSendingSupport(state), isPending: selectIsSendingSupport(state),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
claim: makeSelectClaimForUri(props.uri, false)(state), claim: makeSelectClaimForUri(props.uri, false)(state),
balance: selectBalance(state), balance: selectBalance(state),
instantTipEnabled: makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state), instantTipEnabled: makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state),

View file

@ -1,10 +1,10 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims'; import { selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims';
import WunderbarSuggestion from './view'; import WunderbarSuggestion from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: selectClaimForUri(state, props.uri),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state), isResolvingUri: selectIsUriResolving(state, props.uri),
}); });
export default connect(select)(WunderbarSuggestion); export default connect(select)(WunderbarSuggestion);

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectIsUriResolving, selectIsUriResolving,
makeSelectTagInClaimOrChannelForUri, makeSelectTagInClaimOrChannelForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doResolveUris } from 'redux/actions/claims'; import { doResolveUris } from 'redux/actions/claims';
@ -23,7 +23,7 @@ const select = (state, props) => {
} }
} catch (e) {} } 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 winningUri = makeSelectWinningUriForQuery(props.query)(state);
const winningClaim = winningUri ? makeSelectClaimForUri(winningUri)(state) : undefined; const winningClaim = winningUri ? makeSelectClaimForUri(winningUri)(state) : undefined;
const preferEmbed = makeSelectTagInClaimOrChannelForUri(winningUri, PREFERENCE_EMBED)(state); const preferEmbed = makeSelectTagInClaimOrChannelForUri(winningUri, PREFERENCE_EMBED)(state);

View file

@ -1,18 +1,18 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file'; import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file';
import { import {
makeSelectTitleForUri, selectTitleForUri,
selectClaimForUri, selectClaimForUri,
makeSelectIsAbandoningClaimForUri, makeSelectIsAbandoningClaimForUri,
makeSelectClaimIsMine, selectClaimIsMineForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { doHideModal } from 'redux/actions/app'; import { doHideModal } from 'redux/actions/app';
import ModalRemoveFile from './view'; import ModalRemoveFile from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claimIsMine: makeSelectClaimIsMine(props.uri)(state), claimIsMine: selectClaimIsMineForUri(state, props.uri),
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
claim: selectClaimForUri(state, props.uri), claim: selectClaimForUri(state, props.uri),
isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state), isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state),
}); });

View file

@ -1,8 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
selectClaimIsMine, selectClaimIsMine,
makeSelectTitleForUri, selectTitleForUri,
makeSelectThumbnailForUri, getThumbnailFromClaim,
makeSelectCoverForUri, makeSelectCoverForUri,
selectCurrentChannelPage, selectCurrentChannelPage,
selectClaimForUri, selectClaimForUri,
@ -11,7 +11,7 @@ import {
import { selectMyUnpublishedCollections } from 'redux/selectors/collections'; import { selectMyUnpublishedCollections } from 'redux/selectors/collections';
import { selectBlackListedOutpoints, doFetchSubCount, selectSubCountForUri } from 'lbryinc'; // ban state import { selectBlackListedOutpoints, doFetchSubCount, selectSubCountForUri } from 'lbryinc'; // ban state
import { selectYoutubeChannels } from 'redux/selectors/user'; 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 { selectModerationBlockList } from 'redux/selectors/comments';
import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectMutedChannels } from 'redux/selectors/blocked';
import { doOpenModal } from 'redux/actions/app'; import { doOpenModal } from 'redux/actions/app';
@ -21,13 +21,13 @@ const select = (state, props) => {
const claim = selectClaimForUri(state, props.uri); const claim = selectClaimForUri(state, props.uri);
return { return {
title: makeSelectTitleForUri(props.uri)(state), title: selectTitleForUri(state, props.uri),
thumbnail: makeSelectThumbnailForUri(props.uri)(state), thumbnail: getThumbnailFromClaim(claim),
cover: makeSelectCoverForUri(props.uri)(state), cover: makeSelectCoverForUri(props.uri)(state),
channelIsMine: selectClaimIsMine(state, claim), channelIsMine: selectClaimIsMine(state, claim),
page: selectCurrentChannelPage(state), page: selectCurrentChannelPage(state),
claim, claim,
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), isSubscribed: selectIsSubscribedForUri(state, props.uri),
blackListedOutpoints: selectBlackListedOutpoints(state), blackListedOutpoints: selectBlackListedOutpoints(state),
subCount: selectSubCountForUri(state, props.uri), subCount: selectSubCountForUri(state, props.uri),
pending: makeSelectClaimIsPending(props.uri)(state), pending: makeSelectClaimIsPending(props.uri)(state),

View file

@ -3,8 +3,8 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import CollectionPage from './view'; import CollectionPage from './view';
import { import {
makeSelectTitleForUri, selectTitleForUri,
makeSelectThumbnailForUri, getThumbnailFromClaim,
selectClaimIsMine, selectClaimIsMine,
makeSelectClaimIsPending, makeSelectClaimIsPending,
makeSelectClaimForClaimId, makeSelectClaimForClaimId,
@ -38,8 +38,8 @@ const select = (state, props) => {
collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state), collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state),
collectionCount: makeSelectCountForCollectionId(collectionId)(state), collectionCount: makeSelectCountForCollectionId(collectionId)(state),
isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state), isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state),
title: makeSelectTitleForUri(uri)(state), title: selectTitleForUri(state, uri),
thumbnail: makeSelectThumbnailForUri(uri)(state), thumbnail: getThumbnailFromClaim(claim),
isMyClaim: selectClaimIsMine(state, claim), // or collection is mine? isMyClaim: selectClaimIsMine(state, claim), // or collection is mine?
isMyCollection: makeSelectCollectionIsMine(collectionId)(state), isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
claimIsPending: makeSelectClaimIsPending(uri)(state), claimIsPending: makeSelectClaimIsPending(uri)(state),

View file

@ -11,7 +11,7 @@ import { doFetchFileInfo } from 'redux/actions/file_info';
import { makeSelectCollectionForId } from 'redux/selectors/collections'; import { makeSelectCollectionForId } from 'redux/selectors/collections';
import * as COLLECTIONS_CONSTS from 'constants/collections'; import * as COLLECTIONS_CONSTS from 'constants/collections';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import { makeSelectCostInfoForUri, doFetchCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri, doFetchCostInfoForUri } from 'lbryinc';
import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings'; import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings';
import { makeSelectFileRenderModeForUri, makeSelectContentPositionForUri } from 'redux/selectors/content'; import { makeSelectFileRenderModeForUri, makeSelectContentPositionForUri } from 'redux/selectors/content';
import { DISABLE_COMMENTS_TAG } from 'constants/tags'; import { DISABLE_COMMENTS_TAG } from 'constants/tags';
@ -25,7 +25,7 @@ const select = (state, props) => {
return { return {
linkedCommentId: urlParams.get('lc'), linkedCommentId: urlParams.get('lc'),
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: selectCostInfoForUri(state, props.uri),
metadata: makeSelectMetadataForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state),
obscureNsfw: !selectShowMatureContent(state), obscureNsfw: !selectShowMatureContent(state),
isMature: makeSelectClaimIsNsfw(props.uri)(state), isMature: makeSelectClaimIsNsfw(props.uri)(state),

View file

@ -4,10 +4,10 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { PAGE_SIZE } from 'constants/claim'; import { PAGE_SIZE } from 'constants/claim';
import { import {
selectIsUriResolving,
selectClaimForUri, selectClaimForUri,
makeSelectIsUriResolving,
makeSelectTotalPagesForChannel, makeSelectTotalPagesForChannel,
makeSelectTitleForUri, selectTitleForUri,
selectClaimIsMine, selectClaimIsMine,
makeSelectClaimIsPending, makeSelectClaimIsPending,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
@ -71,11 +71,11 @@ const select = (state, props) => {
return { return {
uri, uri,
claim, claim,
isResolvingUri: makeSelectIsUriResolving(uri)(state), isResolvingUri: selectIsUriResolving(state, uri),
blackListedOutpoints: selectBlackListedOutpoints(state), blackListedOutpoints: selectBlackListedOutpoints(state),
totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state), totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state),
isSubscribed: makeSelectChannelInSubscriptions(uri)(state), isSubscribed: makeSelectChannelInSubscriptions(uri)(state),
title: makeSelectTitleForUri(uri)(state), title: selectTitleForUri(state, uri),
claimIsMine: selectClaimIsMine(state, claim), claimIsMine: selectClaimIsMine(state, claim),
claimIsPending: makeSelectClaimIsPending(uri)(state), claimIsPending: makeSelectClaimIsPending(uri)(state),
collection: makeSelectCollectionForId(collectionId)(state), collection: makeSelectCollectionForId(collectionId)(state),

View file

@ -22,7 +22,7 @@ import { doToast } from 'redux/actions/notifications';
import { doPurchaseUri } from 'redux/actions/file'; import { doPurchaseUri } from 'redux/actions/file';
import Lbry from 'lbry'; import Lbry from 'lbry';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import { makeSelectCostInfoForUri, Lbryio } from 'lbryinc'; import { selectCostInfoForUri, Lbryio } from 'lbryinc';
import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings'; import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings';
const DOWNLOAD_POLL_INTERVAL = 1000; const DOWNLOAD_POLL_INTERVAL = 1000;
@ -169,7 +169,7 @@ export function doPlayUri(
} }
const daemonSettings = selectDaemonSettings(state); const daemonSettings = selectDaemonSettings(state);
const costInfo = makeSelectCostInfoForUri(uri)(state); const costInfo = selectCostInfoForUri(state, uri);
const cost = (costInfo && Number(costInfo.cost)) || 0; const cost = (costInfo && Number(costInfo.cost)) || 0;
const saveFile = !uriIsStreamable ? true : daemonSettings.save_files || saveFileOverride || cost > 0; const saveFile = !uriIsStreamable ? true : daemonSettings.save_files || saveFileOverride || cost > 0;
const instantPurchaseEnabled = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state); const instantPurchaseEnabled = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state);

View file

@ -22,7 +22,7 @@ import {
} from 'redux/selectors/file_info'; } from 'redux/selectors/file_info';
type Dispatch = (action: any) => any; type Dispatch = (action: any) => any;
type GetState = () => { file: FileState }; type GetState = () => { claims: any, file: FileState, content: any };
export function doOpenFileInFolder(path: string) { export function doOpenFileInFolder(path: string) {
return () => { return () => {
shell.showItemInFolder(path); shell.showItemInFolder(path);

View file

@ -12,7 +12,7 @@ import { getRecommendationSearchOptions } from 'util/search';
import { SEARCH_SERVER_API } from 'config'; import { SEARCH_SERVER_API } from 'config';
type Dispatch = (action: any) => any; type Dispatch = (action: any) => any;
type GetState = () => { search: SearchState }; type GetState = () => { claims: any, search: SearchState };
type SearchOptions = { type SearchOptions = {
size?: number, size?: number,

View file

@ -332,10 +332,11 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) =>
return byChannel['pageCount']; 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; const metadata = claim && claim.value;
return metadata || (claim === undefined ? undefined : null); return metadata || (claim === undefined ? undefined : null);
})((state, uri) => String(uri)); };
export const makeSelectMetadataForUri = (uri: string) => export const makeSelectMetadataForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => { createSelector(makeSelectClaimForUri(uri), (claim) => {
@ -348,8 +349,10 @@ export const makeSelectMetadataItemForUri = (uri: string, key: string) =>
return metadata ? metadata[key] : undefined; return metadata ? metadata[key] : undefined;
}); });
export const makeSelectTitleForUri = (uri: string) => export const selectTitleForUri = (state: State, uri: string) => {
createSelector(makeSelectMetadataForUri(uri), (metadata) => metadata && metadata.title); const metadata = selectMetadataForUri(state, uri);
return metadata && metadata.title;
};
export const selectDateForUri = createCachedSelector( export const selectDateForUri = createCachedSelector(
selectClaimForUri, // input: (state, uri, ?returnRepost) selectClaimForUri, // input: (state, uri, ?returnRepost)
@ -388,11 +391,14 @@ export const makeSelectContentTypeForUri = (uri: string) =>
return source ? source.media_type : undefined; return source ? source.media_type : undefined;
}); });
export const makeSelectThumbnailForUri = (uri: string) => export const getThumbnailFromClaim = (claim: Claim) => {
createSelector(makeSelectClaimForUri(uri), (claim) => {
const thumbnail = claim && claim.value && claim.value.thumbnail; const thumbnail = claim && claim.value && claim.value.thumbnail;
return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; 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) => export const makeSelectCoverForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => { 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 selectChannelImportPending = (state: State) => selectState(state).pendingChannelImport;
export const makeSelectIsUriResolving = (uri: string) => export const selectIsUriResolving = (state: State, uri: string) => {
createSelector(selectResolvingUris, (resolvingUris) => resolvingUris && resolvingUris.indexOf(uri) !== -1); const resolvingUris = selectResolvingUris(state);
return resolvingUris && resolvingUris.includes(uri);
};
export const selectPlayingUri = (state: State) => selectState(state).playingUri; 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) => export const makeSelectClaimIsNsfw = (uri: string) =>
createSelector( createSelector(
makeSelectClaimForUri(uri), makeSelectClaimForUri(uri),
@ -582,7 +601,6 @@ export const makeSelectClaimIsNsfw = (uri: string) =>
return isClaimNsfw(claim); return isClaimNsfw(claim);
} }
); );
// Returns the associated channel uri for a given claim uri // Returns the associated channel uri for a given claim uri
// accepts a regular claim uri lbry://something // accepts a regular claim uri lbry://something
// returns the channel uri that created this claim lbry://@channel // returns the channel uri that created this claim lbry://@channel
@ -644,15 +662,31 @@ export const selectClaimSearchByQueryLastPageReached = createSelector(
(state) => state.claimSearchByQueryLastPageReached || {} (state) => state.claimSearchByQueryLastPageReached || {}
); );
// Deprecated
export const makeSelectShortUrlForUri = (uri: string) => export const makeSelectShortUrlForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.short_url); createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.short_url);
// Deprecated
export const makeSelectCanonicalUrlForUri = (uri: string) => export const makeSelectCanonicalUrlForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.canonical_url); createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.canonical_url);
// Deprecated
export const makeSelectPermanentUrlForUri = (uri: string) => export const makeSelectPermanentUrlForUri = (uri: string) =>
createSelector(makeSelectClaimForUri(uri), (claim) => claim && claim.permanent_url); 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) => export const makeSelectSupportsForUri = (uri: string) =>
createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim: ?StreamClaim) => { createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim: ?StreamClaim) => {
if (!claim || !claim.is_my_output) { if (!claim || !claim.is_my_output) {

View file

@ -3,13 +3,14 @@ import { createSelector } from 'reselect';
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
selectClaimsByUri, selectClaimsByUri,
selectClaimIsNsfwForUri,
selectClaimIsMineForUri,
makeSelectClaimIsNsfw, makeSelectClaimIsNsfw,
makeSelectClaimIsMine,
makeSelectContentTypeForUri, makeSelectContentTypeForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { makeSelectMediaTypeForUri, makeSelectFileNameForUri } from 'redux/selectors/file_info'; import { makeSelectMediaTypeForUri, makeSelectFileNameForUri } from 'redux/selectors/file_info';
import { selectBalance } from 'redux/selectors/wallet'; import { selectBalance } from 'redux/selectors/wallet';
import { makeSelectCostInfoForUri } from 'lbryinc'; import { selectCostInfoForUri } from 'lbryinc';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import * as RENDER_MODES from 'constants/file_render_modes'; import * as RENDER_MODES from 'constants/file_render_modes';
import path from 'path'; 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 RECENT_HISTORY_AMOUNT = 10;
const HISTORY_ITEMS_PER_PAGE = 50; 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 selectState = (state: State) => state.content || {};
export const selectPrimaryUri = createSelector(selectState, (state) => state.primaryUri);
export const selectListLoop = createSelector(selectState, (state) => state.loopList); export const selectPlayingUri = (state: State) => selectState(state).playingUri;
export const selectListShuffle = createSelector(selectState, (state) => state.shuffleList); 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) => export const makeSelectIsPlaying = (uri: string) =>
createSelector(selectPrimaryUri, (primaryUri) => primaryUri === uri); createSelector(selectPrimaryUri, (primaryUri) => primaryUri === uri);
@ -84,6 +86,13 @@ export const selectRecentHistory = createSelector(selectHistory, (history) => {
return history.slice(0, RECENT_HISTORY_AMOUNT); 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) => export const makeSelectShouldObscurePreview = (uri: string) =>
createSelector(selectShowMatureContent, makeSelectClaimIsNsfw(uri), (showMatureContent, isClaimMature) => { createSelector(selectShowMatureContent, makeSelectClaimIsNsfw(uri), (showMatureContent, isClaimMature) => {
return isClaimMature && !showMatureContent; return isClaimMature && !showMatureContent;
@ -155,12 +164,9 @@ export const makeSelectFileRenderModeForUri = (uri: string) =>
} }
); );
export const makeSelectInsufficientCreditsForUri = (uri: string) => export const selectInsufficientCreditsForUri = (state: State, uri: string) => {
createSelector( const isMine = selectClaimIsMineForUri(state, uri);
makeSelectClaimIsMine(uri), const costInfo = selectCostInfoForUri(state, uri);
makeSelectCostInfoForUri(uri), const balance = selectBalance(state);
selectBalance,
(isMine, costInfo, balance) => {
return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance; return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance;
} };
);

View file

@ -8,7 +8,7 @@ import {
makeSelectClaimForClaimId, makeSelectClaimForClaimId,
makeSelectClaimIsNsfw, makeSelectClaimIsNsfw,
makeSelectPendingClaimForUri, makeSelectPendingClaimForUri,
makeSelectIsUriResolving, selectIsUriResolving,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { parseURI } from 'util/lbryURI'; import { parseURI } from 'util/lbryURI';
import { isClaimNsfw } from 'util/claim'; import { isClaimNsfw } from 'util/claim';
@ -18,7 +18,7 @@ import { selectMutedChannels } from 'redux/selectors/blocked';
import { selectHistory } from 'redux/selectors/content'; import { selectHistory } from 'redux/selectors/content';
import { selectAllCostInfoByUri } from 'lbryinc'; import { selectAllCostInfoByUri } from 'lbryinc';
type State = { search: SearchState }; type State = { claims: any, search: SearchState };
export const selectState = (state: State): SearchState => state.search; 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}`; const uriFromQuery = `lbry://${query}`;
let channelUriFromQuery; let channelUriFromQuery;
try { try {
@ -248,13 +248,9 @@ export const makeSelectIsResolvingWinningUri = (query: string = '') => {
} }
} catch (e) {} } catch (e) {}
return createSelector( const claim1IsResolving = selectIsUriResolving(state, uriFromQuery);
makeSelectIsUriResolving(uriFromQuery), const claim2IsResolving = channelUriFromQuery ? selectIsUriResolving(state, channelUriFromQuery) : false;
channelUriFromQuery ? makeSelectIsUriResolving(channelUriFromQuery) : () => {},
(claim1IsResolving, claim2IsResolving) => {
return claim1IsResolving || claim2IsResolving; return claim1IsResolving || claim2IsResolving;
}
);
}; };
export const makeSelectUrlForClaimId = (claimId: string) => export const makeSelectUrlForClaimId = (claimId: string) =>

View file

@ -1,12 +1,15 @@
import { SUGGESTED_FEATURED, SUGGESTED_TOP_SUBSCRIBED } from 'constants/subscriptions'; import { SUGGESTED_FEATURED, SUGGESTED_TOP_SUBSCRIBED } from 'constants/subscriptions';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { createCachedSelector } from 're-reselect';
import { parseURI, isURIEqual } from 'util/lbryURI'; import { parseURI, isURIEqual } from 'util/lbryURI';
import { import {
selectAllFetchingChannelClaims, selectAllFetchingChannelClaims,
makeSelectChannelForClaimUri, makeSelectChannelForClaimUri,
makeSelectClaimForUri, makeSelectClaimForUri,
selectClaimForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { swapKeyAndValue } from 'util/swap-json'; import { swapKeyAndValue } from 'util/swap-json';
import { getChannelFromClaim } from 'util/claim';
// Returns the entire subscriptions state // Returns the entire subscriptions state
const selectState = (state) => state.subscriptions || {}; const selectState = (state) => state.subscriptions || {};
@ -105,34 +108,18 @@ export const selectSubscriptionsBeingFetched = createSelector(
export const makeSelectChannelInSubscriptions = (uri) => export const makeSelectChannelInSubscriptions = (uri) =>
createSelector(selectSubscriptions, (subscriptions) => subscriptions.some((sub) => sub.uri === uri)); createSelector(selectSubscriptions, (subscriptions) => subscriptions.some((sub) => sub.uri === uri));
export const makeSelectIsSubscribed = (uri) => export const selectIsSubscribedForUri = createCachedSelector(
createSelector( selectClaimForUri,
selectSubscriptions, selectSubscriptions,
makeSelectChannelForClaimUri(uri, true), (claim, subscriptions) => {
makeSelectClaimForUri(uri), const channelClaim = getChannelFromClaim(claim);
(subscriptions, channelUri, claim) => { if (channelClaim) {
if (channelUri) { const uri = channelClaim.permanent_url;
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)); return subscriptions.some((sub) => isURIEqual(sub.uri, uri));
} }
if (isChannel && !claim) {
return subscriptions.some((sub) => isURIEqual(sub.uri, uri));
}
return false; return false;
} }
); )((state, uri) => String(uri));
export const makeSelectNotificationsDisabled = (uri) => export const makeSelectNotificationsDisabled = (uri) =>
createSelector( createSelector(

View file

@ -144,6 +144,32 @@ export function GetLinksData(
let rowData: Array<RowDataItem> = []; let rowData: Array<RowDataItem> = [];
const individualTagDataItems: Array<RowDataItem> = []; const individualTagDataItems: Array<RowDataItem> = [];
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<string>
rowData.push(RECENT_FROM_FOLLOWING);
}
// **************************************************************************
// @if CUSTOM_HOMEPAGE='false'
const YOUTUBER_CHANNEL_IDS = [ const YOUTUBER_CHANNEL_IDS = [
'fb364ef587872515f545a5b4b3182b58073f230f', 'fb364ef587872515f545a5b4b3182b58073f230f',
'589276465a23c589801d874f484cc39f307d7ec7', '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<string>
rowData.push(RECENT_FROM_FOLLOWING);
}
if (isHomepage && !CUSTOM_HOMEPAGE) { if (isHomepage && !CUSTOM_HOMEPAGE) {
if (followedTags) { if (followedTags) {
const TRENDING_FOR_TAGS = { const TRENDING_FOR_TAGS = {
@ -330,6 +334,7 @@ export function GetLinksData(
} }
} }
} }
if (!CUSTOM_HOMEPAGE) { if (!CUSTOM_HOMEPAGE) {
if (!authenticated) { if (!authenticated) {
rowData.push(YOUTUBE_CREATOR_ROW); rowData.push(YOUTUBE_CREATOR_ROW);
@ -338,6 +343,10 @@ export function GetLinksData(
rowData.push(LATEST_FROM_LBRY); rowData.push(LATEST_FROM_LBRY);
if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS); if (!showPersonalizedChannels) rowData.push(TOP_CHANNELS);
} }
// @endif
// **************************************************************************
// TODO: provide better method for exempting from homepage // TODO: provide better method for exempting from homepage
(Object.values(all): any) (Object.values(all): any)
.filter((row) => !(isHomepage && row.name === 'news')) .filter((row) => !(isHomepage && row.name === 'news'))