provide ability to unfollow abandoned channels

This commit is contained in:
jessop 2020-02-05 01:14:37 -05:00 committed by Sean Yesmunt
parent 7ae8f79299
commit 8ce05ebf76
8 changed files with 108 additions and 4 deletions

View 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);

View 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;

View file

@ -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) => {

View file

@ -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;
}

View file

@ -38,6 +38,7 @@ function ChannelsFollowingManagePage(props: Props) {
return (
<Page>
<ClaimList
nullPreviewBehavior={'abandonedChannel'}
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
headerAltControls={
<Button

View file

@ -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),

View file

@ -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] === '@') {

View file

@ -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,