Show channel thumbnails in side menu
This commit is contained in:
parent
72a4ed107b
commit
d8b40931f3
4 changed files with 65 additions and 24 deletions
|
@ -5,7 +5,14 @@ import { selectGetSyncErrorMessage, selectSyncFatalError } from 'redux/selectors
|
|||
import { doFetchAccessToken, doUserSetReferrer } from 'redux/actions/user';
|
||||
import { selectUser, selectAccessToken, selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
import { selectUnclaimedRewards } from 'redux/selectors/rewards';
|
||||
import { doFetchChannelListMine, doFetchCollectionListMine, SETTINGS, selectMyChannelUrls } from 'lbry-redux';
|
||||
import {
|
||||
doFetchChannelListMine,
|
||||
doFetchCollectionListMine,
|
||||
SETTINGS,
|
||||
selectMyChannelUrls,
|
||||
doResolveUris,
|
||||
} from 'lbry-redux';
|
||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import {
|
||||
makeSelectClientSetting,
|
||||
selectLanguage,
|
||||
|
@ -47,6 +54,7 @@ const select = (state) => ({
|
|||
syncFatalError: selectSyncFatalError(state),
|
||||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
myChannelUrls: selectMyChannelUrls(state),
|
||||
subscriptions: selectSubscriptions(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
|
@ -63,6 +71,7 @@ const perform = (dispatch) => ({
|
|||
setActiveChannelIfNotSet: () => dispatch(doSetActiveChannel()),
|
||||
setIncognito: () => dispatch(doSetIncognito()),
|
||||
fetchModBlockedList: () => dispatch(doFetchModBlockedList()),
|
||||
resolveUris: (uris) => dispatch(doResolveUris(uris)),
|
||||
});
|
||||
|
||||
export default hot(connect(select, perform)(App));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState, useLayoutEffect } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import analytics from 'analytics';
|
||||
import { buildURI, parseURI } from 'lbry-redux';
|
||||
|
@ -84,9 +84,11 @@ type Props = {
|
|||
syncFatalError: boolean,
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
myChannelUrls: ?Array<string>,
|
||||
subscriptions: Array<Subscription>,
|
||||
setActiveChannelIfNotSet: () => void,
|
||||
setIncognito: (boolean) => void,
|
||||
fetchModBlockedList: () => void,
|
||||
resolveUris: (Array<string>) => void,
|
||||
};
|
||||
|
||||
function App(props: Props) {
|
||||
|
@ -119,6 +121,8 @@ function App(props: Props) {
|
|||
setActiveChannelIfNotSet,
|
||||
setIncognito,
|
||||
fetchModBlockedList,
|
||||
resolveUris,
|
||||
subscriptions,
|
||||
} = props;
|
||||
|
||||
const appRef = useRef();
|
||||
|
@ -136,6 +140,8 @@ function App(props: Props) {
|
|||
// @endif
|
||||
const { pathname, hash, search } = props.location;
|
||||
const [upgradeNagClosed, setUpgradeNagClosed] = useState(false);
|
||||
const [resolvedSubscriptions, setResolvedSubscriptions] = useState(false);
|
||||
const [sidebarOpen] = usePersistedState('sidebar', true);
|
||||
const showUpgradeButton =
|
||||
(autoUpdateDownloaded || (process.platform === 'linux' && isUpgradeAvailable)) && !upgradeNagClosed;
|
||||
// referral claiming
|
||||
|
@ -150,6 +156,7 @@ function App(props: Props) {
|
|||
const hasNoChannels = myChannelUrls && myChannelUrls.length === 0;
|
||||
const shouldMigrateLanguage = LANGUAGE_MIGRATIONS[language];
|
||||
const hasActiveChannelClaim = activeChannelClaim !== undefined;
|
||||
const isPersonalized = !IS_WEB || hasVerifiedEmail;
|
||||
|
||||
let uri;
|
||||
try {
|
||||
|
@ -338,6 +345,16 @@ function App(props: Props) {
|
|||
}
|
||||
}, [hasVerifiedEmail, signIn, hasSignedIn]);
|
||||
|
||||
// batch resolve subscriptions to be used by the sideNavigation component.
|
||||
// add it here so that it only resolves the first time, despite route changes.
|
||||
// useLayoutEffect because it has to be executed before the sideNavigation component requests them
|
||||
useLayoutEffect(() => {
|
||||
if (sidebarOpen && isPersonalized && subscriptions && !resolvedSubscriptions) {
|
||||
setResolvedSubscriptions(true);
|
||||
resolveUris(subscriptions.map((sub) => sub.uri));
|
||||
}
|
||||
}, [sidebarOpen, isPersonalized, resolvedSubscriptions, subscriptions, resolveUris, setResolvedSubscriptions]);
|
||||
|
||||
// @if TARGET='web'
|
||||
useDegradedPerformance(setLbryTvApiStatus, user);
|
||||
// @endif
|
||||
|
|
|
@ -8,6 +8,7 @@ import classnames from 'classnames';
|
|||
import Icon from 'component/common/icon';
|
||||
import NotificationBubble from 'component/notificationBubble';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import { PINNED_LABEL_1, PINNED_URI_1, PINNED_URI_2, PINNED_LABEL_2, SIMPLE_SITE, DOMAIN } from 'config';
|
||||
// @if TARGET='app'
|
||||
import { IS_MAC } from 'component/app/view';
|
||||
|
@ -362,15 +363,8 @@ function SideNavigation(props: Props) {
|
|||
|
||||
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
|
||||
<ul className="navigation__secondary navigation-links">
|
||||
{subscriptions.map(({ uri, channelName }, index) => (
|
||||
<li key={uri} className="navigation-link__wrapper">
|
||||
<Button
|
||||
navigate={uri}
|
||||
label={channelName}
|
||||
className="navigation-link"
|
||||
activeClass="navigation-link--active"
|
||||
/>
|
||||
</li>
|
||||
{subscriptions.map((subscription) => (
|
||||
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
@ -445,15 +439,8 @@ function SideNavigation(props: Props) {
|
|||
</ul>
|
||||
{sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0 && (
|
||||
<ul className="navigation__secondary navigation-links">
|
||||
{subscriptions.map(({ uri, channelName }, index) => (
|
||||
<li key={uri} className="navigation-link__wrapper">
|
||||
<Button
|
||||
navigate={uri}
|
||||
label={channelName}
|
||||
className="navigation-link"
|
||||
activeClass="navigation-link--active"
|
||||
/>
|
||||
</li>
|
||||
{subscriptions.map((subscription) => (
|
||||
<SubscriptionListItem key={subscription.uri} subscription={subscription} />
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
@ -484,4 +471,22 @@ function SideNavigation(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
function SubscriptionListItem({ subscription }: { subscription: Subscription }) {
|
||||
const { uri, channelName } = subscription;
|
||||
return (
|
||||
<li className="navigation-link__wrapper">
|
||||
<Button
|
||||
navigate={uri}
|
||||
className="navigation-link navigation-link--with-thumbnail"
|
||||
activeClass="navigation-link--active"
|
||||
>
|
||||
<ChannelThumbnail uri={uri} />
|
||||
<span dir="auto" className="button__label">
|
||||
{channelName}
|
||||
</span>
|
||||
</Button>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
export default SideNavigation;
|
||||
|
|
|
@ -104,6 +104,16 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.navigation-link--with-thumbnail .button__content {
|
||||
flex-direction: row;
|
||||
|
||||
.channel-thumbnail {
|
||||
@include handleChannelGif(1.5rem);
|
||||
flex-shrink: 0;
|
||||
margin-right: var(--spacing-s);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(.navigation-link--active),
|
||||
&:focus {
|
||||
@extend .navigation-link--highlighted;
|
||||
|
@ -114,8 +124,8 @@
|
|||
margin-bottom: 0;
|
||||
|
||||
.icon {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.button__content {
|
||||
|
@ -201,8 +211,8 @@
|
|||
margin-bottom: 0;
|
||||
|
||||
.icon {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.button__content {
|
||||
|
|
Loading…
Reference in a new issue