Change what AddressTile takes to be Objects
Rather than just passing in a list of strings. This paves the way for passing in display names & avatars of looked-up threepids.pull/21833/head
							parent
							
								
									5091bab657
								
							
						
					
					
						commit
						6c263c1c89
					
				|  | @ -164,7 +164,13 @@ module.exports = React.createClass({ | |||
|             queryList = this._userList.filter((user) => { | ||||
|                 return this._matches(query, user); | ||||
|             }).map((user) => { | ||||
|                 return user.userId; | ||||
|                 return { | ||||
|                     addressType: 'mx', | ||||
|                     address: user.userId, | ||||
|                     displayName: user.displayName, | ||||
|                     avatarMxc: user.avatarUrl, | ||||
|                     isKnown: true, | ||||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|             // If the query isn't a user we know about, but is a
 | ||||
|  | @ -172,7 +178,11 @@ module.exports = React.createClass({ | |||
|             if (queryList.length == 0) { | ||||
|                 const addrType = Invite.getAddressType(query); | ||||
|                 if (addrType !== null) { | ||||
|                     queryList.push(query); | ||||
|                     queryList.push({ | ||||
|                         addressType: addrType, | ||||
|                         address: query, | ||||
|                         isKnown: false, | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -204,7 +214,7 @@ module.exports = React.createClass({ | |||
| 
 | ||||
|     onSelected: function(index) { | ||||
|         var inviteList = this.state.inviteList.slice(); | ||||
|         inviteList.push(this.state.queryList[index].userId); | ||||
|         inviteList.push(this.state.queryList[index]); | ||||
|         this.setState({ | ||||
|             inviteList: inviteList, | ||||
|             queryList: [], | ||||
|  | @ -239,10 +249,14 @@ module.exports = React.createClass({ | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const addrTexts = addrs.map((addr) => { | ||||
|             return addr.address; | ||||
|         }); | ||||
| 
 | ||||
|         if (this.props.roomId) { | ||||
|             // Invite new user to a room
 | ||||
|             var self = this; | ||||
|             Invite.inviteMultipleToRoom(this.props.roomId, addrs) | ||||
|             Invite.inviteMultipleToRoom(this.props.roomId, addrTexts) | ||||
|             .then(function(addrs) { | ||||
|                 var room = MatrixClientPeg.get().getRoom(self.props.roomId); | ||||
|                 return self._showAnyInviteErrors(addrs, room); | ||||
|  | @ -257,9 +271,9 @@ module.exports = React.createClass({ | |||
|                 return null; | ||||
|             }) | ||||
|             .done(); | ||||
|         } else if (this._isDmChat(addrs)) { | ||||
|         } else if (this._isDmChat(addrTexts)) { | ||||
|             // Start the DM chat
 | ||||
|             createRoom({dmUserId: addrs[0]}) | ||||
|             createRoom({dmUserId: addrTexts[0]}) | ||||
|             .catch(function(err) { | ||||
|                 console.error(err.stack); | ||||
|                 var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); | ||||
|  | @ -276,7 +290,7 @@ module.exports = React.createClass({ | |||
|             var room; | ||||
|             createRoom().then(function(roomId) { | ||||
|                 room = MatrixClientPeg.get().getRoom(roomId); | ||||
|                 return Invite.inviteMultipleToRoom(roomId, addrs); | ||||
|                 return Invite.inviteMultipleToRoom(roomId, addrTexts); | ||||
|             }) | ||||
|             .then(function(addrs) { | ||||
|                 return self._showAnyInviteErrors(addrs, room); | ||||
|  | @ -294,7 +308,7 @@ module.exports = React.createClass({ | |||
|         } | ||||
| 
 | ||||
|         // Close - this will happen before the above, as that is async
 | ||||
|         this.props.onFinished(true, addrs); | ||||
|         this.props.onFinished(true, addrTexts); | ||||
|     }, | ||||
| 
 | ||||
|     _updateUserList: new rate_limited_func(function() { | ||||
|  | @ -345,7 +359,10 @@ module.exports = React.createClass({ | |||
| 
 | ||||
|     _isOnInviteList: function(uid) { | ||||
|         for (let i = 0; i < this.state.inviteList.length; i++) { | ||||
|             if (this.state.inviteList[i].toLowerCase() === uid) { | ||||
|             if ( | ||||
|                 this.state.inviteList[i].addressType == 'mx' && | ||||
|                 this.state.inviteList[i].address.toLowerCase() === uid | ||||
|             ) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | @ -380,24 +397,35 @@ module.exports = React.createClass({ | |||
|     }, | ||||
| 
 | ||||
|     _addInputToList: function() { | ||||
|         const addrType = Invite.getAddressType(this.refs.textinput.value); | ||||
|         if (addrType !== null) { | ||||
|             const inviteList = this.state.inviteList.slice(); | ||||
|             inviteList.push(this.refs.textinput.value.trim()); | ||||
|             this.setState({ | ||||
|                 inviteList: inviteList, | ||||
|                 queryList: [], | ||||
|             }); | ||||
|             return inviteList; | ||||
|         } else { | ||||
|             this.setState({ error: true }); | ||||
|             return null; | ||||
|         const addressText = this.refs.textinput.value.trim(); | ||||
|         const addrType = Invite.getAddressType(addressText); | ||||
|         const addrObj = { | ||||
|             addressType: addrType, | ||||
|             address: addressText, | ||||
|             isKnown: false, | ||||
|         }; | ||||
|         if (addrType == null) { | ||||
|         } else if (addrType == 'mx') { | ||||
|             const user = MatrixClientPeg.get().getUser(addrObj.address); | ||||
|             if (user) { | ||||
|                 addrObj.displayName = user.displayName; | ||||
|                 addrObj.avatarMxc = user.avatarUrl; | ||||
|                 addrObj.isKnown = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         const inviteList = this.state.inviteList.slice(); | ||||
|         inviteList.push(addrObj); | ||||
|         this.setState({ | ||||
|             inviteList: inviteList, | ||||
|             queryList: [], | ||||
|         }); | ||||
|         return inviteList; | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var TintableSvg = sdk.getComponent("elements.TintableSvg"); | ||||
|         var AddressSelector = sdk.getComponent("elements.AddressSelector"); | ||||
|         const TintableSvg = sdk.getComponent("elements.TintableSvg"); | ||||
|         const AddressSelector = sdk.getComponent("elements.AddressSelector"); | ||||
|         this.scrollElement = null; | ||||
| 
 | ||||
|         var query = []; | ||||
|  |  | |||
|  | @ -16,18 +16,19 @@ limitations under the License. | |||
| 
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| var React = require("react"); | ||||
| var sdk = require("../../../index"); | ||||
| var classNames = require('classnames'); | ||||
| const React = require("react"); | ||||
| const sdk = require("../../../index"); | ||||
| const classNames = require('classnames'); | ||||
| const InviteAddressType = require("./AddressTile"); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
| export default React.createClass({ | ||||
|     displayName: 'AddressSelector', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         onSelected: React.PropTypes.func.isRequired, | ||||
| 
 | ||||
|         // List of strings: the addresses to display
 | ||||
|         addressList: React.PropTypes.array.isRequired, | ||||
|         // List of the addresses to display
 | ||||
|         addressList: React.PropTypes.arrayOf(InviteAddressType).isRequired, | ||||
|         truncateAt: React.PropTypes.number.isRequired, | ||||
|         selected: React.PropTypes.number, | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,16 +23,33 @@ var Invite = require("../../../Invite"); | |||
| var MatrixClientPeg = require("../../../MatrixClientPeg"); | ||||
| var Avatar = require('../../../Avatar'); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
| // React PropType definition for an object describing
 | ||||
| // an address that can be invited to a room (which
 | ||||
| // could be a third party identifier or a matrix ID)
 | ||||
| // along with some additional information about the
 | ||||
| // address / target.
 | ||||
| export const InviteAddressType = React.PropTypes.shape({ | ||||
|     addressType: React.PropTypes.oneOf([ | ||||
|         'mx', 'email' | ||||
|     ]).isRequired, | ||||
|     address: React.PropTypes.string.isRequired, | ||||
|     displayName: React.PropTypes.string, | ||||
|     avatarMxc: React.PropTypes.string, | ||||
|     // true if the address is known to be a valid address (eg. is a real
 | ||||
|     // user we've seen) or false otherwise (eg. is just an address the
 | ||||
|     // user has entered)
 | ||||
|     isKnown: React.PropTypes.bool, | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| export default React.createClass({ | ||||
|     displayName: 'AddressTile', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         address: React.PropTypes.string.isRequired, | ||||
|         address: InviteAddressType.isRequired, | ||||
|         canDismiss: React.PropTypes.bool, | ||||
|         onDismissed: React.PropTypes.func, | ||||
|         justified: React.PropTypes.bool, | ||||
|         networkName: React.PropTypes.string, | ||||
|         networkUrl: React.PropTypes.string, | ||||
|     }, | ||||
| 
 | ||||
|     getDefaultProps: function() { | ||||
|  | @ -40,35 +57,26 @@ module.exports = React.createClass({ | |||
|             canDismiss: false, | ||||
|             onDismissed: function() {}, // NOP
 | ||||
|             justified: false, | ||||
|             networkName: "", | ||||
|             networkUrl: "", | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var userId, name, imgUrl, email; | ||||
|         var BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); | ||||
|         var TintableSvg = sdk.getComponent("elements.TintableSvg"); | ||||
|         const address = this.props.address; | ||||
|         const name = address.displayName || address.address; | ||||
| 
 | ||||
|         // Check if the addr is a valid type
 | ||||
|         var addrType = Invite.getAddressType(this.props.address); | ||||
|         if (addrType === "mx") { | ||||
|             let user = MatrixClientPeg.get().getUser(this.props.address); | ||||
|             if (user) { | ||||
|                 userId = user.userId; | ||||
|                 name = user.rawDisplayName || userId; | ||||
|                 imgUrl = Avatar.avatarUrlForUser(user, 25, 25, "crop"); | ||||
|             } else { | ||||
|                 name=this.props.address; | ||||
|                 imgUrl = "img/icon-mx-user.svg"; | ||||
|             } | ||||
|         } else if (addrType === "email") { | ||||
|             email = this.props.address; | ||||
|             name="email"; | ||||
|             imgUrl = "img/icon-email-user.svg"; | ||||
|         let imgUrl; | ||||
|         if (address.avatarMxc) { | ||||
|             imgUrl = MatrixClientPeg.get().mxcUrlToHttp( | ||||
|                 address.avatarMxc, 25, 25, 'crop' | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         if (address.addressType === "mx") { | ||||
|             if (!imgUrl) imgUrl = 'img/icon-mx-user.svg'; | ||||
|         } else if (address.addressType === 'email') { | ||||
|             if (!imgUrl) imgUrl = 'img/icon-email-user.svg'; | ||||
|         } else { | ||||
|             name="Unknown"; | ||||
|             imgUrl = "img/avatar-error.svg"; | ||||
|             if (!imgUrl) imgUrl = "img/avatar-error.svg"; | ||||
|         } | ||||
| 
 | ||||
|         // Removing networks for now as they're not really supported
 | ||||
|  | @ -83,15 +91,18 @@ module.exports = React.createClass({ | |||
|         } | ||||
|         */ | ||||
| 
 | ||||
|         var info; | ||||
|         var error = false; | ||||
|         if (addrType === "mx" && userId) { | ||||
|             var nameClasses = classNames({ | ||||
|         const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); | ||||
|         const TintableSvg = sdk.getComponent("elements.TintableSvg"); | ||||
| 
 | ||||
|         let info; | ||||
|         let error = false; | ||||
|         if (address.addressType === "mx" && address.isKnown) { | ||||
|             const nameClasses = classNames({ | ||||
|                 "mx_AddressTile_name": true, | ||||
|                 "mx_AddressTile_justified": this.props.justified, | ||||
|             }); | ||||
| 
 | ||||
|             var idClasses = classNames({ | ||||
|             const idClasses = classNames({ | ||||
|                 "mx_AddressTile_id": true, | ||||
|                 "mx_AddressTile_justified": this.props.justified, | ||||
|             }); | ||||
|  | @ -99,26 +110,26 @@ module.exports = React.createClass({ | |||
|             info = ( | ||||
|                 <div className="mx_AddressTile_mx"> | ||||
|                     <div className={nameClasses}>{ name }</div> | ||||
|                     <div className={idClasses}>{ userId }</div> | ||||
|                     <div className={idClasses}>{ address.address }</div> | ||||
|                 </div> | ||||
|             ); | ||||
|         } else if (addrType === "mx") { | ||||
|             var unknownMxClasses = classNames({ | ||||
|         } else if (address.addressType === "mx") { | ||||
|             const unknownMxClasses = classNames({ | ||||
|                 "mx_AddressTile_unknownMx": true, | ||||
|                 "mx_AddressTile_justified": this.props.justified, | ||||
|             }); | ||||
| 
 | ||||
|             info = ( | ||||
|                 <div className={unknownMxClasses}>{ this.props.address }</div> | ||||
|                 <div className={unknownMxClasses}>{ this.props.address.address }</div> | ||||
|             ); | ||||
|         } else if (email) { | ||||
|         } else if (address.addressType === "email") { | ||||
|             var emailClasses = classNames({ | ||||
|                 "mx_AddressTile_email": true, | ||||
|                 "mx_AddressTile_justified": this.props.justified, | ||||
|             }); | ||||
| 
 | ||||
|             info = ( | ||||
|                 <div className={emailClasses}>{ email }</div> | ||||
|                 <div className={emailClasses}>{ address.address }</div> | ||||
|             ); | ||||
|         } else { | ||||
|             error = true; | ||||
|  | @ -132,12 +143,12 @@ module.exports = React.createClass({ | |||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         var classes = classNames({ | ||||
|         const classes = classNames({ | ||||
|             "mx_AddressTile": true, | ||||
|             "mx_AddressTile_error": error, | ||||
|         }); | ||||
| 
 | ||||
|         var dismiss; | ||||
|         let dismiss; | ||||
|         if (this.props.canDismiss) { | ||||
|             dismiss = ( | ||||
|                 <div className="mx_AddressTile_dismiss" onClick={this.props.onDismissed} > | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 David Baker
						David Baker