From ddf1e4841a2cec22c62b8f4c11b81d3a2a9dc745 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Tue, 6 Sep 2016 13:07:06 +0100 Subject: [PATCH] Selecting users with arrow keys added --- .../views/dialogs/ChatInviteDialog.js | 50 ++++++++++++++++--- src/components/views/elements/AddressTile.js | 7 +-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 5c3b5bbbc8..62be6cd67b 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -55,6 +55,7 @@ module.exports = React.createClass({ query: "", queryList: [], addressSelected: false, + selected: 0, }; }, @@ -79,12 +80,26 @@ module.exports = React.createClass({ e.stopPropagation(); e.preventDefault(); this.props.onFinished(false); - } - else if (e.keyCode === 13) { // enter + } else if (e.keyCode === 38) { // up arrow e.stopPropagation(); e.preventDefault(); - //this._startChat(this.refs.textinput.value); - this.setState({ addressSelected: true }); + if (this.state.selected > 0) { + this.setState({ selected: this.state.selected - 1 }); + } + } else if (e.keyCode === 40) { // down arrow + e.stopPropagation(); + e.preventDefault(); + if (this.state.selected < this._maxSelected(this.state.queryList)) { + this.setState({ selected: this.state.selected + 1 }); + } + } else if (e.keyCode === 13) { // enter + e.stopPropagation(); + e.preventDefault(); + if (this.state.addressSelected && this.state.queryList.length > 0) { + this._startChat(this.refs.textinput.value); + } else if (this.state.queryList.length > 0) { + this.setState({ addressSelected: true }); + } } }, @@ -100,11 +115,26 @@ module.exports = React.createClass({ var queryList = list.filter((user) => { return this._matches(query, user); }); - this.setState({ queryList: queryList }); + + // Make sure the selected item is still isn't outside the list bounds + var selected = this.state.selected; + var maxSelected = this._maxSelected(queryList); + if (selected > maxSelected) { + selected = maxSelected; + } + this.setState({ + queryList: queryList, + selected: selected, + }); }, onDismissed: function() { - this.setState({ addressSelected: false }); + this.setState({ + query: "", + addressSelected: false, + selected: 0, + queryList: [], + }); }, _startChat: function(addr) { @@ -131,6 +161,11 @@ module.exports = React.createClass({ this._userList = MatrixClientPeg.get().getUsers(); }, 500), + _maxSelected: function(list) { + var listSize = list.length === 0 ? 0 : list.length - 1; + var maxSelected = listSize > TRUNCATE_QUERY_LIST ? TRUNCATE_QUERY_LIST : listSize; + }, + // This is the search algorithm for matching users _matches: function(query, user) { var name = user.displayName.toLowerCase(); @@ -165,9 +200,8 @@ module.exports = React.createClass({ var query; if (this.state.addressSelected) { var AddressTile = sdk.getComponent("elements.AddressTile"); - // NOTE: this.state.queryList[0] is just a place holder until the selection logic is completed query = ( - + ); } else { query = ( diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index c06de8fff9..df1e5f9db6 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -41,7 +41,8 @@ module.exports = React.createClass({ console.log(this.props.user); var BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); var TintableSvg = sdk.getComponent("elements.TintableSvg"); - var name = this.props.user.displayName || this.props.user.userId + var userId = this.props.user.userId; + var name = this.props.user.displayName || userId; var imgUrl = Avatar.avatarUrlForUser(this.props.user, 25, 25, "crop"); var dismiss; @@ -56,10 +57,10 @@ module.exports = React.createClass({ return (
- +
{ name }
-
{ this.props.user.userId }
+
{ userId }
{ dismiss }
);