diff --git a/ui/component/channelEdit/index.js b/ui/component/channelEdit/index.js index 43e054f7e..17ef05479 100644 --- a/ui/component/channelEdit/index.js +++ b/ui/component/channelEdit/index.js @@ -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), diff --git a/ui/component/channelThumbnail/index.js b/ui/component/channelThumbnail/index.js index ebedaff1a..c5ac39490 100644 --- a/ui/component/channelThumbnail/index.js +++ b/ui/component/channelThumbnail/index.js @@ -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), }); diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js index c19121726..5789b1565 100644 --- a/ui/component/claimPreviewTile/index.js +++ b/ui/component/claimPreviewTile/index.js @@ -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), diff --git a/ui/component/collectionEdit/index.js b/ui/component/collectionEdit/index.js index 54cf51ee3..5ecf17e87 100644 --- a/ui/component/collectionEdit/index.js +++ b/ui/component/collectionEdit/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { makeSelectTitleForUri, - makeSelectThumbnailForUri, + 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), diff --git a/ui/component/collectionPreviewTile/index.js b/ui/component/collectionPreviewTile/index.js index 706cd974d..aec991b35 100644 --- a/ui/component/collectionPreviewTile/index.js +++ b/ui/component/collectionPreviewTile/index.js @@ -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), diff --git a/ui/component/comment/index.js b/ui/component/comment/index.js index 27a847ee1..9ad2c532c 100644 --- a/ui/component/comment/index.js +++ b/ui/component/comment/index.js @@ -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), diff --git a/ui/component/embedPlayButton/index.js b/ui/component/embedPlayButton/index.js index 70847b149..339f02b3b 100644 --- a/ui/component/embedPlayButton/index.js +++ b/ui/component/embedPlayButton/index.js @@ -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), diff --git a/ui/component/fileRender/index.js b/ui/component/fileRender/index.js index 83a29abc0..6ddfd880f 100644 --- a/ui/component/fileRender/index.js +++ b/ui/component/fileRender/index.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import { makeSelectDownloadPathForUri, makeSelectStreamingUrlForUri } from 'redux/selectors/file_info'; -import { makeSelectClaimForUri, makeSelectThumbnailForUri, makeSelectContentTypeForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectThumbnailForUri, makeSelectContentTypeForUri } from 'redux/selectors/claims'; import * as SETTINGS from 'constants/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content'; @@ -11,7 +11,7 @@ const select = (state, props) => { return { currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), claim: makeSelectClaimForUri(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), + thumbnail: selectThumbnailForUri(state, props.uri), contentType: makeSelectContentTypeForUri(props.uri)(state), downloadPath: makeSelectDownloadPathForUri(props.uri)(state), fileExtension: makeSelectFileExtensionForUri(props.uri)(state), diff --git a/ui/component/fileRenderInitiator/index.js b/ui/component/fileRenderInitiator/index.js index 178ccb403..3c581a47f 100644 --- a/ui/component/fileRenderInitiator/index.js +++ b/ui/component/fileRenderInitiator/index.js @@ -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), diff --git a/ui/component/livestreamLayout/index.js b/ui/component/livestreamLayout/index.js index 03547a34d..0a4f1be4d 100644 --- a/ui/component/livestreamLayout/index.js +++ b/ui/component/livestreamLayout/index.js @@ -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), }); diff --git a/ui/component/previewLink/index.js b/ui/component/previewLink/index.js index 9d93d2c63..25a3aad39 100644 --- a/ui/component/previewLink/index.js +++ b/ui/component/previewLink/index.js @@ -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), diff --git a/ui/component/sideNavigation/view.jsx b/ui/component/sideNavigation/view.jsx index 2e8d07096..c17c3ca15 100644 --- a/ui/component/sideNavigation/view.jsx +++ b/ui/component/sideNavigation/view.jsx @@ -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> diff --git a/ui/component/viewers/videoViewer/index.js b/ui/component/viewers/videoViewer/index.js index 5ad8a88c1..b3f09eb04 100644 --- a/ui/component/viewers/videoViewer/index.js +++ b/ui/component/viewers/videoViewer/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { makeSelectClaimForUri, makeSelectThumbnailForUri } from 'redux/selectors/claims'; +import { makeSelectClaimForUri, selectThumbnailForUri } from 'redux/selectors/claims'; import { makeSelectNextUrlForCollectionAndUrl, makeSelectPreviousUrlForCollectionAndUrl, @@ -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), diff --git a/ui/page/channel/index.js b/ui/page/channel/index.js index 7396217bd..c1920a636 100644 --- a/ui/page/channel/index.js +++ b/ui/page/channel/index.js @@ -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), diff --git a/ui/page/collection/index.js b/ui/page/collection/index.js index 62585eafe..863a1107d 100644 --- a/ui/page/collection/index.js +++ b/ui/page/collection/index.js @@ -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), diff --git a/ui/redux/selectors/claims.js b/ui/redux/selectors/claims.js index 0bc7ef723..c088468e9 100644 --- a/ui/redux/selectors/claims.js +++ b/ui/redux/selectors/claims.js @@ -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) => { diff --git a/ui/util/buildHomepage.js b/ui/util/buildHomepage.js index ee9b7b985..dea87c2a3 100644 --- a/ui/util/buildHomepage.js +++ b/ui/util/buildHomepage.js @@ -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'))