A11y: repurpose more divs into AccessibleButtons.
With this more of the controls that look like buttons can be operated via the keyboard and navigated to by screen reader users. This includes editor buttons such as File upload, Audio / Video call, Right pannel hide button, Jump to the bottom timeline button, and some more buttons found in the user settings. Also I have added alt texts to some images that in turn label buttons which these happen to be packed in and removed some untranslated alt texts from decorative non-actionable images that might add more verbosity when talking about screen reader user experience.
This commit is contained in:
parent
862d67c0f7
commit
ded35e43a0
14 changed files with 57 additions and 51 deletions
|
@ -51,6 +51,7 @@ class HeaderButton extends React.Component {
|
||||||
|
|
||||||
return <AccessibleButton
|
return <AccessibleButton
|
||||||
aria-label={this.props.title}
|
aria-label={this.props.title}
|
||||||
|
aria-expanded={this.props.isHighlighted}
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
className="mx_RightPanel_headerButton"
|
className="mx_RightPanel_headerButton"
|
||||||
onClick={this.onClick} >
|
onClick={this.onClick} >
|
||||||
|
@ -345,11 +346,11 @@ module.exports = React.createClass({
|
||||||
// being put in the RoomHeader or GroupView header, so only show the minimise
|
// being put in the RoomHeader or GroupView header, so only show the minimise
|
||||||
// button on these 2 screens or you won't be able to re-expand the panel.
|
// button on these 2 screens or you won't be able to re-expand the panel.
|
||||||
headerButtons.push(
|
headerButtons.push(
|
||||||
<div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton"
|
<AccessibleButton className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" key="_minimizeButton"
|
||||||
title={_t("Hide panel")} aria-label={_t("Hide panel")} onClick={this.onCollapseClick}
|
title={_t("Hide panel")} aria-label={_t("Hide panel")} onClick={this.onCollapseClick}
|
||||||
>
|
>
|
||||||
<TintableSvg src="img/minimise.svg" width="10" height="16" />
|
<TintableSvg src="img/minimise.svg" width="10" height="16" alt="" />
|
||||||
</div>,
|
</AccessibleButton>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,14 +223,15 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||||
if (!this.props.atEndOfLiveTimeline) {
|
if (!this.props.atEndOfLiveTimeline) {
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomStatusBar_scrollDownIndicator"
|
<AccessibleButton className="mx_RoomStatusBar_scrollDownIndicator"
|
||||||
onClick={this.props.onScrollToBottomClick}>
|
onClick={this.props.onScrollToBottomClick}>
|
||||||
<img src="img/scrolldown.svg" width="24" height="24"
|
<img src="img/scrolldown.svg" width="24" height="24"
|
||||||
alt={_t("Scroll to bottom of page")}
|
alt={_t("Scroll to bottom of page")}
|
||||||
title={_t("Scroll to bottom of page")} />
|
title={_t("Scroll to bottom of page")} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +386,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="mx_RoomStatusBar_connectionLostBar">
|
return <div className="mx_RoomStatusBar_connectionLostBar">
|
||||||
<img src="img/warning.svg" width="24" height="23" title={_t("Warning")} alt={_t("Warning")} />
|
<img src="img/warning.svg" width="24" height="23" title={_t("Warning")} alt="" />
|
||||||
<div>
|
<div>
|
||||||
<div className="mx_RoomStatusBar_connectionLostBar_title">
|
<div className="mx_RoomStatusBar_connectionLostBar_title">
|
||||||
{ title }
|
{ title }
|
||||||
|
@ -485,8 +486,10 @@ module.exports = React.createClass({
|
||||||
<div className="mx_RoomStatusBar_indicator">
|
<div className="mx_RoomStatusBar_indicator">
|
||||||
{ indicator }
|
{ indicator }
|
||||||
</div>
|
</div>
|
||||||
|
<div role="alert">
|
||||||
{ content }
|
{ content }
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -831,9 +831,9 @@ module.exports = React.createClass({
|
||||||
<br />
|
<br />
|
||||||
{ _t('Privacy is important to us, so we don\'t collect any personal'
|
{ _t('Privacy is important to us, so we don\'t collect any personal'
|
||||||
+ ' or identifiable data for our analytics.') }
|
+ ' or identifiable data for our analytics.') }
|
||||||
<div className="mx_UserSettings_advanced_spoiler" onClick={Analytics.showDetailsModal}>
|
<AccessibleButton className="mx_UserSettings_advanced_spoiler" onClick={Analytics.showDetailsModal}>
|
||||||
{ _t('Learn more about how we use analytics.') }
|
{ _t('Learn more about how we use analytics.') }
|
||||||
</div>
|
</AccessibleButton>
|
||||||
{ ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
|
{ ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -1065,9 +1065,9 @@ module.exports = React.createClass({
|
||||||
_renderWebRtcDeviceSettings: function() {
|
_renderWebRtcDeviceSettings: function() {
|
||||||
if (this.state.mediaDevices === false) {
|
if (this.state.mediaDevices === false) {
|
||||||
return (
|
return (
|
||||||
<p className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
<AccessibleButton element="p" className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
||||||
{ _t('Missing Media Permissions, click here to request.') }
|
{ _t('Missing Media Permissions, click here to request.') }
|
||||||
</p>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
} else if (!this.state.mediaDevices) return;
|
} else if (!this.state.mediaDevices) return;
|
||||||
|
|
||||||
|
@ -1233,10 +1233,10 @@ module.exports = React.createClass({
|
||||||
value={this.presentableTextForThreepid(val)} disabled
|
value={this.presentableTextForThreepid(val)} disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
<AccessibleButton className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||||
<img src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")}
|
<img src="img/cancel-small.svg" width="14" height="14" alt={_t("Remove")}
|
||||||
onClick={onRemoveClick} />
|
onClick={onRemoveClick} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1258,9 +1258,9 @@ module.exports = React.createClass({
|
||||||
blurToCancel={false}
|
blurToCancel={false}
|
||||||
onValueChanged={this._onAddEmailEditFinished} />
|
onValueChanged={this._onAddEmailEditFinished} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
<AccessibleButton className="mx_UserSettings_threepidButton mx_filterFlipColor">
|
||||||
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
<img src="img/plus.svg" width="14" height="14" alt={_t("Add")} onClick={this._addEmail} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1328,25 +1328,25 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_UserSettings_avatarPicker">
|
<div className="mx_UserSettings_avatarPicker">
|
||||||
<div className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
|
<AccessibleButton className="mx_UserSettings_avatarPicker_remove" onClick={this.onAvatarRemoveClick}>
|
||||||
<img src="img/cancel.svg"
|
<img src="img/cancel.svg"
|
||||||
width="15" height="15"
|
width="15" height="15"
|
||||||
className="mx_filterFlipColor"
|
className="mx_filterFlipColor"
|
||||||
alt={_t("Remove avatar")}
|
alt={_t("Remove avatar")}
|
||||||
title={_t("Remove avatar")} />
|
title={_t("Remove avatar")} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
<div onClick={this.onAvatarPickerClick} className="mx_UserSettings_avatarPicker_imgContainer">
|
<div onClick={this.onAvatarPickerClick} className="mx_UserSettings_avatarPicker_imgContainer">
|
||||||
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
<ChangeAvatar ref="changeAvatar" initialAvatarUrl={avatarUrl}
|
||||||
showUploadSection={false} className="mx_UserSettings_avatarPicker_img" />
|
showUploadSection={false} className="mx_UserSettings_avatarPicker_img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_avatarPicker_edit">
|
<AccessibleButton className="mx_UserSettings_avatarPicker_edit">
|
||||||
<label htmlFor="avatarInput" ref="file_label">
|
<label htmlFor="avatarInput" ref="file_label">
|
||||||
<img src="img/camera.svg" className="mx_filterFlipColor"
|
<img src="img/camera.svg" className="mx_filterFlipColor"
|
||||||
alt={_t("Upload avatar")} title={_t("Upload avatar")}
|
alt={_t("Upload avatar")} title={_t("Upload avatar")}
|
||||||
width="17" height="15" />
|
width="17" height="15" />
|
||||||
</label>
|
</label>
|
||||||
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
<input id="avatarInput" type="file" onChange={this.onAvatarSelected} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1395,11 +1395,11 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_advanced">
|
<div className="mx_UserSettings_advanced">
|
||||||
{ _t('Access Token:') + ' ' }
|
{ _t('Access Token:') + ' ' }
|
||||||
<span className="mx_UserSettings_advanced_spoiler"
|
<AccessibleButton element="span" className="mx_UserSettings_advanced_spoiler"
|
||||||
onClick={this._showSpoiler}
|
onClick={this._showSpoiler}
|
||||||
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
data-spoiler={MatrixClientPeg.get().getAccessToken()}>
|
||||||
<{ _t("click to reveal") }>
|
<{ _t("click to reveal") }>
|
||||||
</span>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_advanced">
|
<div className="mx_UserSettings_advanced">
|
||||||
{ _t("Homeserver is") } { MatrixClientPeg.get().getHomeserverUrl() }
|
{ _t("Homeserver is") } { MatrixClientPeg.get().getHomeserverUrl() }
|
||||||
|
|
|
@ -6,7 +6,7 @@ const AppWarning = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className='mx_AppPermissionWarning'>
|
<div className='mx_AppPermissionWarning'>
|
||||||
<div className='mx_AppPermissionWarningImage'>
|
<div className='mx_AppPermissionWarningImage'>
|
||||||
<img src='img/warning.svg' alt={_t('Warning!')} />
|
<img src='img/warning.svg' alt='' />
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_AppPermissionWarningText'>
|
<div className='mx_AppPermissionWarningText'>
|
||||||
<span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span>
|
<span className='mx_AppPermissionWarningTextLabel'>{ props.errorMsg }</span>
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default class CookieBar extends React.Component {
|
||||||
const toolbarClasses = "mx_MatrixToolbar";
|
const toolbarClasses = "mx_MatrixToolbar";
|
||||||
return (
|
return (
|
||||||
<div className={toolbarClasses}>
|
<div className={toolbarClasses}>
|
||||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="Warning" />
|
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="" />
|
||||||
<div className="mx_MatrixToolbar_content">
|
<div className="mx_MatrixToolbar_content">
|
||||||
{ this.props.policyUrl ? _t(
|
{ this.props.policyUrl ? _t(
|
||||||
"Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
|
"Please help improve Riot.im by sending <UsageDataLink>anonymous usage data</UsageDataLink>. " +
|
||||||
|
@ -95,7 +95,7 @@ export default class CookieBar extends React.Component {
|
||||||
{ _t("Yes, I want to help!") }
|
{ _t("Yes, I want to help!") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}>
|
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.onReject}>
|
||||||
<img src="img/cancel.svg" width="18" height="18" />
|
<img src="img/cancel.svg" width="18" height="18" alt={_t('Close')}/>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -35,11 +35,11 @@ module.exports = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixToolbar">
|
<div className="mx_MatrixToolbar">
|
||||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="Warning"/>
|
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" />
|
||||||
<div className="mx_MatrixToolbar_content">
|
<div className="mx_MatrixToolbar_content">
|
||||||
{ _t('You are not receiving desktop notifications') } <a className="mx_MatrixToolbar_link" onClick={ this.onClick }> { _t('Enable them now') }</a>
|
{ _t('You are not receiving desktop notifications') } <a className="mx_MatrixToolbar_link" onClick={ this.onClick }> { _t('Enable them now') }</a>
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className="mx_MatrixToolbar_close" onClick={ this.hideToolbar } ><img src="img/cancel.svg" width="18" height="18" /></AccessibleButton>
|
<AccessibleButton className="mx_MatrixToolbar_close" onClick={ this.hideToolbar } ><img src="img/cancel.svg" width="18" height="18" alt={_t('Close')}/></AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -96,7 +96,7 @@ export default React.createClass({
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixToolbar">
|
<div className="mx_MatrixToolbar">
|
||||||
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="Warning"/>
|
<img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" />
|
||||||
<div className="mx_MatrixToolbar_content">
|
<div className="mx_MatrixToolbar_content">
|
||||||
{_t("A new version of Riot is available.")}
|
{_t("A new version of Riot is available.")}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default React.createClass({
|
||||||
src="img/warning.svg"
|
src="img/warning.svg"
|
||||||
width="24"
|
width="24"
|
||||||
height="23"
|
height="23"
|
||||||
alt="Warning"
|
alt=""
|
||||||
/>
|
/>
|
||||||
<div className="mx_MatrixToolbar_content">
|
<div className="mx_MatrixToolbar_content">
|
||||||
{ _t(
|
{ _t(
|
||||||
|
|
|
@ -71,9 +71,9 @@ export default React.createClass({
|
||||||
|
|
||||||
let image;
|
let image;
|
||||||
if (doneStatuses.includes(this.props.status)) {
|
if (doneStatuses.includes(this.props.status)) {
|
||||||
image = <img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt={warning}/>;
|
image = <img className="mx_MatrixToolbar_warning" src="img/warning.svg" width="24" height="23" alt="" />;
|
||||||
} else {
|
} else {
|
||||||
image = <img className="mx_MatrixToolbar_warning" src="img/spinner.gif" width="24" height="23" alt={message}/>;
|
image = <img className="mx_MatrixToolbar_warning" src="img/spinner.gif" width="24" height="23" alt="" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -83,7 +83,7 @@ export default React.createClass({
|
||||||
{message}
|
{message}
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.hideToolbar}>
|
<AccessibleButton className="mx_MatrixToolbar_close" onClick={this.hideToolbar}>
|
||||||
<img src="img/cancel.svg" width="18" height="18" />
|
<img src="img/cancel.svg" width="18" height="18" alt={_t('Close')}/>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,6 +30,7 @@ import ScalarMessaging from '../../../ScalarMessaging';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import WidgetUtils from '../../../utils/WidgetUtils';
|
import WidgetUtils from '../../../utils/WidgetUtils';
|
||||||
import WidgetEchoStore from "../../../stores/WidgetEchoStore";
|
import WidgetEchoStore from "../../../stores/WidgetEchoStore";
|
||||||
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
|
||||||
// The maximum number of widgets that can be added in a room
|
// The maximum number of widgets that can be added in a room
|
||||||
const MAX_WIDGETS = 2;
|
const MAX_WIDGETS = 2;
|
||||||
|
@ -193,17 +194,15 @@ module.exports = React.createClass({
|
||||||
if (this.props.showApps &&
|
if (this.props.showApps &&
|
||||||
this._canUserModify()
|
this._canUserModify()
|
||||||
) {
|
) {
|
||||||
addWidget = <div
|
addWidget = <AccessibleButton
|
||||||
onClick={this.onClickAddWidget}
|
onClick={this.onClickAddWidget}
|
||||||
role='button'
|
|
||||||
tabIndex='0'
|
|
||||||
className={this.state.apps.length<2 ?
|
className={this.state.apps.length<2 ?
|
||||||
'mx_AddWidget_button mx_AddWidget_button_full_width' :
|
'mx_AddWidget_button mx_AddWidget_button_full_width' :
|
||||||
'mx_AddWidget_button'
|
'mx_AddWidget_button'
|
||||||
}
|
}
|
||||||
title={_t('Add a widget')}>
|
title={_t('Add a widget')}>
|
||||||
[+] { _t('Add a widget') }
|
[+] { _t('Add a widget') }
|
||||||
</div>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let spinner;
|
let spinner;
|
||||||
|
|
|
@ -935,7 +935,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
<div className="mx_MemberInfo">
|
<div className="mx_MemberInfo">
|
||||||
<GeminiScrollbarWrapper autoshow={true}>
|
<GeminiScrollbarWrapper autoshow={true}>
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}>
|
||||||
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" />
|
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" alt={_t('Close')} />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<div className="mx_MemberInfo_avatar">
|
<div className="mx_MemberInfo_avatar">
|
||||||
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
|
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
|
||||||
|
|
|
@ -292,21 +292,22 @@ export default class MessageComposer extends React.Component {
|
||||||
let videoCallButton;
|
let videoCallButton;
|
||||||
let hangupButton;
|
let hangupButton;
|
||||||
|
|
||||||
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
// Call buttons
|
// Call buttons
|
||||||
if (this.props.callState && this.props.callState !== 'ended') {
|
if (this.props.callState && this.props.callState !== 'ended') {
|
||||||
hangupButton =
|
hangupButton =
|
||||||
<div key="controls_hangup" className="mx_MessageComposer_hangup" onClick={this.onHangupClick}>
|
<AccessibleButton key="controls_hangup" className="mx_MessageComposer_hangup" onClick={this.onHangupClick}>
|
||||||
<img src="img/hangup.svg" alt={_t('Hangup')} title={_t('Hangup')} width="25" height="26" />
|
<img src="img/hangup.svg" alt={_t('Hangup')} title={_t('Hangup')} width="25" height="26" />
|
||||||
</div>;
|
</AccessibleButton>;
|
||||||
} else {
|
} else {
|
||||||
callButton =
|
callButton =
|
||||||
<div key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={_t('Voice call')}>
|
<AccessibleButton key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={_t('Voice call')}>
|
||||||
<TintableSvg src="img/icon-call.svg" width="35" height="35" />
|
<TintableSvg src="img/icon-call.svg" width="35" height="35" />
|
||||||
</div>;
|
</AccessibleButton>;
|
||||||
videoCallButton =
|
videoCallButton =
|
||||||
<div key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={_t('Video call')}>
|
<AccessibleButton key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={_t('Video call')}>
|
||||||
<TintableSvg src="img/icons-video.svg" width="35" height="35" />
|
<TintableSvg src="img/icons-video.svg" width="35" height="35" />
|
||||||
</div>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const canSendMessages = !this.state.tombstone &&
|
const canSendMessages = !this.state.tombstone &&
|
||||||
|
@ -317,18 +318,19 @@ export default class MessageComposer extends React.Component {
|
||||||
// check separately for whether we can call, but this is slightly
|
// check separately for whether we can call, but this is slightly
|
||||||
// complex because of conference calls.
|
// complex because of conference calls.
|
||||||
const uploadButton = (
|
const uploadButton = (
|
||||||
<div key="controls_upload" className="mx_MessageComposer_upload"
|
<AccessibleButton key="controls_upload" className="mx_MessageComposer_upload"
|
||||||
onClick={this.onUploadClick} title={_t('Upload file')}>
|
onClick={this.onUploadClick} title={_t('Upload file')}>
|
||||||
<TintableSvg src="img/icons-upload.svg" width="35" height="35" />
|
<TintableSvg src="img/icons-upload.svg" width="35" height="35" />
|
||||||
<input ref="uploadInput" type="file"
|
<input ref="uploadInput" type="file"
|
||||||
style={uploadInputStyle}
|
style={uploadInputStyle}
|
||||||
multiple
|
multiple
|
||||||
onChange={this.onUploadFileSelected} />
|
onChange={this.onUploadFileSelected} />
|
||||||
</div>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
|
||||||
const formattingButton = this.state.inputState.isRichTextEnabled ? (
|
const formattingButton = this.state.inputState.isRichTextEnabled ? (
|
||||||
<img className="mx_MessageComposer_formatting"
|
<AccessibleButton element="img" className="mx_MessageComposer_formatting"
|
||||||
|
alt={_t("Show Text Formatting Toolbar")}
|
||||||
title={_t("Show Text Formatting Toolbar")}
|
title={_t("Show Text Formatting Toolbar")}
|
||||||
src="img/button-text-formatting.svg"
|
src="img/button-text-formatting.svg"
|
||||||
onClick={this.onToggleFormattingClicked}
|
onClick={this.onToggleFormattingClicked}
|
||||||
|
@ -372,7 +374,6 @@ export default class MessageComposer extends React.Component {
|
||||||
} else if (this.state.tombstone) {
|
} else if (this.state.tombstone) {
|
||||||
const replacementRoomId = this.state.tombstone.getContent()['replacement_room'];
|
const replacementRoomId = this.state.tombstone.getContent()['replacement_room'];
|
||||||
|
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
controls.push(<div className="mx_MessageComposer_replaced_wrapper">
|
controls.push(<div className="mx_MessageComposer_replaced_wrapper">
|
||||||
<div className="mx_MessageComposer_replaced_valign">
|
<div className="mx_MessageComposer_replaced_valign">
|
||||||
<img className="mx_MessageComposer_roomReplaced_icon" src="img/room_replaced.svg" />
|
<img className="mx_MessageComposer_roomReplaced_icon" src="img/room_replaced.svg" />
|
||||||
|
@ -423,7 +424,7 @@ export default class MessageComposer extends React.Component {
|
||||||
onMouseDown={this.onToggleMarkdownClicked}
|
onMouseDown={this.onToggleMarkdownClicked}
|
||||||
className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor"
|
className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor"
|
||||||
src={`img/button-md-${!this.state.inputState.isRichTextEnabled}.png`} />
|
src={`img/button-md-${!this.state.inputState.isRichTextEnabled}.png`} />
|
||||||
<img title={_t("Hide Text Formatting Toolbar")}
|
<AccessibleButton element="img" title={_t("Hide Text Formatting Toolbar")}
|
||||||
onClick={this.onToggleFormattingClicked}
|
onClick={this.onToggleFormattingClicked}
|
||||||
className="mx_MessageComposer_formatbar_cancel mx_filterFlipColor"
|
className="mx_MessageComposer_formatbar_cancel mx_filterFlipColor"
|
||||||
src="img/icon-text-cancel.svg" />
|
src="img/icon-text-cancel.svg" />
|
||||||
|
|
|
@ -164,6 +164,7 @@ export default class DevicesPanel extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
|
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||||
|
|
||||||
if (this.state.deviceLoadError !== undefined) {
|
if (this.state.deviceLoadError !== undefined) {
|
||||||
const classes = classNames(this.props.className, "error");
|
const classes = classNames(this.props.className, "error");
|
||||||
|
@ -185,9 +186,9 @@ export default class DevicesPanel extends React.Component {
|
||||||
|
|
||||||
const deleteButton = this.state.deleting ?
|
const deleteButton = this.state.deleting ?
|
||||||
<Spinner w={22} h={22} /> :
|
<Spinner w={22} h={22} /> :
|
||||||
<div className="mx_textButton" onClick={this._onDeleteClick}>
|
<AccessibleButton className="mx_textButton" onClick={this._onDeleteClick}>
|
||||||
{ _t("Delete %(count)s devices", {count: this.state.selectedDevices.length}) }
|
{ _t("Delete %(count)s devices", {count: this.state.selectedDevices.length}) }
|
||||||
</div>;
|
</AccessibleButton>;
|
||||||
|
|
||||||
const classes = classNames(this.props.className, "mx_DevicesPanel");
|
const classes = classNames(this.props.className, "mx_DevicesPanel");
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -125,14 +125,15 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const VideoView = sdk.getComponent('voip.VideoView');
|
const VideoView = sdk.getComponent('voip.VideoView');
|
||||||
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
|
|
||||||
let voice;
|
let voice;
|
||||||
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) {
|
||||||
const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId);
|
||||||
voice = (
|
voice = (
|
||||||
<div className="mx_CallView_voice" onClick={this.props.onClick}>
|
<AccessibleButton className="mx_CallView_voice" onClick={this.props.onClick}>
|
||||||
{ _t("Active call (%(roomName)s)", {roomName: callRoom.name}) }
|
{ _t("Active call (%(roomName)s)", {roomName: callRoom.name}) }
|
||||||
</div>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue