use claim_search for channel discovery
This commit is contained in:
parent
9f04dd5bfc
commit
e1aac34079
11 changed files with 124 additions and 121 deletions
|
@ -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"
|
||||||
}
|
}
|
|
@ -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} />
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
57
ui/page/channelsFollowingDiscover/view.jsx
Normal file
57
ui/page/channelsFollowingDiscover/view.jsx
Normal 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;
|
|
@ -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;
|
|
|
@ -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">
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue