diff --git a/src/components/views/dialogs/ChatInviteDialog.js b/src/components/views/dialogs/ChatInviteDialog.js
index 7f04986b6b..06a46a6d29 100644
--- a/src/components/views/dialogs/ChatInviteDialog.js
+++ b/src/components/views/dialogs/ChatInviteDialog.js
@@ -71,10 +71,21 @@ module.exports = React.createClass({
},
onButtonClick: function() {
- if (this.state.inviteList.length > 0) {
- if (this._isDmChat()) {
+ var inviteList = this.state.inviteList.slice();
+ // Check the text input field to see if user has an unconverted address
+ // If there is and it's valid add it to the local inviteList
+ var check = Invite.isValidAddress(this.refs.textinput.value);
+ if (check === true || check === null) {
+ inviteList.push(this.refs.textinput.value);
+ } else if (this.refs.textinput.value.length > 0) {
+ this.setState({ error: true });
+ return;
+ }
+
+ if (inviteList.length > 0) {
+ if (this._isDmChat(inviteList)) {
// Direct Message chat
- var room = this._getDirectMessageRoom(this.state.inviteList[0]);
+ var room = this._getDirectMessageRoom(inviteList[0]);
if (room) {
// A Direct Message room already exists for this user and you
// so go straight to that room
@@ -82,13 +93,13 @@ module.exports = React.createClass({
action: 'view_room',
room_id: room.roomId,
});
- this.props.onFinished(true, this.state.inviteList[0]);
+ this.props.onFinished(true, inviteList[0]);
} else {
- this._startChat(this.state.inviteList);
+ this._startChat(inviteList);
}
} else {
// Multi invite chat
- this._startChat(this.state.inviteList);
+ this._startChat(inviteList);
}
} else {
// No addresses supplied
@@ -108,16 +119,16 @@ module.exports = React.createClass({
} else if (e.keyCode === 38) { // up arrow
e.stopPropagation();
e.preventDefault();
- this.addressSelector.onKeyUpArrow();
+ this.addressSelector.onKeyU();
} else if (e.keyCode === 40) { // down arrow
e.stopPropagation();
e.preventDefault();
- this.addressSelector.onKeyDownArrow();
- } else if (e.keyCode === 13) { // enter
+ this.addressSelector.onKeyDown();
+ } else if (e.keyCode === 13 || (e.keyCode === 9 && this.state.queryList.length > 0)) { // enter or tab
e.stopPropagation();
e.preventDefault();
- this.addressSelector.onKeyReturn();
- } else if (e.keyCode === 32 || e.keyCode === 188) { // space or comma
+ this.addressSelector.onKeySelect();
+ } else if (e.keyCode === 32 || e.keyCode === 188 || e.keyCode === 9) { // space, comma or tab
e.stopPropagation();
e.preventDefault();
var check = Invite.isValidAddress(this.refs.textinput.value);
@@ -200,17 +211,22 @@ module.exports = React.createClass({
_startChat: function(addrs) {
if (this.props.roomId) {
// Invite new user to a room
+ var self = this;
Invite.inviteMultipleToRoom(this.props.roomId, addrs)
+ .then(function(addrs) {
+ var room = MatrixClientPeg.get().getRoom(this.props.roomId);
+ return self._showAnyInviteErrors(addrs, room);
+ })
.catch(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
- title: "Failure to invite user",
+ title: "Failure to invite",
description: err.toString()
});
return null;
})
.done();
- } else if (this._isDmChat()) {
+ } else if (this._isDmChat(addrs)) {
// Start the DM chat
createRoom({dmUserId: addrs[0]})
.catch(function(err) {
@@ -225,13 +241,18 @@ module.exports = React.createClass({
} else {
// Start multi user chat
var self = this;
+ var room;
createRoom().then(function(roomId) {
+ room = MatrixClientPeg.get().getRoom(roomId);
return Invite.inviteMultipleToRoom(roomId, addrs);
})
+ .then(function(addrs) {
+ return self._showAnyInviteErrors(addrs, room);
+ })
.catch(function(err) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
- title: "Failure to invite user",
+ title: "Failure to invite",
description: err.toString()
});
return null;
@@ -254,11 +275,16 @@ module.exports = React.createClass({
var uid = user.userId.toLowerCase();
query = query.toLowerCase();
- // dount match any that are already on the invite list
+ // don't match any that are already on the invite list
if (this._isOnInviteList(uid)) {
return false;
}
+ // ignore current user
+ if (uid === MatrixClientPeg.get().credentials.userId) {
+ return false;
+ }
+
// direct prefix matches
if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) {
return true;
@@ -288,14 +314,33 @@ module.exports = React.createClass({
return false;
},
- _isDmChat: function() {
- if (this.state.inviteList.length === 1 && Invite.getAddressType(this.state.inviteList[0]) === "mx" && !this.props.roomId) {
+ _isDmChat: function(addrs) {
+ if (addrs.length === 1 && Invite.getAddressType(addrs[0]) === "mx" && !this.props.roomId) {
return true;
} else {
return false;
}
},
+ _showAnyInviteErrors: function(addrs, room) {
+ // Show user any errors
+ var errorList = [];
+ for (var addr in addrs) {
+ if (addrs.hasOwnProperty(addr) && addrs[addr] === "error") {
+ errorList.push(addr);
+ }
+ }
+
+ if (errorList.length > 0) {
+ var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+ Modal.createDialog(ErrorDialog, {
+ title: "Failed to invite the following users to the " + room.name + " room:",
+ description: errorList.join(", "),
+ });
+ }
+ return addrs;
+ },
+
render: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var AddressSelector = sdk.getComponent("elements.AddressSelector");
diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js
index 204e08404e..2c2d7e2d61 100644
--- a/src/components/views/elements/AddressSelector.js
+++ b/src/components/views/elements/AddressSelector.js
@@ -55,7 +55,7 @@ module.exports = React.createClass({
}
},
- onKeyUpArrow: function() {
+ onKeyUp: function() {
if (this.state.selected > 0) {
this.setState({
selected: this.state.selected - 1,
@@ -64,7 +64,7 @@ module.exports = React.createClass({
}
},
- onKeyDownArrow: function() {
+ onKeyDown: function() {
if (this.state.selected < this._maxSelected(this.props.addressList)) {
this.setState({
selected: this.state.selected + 1,
@@ -73,7 +73,7 @@ module.exports = React.createClass({
}
},
- onKeyReturn: function() {
+ onKeySelect: function() {
this.selectAddress(this.state.selected);
},
diff --git a/src/components/views/rooms/InviteMemberList.js b/src/components/views/rooms/InviteMemberList.js
index 1e5b19fdf1..ee5eabbeab 100644
--- a/src/components/views/rooms/InviteMemberList.js
+++ b/src/components/views/rooms/InviteMemberList.js
@@ -90,7 +90,7 @@ module.exports = React.createClass({
var EntityTile = sdk.getComponent("rooms.EntityTile");
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
- var label = input;
+ // var label = input;
// if (input[0] === "@") {
// label = input;
// }
@@ -98,16 +98,16 @@ module.exports = React.createClass({
// label = "Email: " + input;
// }
- this._emailEntity = new Entities.newEntity(
- }
- className="mx_EntityTile_invitePlaceholder"
- presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"}
- />,
- function(query) {
- return true; // always show this
- }
- );
+ // this._emailEntity = new Entities.newEntity(
+ // }
+ // className="mx_EntityTile_invitePlaceholder"
+ // presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"}
+ // />,
+ // function(query) {
+ // return true; // always show this
+ // }
+ // );
this.props.onSearchQueryChanged(input);
},
@@ -117,9 +117,9 @@ module.exports = React.createClass({
var entities = Entities.fromUsers(this._userList || [], true, this.props.onInvite);
// Add an "Email: foo@bar.com" tile as the first tile
- if (this._emailEntity) {
- entities.unshift(this._emailEntity);
- }
+ // if (this._emailEntity) {
+ // entities.unshift(this._emailEntity);
+ // }
return (
{
- if (this._blurTimeout) {
- clearTimeout(this.blurTimeout);
- }
- this.setState({ focused: true });
- } }
- onBlur={ ()=>{
- // nasty setTimeout heuristic to avoid the 'invite by email' prompt disappearing
- // due to the onBlur before we can click on it
- this._blurTimeout = setTimeout(
- ()=>{ this.setState({ focused: false }) },
- 300
- );
- } }
+ onFocus= {() => { this.setState({ focused: true }) }}
+ onBlur= {() => { this.setState({ focused: false }) }}
placeholder={this.props.searchPlaceholderText} />
);