use new aria label format for claim preview
This commit is contained in:
parent
06e6feaf3b
commit
d1a8f28464
4 changed files with 76 additions and 32 deletions
|
@ -15,6 +15,8 @@ import {
|
||||||
doCollectionEdit,
|
doCollectionEdit,
|
||||||
makeSelectUrlsForCollectionId,
|
makeSelectUrlsForCollectionId,
|
||||||
makeSelectIndexForUrlInCollection,
|
makeSelectIndexForUrlInCollection,
|
||||||
|
makeSelectTitleForUri,
|
||||||
|
makeSelectDateForUri,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { selectMutedChannels, makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { selectMutedChannels, makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
|
import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
|
||||||
|
@ -22,32 +24,43 @@ import { selectShowMatureContent } from 'redux/selectors/settings';
|
||||||
import { makeSelectHasVisitedUri } from 'redux/selectors/content';
|
import { makeSelectHasVisitedUri } from 'redux/selectors/content';
|
||||||
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
||||||
import { selectModerationBlockList } from 'redux/selectors/comments';
|
import { selectModerationBlockList } from 'redux/selectors/comments';
|
||||||
import ClaimPreview from './view';
|
|
||||||
|
|
||||||
const select = (state, props) => ({
|
import ClaimPreview from './view';
|
||||||
pending: props.uri && makeSelectClaimIsPending(props.uri)(state),
|
import formatMediaDuration from 'util/formatMediaDuration';
|
||||||
claim: props.uri && makeSelectClaimForUri(props.uri)(state),
|
|
||||||
reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state),
|
const select = (state, props) => {
|
||||||
obscureNsfw: selectShowMatureContent(state) === false,
|
const claim = props.uri && makeSelectClaimForUri(props.uri)(state);
|
||||||
claimIsMine: props.uri && makeSelectClaimIsMine(props.uri)(state),
|
const media = claim && claim.value && (claim.value.video || claim.value.audio);
|
||||||
isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state),
|
const mediaDuration = media && media.duration && formatMediaDuration(media.duration, { screenReader: true });
|
||||||
isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state),
|
|
||||||
repostClaim: props.uri && makeSelectClaimForUri(props.uri)(state),
|
return {
|
||||||
nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state),
|
claim,
|
||||||
blackListedOutpoints: selectBlackListedOutpoints(state),
|
mediaDuration,
|
||||||
filteredOutpoints: selectFilteredOutpoints(state),
|
date: props.uri && makeSelectDateForUri(props.uri)(state),
|
||||||
mutedUris: selectMutedChannels(state),
|
title: props.uri && makeSelectTitleForUri(props.uri)(state),
|
||||||
blockedUris: selectModerationBlockList(state),
|
pending: props.uri && makeSelectClaimIsPending(props.uri)(state),
|
||||||
hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state),
|
reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state),
|
||||||
channelIsBlocked: props.uri && makeSelectChannelIsMuted(props.uri)(state),
|
obscureNsfw: selectShowMatureContent(state) === false,
|
||||||
isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state),
|
claimIsMine: props.uri && makeSelectClaimIsMine(props.uri)(state),
|
||||||
streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state),
|
isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state),
|
||||||
wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
|
isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state),
|
||||||
isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
|
repostClaim: props.uri && makeSelectClaimForUri(props.uri)(state),
|
||||||
isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state),
|
nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state),
|
||||||
collectionUris: makeSelectUrlsForCollectionId(props.collectionId)(state),
|
blackListedOutpoints: selectBlackListedOutpoints(state),
|
||||||
collectionIndex: makeSelectIndexForUrlInCollection(props.uri, props.collectionId)(state),
|
filteredOutpoints: selectFilteredOutpoints(state),
|
||||||
});
|
mutedUris: selectMutedChannels(state),
|
||||||
|
blockedUris: selectModerationBlockList(state),
|
||||||
|
hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state),
|
||||||
|
channelIsBlocked: props.uri && makeSelectChannelIsMuted(props.uri)(state),
|
||||||
|
isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state),
|
||||||
|
streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state),
|
||||||
|
wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
|
||||||
|
isLivestream: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
|
||||||
|
isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state),
|
||||||
|
collectionUris: makeSelectUrlsForCollectionId(props.collectionId)(state),
|
||||||
|
collectionIndex: makeSelectIndexForUrlInCollection(props.uri, props.collectionId)(state),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
resolveUri: (uri) => dispatch(doResolveUri(uri)),
|
resolveUri: (uri) => dispatch(doResolveUri(uri)),
|
||||||
|
|
|
@ -27,6 +27,7 @@ import ClaimPreviewHidden from './claim-preview-no-mature';
|
||||||
import ClaimPreviewNoContent from './claim-preview-no-content';
|
import ClaimPreviewNoContent from './claim-preview-no-content';
|
||||||
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import DateTime from 'component/dateTime';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
|
||||||
const AbandonedChannelPreview = lazyImport(() =>
|
const AbandonedChannelPreview = lazyImport(() =>
|
||||||
|
@ -84,6 +85,8 @@ type Props = {
|
||||||
collectionUris: Array<Collection>,
|
collectionUris: Array<Collection>,
|
||||||
collectionIndex?: number,
|
collectionIndex?: number,
|
||||||
disableNavigation?: boolean,
|
disableNavigation?: boolean,
|
||||||
|
mediaDuration?: string,
|
||||||
|
date?: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
|
@ -98,8 +101,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
// claim properties
|
// claim properties
|
||||||
// is the claim consider nsfw?
|
// is the claim consider nsfw?
|
||||||
nsfw,
|
nsfw,
|
||||||
|
date,
|
||||||
|
title,
|
||||||
claimIsMine,
|
claimIsMine,
|
||||||
streamingUrl,
|
streamingUrl,
|
||||||
|
mediaDuration,
|
||||||
// user properties
|
// user properties
|
||||||
channelIsBlocked,
|
channelIsBlocked,
|
||||||
hasVisitedUri,
|
hasVisitedUri,
|
||||||
|
@ -172,6 +178,23 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
const isCollection = claim && claim.value_type === 'collection';
|
const isCollection = claim && claim.value_type === 'collection';
|
||||||
const isChannelUri = isValid ? parseURI(uri).isChannel : false;
|
const isChannelUri = isValid ? parseURI(uri).isChannel : false;
|
||||||
const signingChannel = claim && claim.signing_channel;
|
const signingChannel = claim && claim.signing_channel;
|
||||||
|
const channelTitle = signingChannel && (signingChannel.value.title || signingChannel.name);
|
||||||
|
|
||||||
|
// Aria-label value for claim preview
|
||||||
|
let ariaLabelData = title;
|
||||||
|
|
||||||
|
if (!isChannelUri && channelTitle) {
|
||||||
|
ariaLabelData += ' ' + __('by %channelTitle%', { channelTitle });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date) {
|
||||||
|
ariaLabelData += ' ' + DateTime.getTimeAgoStr(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mediaDuration) {
|
||||||
|
ariaLabelData += ', ' + mediaDuration;
|
||||||
|
}
|
||||||
|
|
||||||
let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/');
|
let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/');
|
||||||
if (collectionId) {
|
if (collectionId) {
|
||||||
const collectionParams = new URLSearchParams();
|
const collectionParams = new URLSearchParams();
|
||||||
|
@ -310,7 +333,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{isChannelUri && claim ? (
|
{isChannelUri && claim ? (
|
||||||
<UriIndicator aria-hidden tabIndex={-1} uri={uri} link>
|
<UriIndicator focusable={false} uri={uri} link>
|
||||||
<ChannelThumbnail uri={uri} small={type === 'inline'} />
|
<ChannelThumbnail uri={uri} small={type === 'inline'} />
|
||||||
</UriIndicator>
|
</UriIndicator>
|
||||||
) : (
|
) : (
|
||||||
|
@ -349,7 +372,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
{pending ? (
|
{pending ? (
|
||||||
<ClaimPreviewTitle uri={uri} />
|
<ClaimPreviewTitle uri={uri} />
|
||||||
) : (
|
) : (
|
||||||
<NavLink {...navLinkProps}>
|
<NavLink aria-label={ariaLabelData} {...navLinkProps}>
|
||||||
<ClaimPreviewTitle uri={uri} />
|
<ClaimPreviewTitle uri={uri} />
|
||||||
</NavLink>
|
</NavLink>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -268,7 +268,7 @@ function ClaimPreviewTile(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<UriIndicator aria-hidden tabIndex={-1} uri={uri} link hideAnonymous>
|
<UriIndicator focusable={false} uri={uri} link hideAnonymous>
|
||||||
<ChannelThumbnail uri={channelUri} xsmall />
|
<ChannelThumbnail uri={channelUri} xsmall />
|
||||||
</UriIndicator>
|
</UriIndicator>
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ type Props = {
|
||||||
inline: boolean,
|
inline: boolean,
|
||||||
external?: boolean,
|
external?: boolean,
|
||||||
className?: string,
|
className?: string,
|
||||||
|
focusable: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class UriIndicator extends React.PureComponent<Props> {
|
class UriIndicator extends React.PureComponent<Props> {
|
||||||
|
@ -45,10 +46,10 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
claim,
|
claim,
|
||||||
children,
|
children,
|
||||||
inline,
|
inline,
|
||||||
hideAnonymous = false,
|
focusable = true,
|
||||||
external = false,
|
external = false,
|
||||||
|
hideAnonymous = false,
|
||||||
className,
|
className,
|
||||||
...props
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
|
@ -87,7 +88,13 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
|
|
||||||
if (children) {
|
if (children) {
|
||||||
return (
|
return (
|
||||||
<Button className={className} target={external ? '_blank' : undefined} navigate={channelLink} {...props}>
|
<Button
|
||||||
|
aria-hidden={!focusable}
|
||||||
|
tabIndex={focusable ? 0 : -1}
|
||||||
|
className={className}
|
||||||
|
target={external ? '_blank' : undefined}
|
||||||
|
navigate={channelLink}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
@ -97,7 +104,8 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
className={classnames(className, 'button--uri-indicator')}
|
className={classnames(className, 'button--uri-indicator')}
|
||||||
navigate={channelLink}
|
navigate={channelLink}
|
||||||
target={external ? '_blank' : undefined}
|
target={external ? '_blank' : undefined}
|
||||||
{...props}
|
aria-hidden={!focusable}
|
||||||
|
tabIndex={focusable ? 0 : -1}
|
||||||
>
|
>
|
||||||
{inner}
|
{inner}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
Loading…
Add table
Reference in a new issue