diff --git a/src/component-index.js b/src/component-index.js index df31acfeaa..4cf2ba4016 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -54,6 +54,7 @@ module.exports.components['views.dialogs.NeedToRegisterDialog'] = require('./com module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog'); module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog'); module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog'); +module.exports.components['views.elements.AddressTile'] = require('./components/views/elements/AddressTile'); module.exports.components['views.elements.EditableText'] = require('./components/views/elements/EditableText'); module.exports.components['views.elements.EditableTextContainer'] = require('./components/views/elements/EditableTextContainer'); module.exports.components['views.elements.EmojiText'] = require('./components/views/elements/EmojiText'); diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js index 2445dfb8f3..e704289259 100644 --- a/src/components/views/dialogs/ChatInviteDialog.js +++ b/src/components/views/dialogs/ChatInviteDialog.js @@ -18,8 +18,12 @@ var React = require("react"); var sdk = require("../../../index"); var Invite = require("../../../Invite"); var createRoom = require("../../../createRoom"); +var MatrixClientPeg = require("../../../MatrixClientPeg"); +var rate_limited_func = require("../../../ratelimitedfunc"); var Modal = require('../../../Modal'); +const TRUNCATE_QUERY_LIST = 4; + module.exports = React.createClass({ displayName: "ChatInviteDialog", propTypes: { @@ -46,17 +50,56 @@ module.exports = React.createClass({ }; }, + getInitialState: function() { + return { + query: "", + queryList: [], + addressSelected: false, + }; + }, + componentDidMount: function() { if (this.props.focus) { // Set the cursor at the end of the text input this.refs.textinput.value = this.props.value; } + this._updateUserList(); }, onStartChat: function() { this._startChat(this.refs.textinput.value); }, + onCancel: function() { + this.props.onFinished(false); + }, + + onKeyDown: function(e) { + if (e.keyCode === 27) { // escape + e.stopPropagation(); + e.preventDefault(); + this.props.onFinished(false); + } + else if (e.keyCode === 13) { // enter + e.stopPropagation(); + e.preventDefault(); + //this._startChat(this.refs.textinput.value); + this.setState({ addressSelected: true }); + } + }, + + onQueryChanged: function(ev) { + var query = ev.target.value; + var queryList = this._userList.filter((user) => { + return this._matches(query, user); + }); + this.setState({ queryList: queryList }); + }, + + onDismissed: function() { + this.setState({ addressSelected: false }); + }, + _startChat: function(addr) { // Start the chat createRoom().then(function(roomId) { @@ -76,25 +119,65 @@ module.exports = React.createClass({ this.props.onFinished(true, addr); }, - onCancel: function() { - this.props.onFinished(false); - }, + _updateUserList: new rate_limited_func(function() { + // Get all the users + this._userList = MatrixClientPeg.get().getUsers(); + }, 500), - onKeyDown: function(e) { - if (e.keyCode === 27) { // escape - e.stopPropagation(); - e.preventDefault(); - this.props.onFinished(false); + // This is the search algorithm for matching users + _matches: function(query, user) { + var name = user.displayName.toLowerCase(); + var uid = user.userId.toLowerCase(); + query = query.toLowerCase(); + + // direct prefix matches + if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) { + return true; } - else if (e.keyCode === 13) { // enter - e.stopPropagation(); - e.preventDefault(); - this._startChat(this.refs.textinput.value); + + // strip @ on uid and try matching again + if (uid.length > 1 && uid[0] === "@" && uid.substring(1).indexOf(query) === 0) { + return true; } + + // split spaces in name and try matching constituent parts + var parts = name.split(" "); + for (var i = 0; i < parts.length; i++) { + if (parts[i].indexOf(query) === 0) { + return true; + } + } + return false; }, render: function() { var TintableSvg = sdk.getComponent("elements.TintableSvg"); + console.log("### D E B U G - queryList:"); + console.log(this.state.queryList); + + var query; + if (this.state.addressSelected) { + var AddressTile = sdk.getComponent("elements.AddressTile"); + // NOTE: _userList[0] is just a place holder until the selection logic is completed + query = ( + + ); + } else { + query = ( + + ); + } + return (
@@ -107,9 +190,7 @@ module.exports = React.createClass({
-
- -
+
{ query }