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

## Issue
Too slow for huge lists

## Change
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 GitHub
parent 529a9cbc40
commit 6d217dbc50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 190 additions and 197 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,
@ -28,7 +28,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),
showMature: selectShowMatureContent(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,7 @@ import { connect } from 'react-redux';
import {
selectStakedLevelForChannelUri,
makeSelectClaimForUri,
makeSelectThumbnailForUri,
selectThumbnailForUri,
selectHasChannels,
} from 'redux/selectors/claims';
import { doCommentUpdate, doCommentList } from 'redux/actions/comments';
@ -26,7 +26,7 @@ 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: IS_WEB ? Boolean(selectUserVerifiedEmail(state)) : true,
othersReacts: selectOthersReactsForComment(state, reactionKey),

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';
@ -23,7 +23,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,14 +2,14 @@ import { connect } from 'react-redux';
import {
makeSelectClaimForUri,
makeSelectTagInClaimOrChannelForUri,
makeSelectThumbnailForUri,
selectThumbnailForUri,
} from 'redux/selectors/claims';
import LivestreamLayout from './view';
import { DISABLE_COMMENTS_TAG } from 'constants/tags';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
thumbnail: selectThumbnailForUri(state, props.uri),
chatDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(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

@ -11,16 +11,19 @@ import NotificationBubble from 'component/notificationBubble';
import I18nMessage from 'component/i18nMessage';
import ChannelThumbnail from 'component/channelThumbnail';
import { GetLinksData } from 'util/buildHomepage';
import {
SIMPLE_SITE,
DOMAIN,
ENABLE_UI_NOTIFICATIONS,
ENABLE_NO_SOURCE_CLAIMS,
CHANNEL_STAKED_LEVEL_LIVESTREAM,
} from 'config';
// @if TARGET='app'
import { IS_MAC } from 'component/app/view';
// @endif
import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
const FOLLOWED_ITEM_INITIAL_LIMIT = 10;
type SideNavLink = {
title: string,
link?: string,
route?: string,
onClick?: () => any,
icon: string,
extra?: Node,
hideForUnauth?: boolean,
};
const HOME = {
title: 'Home',
@ -37,6 +40,39 @@ const RECENT_FROM_FOLLOWING = {
icon: ICONS.SUBSCRIBE,
};
const PLAYLISTS = {
title: 'Lists',
link: `/$/${PAGES.LISTS}`,
icon: ICONS.STACK,
hideForUnauth: true,
};
const UNAUTH_LINKS: Array<SideNavLink> = [
{
title: 'Log In',
link: `/$/${PAGES.AUTH_SIGNIN}`,
icon: ICONS.SIGN_IN,
},
{
title: 'Sign Up',
link: `/$/${PAGES.AUTH}`,
icon: ICONS.SIGN_UP,
},
{
title: 'Settings',
link: `/$/${PAGES.SETTINGS}`,
icon: ICONS.SETTINGS,
},
{
title: 'Help',
link: `/$/${PAGES.HELP}`,
icon: ICONS.HELP,
},
];
// ****************************************************************************
// ****************************************************************************
type Props = {
subscriptions: Array<Subscription>,
followedTags: Array<Tag>,
@ -55,16 +91,6 @@ type Props = {
activeChannelStakedLevel: number,
};
type SideNavLink = {
title: string,
link?: string,
route?: string,
onClick?: () => any,
icon: string,
extra?: Node,
hideForUnauth?: boolean,
};
function SideNavigation(props: Props) {
const {
subscriptions,
@ -85,26 +111,6 @@ function SideNavigation(props: Props) {
const EXTRA_SIDEBAR_LINKS = GetLinksData(homepageData).map(({ pinnedUrls, ...theRest }) => theRest);
const FULL_LINKS: Array<SideNavLink> = [
{
title: 'Your Tags',
link: `/$/${PAGES.TAGS_FOLLOWING}`,
icon: ICONS.TAG,
hideForUnauth: true,
},
{
title: 'Discover',
link: `/$/${PAGES.DISCOVER}`,
icon: ICONS.DISCOVER,
},
{
title: IS_WEB ? 'Purchased' : 'Library',
link: `/$/${PAGES.LIBRARY}`,
icon: ICONS.PURCHASED,
hideForUnauth: true,
},
];
const MOBILE_LINKS: Array<SideNavLink> = [
{
title: 'Notifications',
@ -181,56 +187,17 @@ function SideNavigation(props: Props) {
},
];
const UNAUTH_LINKS: Array<SideNavLink> = [
{
title: 'Log In',
link: `/$/${PAGES.AUTH_SIGNIN}`,
icon: ICONS.SIGN_IN,
},
{
title: 'Sign Up',
link: `/$/${PAGES.AUTH}`,
icon: ICONS.SIGN_UP,
},
{
title: 'Settings',
link: `/$/${PAGES.SETTINGS}`,
icon: ICONS.SETTINGS,
},
{
title: 'Help',
link: `/$/${PAGES.HELP}`,
icon: ICONS.HELP,
},
];
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
const isAuthenticated = Boolean(email);
// SIDE LINKS: FOLLOWING, HOME, [FULL,] [EXTRA]
let SIDE_LINKS: Array<SideNavLink> = [];
SIDE_LINKS.push(HOME);
SIDE_LINKS.push(RECENT_FROM_FOLLOWING);
if (!SIMPLE_SITE) {
FULL_LINKS.push({
title: 'Lists',
link: `/$/${PAGES.LISTS}`,
icon: ICONS.STACK,
hideForUnauth: true,
});
}
if (!SIMPLE_SITE) {
SIDE_LINKS.push(...FULL_LINKS);
} else if (SIMPLE_SITE) {
SIDE_LINKS.push({
title: 'Lists',
link: `/$/${PAGES.LISTS}`,
icon: ICONS.STACK,
hideForUnauth: true,
});
}
SIDE_LINKS.push(PLAYLISTS);
if (SIMPLE_SITE && EXTRA_SIDEBAR_LINKS) {
if (EXTRA_SIDEBAR_LINKS) {
// $FlowFixMe
SIDE_LINKS.push(...EXTRA_SIDEBAR_LINKS);
@ -251,6 +218,9 @@ function SideNavigation(props: Props) {
);
const [pulseLibrary, setPulseLibrary] = React.useState(false);
const [expandSubscriptions, setExpandSubscriptions] = React.useState(false);
const [expandTags, setExpandTags] = React.useState(false);
const isPersonalized = !IS_WEB || isAuthenticated;
const isAbsolute = isOnFilePage || isMediumScreen;
const microNavigation = !sidebarOpen || isMediumScreen;
@ -264,6 +234,65 @@ function SideNavigation(props: Props) {
})
: UNAUTH_LINKS;
const showSubscriptionSection = sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0;
const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length;
let displayedSubscriptions = subscriptions;
if (showSubscriptionSection && subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && !expandSubscriptions) {
displayedSubscriptions = subscriptions.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
}
let displayedFollowedTags = followedTags;
if (showTagSection && followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && !expandTags) {
displayedFollowedTags = followedTags.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
}
function getSubscriptionSection() {
if (showSubscriptionSection) {
return (
<>
<ul className="navigation__secondary navigation-links">
{displayedSubscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
</ul>
{subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
<Button
label={expandSubscriptions ? __('Show less') : __('Show more')}
className="navigation-link"
onClick={() => setExpandSubscriptions(!expandSubscriptions)}
/>
)}
</>
);
}
return null;
}
function getFollowedTagsSection() {
if (showTagSection) {
return (
<>
<ul className="navigation__secondary navigation-links navigation-links--small">
{displayedFollowedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
</ul>
{followedTags.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
<Button
label={expandTags ? __('Show less') : __('Show more')}
className="navigation-link"
onClick={() => setExpandTags(!expandTags)}
/>
)}
</>
);
}
return null;
}
React.useEffect(() => {
if (purchaseSuccess) {
setPulseLibrary(true);
@ -316,11 +345,9 @@ function SideNavigation(props: Props) {
<li className="navigation-link">
<Button label={__('FAQ and Support')} href="https://odysee.com/@OdyseeHelp:b" />
</li>
{SIMPLE_SITE && ( // GUIDELINES_URL?
<li className="navigation-link">
<Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" />
</li>
)}
<li className="navigation-link">
<Button label={__('Community Guidelines')} href="https://odysee.com/@OdyseeHelp:b/Community-Guidelines:c" />
</li>
<li className="navigation-link">
<Button label={__('Terms')} href="https://odysee.com/$/tos" />
</li>
@ -342,9 +369,6 @@ function SideNavigation(props: Props) {
aria-label={'Sidebar'}
className={classnames('navigation', {
'navigation--micro': microNavigation,
// @if TARGET='app'
'navigation--mac': IS_MAC,
// @endif
})}
>
<div>
@ -372,40 +396,18 @@ function SideNavigation(props: Props) {
);
})}
</ul>
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
<ul className="navigation__secondary navigation-links">
{subscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
</ul>
)}
{sidebarOpen && isPersonalized && followedTags && followedTags.length > 0 && (
<ul className="navigation__secondary navigation-links navigation-links--small">
{followedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
</ul>
)}
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && sidebarOpen && unAuthNudge}
</div>
{SIMPLE_SITE && sidebarOpen && helpLinks}
{sidebarOpen && helpLinks}
</nav>
)}
{(isOnFilePage || isMediumScreen) && sidebarOpen && (
<>
<nav
className={classnames('navigation--absolute', {
// @if TARGET='app'
'navigation--mac': IS_MAC,
// @endif
})}
>
<nav className="navigation--absolute">
<div>
<ul className="navigation-links--absolute mobile-only">
{email && livestreamEnabled && (
@ -463,34 +465,13 @@ function SideNavigation(props: Props) {
);
})}
</ul>
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
<ul className="navigation__secondary navigation-links">
{subscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
))}
</ul>
)}
{sidebarOpen && isPersonalized && followedTags && followedTags.length > 0 && (
<ul className="navigation__secondary navigation-links navigation-links--small">
{followedTags.map(({ name }, key) => (
<li key={name} className="navigation-link__wrapper">
<Button navigate={`/$/discover?t=${name}`} label={`#${name}`} className="navigation-link" />
</li>
))}
</ul>
)}
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && unAuthNudge}
{SIMPLE_SITE && helpLinks}
{helpLinks}
</div>
</nav>
<div
className={classnames('navigation__overlay', {
// @if TARGET='app'
'navigation__overlay--mac': IS_MAC,
// @endif
})}
onClick={() => setSidebarOpen(false)}
/>
<div className="navigation__overlay" onClick={() => setSidebarOpen(false)} />
</>
)}
</div>

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,
@ -61,7 +61,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),
authenticated: selectUserVerifiedEmail(state),

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

@ -147,6 +147,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',
@ -277,28 +303,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 = {
@ -333,6 +337,7 @@ export function GetLinksData(
}
}
}
if (!CUSTOM_HOMEPAGE) {
if (!authenticated) {
rowData.push(YOUTUBE_CREATOR_ROW);
@ -341,6 +346,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'))