// @flow import React from 'react'; import classnames from 'classnames'; import { NavLink, withRouter } from 'react-router-dom'; import ClaimPreviewProgress from 'component/claimPreviewProgress'; import FileThumbnail from 'component/fileThumbnail'; import UriIndicator from 'component/uriIndicator'; import Icon from 'component/common/icon'; import TruncatedText from 'component/common/truncated-text'; import DateTime from 'component/dateTime'; import LivestreamDateTime from 'component/livestreamDateTime'; import ChannelThumbnail from 'component/channelThumbnail'; import FileViewCountInline from 'component/fileViewCountInline'; // import SubscribeButton from 'component/subscribeButton'; import useGetThumbnail from 'effects/use-get-thumbnail'; import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url'; import { formatClaimPreviewTitle } from 'util/formatAriaLabel'; import { parseURI } from 'util/lbryURI'; import PreviewOverlayProperties from 'component/previewOverlayProperties'; import FileDownloadLink from 'component/fileDownloadLink'; import FileHideRecommendation from 'component/fileHideRecommendation'; import FileWatchLaterLink from 'component/fileWatchLaterLink'; import ClaimRepostAuthor from 'component/claimRepostAuthor'; import ClaimMenuList from 'component/claimMenuList'; import CollectionPreviewOverlay from 'component/collectionPreviewOverlay'; import * as ICONS from 'constants/icons'; import { FYP_ID } from 'constants/urlParams'; // $FlowFixMe cannot resolve ... import PlaceholderTx from 'static/img/placeholderTx.gif'; type Props = { uri: string, date?: any, claim: ?Claim, mediaDuration?: string, resolveUri: (string) => void, isResolvingUri: boolean, history: { push: (string) => void }, thumbnail: string, title: string, placeholder: boolean, banState: { blacklisted?: boolean, filtered?: boolean, muted?: boolean, blocked?: boolean }, getFile: (string) => void, streamingUrl: string, isMature: boolean, showMature: boolean, showHiddenByUser?: boolean, showNoSourceClaims?: boolean, showUnresolvedClaims?: boolean, properties?: (Claim) => void, collectionId?: string, fypId?: string, isLivestream: boolean, viewCount: string, isLivestreamActive: boolean, livestreamViewerCount: ?number, swipeLayout: boolean, onHidden?: (string) => void, pulse?: boolean, }; // preview image cards used in related video functionality, channel overview page and homepage function ClaimPreviewTile(props: Props) { const { history, uri, date, isResolvingUri, thumbnail, title, resolveUri, claim, placeholder, banState, getFile, streamingUrl, isMature, showMature, showHiddenByUser, properties, showNoSourceClaims, showUnresolvedClaims, isLivestream, isLivestreamActive, livestreamViewerCount, collectionId, fypId, mediaDuration, viewCount, swipeLayout = false, onHidden, pulse, } = props; const isRepost = claim && claim.repost_channel_url; const isCollection = claim && claim.value_type === 'collection'; const isStream = claim && claim.value_type === 'stream'; const isAbandoned = !isResolvingUri && !claim; // $FlowFixMe const isPlayable = claim && // $FlowFixMe claim.value && // $FlowFixMe claim.value.stream_type && // $FlowFixMe (claim.value.stream_type === 'audio' || claim.value.stream_type === 'video'); const collectionClaimId = isCollection && claim && claim.claim_id; const shouldFetch = claim === undefined; const thumbnailUrl = useGetThumbnail(uri, claim, streamingUrl, getFile, placeholder) || thumbnail; const canonicalUrl = claim && claim.canonical_url; const repostedContentUri = claim && (claim.reposted_claim ? claim.reposted_claim.permanent_url : claim.permanent_url); const listId = collectionId || collectionClaimId; const navigateUrl = formatLbryUrlForWeb(canonicalUrl || uri || '/') + (listId ? generateListSearchUrlParams(listId) : '') + (fypId ? `?${FYP_ID}=${fypId}` : ''); // sigh... const navLinkProps = { to: navigateUrl, onClick: (e) => e.stopPropagation(), }; let isValid = false; if (uri) { try { parseURI(uri); isValid = true; } catch (e) { isValid = false; } } const signingChannel = claim && claim.signing_channel; const isChannel = claim && claim.value_type === 'channel'; const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url; const channelTitle = signingChannel && ((signingChannel.value && signingChannel.value.title) || signingChannel.name); // Aria-label value for claim preview let ariaLabelData = isChannel ? title : formatClaimPreviewTitle(title, channelTitle, date, mediaDuration); 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; } else { shouldHide = !placeholder && (banState.blacklisted || banState.filtered || (!showHiddenByUser && (banState.muted || banState.blocked)) || (isAbandoned && !showUnresolvedClaims)); if (onHidden && shouldHide) onHidden(props.uri); } if (shouldHide || (isLivestream && !showNoSourceClaims)) { return null; } const isChannelPage = window.location.pathname.startsWith('/@'); const shouldShowViewCount = !(!viewCount || (claim && claim.repost_url) || isLivestream || !isChannelPage); if (placeholder || (!claim && isResolvingUri)) { return (
  • Placeholder
  • ); } let liveProperty = null; if (isLivestream) { if (isLivestreamActive === true && livestreamViewerCount) { liveProperty = (claim) => ( {livestreamViewerCount} ); } else { liveProperty = (claim) => <>LIVE; } } return (
  • {!isChannel && (
    {isPlayable && }
    {fypId && (
    {isStream && }
    )} {/* @if TARGET='app' */}
    {isStream && }
    {/* @endif */}
    )} {isCollection && (
    )}

    {isChannel && (
    )}

    {isChannel ? ( //
    // //
    <> ) : (
    {isLivestream && } {!isLivestream && }
    )}
    {isRepost && (
    )}
  • ); } export default withRouter(ClaimPreviewTile);