provide ability to unfollow abandoned channels
This commit is contained in:
parent
7ae8f79299
commit
8ce05ebf76
8 changed files with 108 additions and 4 deletions
10
ui/component/abandonedChannelPreview/index.js
Normal file
10
ui/component/abandonedChannelPreview/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doChannelUnsubscribe } from 'redux/actions/subscriptions';
|
||||
import AbandonedChannelPreview from './view';
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
{
|
||||
doChannelUnsubscribe,
|
||||
}
|
||||
)(AbandonedChannelPreview);
|
62
ui/component/abandonedChannelPreview/view.jsx
Normal file
62
ui/component/abandonedChannelPreview/view.jsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import Button from 'component/button';
|
||||
import { parseURI } from 'lbry-redux';
|
||||
import * as ICONS from '../../constants/icons';
|
||||
|
||||
type SubscriptionArgs = {
|
||||
channelName: string,
|
||||
uri: string,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
doChannelUnsubscribe: SubscriptionArgs => void,
|
||||
type: string,
|
||||
};
|
||||
|
||||
function AbandonedChannelPreview(props: Props) {
|
||||
const { uri, doChannelUnsubscribe, type } = props;
|
||||
const { channelName } = parseURI(uri);
|
||||
|
||||
return (
|
||||
<li
|
||||
className={classnames('claim-preview__wrapper', {
|
||||
'claim-preview__wrapper--channel': type !== 'inline',
|
||||
'claim-preview__wrapper--inline': type === 'inline',
|
||||
})}
|
||||
>
|
||||
<div className={classnames('claim-preview', { 'claim-preview--large': type === 'large' })}>
|
||||
<ChannelThumbnail uri={uri} />
|
||||
<div className="claim-preview__text">
|
||||
<div className="claim-preview-metadata">
|
||||
<div className="claim-preview-info">
|
||||
<div className="claim-preview__title">{channelName}</div>
|
||||
</div>
|
||||
<div className="media__subtitle">{`This channel may have been abandoned.`}</div>
|
||||
</div>
|
||||
<div className="claim-preview__actions">
|
||||
<Button
|
||||
// ref={buttonRef}
|
||||
iconColor="red"
|
||||
icon={ICONS.UNSUBSCRIBE}
|
||||
button={'alt'}
|
||||
label={__('Unfollow')}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
doChannelUnsubscribe({
|
||||
channelName,
|
||||
uri,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
export default AbandonedChannelPreview;
|
|
@ -29,6 +29,7 @@ type Props = {
|
|||
persistedStorageKey?: string,
|
||||
showHiddenByUser: boolean,
|
||||
headerLabel?: string | Node,
|
||||
nullPreviewBehavior?: string,
|
||||
};
|
||||
|
||||
export default function ClaimList(props: Props) {
|
||||
|
@ -47,6 +48,7 @@ export default function ClaimList(props: Props) {
|
|||
id,
|
||||
showHiddenByUser,
|
||||
headerLabel,
|
||||
nullPreviewBehavior,
|
||||
} = props;
|
||||
const [scrollBottomCbMap, setScrollBottomCbMap] = useState({});
|
||||
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
|
||||
|
@ -130,6 +132,7 @@ export default function ClaimList(props: Props) {
|
|||
key={uri}
|
||||
uri={uri}
|
||||
type={type}
|
||||
nullPreview={nullPreviewBehavior}
|
||||
properties={type !== 'small' ? undefined : false}
|
||||
showUserBlocked={showHiddenByUser}
|
||||
customShouldHide={(claim: StreamClaim) => {
|
||||
|
|
|
@ -19,6 +19,7 @@ import ClaimPreviewTitle from 'component/claimPreviewTitle';
|
|||
import ClaimPreviewSubtitle from 'component/claimPreviewSubtitle';
|
||||
import ClaimRepostAuthor from 'component/claimRepostAuthor';
|
||||
import FileDownloadLink from 'component/fileDownloadLink';
|
||||
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
@ -54,6 +55,7 @@ type Props = {
|
|||
streamingUrl: ?string,
|
||||
getFile: string => void,
|
||||
customShouldHide?: Claim => boolean,
|
||||
nullPreview?: string,
|
||||
};
|
||||
|
||||
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||
|
@ -84,6 +86,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
getFile,
|
||||
streamingUrl,
|
||||
customShouldHide,
|
||||
nullPreview,
|
||||
} = props;
|
||||
const shouldFetch =
|
||||
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
|
||||
|
@ -114,7 +117,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
let shouldHide =
|
||||
placeholder !== 'loading' &&
|
||||
!showUserBlocked &&
|
||||
((abandoned && !showPublishLink) || (!claimIsMine && obscureNsfw && nsfw));
|
||||
((abandoned && !nullPreview === 'abandonedChannel' && !showPublishLink) || (!claimIsMine && obscureNsfw && nsfw));
|
||||
|
||||
// This will be replaced once blocking is done at the wallet server level
|
||||
if (claim && !claimIsMine && !shouldHide && blackListedOutpoints) {
|
||||
|
@ -203,6 +206,9 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (nullPreview === 'abandonedChannel' && !isResolvingUri && !claim) {
|
||||
return <AbandonedChannelPreview uri={uri} type />;
|
||||
}
|
||||
if (placeholder === 'publish' && !claim && uri.startsWith('lbry://@')) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ function ChannelsFollowingManagePage(props: Props) {
|
|||
return (
|
||||
<Page>
|
||||
<ClaimList
|
||||
nullPreviewBehavior={'abandonedChannel'}
|
||||
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
|
||||
headerAltControls={
|
||||
<Button
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
normalizeURI,
|
||||
makeSelectClaimIsMine,
|
||||
} from 'lbry-redux';
|
||||
import { makeSelectChannelInSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import { selectBlackListedOutpoints } from 'lbryinc';
|
||||
import ShowPage from './view';
|
||||
|
||||
|
@ -37,6 +38,7 @@ const select = (state, props) => {
|
|||
isResolvingUri: makeSelectIsUriResolving(uri)(state),
|
||||
blackListedOutpoints: selectBlackListedOutpoints(state),
|
||||
totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state),
|
||||
isSubscribed: makeSelectChannelInSubscriptions(uri)(state),
|
||||
uri,
|
||||
title: makeSelectTitleForUri(uri)(state),
|
||||
claimIsMine: makeSelectClaimIsMine(uri)(state),
|
||||
|
|
|
@ -8,10 +8,12 @@ import Page from 'component/page';
|
|||
import Button from 'component/button';
|
||||
import { SITE_TITLE } from 'config';
|
||||
import Card from 'component/common/card';
|
||||
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
|
||||
|
||||
type Props = {
|
||||
isResolvingUri: boolean,
|
||||
resolveUri: string => void,
|
||||
isSubscribed: boolean,
|
||||
uri: string,
|
||||
claim: StreamClaim,
|
||||
location: UrlLocation,
|
||||
|
@ -24,7 +26,17 @@ type Props = {
|
|||
};
|
||||
|
||||
function ShowPage(props: Props) {
|
||||
const { isResolvingUri, resolveUri, uri, claim, blackListedOutpoints, location, title, claimIsMine } = props;
|
||||
const {
|
||||
isResolvingUri,
|
||||
resolveUri,
|
||||
uri,
|
||||
claim,
|
||||
blackListedOutpoints,
|
||||
location,
|
||||
title,
|
||||
claimIsMine,
|
||||
isSubscribed,
|
||||
} = props;
|
||||
const { channelName, streamName } = parseURI(uri);
|
||||
const signingChannel = claim && claim.signing_channel;
|
||||
const canonicalUrl = claim && claim.canonical_url;
|
||||
|
@ -70,11 +82,13 @@ function ShowPage(props: Props) {
|
|||
// This shouldn't happen, so hopefully this helps track it down
|
||||
console.error('No name for associated claim: ', claim.claim_id); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
innerContent = (
|
||||
<Page>
|
||||
{isResolvingUri && <BusyIndicator message={__('Loading decentralized data...')} />}
|
||||
{!isResolvingUri && <span className="empty">{__("There's nothing available at this location.")}</span>}
|
||||
{!isResolvingUri && !isSubscribed && (
|
||||
<span className="empty">{__("There's nothing available at this location.")}</span>
|
||||
)}
|
||||
{!isResolvingUri && isSubscribed && <AbandonedChannelPreview uri={uri} type={'large'} />}
|
||||
</Page>
|
||||
);
|
||||
} else if (claim.name.length && claim.name[0] === '@') {
|
||||
|
|
|
@ -257,6 +257,12 @@ export const selectSubscriptionClaims = createSelector(
|
|||
|
||||
// Returns true if a user is subscribed to the channel associated with the uri passed in
|
||||
// Accepts content or channel uris
|
||||
export const makeSelectChannelInSubscriptions = uri =>
|
||||
createSelector(
|
||||
selectSubscriptions,
|
||||
subscriptions => subscriptions.some(sub => sub.uri === uri)
|
||||
);
|
||||
|
||||
export const makeSelectIsSubscribed = uri =>
|
||||
createSelector(
|
||||
selectSubscriptions,
|
||||
|
|
Loading…
Add table
Reference in a new issue