diff --git a/static/app-strings.json b/static/app-strings.json index fa3fb23ff..5f1059235 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -2054,5 +2054,7 @@ "Item removed from Watch Later": "Item removed from Watch Later", "Skip Navigation": "Skip Navigation", "In Favorites": "In Favorites", + "%title% by %channelTitle%, %mediaDuration%": "%title% by %channelTitle%, %mediaDuration%", + "%title% by %channelTitle%": "%title% by %channelTitle%", "--end--": "--end--" } diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js index 256ca5f45..878be3e22 100644 --- a/ui/component/claimPreviewTile/index.js +++ b/ui/component/claimPreviewTile/index.js @@ -14,20 +14,28 @@ import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc'; import { selectShowMatureContent } from 'redux/selectors/settings'; import ClaimPreviewTile from './view'; +import formatMediaDuration from 'util/formatMediaDuration'; -const select = (state, props) => ({ - claim: props.uri && makeSelectClaimForUri(props.uri)(state), - channel: props.uri && makeSelectChannelForClaimUri(props.uri)(state), - isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), - thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), - title: props.uri && makeSelectTitleForUri(props.uri)(state), - blackListedOutpoints: selectBlackListedOutpoints(state), - filteredOutpoints: selectFilteredOutpoints(state), - blockedChannelUris: selectMutedChannels(state), - showMature: selectShowMatureContent(state), - isMature: makeSelectClaimIsNsfw(props.uri)(state), - isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state), -}); +const select = (state, props) => { + const claim = props.uri && makeSelectClaimForUri(props.uri)(state); + const media = claim && claim.value && (claim.value.video || claim.value.audio); + const mediaDuration = media && media.duration && formatMediaDuration(media.duration, { screenReader: true }); + + return { + claim, + mediaDuration, + channel: props.uri && makeSelectChannelForClaimUri(props.uri)(state), + isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), + thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), + title: props.uri && makeSelectTitleForUri(props.uri)(state), + blackListedOutpoints: selectBlackListedOutpoints(state), + filteredOutpoints: selectFilteredOutpoints(state), + blockedChannelUris: selectMutedChannels(state), + showMature: selectShowMatureContent(state), + isMature: makeSelectClaimIsNsfw(props.uri)(state), + isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state), + }; +}; const perform = (dispatch) => ({ resolveUri: (uri) => dispatch(doResolveUri(uri)), diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx index 6a1e3b4ae..c238b44fb 100644 --- a/ui/component/claimPreviewTile/view.jsx +++ b/ui/component/claimPreviewTile/view.jsx @@ -21,6 +21,7 @@ import CollectionPreviewOverlay from 'component/collectionPreviewOverlay'; type Props = { uri: string, claim: ?Claim, + mediaDuration?: string, resolveUri: (string) => void, isResolvingUri: boolean, history: { push: (string) => void }, @@ -72,6 +73,7 @@ function ClaimPreviewTile(props: Props) { showNoSourceClaims, isLivestream, collectionId, + mediaDuration, } = props; const isRepost = claim && claim.repost_channel_url; const isCollection = claim && claim.value_type === 'collection'; @@ -114,6 +116,18 @@ function ClaimPreviewTile(props: Props) { const signingChannel = claim && claim.signing_channel; const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url; + const channelTitle = signingChannel && (signingChannel.value.title || signingChannel.name); + + // Aria-label value for claim preview + let ariaLabelData = title; + + if (!isChannel && channelTitle) { + if (mediaDuration) { + ariaLabelData = __('%title% by %channelTitle%, %mediaDuration%', { title, channelTitle, mediaDuration }); + } else { + ariaLabelData = __('%title% by %channelTitle%', { title, channelTitle }); + } + } function handleClick(e) { if (navigateUrl) { @@ -226,7 +240,7 @@ function ClaimPreviewTile(props: Props) {