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

234 lines
6.8 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';
import ClaimMenuList from 'component/claimMenuList';
2021-02-17 08:28:58 +01:00
// @if TARGET='app'
import { openClaimPreviewMenu } from 'util/context-menu';
2021-02-17 08:28:58 +01:00
// @endif
2020-01-20 17:47:03 +01:00
type Props = {
uri: string,
claim: ?Claim,
resolveUri: (string) => void,
2020-01-20 17:47:03 +01:00
isResolvingUri: boolean,
history: { push: (string) => void },
2020-01-20 17:47:03 +01:00
thumbnail: string,
title: string,
placeholder: boolean,
blackListedOutpoints: Array<{
txid: string,
nout: number,
}>,
filteredOutpoints: Array<{
txid: string,
nout: number,
}>,
blockedChannelUris: Array<string>,
getFile: (string) => void,
2020-01-20 17:47:03 +01:00
placeholder: boolean,
streamingUrl: string,
isMature: boolean,
showMature: boolean,
showHiddenByUser?: 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,
showHiddenByUser,
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 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;
}
}
let channelUri;
2020-01-20 17:47:03 +01:00
const signingChannel = claim && claim.signing_channel;
if (signingChannel) {
channelUri = signingChannel.permanent_url;
2020-01-20 17:47:03 +01:00
}
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) =>
2020-01-20 17:47:03 +01:00
(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) =>
2020-01-20 17:47:03 +01:00
(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 && !showHiddenByUser && blockedChannelUris.length && signingChannel) {
shouldHide = blockedChannelUris.some((blockedUri) => blockedUri === signingChannel.permanent_url);
2020-01-20 19:55:28 +01:00
}
// block channel claims if we can't control for them in claim search
// e.g. fetchRecommendedSubscriptions
if (claim && isChannel && !shouldHide && !showHiddenByUser && blockedChannelUris.length) {
shouldHide = blockedChannelUris.some((blockedUri) => blockedUri === claim.permanent_url);
2020-01-20 19:55:28 +01:00
}
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>
);
}
function handleContextMenu(e) {
// @if TARGET='app'
e.preventDefault();
e.stopPropagation();
openClaimPreviewMenu(claim, e);
// @endif
}
2020-01-20 17:47:03 +01:00
return (
<li
role="link"
onClick={handleClick}
onContextMenu={handleContextMenu}
2020-01-20 17:47:03 +01:00
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-preview__file-property-overlay">
2020-01-29 19:58:43 +01:00
<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={isChannel ? 1 : 2} />
{isChannel && (
<div className="claim-tile__about">
<UriIndicator uri={uri} link />
</div>
)}
<ClaimMenuList uri={uri} />
</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">
2020-07-09 20:18:56 +02:00
<SubscribeButton uri={uri} />
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 uri={channelUri} />
2020-01-31 17:43:14 +01:00
</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);