mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 18:25:49 +03:00
Merge pull request #3007 from matrix-org/travis/sr/mute-timeline
Make the timeline less noisy for screen readers
This commit is contained in:
commit
983214f4bf
5 changed files with 34 additions and 11 deletions
|
@ -67,8 +67,8 @@ export default function AccessibleButton(props) {
|
|||
restProps.ref = restProps.inputRef;
|
||||
delete restProps.inputRef;
|
||||
|
||||
restProps.tabIndex = restProps.tabIndex || "0";
|
||||
restProps.role = "button";
|
||||
restProps.tabIndex = restProps.tabIndex === undefined ? "0" : restProps.tabIndex;
|
||||
restProps.role = restProps.role === undefined ? "button" : restProps.role;
|
||||
restProps.className = (restProps.className ? restProps.className + " " : "") +
|
||||
"mx_AccessibleButton";
|
||||
|
||||
|
|
|
@ -45,12 +45,18 @@ class FlairAvatar extends React.Component {
|
|||
const tooltip = this.props.groupProfile.name ?
|
||||
`${this.props.groupProfile.name} (${this.props.groupProfile.groupId})`:
|
||||
this.props.groupProfile.groupId;
|
||||
|
||||
// Note: we hide flair from screen readers but ideally we'd support
|
||||
// reading something out on hover. There's no easy way to do this though,
|
||||
// so instead we just hide it completely.
|
||||
return <img
|
||||
src={httpUrl}
|
||||
width="16"
|
||||
height="16"
|
||||
onClick={this.onClick}
|
||||
title={tooltip} />;
|
||||
title={tooltip}
|
||||
aria-hidden={true}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,12 +23,17 @@ export default class MessageTimestamp extends React.Component {
|
|||
static propTypes = {
|
||||
ts: PropTypes.number.isRequired,
|
||||
showTwelveHour: PropTypes.bool,
|
||||
ariaHidden: PropTypes.bool,
|
||||
};
|
||||
|
||||
render() {
|
||||
const date = new Date(this.props.ts);
|
||||
return (
|
||||
<span className="mx_MessageTimestamp" title={formatFullDate(date, this.props.showTwelveHour)}>
|
||||
<span
|
||||
className="mx_MessageTimestamp"
|
||||
title={formatFullDate(date, this.props.showTwelveHour)}
|
||||
aria-hidden={this.props.ariaHidden}
|
||||
>
|
||||
{ formatTime(date, this.props.showTwelveHour) }
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -545,6 +545,8 @@ module.exports = withMatrixClient(React.createClass({
|
|||
const isRedacted = isMessageEvent(this.props.mxEvent) && this.props.isRedacted;
|
||||
const isEncryptionFailure = this.props.mxEvent.isDecryptionFailure();
|
||||
|
||||
const muteScreenReader = isSending || !this.props.eventSendStatus;
|
||||
|
||||
const classes = classNames({
|
||||
mx_EventTile: true,
|
||||
mx_EventTile_isEditing: this.props.isEditing,
|
||||
|
@ -601,9 +603,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (this.props.mxEvent.sender && avatarSize) {
|
||||
avatar = (
|
||||
<div className="mx_EventTile_avatar">
|
||||
<MemberAvatar member={this.props.mxEvent.sender}
|
||||
<MemberAvatar
|
||||
member={this.props.mxEvent.sender}
|
||||
width={avatarSize} height={avatarSize}
|
||||
viewUserOnClick={true}
|
||||
aria-hidden={true} /* silence screen readers */
|
||||
buttonRole={null} /* trick screen readers into thinking this is not a button */
|
||||
tabIndex={null} /* trick screen readers into thinking this is not a button */
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -634,8 +640,12 @@ module.exports = withMatrixClient(React.createClass({
|
|||
onFocusChange={this.onActionBarFocusChange}
|
||||
/> : undefined;
|
||||
|
||||
const timestamp = this.props.mxEvent.getTs() ?
|
||||
<MessageTimestamp showTwelveHour={this.props.isTwelveHour} ts={this.props.mxEvent.getTs()} /> : null;
|
||||
const timestamp = this.props.mxEvent.getTs()
|
||||
? <MessageTimestamp
|
||||
showTwelveHour={this.props.isTwelveHour}
|
||||
ts={this.props.mxEvent.getTs()}
|
||||
ariaHidden={muteScreenReader}
|
||||
/> : null;
|
||||
|
||||
const keyRequestHelpText =
|
||||
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
|
||||
|
@ -773,13 +783,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
'replyThread',
|
||||
);
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className={classes} aria-hidden={muteScreenReader}>
|
||||
<div className="mx_EventTile_msgOption">
|
||||
{ readAvatars }
|
||||
</div>
|
||||
{ sender }
|
||||
<div className="mx_EventTile_line">
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkClicked} aria-hidden={muteScreenReader}>
|
||||
{ timestamp }
|
||||
</a>
|
||||
{ this._renderE2EPadlock() }
|
||||
|
@ -797,7 +807,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
{ actionBar }
|
||||
</div>
|
||||
{
|
||||
// The avatar goes after the event tile as it's absolutly positioned to be over the
|
||||
// The avatar goes after the event tile as it's absolutely positioned to be over the
|
||||
// event tile line, so needs to be later in the DOM so it appears on top (this avoids
|
||||
// the need for further z-indexing chaos)
|
||||
}
|
||||
|
|
|
@ -211,11 +211,13 @@ module.exports = React.createClass({
|
|||
<MemberAvatar
|
||||
member={this.props.member}
|
||||
fallbackUserId={this.props.fallbackUserId}
|
||||
aria-hidden="true"
|
||||
width={14} height={14} resizeMethod="crop"
|
||||
style={style}
|
||||
title={title}
|
||||
onClick={this.props.onClick}
|
||||
aria-hidden={true} /* silence screen readers */
|
||||
buttonRole={null} /* trick screen readers into thinking this is not a button */
|
||||
tabIndex={null} /* trick screen readers into thinking this is not a button */
|
||||
/>
|
||||
</Velociraptor>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue