Merge pull request #473 from matrix-org/wmwragg/multi-invite-bugfix
Wmwragg/multi invite bugfixpull/21833/head
						commit
						1a126fee54
					
				|  | @ -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"); | ||||
|  |  | |||
|  | @ -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); | ||||
|     }, | ||||
| 
 | ||||
|  |  | |||
|  | @ -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( | ||||
|             <EntityTile key="dynamic_invite_tile" suppressOnHover={true} showInviteButton={true} | ||||
|                 avatarJsx={ <BaseAvatar name="@" width={36} height={36} /> } | ||||
|                 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(
 | ||||
|         //     <EntityTile key="dynamic_invite_tile" suppressOnHover={true} showInviteButton={true}
 | ||||
|         //         avatarJsx={ <BaseAvatar name="@" width={36} height={36} /> }
 | ||||
|         //         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 ( | ||||
|             <SearchableEntityList searchPlaceholderText={"Search/invite by name, email, id"} | ||||
|  |  | |||
|  | @ -102,7 +102,7 @@ var SearchableEntityList = React.createClass({ | |||
| 
 | ||||
|     getSearchResults: function(query, entities) { | ||||
|         if (!query || query.length === 0) { | ||||
|             return this.props.emptyQueryShowsAll ? entities : [ entities[0] ] | ||||
|             return this.props.emptyQueryShowsAll ? entities : []; | ||||
|         } | ||||
|         return entities.filter(function(e) { | ||||
|             return e.matches(query); | ||||
|  | @ -135,20 +135,8 @@ var SearchableEntityList = React.createClass({ | |||
|                 <form onSubmit={this.onQuerySubmit} autoComplete="off"> | ||||
|                     <input className="mx_SearchableEntityList_query" id="mx_SearchableEntityList_query" type="text" | ||||
|                         onChange={this.onQueryChanged} value={this.state.query} | ||||
|                         onFocus={ ()=>{ | ||||
|                             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} /> | ||||
|                 </form> | ||||
|             ); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Matthew Hodgson
						Matthew Hodgson