use claim_search for channel discovery

This commit is contained in:
Sean Yesmunt 2020-02-17 14:12:28 -05:00
parent 9f04dd5bfc
commit e1aac34079
11 changed files with 124 additions and 121 deletions

View file

@ -957,5 +957,10 @@
"Cover Recommended ratio is 6.25:1": "Cover Recommended ratio is 6.25:1", "Cover Recommended ratio is 6.25:1": "Cover Recommended ratio is 6.25:1",
"You already have a claim with this name.": "You already have a claim with this name.", "You already have a claim with this name.": "You already have a claim with this name.",
"You are not currently sharing diagnostic data so this error was not reported.": "You are not currently sharing diagnostic data so this error was not reported.", "You are not currently sharing diagnostic data so this error was not reported.": "You are not currently sharing diagnostic data so this error was not reported.",
"Go to Invites": "Go to Invites" "Go to Invites": "Go to Invites",
"Find Channels to Follow": "Find Channels to Follow",
"Sign in with lbry.tv to receive notifications about new content.": "Sign in with lbry.tv to receive notifications about new content.",
"Find new channels to follow": "Find new channels to follow",
"You aren't currently following any channels. %discover_channels_link%.": "You aren't currently following any channels. %discover_channels_link%.",
"LBRY Works Better If You Are Following Channels": "LBRY Works Better If You Are Following Channels"
} }

View file

@ -21,7 +21,7 @@ import WalletPage from 'page/wallet';
import TagsPage from 'page/tags'; import TagsPage from 'page/tags';
import TagsFollowingPage from 'page/tagsFollowing'; import TagsFollowingPage from 'page/tagsFollowing';
import ChannelsFollowingPage from 'page/channelsFollowing'; import ChannelsFollowingPage from 'page/channelsFollowing';
import ChannelsFollowingManagePage from 'page/channelsFollowingManage'; import ChannelsFollowingDiscoverPage from 'page/channelsFollowingDiscover';
import TagsFollowingManagePage from 'page/tagsFollowingManage'; import TagsFollowingManagePage from 'page/tagsFollowingManage';
import ListBlockedPage from 'page/listBlocked'; import ListBlockedPage from 'page/listBlocked';
import FourOhFourPage from 'page/fourOhFour'; import FourOhFourPage from 'page/fourOhFour';
@ -130,6 +130,8 @@ function AppRouter(props: Props) {
return ( return (
<Switch> <Switch>
<Redirect from={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`} to={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`} />
<Route path={`/`} exact component={HomePage} /> <Route path={`/`} exact component={HomePage} />
<Route path={`/$/${PAGES.DISCOVER}`} exact component={DiscoverPage} /> <Route path={`/$/${PAGES.DISCOVER}`} exact component={DiscoverPage} />
<Route path={`/$/${PAGES.AUTH}`} exact component={SignInPage} /> <Route path={`/$/${PAGES.AUTH}`} exact component={SignInPage} />
@ -140,7 +142,7 @@ function AppRouter(props: Props) {
exact exact
component={isAuthenticated || !IS_WEB ? ChannelsFollowingPage : DiscoverPage} component={isAuthenticated || !IS_WEB ? ChannelsFollowingPage : DiscoverPage}
/> />
<Route path={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`} exact component={ChannelsFollowingManagePage} /> <Route path={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`} exact component={ChannelsFollowingDiscoverPage} />
<Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} /> <Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} />
<Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} /> <Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} />
<Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} /> <Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} />

View file

@ -24,6 +24,7 @@ exports.TAGS_FOLLOWING = 'following/tags';
exports.TAGS_FOLLOWING_MANAGE = 'following/tags/manage'; exports.TAGS_FOLLOWING_MANAGE = 'following/tags/manage';
exports.CHANNELS_FOLLOWING = 'following/channels'; exports.CHANNELS_FOLLOWING = 'following/channels';
exports.CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage'; exports.CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage';
exports.CHANNELS_FOLLOWING_DISCOVER = 'following/channels/discover';
exports.WALLET = 'wallet'; exports.WALLET = 'wallet';
exports.BLOCKED = 'blocked'; exports.BLOCKED = 'blocked';
exports.CHANNELS = 'channels'; exports.CHANNELS = 'channels';

View file

@ -1,20 +1,9 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectUserVerifiedEmail } from 'lbryinc'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { selectSubscriptions, selectSuggestedChannels } from 'redux/selectors/subscriptions'; import ChannelsFollowingPage from './view';
import { doFetchRecommendedSubscriptions } from 'redux/actions/subscriptions';
import DiscoverPage from './view';
const select = state => ({ const select = state => ({
subscribedChannels: selectSubscriptions(state), subscribedChannels: selectSubscriptions(state),
email: selectUserVerifiedEmail(state),
suggestedSubscriptions: selectSuggestedChannels(state),
}); });
const perform = { export default connect(select)(ChannelsFollowingPage);
doFetchRecommendedSubscriptions,
};
export default connect(
select,
perform
)(DiscoverPage);

View file

@ -2,8 +2,8 @@
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import React from 'react'; import React from 'react';
import ChannelsFollowingDiscoverPage from 'page/channelsFollowingDiscover';
import ClaimListDiscover from 'component/claimListDiscover'; import ClaimListDiscover from 'component/claimListDiscover';
import ClaimList from 'component/claimList';
import Page from 'component/page'; import Page from 'component/page';
import Button from 'component/button'; import Button from 'component/button';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
@ -11,59 +11,37 @@ import Icon from 'component/common/icon';
import { TYPE_NEW } from 'component/claimListDiscover/view'; import { TYPE_NEW } from 'component/claimListDiscover/view';
type Props = { type Props = {
email: string,
subscribedChannels: Array<Subscription>, subscribedChannels: Array<Subscription>,
doFetchRecommendedSubscriptions: () => void,
suggestedSubscriptions: Array<{ uri: string }>,
}; };
function ChannelsFollowing(props: Props) { function ChannelsFollowingPage(props: Props) {
const { subscribedChannels, suggestedSubscriptions, doFetchRecommendedSubscriptions } = props; const { subscribedChannels } = props;
const hasSubsribedChannels = subscribedChannels.length > 0; const hasSubsribedChannels = subscribedChannels.length > 0;
const [showTab, setShowTab] = React.useState(!hasSubsribedChannels);
React.useEffect(() => { return !hasSubsribedChannels ? (
if (!hasSubsribedChannels) { <ChannelsFollowingDiscoverPage />
doFetchRecommendedSubscriptions(); ) : (
}
}, [doFetchRecommendedSubscriptions, hasSubsribedChannels]);
return (
<Page> <Page>
{showTab ? ( <ClaimListDiscover
<ClaimList headerLabel={
header={__('Find Channels to Follow')} <span>
headerAltControls={ <Icon icon={ICONS.SUBSCRIBE} size={10} />
<Button {__('Following')}
button="link" </span>
label={hasSubsribedChannels && __('View Your Feed')} }
onClick={() => setShowTab(false)} defaultTypeSort={TYPE_NEW}
/> channelIds={subscribedChannels.map(sub => sub.uri.split('#')[1])}
} meta={
uris={suggestedSubscriptions.map(sub => `lbry://${sub.uri}`)} <Button
/> icon={ICONS.SEARCH}
) : ( button="link"
<ClaimListDiscover label={__('Discover New Channels')}
headerLabel={ navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
<span> />
<Icon icon={ICONS.SUBSCRIBE} size={10} /> }
{__('Following')} />
</span>
}
defaultTypeSort={TYPE_NEW}
channelIds={subscribedChannels.map(sub => sub.uri.split('#')[1])}
meta={
<Button
icon={ICONS.EDIT}
button="link"
label={__('Manage')}
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`}
/>
}
/>
)}
</Page> </Page>
); );
} }
export default ChannelsFollowing; export default ChannelsFollowingPage;

View file

@ -0,0 +1,57 @@
// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import React from 'react';
import Page from 'component/page';
import Button from 'component/button';
import ClaimTilesDiscover from 'component/claimTilesDiscover';
type Props = {};
type RowDataItem = {
title: string,
link?: string,
help?: any,
options?: {},
};
function ChannelsFollowingDiscover(props: Props) {
let rowData: Array<RowDataItem> = [];
rowData.push({
title: 'Top Channels On LBRY',
link: `/$/${PAGES.DISCOVER}`,
options: {
pageSize: 12,
claimType: 'channel',
orderBy: ['effective_amount'],
},
});
return (
<Page>
{rowData.map(({ title, link, help, options = {} }) => (
<div key={title} className="claim-grid__wrapper">
<h1 className="section__actions">
{link ? (
<Button
className="claim-grid__title"
button="link"
navigate={link}
iconRight={ICONS.ARROW_RIGHT}
label={title}
/>
) : (
<span className="claim-grid__title">{title}</span>
)}
{help}
</h1>
<ClaimTilesDiscover {...options} />
</div>
))}
</Page>
);
}
export default ChannelsFollowingDiscover;

View file

@ -1,56 +0,0 @@
// @flow
import * as PAGES from 'constants/pages';
import React, { useEffect } from 'react';
import Page from 'component/page';
import ClaimList from 'component/claimList';
import Button from 'component/button';
type Props = {
subscribedChannels: Array<Subscription>,
location: { search: string },
history: { push: string => void },
doFetchRecommendedSubscriptions: () => void,
suggestedSubscriptions: Array<{ uri: string }>,
};
function ChannelsFollowingManagePage(props: Props) {
const { subscribedChannels, location, history, doFetchRecommendedSubscriptions, suggestedSubscriptions } = props;
const hasSubscriptions = !!subscribedChannels.length;
const channelUris = subscribedChannels.map(({ uri }) => uri);
const { search } = location;
const urlParams = new URLSearchParams(search);
const viewingSuggestedSubs = urlParams.get('view') || !hasSubscriptions;
function onClick() {
let url = `/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`;
if (!viewingSuggestedSubs) {
url += '?view=discover';
}
history.push(url);
}
useEffect(() => {
doFetchRecommendedSubscriptions();
}, [doFetchRecommendedSubscriptions]);
return (
<Page>
<ClaimList
showUnresolvedClaims
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
headerAltControls={
<Button
button="link"
label={viewingSuggestedSubs ? hasSubscriptions && __('View Your Channels') : __('Find New Channels')}
onClick={() => onClick()}
/>
}
uris={viewingSuggestedSubs ? suggestedSubscriptions.map(sub => `lbry://${sub.uri}`) : channelUris}
/>
</Page>
);
}
export default ChannelsFollowingManagePage;

View file

@ -7,6 +7,7 @@ import Page from 'component/page';
import Button from 'component/button'; import Button from 'component/button';
import ClaimTilesDiscover from 'component/claimTilesDiscover'; import ClaimTilesDiscover from 'component/claimTilesDiscover';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
import I18nMessage from 'component/i18nMessage';
import { parseURI } from 'lbry-redux'; import { parseURI } from 'lbry-redux';
import { toCapitalCase } from 'util/string'; import { toCapitalCase } from 'util/string';
@ -193,6 +194,26 @@ function HomePage(props: Props) {
return ( return (
<Page> <Page>
{(authenticated || !IS_WEB) && !subscribedChannels.length && (
<div className="notice-message">
<h1 className="section__title">{__('LBRY Works Better If You Are Following Channels')}</h1>
<p className="section__subtitle">
<I18nMessage
tokens={{
discover_channels_link: (
<Button
button="link"
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
label={__('Find new channels to follow')}
/>
),
}}
>
You aren't currently following any channels. %discover_channels_link%.
</I18nMessage>
</p>
</div>
)}
{rowData.map(({ title, link, help, options = {} }) => ( {rowData.map(({ title, link, help, options = {} }) => (
<div key={title} className="claim-grid__wrapper"> <div key={title} className="claim-grid__wrapper">
<h1 className="section__actions"> <h1 className="section__actions">

View file

@ -314,7 +314,7 @@
@media (min-width: $breakpoint-medium) { @media (min-width: $breakpoint-medium) {
&:first-child, &:first-child,
&:nth-child(5n) { &:nth-child(4n + 1) {
margin-left: 0; margin-left: 0;
} }
} }

View file

@ -257,3 +257,9 @@ a {
.download-text { .download-text {
font-size: var(--font-xsmall); font-size: var(--font-xsmall);
} }
.notice-message {
border-radius: var(--border-radius);
padding: var(--spacing-large);
background-color: var(--color-primary-alt);
}