Actually hide NSFW content #1748

Merged
neb-b merged 8 commits from hide-nsfw into master 2018-07-13 20:31:15 +02:00
4 changed files with 50 additions and 85 deletions
Showing only changes of commit 22483a5b2b - Show all commits

View file

@ -4,46 +4,20 @@ import classnames from 'classnames';
type Props = { type Props = {
thumbnail: ?string, // externally sourced image thumbnail: ?string, // externally sourced image
nsfw: ?boolean,
}; };
const autoThumbColors = [
'purple',
'red',
'pink',
'indigo',
'blue',
'light-blue',
'cyan',
'teal',
'green',
'yellow',
'orange',
];
class CardMedia extends React.PureComponent<Props> { class CardMedia extends React.PureComponent<Props> {
getAutoThumbClass = () => autoThumbColors[Math.floor(Math.random() * autoThumbColors.length)];
render() { render() {
const { thumbnail, nsfw } = this.props; const { thumbnail } = this.props;
const generateAutothumb = !thumbnail && !nsfw;
let autoThumbClass;
if (generateAutothumb) {
autoThumbClass = `card__media--autothumb.${this.getAutoThumbClass()}`;
}
return ( return (
<div <div
style={thumbnail && !nsfw ? { backgroundImage: `url('${thumbnail}')` } : {}} style={thumbnail ? { backgroundImage: `url('${thumbnail}')` } : {}}
className={classnames('card__media', autoThumbClass, { className={classnames('card__media', {
'card__media--no-img': !thumbnail || nsfw, 'card__media--no-img': !thumbnail,
'card__media--nsfw': nsfw,
})} })}
> >
{(!thumbnail || nsfw) && ( {!thumbnail && <span className="card__media-text">LBRY</span>}
<span className="card__media-text">{nsfw ? __('NSFW') : 'LBRY'}</span>
)}
</div> </div>
); );
} }

View file

@ -1,7 +1,7 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import { normalizeURI, convertToShareLink } from 'lbry-redux'; import { normalizeURI, convertToShareLink } from 'lbry-redux';
import Button from 'component/button'; import type { Claim, Metadata } from 'types/claim';
import CardMedia from 'component/cardMedia'; import CardMedia from 'component/cardMedia';
import TruncatedText from 'component/common/truncated-text'; import TruncatedText from 'component/common/truncated-text';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
@ -14,9 +14,9 @@ import { openCopyLinkMenu } from '../../util/contextMenu';
// TODO: iron these out // TODO: iron these out
type Props = { type Props = {
uri: string, uri: string,
claim: ?{ claim_id: string }, claim: ?Claim,
fileInfo: ?{}, fileInfo: ?{},
metadata: ?{ nsfw: boolean, title: string, thumbnail: ?string }, metadata: ?Metadata,
navigate: (string, ?{}) => void, navigate: (string, ?{}) => void,
rewardedContentClaimIds: Array<string>, rewardedContentClaimIds: Array<string>,
obscureNsfw: boolean, obscureNsfw: boolean,
@ -62,10 +62,15 @@ class FileCard extends React.PureComponent<Props> {
showPrice, showPrice,
pending, pending,
} = this.props; } = this.props;
const shouldHide = obscureNsfw && metadata && metadata.nsfw && !claimIsMine;
if (shouldHide) {
return null;
}
const uri = !pending ? normalizeURI(this.props.uri) : this.props.uri; const uri = !pending ? normalizeURI(this.props.uri) : this.props.uri;
const title = metadata && metadata.title ? metadata.title : uri; const title = metadata && metadata.title ? metadata.title : uri;
const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null;
const shouldObscureNsfw = obscureNsfw && metadata && metadata.nsfw && !claimIsMine;
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
const handleContextMenu = event => { const handleContextMenu = event => {
event.preventDefault(); event.preventDefault();
@ -86,46 +91,26 @@ class FileCard extends React.PureComponent<Props> {
})} })}
onContextMenu={handleContextMenu} onContextMenu={handleContextMenu}
> >
<CardMedia nsfw={shouldObscureNsfw} thumbnail={thumbnail} /> <CardMedia thumbnail={thumbnail} />
<div className="card-media__internal-links">{showPrice && <FilePrice uri={uri} />}</div> <div className="card-media__internal-links">{showPrice && <FilePrice uri={uri} />}</div>
<div className="card__title-identity">
{shouldObscureNsfw ? ( <div className="card__title--small">
<div className="card__title-identity"> <TruncatedText lines={3}>{title}</TruncatedText>
<div className="card__title--small">
<TruncatedText lines={3}>
{__('This content is obscured because it is NSFW. You can change this in ')}
<Button
button="link"
label={__('Settings.')}
onClick={e => {
// Don't propagate to the onClick handler of parent element
e.stopPropagation();
navigate('/settings');
}}
/>
</TruncatedText>
</div>
</div> </div>
) : ( <div className="card__subtitle">
<div className="card__title-identity"> {pending ? (
<div className="card__title--small"> <div>Pending...</div>
<TruncatedText lines={3}>{title}</TruncatedText> ) : (
</div> <React.Fragment>
<div className="card__subtitle"> <UriIndicator uri={uri} link />
{pending ? ( <div>
<div>Pending...</div> {isRewardContent && <Icon iconColor="red" icon={icons.FEATURED} />}
) : ( {fileInfo && <Icon icon={icons.LOCAL} />}
<React.Fragment> </div>
<UriIndicator uri={uri} link /> </React.Fragment>
<div> )}
{isRewardContent && <Icon iconColor="red" icon={icons.FEATURED} />}
{fileInfo && <Icon icon={icons.LOCAL} />}
</div>
</React.Fragment>
)}
</div>
</div> </div>
)} </div>
</section> </section>
); );
/* eslint-enable jsx-a11y/click-events-have-key-events */ /* eslint-enable jsx-a11y/click-events-have-key-events */

View file

@ -1,6 +1,7 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
import type { Claim, Metadata } from 'types/claim';
import { normalizeURI, parseURI } from 'lbry-redux'; import { normalizeURI, parseURI } from 'lbry-redux';
import CardMedia from 'component/cardMedia'; import CardMedia from 'component/cardMedia';
import TruncatedText from 'component/common/truncated-text'; import TruncatedText from 'component/common/truncated-text';
@ -19,15 +20,8 @@ type Props = {
uri: string, uri: string,
isResolvingUri: boolean, isResolvingUri: boolean,
rewardedContentClaimIds: Array<string>, rewardedContentClaimIds: Array<string>,
claim: ?{ claim: ?Claim,
name: string, metadata: ?Metadata,
channel_name: string,
claim_id: string,
},
metadata: ?{
title: ?string,
thumbnail: ?string,
},
resolveUri: string => void, resolveUri: string => void,
navigate: (string, ?{}) => void, navigate: (string, ?{}) => void,
clearPublish: () => void, clearPublish: () => void,
@ -70,6 +64,11 @@ class FileTile extends React.PureComponent<Props> {
hideNoResult, hideNoResult,
} = this.props; } = this.props;
const shouldHide = obscureNsfw && metadata && metadata.nsfw && !claimIsMine;
if (shouldHide) {
return null;
}
const uri = normalizeURI(this.props.uri); const uri = normalizeURI(this.props.uri);
const isClaimed = !!claim; const isClaimed = !!claim;
const description = isClaimed && metadata && metadata.description ? metadata.description : ''; const description = isClaimed && metadata && metadata.description ? metadata.description : '';
@ -77,8 +76,6 @@ class FileTile extends React.PureComponent<Props> {
isClaimed && metadata && metadata.title ? metadata.title : parseURI(uri).contentName; isClaimed && metadata && metadata.title ? metadata.title : parseURI(uri).contentName;
const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null;
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
const shouldObscureNsfw = obscureNsfw && metadata && metadata.nsfw && !claimIsMine;
const onClick = () => navigate('/show', { uri }); const onClick = () => navigate('/show', { uri });
let name; let name;
@ -98,7 +95,7 @@ class FileTile extends React.PureComponent<Props> {
role="button" role="button"
tabIndex="0" tabIndex="0"
> >
<CardMedia title={title || name} thumbnail={thumbnail} nsfw={shouldObscureNsfw} /> <CardMedia title={title || name} thumbnail={thumbnail} />
<div className="file-tile__info"> <div className="file-tile__info">
{isResolvingUri && <div className="card__title--small">{__('Loading...')}</div>} {isResolvingUri && <div className="card__title--small">{__('Loading...')}</div>}
{!isResolvingUri && ( {!isResolvingUri && (

View file

@ -1,5 +1,13 @@
// @flow // @flow
// Currently incomplete
export type Metadata = {
nsfw: boolean,
title: string,
thumbnail: ?string,
description: ?string,
};
// Actual claim type has more values than this // Actual claim type has more values than this
// Add them as they are used // Add them as they are used
export type Claim = { export type Claim = {
@ -22,9 +30,10 @@ export type Claim = {
nout: number, nout: number,
signature_is_valid: boolean, signature_is_valid: boolean,
valid_at_height: number, valid_at_height: number,
value: { value: ?{
publisherSignature: ?{ publisherSignature: ?{
certificateId: ?string, certificateId: ?string,
}, },
stream: ?Metadata,
}, },
}; };