// @flow import React, { useContext } 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 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 FileWatchLaterLink from 'component/fileWatchLaterLink'; import ClaimRepostAuthor from 'component/claimRepostAuthor'; import ClaimMenuList from 'component/claimMenuList'; import CollectionPreviewOverlay from 'component/collectionPreviewOverlay'; import ClaimListDiscoverContext from 'component/claimListDiscover/context'; import moment from 'moment'; // $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, properties?: (Claim) => void, collectionId?: string, showNoSourceClaims?: boolean, isLivestream: boolean, viewCount: string, isLivestreamActive: 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, isLivestream, isLivestreamActive, collectionId, mediaDuration, viewCount, } = props; const isRepost = claim && claim.repost_channel_url; const isCollection = claim && claim.value_type === 'collection'; const isStream = claim && claim.value_type === 'stream'; // $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 permanentUrl = claim && claim.permanent_url; const listId = collectionId || collectionClaimId; const navigateUrl = formatLbryUrlForWeb(canonicalUrl || uri || '/') + (listId ? generateListSearchUrlParams(listId) : ''); const navLinkProps = { to: navigateUrl, onClick: (e) => e.stopPropagation(), }; let isValid = false; if (uri) { try { parseURI(uri); isValid = true; } catch (e) { isValid = false; } } const { listingType } = useContext(ClaimListDiscoverContext) || {}; 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); const repostedChannelUri = isRepost && isChannel ? permanentUrl || canonicalUrl : undefined; // 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 = banState.blacklisted || banState.filtered || (!showHiddenByUser && (banState.muted || banState.blocked)); } 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 === true) { liveProperty = (claim) => <>LIVE; } const LivestreamDateTimeLabel = () => { // If showing in upcoming and in the past. (we allow x time in past to show here if not live yet) if (listingType === 'UPCOMING') { // $FlowFixMe if (moment.unix(claim.value.release_time).isBefore()) { return __('Starting Soon'); } } else { // If not in upcoming + live and in the future (started streaming a bit early) // $FlowFixMe if (isLivestreamActive && moment.unix(claim.value.release_time).isAfter()) { return __('Streaming Now'); } } return ; }; return (
  • {!isChannel && (
    {isPlayable && }
    {/* @if TARGET='app' */}
    {isStream && }
    {/* @endif */}
    )} {isCollection && (
    )}

    {isChannel && (
    )}

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