Merge branch 'rav/hotkey-ux' into develop

This commit is contained in:
Richard van der Hoff 2017-02-03 12:01:50 +00:00
commit 0c8223da03
7 changed files with 76 additions and 37 deletions

View File

@ -20,6 +20,7 @@ var React = require('react');
var ReactDOM = require('react-dom'); var ReactDOM = require('react-dom');
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'BottomLeftMenu', displayName: 'BottomLeftMenu',
@ -101,22 +102,22 @@ module.exports = React.createClass({
return ( return (
<div className="mx_BottomLeftMenu"> <div className="mx_BottomLeftMenu">
<div className="mx_BottomLeftMenu_options"> <div className="mx_BottomLeftMenu_options">
<div className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } > <AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } >
<TintableSvg src="img/icons-people.svg" width="25" height="25" /> <TintableSvg src="img/icons-people.svg" width="25" height="25" />
{ this.getLabel("Start chat", this.state.peopleHover) } { this.getLabel("Start chat", this.state.peopleHover) }
</div> </AccessibleButton>
<div className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } > <AccessibleButton className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } >
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/> <TintableSvg src="img/icons-directory.svg" width="25" height="25"/>
{ this.getLabel("Room directory", this.state.directoryHover) } { this.getLabel("Room directory", this.state.directoryHover) }
</div> </AccessibleButton>
<div className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } > <AccessibleButton className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } >
<TintableSvg src="img/icons-create-room.svg" width="25" height="25" /> <TintableSvg src="img/icons-create-room.svg" width="25" height="25" />
{ this.getLabel("Create new room", this.state.roomsHover) } { this.getLabel("Create new room", this.state.roomsHover) }
</div> </AccessibleButton>
<div className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } > <AccessibleButton className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } >
<TintableSvg src="img/icons-settings.svg" width="25" height="25" /> <TintableSvg src="img/icons-settings.svg" width="25" height="25" />
{ this.getLabel("Settings", this.state.settingsHover) } { this.getLabel("Settings", this.state.settingsHover) }
</div> </AccessibleButton>
</div> </div>
</div> </div>
); );

View File

@ -23,6 +23,7 @@ var dis = require('matrix-react-sdk/lib/dispatcher');
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg"); var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc'); var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
var Modal = require('matrix-react-sdk/lib/Modal'); var Modal = require('matrix-react-sdk/lib/Modal');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RightPanel', displayName: 'RightPanel',
@ -183,12 +184,12 @@ module.exports = React.createClass({
if (user_is_in_room) { if (user_is_in_room) {
inviteGroup = inviteGroup =
<div className="mx_RightPanel_invite" onClick={ this.onInviteButtonClick } > <AccessibleButton className="mx_RightPanel_invite" onClick={ this.onInviteButtonClick } >
<div className="mx_RightPanel_icon" > <div className="mx_RightPanel_icon" >
<TintableSvg src="img/icon-invite-people.svg" width="35" height="35" /> <TintableSvg src="img/icon-invite-people.svg" width="35" height="35" />
</div> </div>
<div className="mx_RightPanel_message">Invite to this room</div> <div className="mx_RightPanel_message">Invite to this room</div>
</div>; </AccessibleButton>;
} }
} }
@ -196,21 +197,26 @@ module.exports = React.createClass({
if (this.props.roomId) { if (this.props.roomId) {
buttonGroup = buttonGroup =
<div className="mx_RightPanel_headerButtonGroup"> <div className="mx_RightPanel_headerButtonGroup">
<div className="mx_RightPanel_headerButton" title="Members" onClick={ this.onMemberListButtonClick }> <AccessibleButton className="mx_RightPanel_headerButton"
title="Members" onClick={ this.onMemberListButtonClick }>
<div className="mx_RightPanel_headerButton_badge">{ membersBadge ? membersBadge : <span>&nbsp;</span>}</div> <div className="mx_RightPanel_headerButton_badge">{ membersBadge ? membersBadge : <span>&nbsp;</span>}</div>
<TintableSvg src="img/icons-people.svg" width="25" height="25"/> <TintableSvg src="img/icons-people.svg" width="25" height="25"/>
{ membersHighlight } { membersHighlight }
</div> </AccessibleButton>
<div className="mx_RightPanel_headerButton mx_RightPanel_filebutton" title="Files" onClick={ this.onFileListButtonClick }> <AccessibleButton
className="mx_RightPanel_headerButton mx_RightPanel_filebutton"
title="Files" onClick={ this.onFileListButtonClick }>
<div className="mx_RightPanel_headerButton_badge">&nbsp;</div> <div className="mx_RightPanel_headerButton_badge">&nbsp;</div>
<TintableSvg src="img/icons-files.svg" width="25" height="25"/> <TintableSvg src="img/icons-files.svg" width="25" height="25"/>
{ filesHighlight } { filesHighlight }
</div> </AccessibleButton>
<div className="mx_RightPanel_headerButton mx_RightPanel_notificationbutton" title="Notifications" onClick={ this.onNotificationListButtonClick }> <AccessibleButton
className="mx_RightPanel_headerButton mx_RightPanel_notificationbutton"
title="Notifications" onClick={ this.onNotificationListButtonClick }>
<div className="mx_RightPanel_headerButton_badge">&nbsp;</div> <div className="mx_RightPanel_headerButton_badge">&nbsp;</div>
<TintableSvg src="img/icons-notifications.svg" width="25" height="25"/> <TintableSvg src="img/icons-notifications.svg" width="25" height="25"/>
{ notificationsHighlight } { notificationsHighlight }
</div> </AccessibleButton>
<div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" title="Hide panel" onClick={ this.onCollapseClick }> <div className="mx_RightPanel_headerButton mx_RightPanel_collapsebutton" title="Hide panel" onClick={ this.onCollapseClick }>
<TintableSvg src="img/minimise.svg" width="10" height="16"/> <TintableSvg src="img/minimise.svg" width="10" height="16"/>
</div> </div>
@ -255,4 +261,3 @@ module.exports = React.createClass({
); );
} }
}); });

View File

@ -26,6 +26,7 @@ var Unread = require('matrix-react-sdk/lib/Unread');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs'); var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils'); var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
// turn this on for drop & drag console debugging galore // turn this on for drop & drag console debugging galore
var debug = false; var debug = false;
@ -417,15 +418,17 @@ var RoomSubList = React.createClass({
} }
} }
var tabindex = this.props.searchFilter === "" ? "0" : "-1";
return ( return (
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header"> <div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
<div onClick={ this.onClick } className="mx_RoomSubList_label"> <AccessibleButton onClick={ this.onClick } className="mx_RoomSubList_label" tabIndex={tabindex}>
{ this.props.collapsed ? '' : this.props.label } { this.props.collapsed ? '' : this.props.label }
<div className="mx_RoomSubList_roomCount">{ roomCount }</div> <div className="mx_RoomSubList_roomCount">{ roomCount }</div>
<div className={chevronClasses}></div> <div className={chevronClasses}></div>
{ badge } { badge }
{ incomingCall } { incomingCall }
</div> </AccessibleButton>
</div> </div>
); );
}, },
@ -447,11 +450,11 @@ var RoomSubList = React.createClass({
}); });
return ( return (
<div className="mx_RoomSubList_ellipsis" onClick={this._showFullMemberList}> <AccessibleButton className="mx_RoomSubList_ellipsis" onClick={this._showFullMemberList}>
<div className="mx_RoomSubList_line"></div> <div className="mx_RoomSubList_line"></div>
<div className="mx_RoomSubList_more">more</div> <div className="mx_RoomSubList_more">more</div>
<div className={ badgeClasses }>{ content }</div> <div className={ badgeClasses }>{ content }</div>
</div> </AccessibleButton>
); );
}, },

View File

@ -20,6 +20,7 @@ var React = require('react');
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher'); var dis = require('matrix-react-sdk/lib/dispatcher');
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc'); var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'SearchBox', displayName: 'SearchBox',
@ -35,6 +36,25 @@ module.exports = React.createClass({
}; };
}, },
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
},
onAction: function(payload) {
switch (payload.action) {
// Clear up the text field when a room is selected.
case 'view_room':
if (this.refs.search) {
this._clearSearch();
}
break;
}
},
onChange: function() { onChange: function() {
if (!this.refs.search) return; if (!this.refs.search) return;
this.setState({ searchTerm: this.refs.search.value }); this.setState({ searchTerm: this.refs.search.value });
@ -61,35 +81,42 @@ module.exports = React.createClass({
} }
}, },
_clearSearch: function() {
this.refs.search.value = "";
this.onChange();
},
render: function() { render: function() {
var TintableSvg = sdk.getComponent('elements.TintableSvg'); var TintableSvg = sdk.getComponent('elements.TintableSvg');
var collapseTabIndex = this.refs.search && this.refs.search.value !== "" ? "-1" : "0";
var toggleCollapse; var toggleCollapse;
if (this.props.collapsed) { if (this.props.collapsed) {
toggleCollapse = toggleCollapse =
<div className="mx_SearchBox_maximise" onClick={ this.onToggleCollapse.bind(this, true) }> <AccessibleButton className="mx_SearchBox_maximise" tabIndex={collapseTabIndex} onClick={ this.onToggleCollapse.bind(this, true) }>
<TintableSvg src="img/maximise.svg" width="10" height="16" alt="Expand panel"/> <TintableSvg src="img/maximise.svg" width="10" height="16" alt="Expand panel"/>
</div> </AccessibleButton>
} }
else { else {
toggleCollapse = toggleCollapse =
<div className="mx_SearchBox_minimise" onClick={ this.onToggleCollapse.bind(this, false) }> <AccessibleButton className="mx_SearchBox_minimise" tabIndex={collapseTabIndex} onClick={ this.onToggleCollapse.bind(this, false) }>
<TintableSvg src="img/minimise.svg" width="10" height="16" alt="Collapse panel"/> <TintableSvg src="img/minimise.svg" width="10" height="16" alt="Collapse panel"/>
</div> </AccessibleButton>
} }
var searchControls; var searchControls;
if (!this.props.collapsed) { if (!this.props.collapsed) {
searchControls = [ searchControls = [
this.state.searchTerm.length > 0 ? this.state.searchTerm.length > 0 ?
<div key="button" <AccessibleButton key="button"
className="mx_SearchBox_closeButton" className="mx_SearchBox_closeButton"
onClick={ ()=>{ this.refs.search.value = ""; this.onChange(); } }> onClick={ ()=>{ this._clearSearch(); } }>
<TintableSvg <TintableSvg
className="mx_SearchBox_searchButton" className="mx_SearchBox_searchButton"
src="img/icons-close.svg" width="24" height="24" src="img/icons-close.svg" width="24" height="24"
/> />
</div> </AccessibleButton>
: :
<TintableSvg <TintableSvg
key="button" key="button"

View File

@ -22,6 +22,7 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var DateUtils = require('matrix-react-sdk/lib/DateUtils'); var DateUtils = require('matrix-react-sdk/lib/DateUtils');
var filesize = require('filesize'); var filesize = require('filesize');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'ImageView', displayName: 'ImageView',
@ -162,7 +163,7 @@ module.exports = React.createClass({
<img src={this.props.src} style={style}/> <img src={this.props.src} style={style}/>
<div className="mx_ImageView_labelWrapper"> <div className="mx_ImageView_labelWrapper">
<div className="mx_ImageView_label"> <div className="mx_ImageView_label">
<img className="mx_ImageView_cancel" src="img/cancel-white.svg" width="18" height="18" alt="Close" onClick={ this.props.onFinished }/> <AccessibleButton className="mx_ImageView_cancel" onClick={ this.props.onFinished }><img src="img/cancel-white.svg" width="18" height="18" alt="Close"/></AccessibleButton>
<div className="mx_ImageView_shim"> <div className="mx_ImageView_shim">
</div> </div>
<div className="mx_ImageView_name"> <div className="mx_ImageView_name">

View File

@ -19,6 +19,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
var Notifier = require("matrix-react-sdk/lib/Notifier"); var Notifier = require("matrix-react-sdk/lib/Notifier");
var sdk = require('matrix-react-sdk') var sdk = require('matrix-react-sdk')
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MatrixToolbar', displayName: 'MatrixToolbar',
@ -38,7 +39,7 @@ module.exports = React.createClass({
<div className="mx_MatrixToolbar_content"> <div className="mx_MatrixToolbar_content">
You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a> You are not receiving desktop notifications. <a className="mx_MatrixToolbar_link" onClick={ this.onClick }>Enable them now</a>
</div> </div>
<div className="mx_MatrixToolbar_close"><img src="img/cancel.svg" width="18" height="18" onClick={ this.hideToolbar } /></div> <AccessibleButton className="mx_MatrixToolbar_close" onClick={ this.hideToolbar } ><img src="img/cancel.svg" width="18" height="18" /></AccessibleButton>
</div> </div>
); );
} }

View File

@ -20,6 +20,7 @@ var React = require('react');
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var sdk = require('matrix-react-sdk'); var sdk = require('matrix-react-sdk');
var classNames = require('classnames'); var classNames = require('classnames');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'SearchBar', displayName: 'SearchBar',
@ -57,12 +58,12 @@ module.exports = React.createClass({
var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' }); var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' });
return ( return (
<div className="mx_SearchBar"> <div className="mx_SearchBar">
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/> <input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder="Search..." onKeyDown={this.onSearchChange}/>
<div className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt="Search"/></div> <AccessibleButton className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt="Search"/></AccessibleButton>
<div className={ thisRoomClasses } onClick={this.onThisRoomClick}>This Room</div> <AccessibleButton className={ thisRoomClasses } onClick={this.onThisRoomClick}>This Room</AccessibleButton>
<div className={ allRoomsClasses } onClick={this.onAllRoomsClick}>All Rooms</div> <AccessibleButton className={ allRoomsClasses } onClick={this.onAllRoomsClick}>All Rooms</AccessibleButton>
<img className="mx_SearchBar_cancel" src="img/cancel.svg" width="18" height="18" onClick={this.props.onCancelClick} /> <AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick}><img src="img/cancel.svg" width="18" height="18" /></AccessibleButton>
</div> </div>
); );
} }