From 3b34311e0514b0c14ac60fec4fd398546dbc4551 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 1 Jun 2016 23:42:34 +0100 Subject: [PATCH] implement new UX for 3pid invites --- src/components/views/rooms/InviteMemberList.js | 17 ++++++++++++++--- src/components/views/rooms/MemberInfo.js | 2 +- src/components/views/rooms/MemberList.js | 16 ++++++++++++++++ .../views/rooms/SearchableEntityList.js | 13 ++++++++----- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/components/views/rooms/InviteMemberList.js b/src/components/views/rooms/InviteMemberList.js index 480066771b..8f8b22eaa7 100644 --- a/src/components/views/rooms/InviteMemberList.js +++ b/src/components/views/rooms/InviteMemberList.js @@ -26,6 +26,7 @@ module.exports = React.createClass({ propTypes: { roomId: React.PropTypes.string.isRequired, onInvite: React.PropTypes.func.isRequired, // fn(inputText) + onThirdPartyInvite: React.PropTypes.func.isRequired, // fn(inputText) onSearchQueryChanged: React.PropTypes.func // fn(inputText) }, @@ -49,10 +50,19 @@ module.exports = React.createClass({ } }, + componentDidMount: function() { + // initialise the email tile + this.onSearchQueryChanged(''); + }, + onInvite: function(ev) { this.props.onInvite(this._input); }, + onThirdPartyInvite: function(ev) { + this.props.onThirdPartyInvite(this._input); + }, + onSearchQueryChanged: function(input) { this._input = input; var EntityTile = sdk.getComponent("rooms.EntityTile"); @@ -68,9 +78,10 @@ module.exports = React.createClass({ this._emailEntity = new Entities.newEntity( } - className="mx_EntityTile_invitePlaceholder" - presenceState="online" onClick={this.onInvite} name={label} />, + avatarJsx={ } + className="mx_EntityTile_invitePlaceholder" + presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"} + />, function(query) { return true; // always show this } diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 889bc7bd8a..ba4a3734f5 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -368,7 +368,7 @@ module.exports = React.createClass({ action: 'leave_room', room_id: this.props.member.roomId, }); - this.props.onFinished(); + this.props.onFinished(); }, getInitialState: function() { diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index a1769ad5f3..21c0827fcc 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -166,6 +166,21 @@ module.exports = React.createClass({ }); }, 500), + onThirdPartyInvite: function(inputText) { + var TextInputDialog = sdk.getComponent("dialogs.TextInputDialog"); + Modal.createDialog(TextInputDialog, { + title: "Invite members by email", + description: "Please enter the email addresses to be invited (comma separated)", + value: inputText, + button: "Invite", + onFinished: (should_invite, addresses)=>{ + if (should_invite) { + this.onInvite(addresses); + } + } + }); + }, + onInvite: function(inputText) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); @@ -514,6 +529,7 @@ module.exports = React.createClass({ inviteMemberListSection = ( ); } diff --git a/src/components/views/rooms/SearchableEntityList.js b/src/components/views/rooms/SearchableEntityList.js index c09fc2faee..28e7b1785c 100644 --- a/src/components/views/rooms/SearchableEntityList.js +++ b/src/components/views/rooms/SearchableEntityList.js @@ -48,6 +48,7 @@ var SearchableEntityList = React.createClass({ getInitialState: function() { return { query: "", + focused: false, truncateAt: this.props.truncateAt, results: this.getSearchResults("", this.props.entities) }; @@ -101,7 +102,7 @@ var SearchableEntityList = React.createClass({ getSearchResults: function(query, entities) { if (!query || query.length === 0) { - return this.props.emptyQueryShowsAll ? entities : [] + return this.props.emptyQueryShowsAll ? entities : [ entities[0] ] } return entities.filter(function(e) { return e.matches(query); @@ -128,19 +129,21 @@ var SearchableEntityList = React.createClass({ render: function() { var inputBox; - + if (this.props.showInputBox) { inputBox = (
{ this.setState({ focused: true }) } } + onBlur={ ()=>{ this.setState({ focused: false }) } } placeholder={this.props.searchPlaceholderText} />
); } var list; - if (this.state.results.length) { + if (this.state.results.length > 1 || this.state.focused) { if (this.props.truncateAt) { // caller wants list truncated var TruncatedList = sdk.getComponent("elements.TruncatedList"); list = ( @@ -172,10 +175,10 @@ var SearchableEntityList = React.createClass({ } return ( -
+
{ inputBox } { list } - { this.state.query.length ?

: '' } + { list ?

: '' }
); }