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.
This commit is contained in:
infinite-persistence 2021-11-12 23:59:11 +08:00 committed by zeppi
parent ea072febae
commit 049b1c727e
15 changed files with 68 additions and 54 deletions

View file

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

View file

@ -1,11 +1,11 @@
import { connect } from 'react-redux';
import { makeSelectThumbnailForUri, makeSelectClaimForUri, makeSelectIsUriResolving } from 'redux/selectors/claims';
import { selectThumbnailForUri, selectClaimForUri, makeSelectIsUriResolving } 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),
thumbnail: selectThumbnailForUri(state, props.uri),
claim: selectClaimForUri(state, props.uri),
isResolving: makeSelectIsUriResolving(props.uri)(state),
});

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import {
makeSelectClaimForUri,
makeSelectIsUriResolving,
makeSelectThumbnailForUri,
getThumbnailFromClaim,
makeSelectTitleForUri,
makeSelectChannelForClaimUri,
makeSelectClaimIsNsfw,
@ -27,7 +27,7 @@ const select = (state, props) => {
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),
thumbnail: getThumbnailFromClaim(claim),
title: props.uri && makeSelectTitleForUri(props.uri)(state),
banState: selectBanStateForUri(state, props.uri),
blockedChannelUris: selectMutedChannels(state),

View file

@ -1,7 +1,7 @@
import { connect } from 'react-redux';
import {
makeSelectTitleForUri,
makeSelectThumbnailForUri,
selectThumbnailForUri,
makeSelectMetadataItemForUri,
makeSelectAmountForUri,
makeSelectClaimForUri,
@ -26,7 +26,7 @@ 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),
thumbnailUrl: selectThumbnailForUri(state, props.uri),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
tags: makeSelectMetadataItemForUri(props.uri, 'tags')(state),
locations: makeSelectMetadataItemForUri(props.uri, 'locations')(state),

View file

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

View file

@ -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),

View file

@ -1,5 +1,5 @@
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';
@ -11,7 +11,7 @@ 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),

View file

@ -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),

View file

@ -1,6 +1,6 @@
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';
@ -22,7 +22,7 @@ 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),
isPlaying: makeSelectIsPlaying(props.uri)(state),

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import {
selectClaimIsMine,
makeSelectTitleForUri,
makeSelectThumbnailForUri,
getThumbnailFromClaim,
selectClaimForUri,
makeSelectIsUriResolving,
makeSelectMetadataItemForUri,
@ -18,7 +18,7 @@ const select = (state, props) => {
uri: props.uri,
claim,
title: makeSelectTitleForUri(props.uri)(state),
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
thumbnail: getThumbnailFromClaim(claim),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
channelIsMine: selectClaimIsMine(state, claim),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),

View file

@ -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,

View file

@ -2,7 +2,7 @@ import { connect } from 'react-redux';
import {
selectClaimIsMine,
makeSelectTitleForUri,
makeSelectThumbnailForUri,
getThumbnailFromClaim,
makeSelectCoverForUri,
selectCurrentChannelPage,
selectClaimForUri,
@ -22,7 +22,7 @@ const select = (state, props) => {
return {
title: makeSelectTitleForUri(props.uri)(state),
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
thumbnail: getThumbnailFromClaim(claim),
cover: makeSelectCoverForUri(props.uri)(state),
channelIsMine: selectClaimIsMine(state, claim),
page: selectCurrentChannelPage(state),

View file

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

View file

@ -388,11 +388,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) => {

View file

@ -144,6 +144,32 @@ export function GetLinksData(
let rowData: 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 = [
'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<string>
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'))