lbry-desktop/ui/component/claimPreviewTile/view.jsx

221 lines
6.7 KiB
React
Raw Normal View History

2020-01-20 17:47:03 +01:00
// @flow
import React from 'react';
import classnames from 'classnames';
import { NavLink, withRouter } from 'react-router-dom';
import FileThumbnail from 'component/fileThumbnail';
import UriIndicator from 'component/uriIndicator';
import TruncatedText from 'component/common/truncated-text';
import DateTime from 'component/dateTime';
import ChannelThumbnail from 'component/channelThumbnail';
import SubscribeButton from 'component/subscribeButton';
import useGetThumbnail from 'effects/use-get-thumbnail';
import { formatLbryUrlForWeb } from 'util/url';
import { parseURI } from 'lbry-redux';
2020-01-29 16:26:39 +01:00
import FileProperties from 'component/fileProperties';
import FileDownloadLink from 'component/fileDownloadLink';
2020-01-31 17:43:14 +01:00
import ClaimRepostAuthor from 'component/claimRepostAuthor';
2020-01-20 17:47:03 +01:00
type Props = {
uri: string,
claim: ?Claim,
resolveUri: string => void,
isResolvingUri: boolean,
history: { push: string => void },
thumbnail: string,
title: string,
placeholder: boolean,
blackListedOutpoints: Array<{
txid: string,
nout: number,
}>,
filteredOutpoints: Array<{
txid: string,
nout: number,
}>,
blockedChannelUris: Array<string>,
getFile: string => void,
placeholder: boolean,
streamingUrl: string,
isMature: boolean,
showMature: boolean,
2020-01-20 17:47:03 +01:00
};
function ClaimPreviewTile(props: Props) {
const {
history,
uri,
isResolvingUri,
thumbnail,
title,
resolveUri,
claim,
placeholder,
blackListedOutpoints,
filteredOutpoints,
getFile,
streamingUrl,
2020-01-20 19:55:28 +01:00
blockedChannelUris,
isMature,
showMature,
2020-01-20 17:47:03 +01:00
} = props;
2020-01-31 17:43:14 +01:00
const isRepost = claim && claim.repost_channel_url;
2020-01-20 17:47:03 +01:00
const shouldFetch = claim === undefined;
const thumbnailUrl = useGetThumbnail(uri, claim, streamingUrl, getFile, placeholder) || thumbnail;
const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
const canonicalUrl = claim && claim.canonical_url;
2020-02-05 00:54:49 +01:00
const navigateUrl = formatLbryUrlForWeb(canonicalUrl || uri || '/');
const navLinkProps = {
to: navigateUrl,
onClick: e => e.stopPropagation(),
};
2020-01-20 17:47:03 +01:00
let isChannel;
let isValid = false;
if (uri) {
try {
({ isChannel } = parseURI(uri));
isValid = true;
} catch (e) {
isValid = false;
}
}
const signingChannel = claim && claim.signing_channel;
let channelThumbnail;
if (signingChannel) {
channelThumbnail =
// I should be able to just pass the the uri to <ChannelThumbnail /> but it wasn't working
// Come back to me
(signingChannel.value && signingChannel.value.thumbnail && signingChannel.value.thumbnail.url) || undefined;
}
function handleClick(e) {
if (navigateUrl) {
history.push(navigateUrl);
}
}
React.useEffect(() => {
if (isValid && !isResolvingUri && shouldFetch && uri) {
resolveUri(uri);
}
}, [isValid, isResolvingUri, uri, resolveUri, shouldFetch]);
let shouldHide = false;
if (isMature && !showMature) {
// Unfortunately needed until this is resolved
// https://github.com/lbryio/lbry-sdk/issues/2785
shouldHide = true;
}
2020-01-20 17:47:03 +01:00
// This will be replaced once blocking is done at the wallet server level
if (claim && !shouldHide && blackListedOutpoints) {
shouldHide = blackListedOutpoints.some(
outpoint =>
(signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
(outpoint.txid === claim.txid && outpoint.nout === claim.nout)
);
}
// We're checking to see if the stream outpoint
// or signing channel outpoint is in the filter list
if (claim && !shouldHide && filteredOutpoints) {
shouldHide = filteredOutpoints.some(
outpoint =>
(signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
(outpoint.txid === claim.txid && outpoint.nout === claim.nout)
);
}
2020-01-20 19:55:28 +01:00
// block stream claims
if (claim && !shouldHide && blockedChannelUris.length && signingChannel) {
shouldHide = blockedChannelUris.some(blockedUri => blockedUri === signingChannel.permanent_url);
}
// block channel claims if we can't control for them in claim search
// e.g. fetchRecommendedSubscriptions
if (claim && isChannel && !shouldHide && blockedChannelUris.length) {
shouldHide = blockedChannelUris.some(blockedUri => blockedUri === claim.permanent_url);
}
2020-01-20 17:47:03 +01:00
if (shouldHide) {
return null;
}
if (placeholder || isResolvingUri) {
return (
<li className={classnames('claim-preview--tile', {})}>
<div className="placeholder media__thumb" />
<div className="placeholder__wrapper">
<div className="placeholder claim-tile__title" />
<div className="placeholder claim-tile__info" />
</div>
</li>
);
}
return (
<li
role="link"
onClick={handleClick}
className={classnames('card claim-preview--tile', {
2020-01-31 17:43:14 +01:00
'claim-preview__wrapper--channel': isChannel,
2020-01-20 17:47:03 +01:00
})}
>
<NavLink {...navLinkProps}>
<FileThumbnail thumbnail={thumbnailUrl} allowGifs>
{!isChannel && (
2020-01-29 19:58:43 +01:00
<React.Fragment>
{/* @if TARGET='app' */}
2020-02-05 17:42:46 +01:00
<div className="claim-preview__hover-actions">
<FileDownloadLink uri={canonicalUrl} hideOpenButton />
2020-01-29 19:58:43 +01:00
</div>
{/* @endif */}
<div className="claim-tile__file-properties">
<FileProperties uri={uri} small />
</div>
</React.Fragment>
)}
</FileThumbnail>
2020-01-20 17:47:03 +01:00
</NavLink>
<NavLink {...navLinkProps}>
<h2 className="claim-tile__title">
<TruncatedText text={title || (claim && claim.name)} lines={2} />
</h2>
2020-01-20 17:47:03 +01:00
</NavLink>
2020-01-31 17:43:14 +01:00
<div>
<div className="claim-tile__info">
{isChannel ? (
<div className="claim-tile__about--channel">
<SubscribeButton uri={uri} shrinkOnMobile />
2020-01-31 17:43:14 +01:00
<span className="claim-tile__publishes">
{claimsInChannel === 1
? __('%claimsInChannel% publish', { claimsInChannel })
: __('%claimsInChannel% publishes', { claimsInChannel })}
</span>
2020-01-20 17:47:03 +01:00
</div>
2020-01-31 17:43:14 +01:00
) : (
<React.Fragment>
<UriIndicator uri={uri} link hideAnonymous>
<ChannelThumbnail thumbnailPreview={channelThumbnail} />
</UriIndicator>
<div className="claim-tile__about">
<UriIndicator uri={uri} link />
<DateTime timeAgo uri={uri} />
</div>
</React.Fragment>
)}
</div>
{isRepost && (
<div className="claim-tile__repost-author">
<ClaimRepostAuthor uri={uri} />
</div>
2020-01-20 17:47:03 +01:00
)}
</div>
</li>
);
}
export default withRouter(ClaimPreviewTile);