Manage Subs page
This commit is contained in:
parent
1249b0394e
commit
0090e9b1ae
8 changed files with 126 additions and 16 deletions
|
@ -746,6 +746,7 @@
|
||||||
"gaming, crypto": "gaming, crypto",
|
"gaming, crypto": "gaming, crypto",
|
||||||
"Autocomplete": "Autocomplete",
|
"Autocomplete": "Autocomplete",
|
||||||
"Followed Tags": "Followed Tags",
|
"Followed Tags": "Followed Tags",
|
||||||
|
"Followed Channels": "Followed Channels",
|
||||||
"Manage Tags": "Manage Tags",
|
"Manage Tags": "Manage Tags",
|
||||||
"%selectTagsLabel% (%number% left)": "%selectTagsLabel% (%number% left)",
|
"%selectTagsLabel% (%number% left)": "%selectTagsLabel% (%number% left)",
|
||||||
"Matching": "Matching",
|
"Matching": "Matching",
|
||||||
|
|
|
@ -48,6 +48,9 @@ const ChannelsFollowingDiscoverPage = lazyImport(() =>
|
||||||
const ChannelsFollowingPage = lazyImport(() =>
|
const ChannelsFollowingPage = lazyImport(() =>
|
||||||
import('page/channelsFollowing' /* webpackChunkName: "channelsFollowing" */)
|
import('page/channelsFollowing' /* webpackChunkName: "channelsFollowing" */)
|
||||||
);
|
);
|
||||||
|
const ChannelsFollowingManage = lazyImport(() =>
|
||||||
|
import('page/channelsFollowingManage' /* webpackChunkName: "channelsFollowing" */)
|
||||||
|
);
|
||||||
const ChannelsPage = lazyImport(() => import('page/channels' /* webpackChunkName: "channels" */));
|
const ChannelsPage = lazyImport(() => import('page/channels' /* webpackChunkName: "channels" */));
|
||||||
const CheckoutPage = lazyImport(() => import('page/checkoutPage' /* webpackChunkName: "checkoutPage" */));
|
const CheckoutPage = lazyImport(() => import('page/checkoutPage' /* webpackChunkName: "checkoutPage" */));
|
||||||
const CreatorDashboard = lazyImport(() => import('page/creatorDashboard' /* webpackChunkName: "creatorDashboard" */));
|
const CreatorDashboard = lazyImport(() => import('page/creatorDashboard' /* webpackChunkName: "creatorDashboard" */));
|
||||||
|
@ -330,6 +333,12 @@ function AppRouter(props: Props) {
|
||||||
path={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
path={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
||||||
component={ChannelsFollowingDiscoverPage}
|
component={ChannelsFollowingDiscoverPage}
|
||||||
/>
|
/>
|
||||||
|
<PrivateRoute
|
||||||
|
{...props}
|
||||||
|
exact
|
||||||
|
path={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`}
|
||||||
|
component={ChannelsFollowingManage}
|
||||||
|
/>
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.INVITE}`} component={InvitePage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.INVITE}`} component={InvitePage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.CHANNEL_NEW}`} component={ChannelNew} />
|
<PrivateRoute {...props} path={`/$/${PAGES.CHANNEL_NEW}`} component={ChannelNew} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.REPOST_NEW}`} component={RepostNew} />
|
<PrivateRoute {...props} path={`/$/${PAGES.REPOST_NEW}`} component={RepostNew} />
|
||||||
|
|
|
@ -232,7 +232,6 @@ function SideNavigation(props: Props) {
|
||||||
);
|
);
|
||||||
|
|
||||||
const [pulseLibrary, setPulseLibrary] = React.useState(false);
|
const [pulseLibrary, setPulseLibrary] = React.useState(false);
|
||||||
const [expandSubscriptions, setExpandSubscriptions] = React.useState(false);
|
|
||||||
const [expandTags, setExpandTags] = React.useState(false);
|
const [expandTags, setExpandTags] = React.useState(false);
|
||||||
|
|
||||||
const isPersonalized = !IS_WEB || isAuthenticated;
|
const isPersonalized = !IS_WEB || isAuthenticated;
|
||||||
|
@ -276,12 +275,7 @@ function SideNavigation(props: Props) {
|
||||||
);
|
);
|
||||||
|
|
||||||
let displayedSubscriptions = filteredSubscriptions;
|
let displayedSubscriptions = filteredSubscriptions;
|
||||||
if (
|
if (showSubscriptionSection && !subscriptionFilter && subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT) {
|
||||||
showSubscriptionSection &&
|
|
||||||
!subscriptionFilter &&
|
|
||||||
subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT &&
|
|
||||||
!expandSubscriptions
|
|
||||||
) {
|
|
||||||
displayedSubscriptions = subscriptions.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
|
displayedSubscriptions = subscriptions.slice(0, FOLLOWED_ITEM_INITIAL_LIMIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +331,12 @@ function SideNavigation(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
{!subscriptionFilter && subscriptions.length > FOLLOWED_ITEM_INITIAL_LIMIT && (
|
{!subscriptionFilter && (
|
||||||
<Button
|
<Button
|
||||||
key="showMore"
|
key="showMore"
|
||||||
label={expandSubscriptions ? __('Show less') : __('Show more')}
|
label={__('Manage')}
|
||||||
className="navigation-link"
|
className="navigation-link"
|
||||||
onClick={() => setExpandSubscriptions(!expandSubscriptions)}
|
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -63,6 +63,7 @@ exports.DEPRECATED__CHANNELS_FOLLOWING = 'following/channels';
|
||||||
exports.CHANNELS_FOLLOWING = 'following';
|
exports.CHANNELS_FOLLOWING = 'following';
|
||||||
exports.DEPRECATED__CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage';
|
exports.DEPRECATED__CHANNELS_FOLLOWING_MANAGE = 'following/channels/manage';
|
||||||
exports.CHANNELS_FOLLOWING_DISCOVER = 'following/discover';
|
exports.CHANNELS_FOLLOWING_DISCOVER = 'following/discover';
|
||||||
|
exports.CHANNELS_FOLLOWING_MANAGE = 'following/manage';
|
||||||
exports.WALLET = 'wallet';
|
exports.WALLET = 'wallet';
|
||||||
exports.CHANNELS = 'channels';
|
exports.CHANNELS = 'channels';
|
||||||
exports.EMBED = 'embed';
|
exports.EMBED = 'embed';
|
||||||
|
|
|
@ -69,12 +69,20 @@ function ChannelsFollowingPage(props: Props) {
|
||||||
defaultOrderBy={CS.ORDER_BY_NEW}
|
defaultOrderBy={CS.ORDER_BY_NEW}
|
||||||
channelIds={channelIds}
|
channelIds={channelIds}
|
||||||
meta={
|
meta={
|
||||||
<Button
|
<>
|
||||||
icon={ICONS.SEARCH}
|
<Button
|
||||||
button="secondary"
|
icon={ICONS.SEARCH}
|
||||||
label={__('Discover Channels')}
|
button="secondary"
|
||||||
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
label={__('Discover Channels')}
|
||||||
/>
|
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_DISCOVER}`}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon={ICONS.SETTINGS}
|
||||||
|
button="secondary"
|
||||||
|
label={__('Manage')}
|
||||||
|
navigate={`/$/${PAGES.CHANNELS_FOLLOWING_MANAGE}`}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
subSection={
|
subSection={
|
||||||
<LivestreamSection
|
<LivestreamSection
|
||||||
|
|
9
ui/page/channelsFollowingManage/index.js
Normal file
9
ui/page/channelsFollowingManage/index.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
||||||
|
import ChannelsFollowingManage from './view';
|
||||||
|
|
||||||
|
const select = (state) => ({
|
||||||
|
subscribedChannelUris: selectSubscriptionUris(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select)(ChannelsFollowingManage);
|
81
ui/page/channelsFollowingManage/view.jsx
Normal file
81
ui/page/channelsFollowingManage/view.jsx
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import ClaimList from 'component/claimList';
|
||||||
|
import ClaimListDiscover from 'component/claimListDiscover';
|
||||||
|
import DebouncedInput from 'component/common/debounced-input';
|
||||||
|
import Empty from 'component/common/empty';
|
||||||
|
import Page from 'component/page';
|
||||||
|
import Spinner from 'component/spinner';
|
||||||
|
import * as CS from 'constants/claim_search';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import { parseURI } from 'util/lbryURI';
|
||||||
|
|
||||||
|
function getFilteredUris(uris, filterQuery) {
|
||||||
|
if (filterQuery) {
|
||||||
|
const filterQueryLowerCase = filterQuery.toLowerCase();
|
||||||
|
return uris.filter((uri) => uri.toLowerCase().includes(filterQueryLowerCase));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseIdFromUri(uri) {
|
||||||
|
try {
|
||||||
|
const { channelClaimId } = parseURI(uri);
|
||||||
|
return channelClaimId;
|
||||||
|
} catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ****************************************************************************
|
||||||
|
// ChannelsFollowingManage
|
||||||
|
// ****************************************************************************
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
subscribedChannelUris: Array<string>,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ChannelsFollowingManage(props: Props) {
|
||||||
|
const { subscribedChannelUris } = props;
|
||||||
|
const [uris, setUris] = React.useState([]);
|
||||||
|
const [filterQuery, setFilterQuery] = React.useState('');
|
||||||
|
const filteredUris = getFilteredUris(uris, filterQuery);
|
||||||
|
const [channelIds, setChannelIds] = React.useState(null);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setUris(subscribedChannelUris);
|
||||||
|
setChannelIds(subscribedChannelUris.map((uri) => parseIdFromUri(uri)));
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps, (lock list on mount so it doesn't shift when unfollow)
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page className="followManage-wrapper" noFooter>
|
||||||
|
<div className="card__title-section">
|
||||||
|
<div className="card__title"> {__('Followed Channels')}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{channelIds === null ? (
|
||||||
|
<div className="main--empty">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
) : uris && uris.length === 0 ? (
|
||||||
|
<Empty padded text="No followed channels." />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<DebouncedInput icon={ICONS.SEARCH} placeholder={__('Filter')} onChange={setFilterQuery} inline />
|
||||||
|
{filteredUris && <ClaimList uris={filteredUris} />}
|
||||||
|
{!filteredUris && channelIds.length && (
|
||||||
|
<ClaimListDiscover
|
||||||
|
orderBy={CS.ORDER_BY_NAME_ASC}
|
||||||
|
claimType={CS.CLAIM_CHANNEL}
|
||||||
|
claimIds={channelIds}
|
||||||
|
showHeader={false}
|
||||||
|
hideFilters
|
||||||
|
hideAdvancedFilter
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
|
@ -653,6 +653,13 @@ img {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.followManage-wrapper {
|
||||||
|
@extend .discoverPage-wrapper;
|
||||||
|
.claim-list {
|
||||||
|
margin-top: var(--spacing-m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.uploadPage-wraper {
|
.uploadPage-wraper {
|
||||||
&.card-stack {
|
&.card-stack {
|
||||||
.card:not(:last-of-type) {
|
.card:not(:last-of-type) {
|
||||||
|
|
Loading…
Reference in a new issue