mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-17 22:14:58 +08:00
Merge pull request #297 from matrix-org/matthew/new-3pid-invite
implement new UX for 3pid invites
This commit is contained in:
commit
0ef0120227
@ -26,6 +26,7 @@ module.exports = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
roomId: React.PropTypes.string.isRequired,
|
roomId: React.PropTypes.string.isRequired,
|
||||||
onInvite: React.PropTypes.func.isRequired, // fn(inputText)
|
onInvite: React.PropTypes.func.isRequired, // fn(inputText)
|
||||||
|
onThirdPartyInvite: React.PropTypes.func.isRequired, // fn(inputText)
|
||||||
onSearchQueryChanged: React.PropTypes.func // 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) {
|
onInvite: function(ev) {
|
||||||
this.props.onInvite(this._input);
|
this.props.onInvite(this._input);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onThirdPartyInvite: function(ev) {
|
||||||
|
this.props.onThirdPartyInvite(this._input);
|
||||||
|
},
|
||||||
|
|
||||||
onSearchQueryChanged: function(input) {
|
onSearchQueryChanged: function(input) {
|
||||||
this._input = input;
|
this._input = input;
|
||||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||||
@ -68,9 +78,10 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
this._emailEntity = new Entities.newEntity(
|
this._emailEntity = new Entities.newEntity(
|
||||||
<EntityTile key="dynamic_invite_tile" suppressOnHover={true} showInviteButton={true}
|
<EntityTile key="dynamic_invite_tile" suppressOnHover={true} showInviteButton={true}
|
||||||
avatarJsx={ <BaseAvatar name="@" width={36} height={36} /> }
|
avatarJsx={ <BaseAvatar name="@" width={36} height={36} /> }
|
||||||
className="mx_EntityTile_invitePlaceholder"
|
className="mx_EntityTile_invitePlaceholder"
|
||||||
presenceState="online" onClick={this.onInvite} name={label} />,
|
presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"}
|
||||||
|
/>,
|
||||||
function(query) {
|
function(query) {
|
||||||
return true; // always show this
|
return true; // always show this
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ module.exports = React.createClass({
|
|||||||
action: 'leave_room',
|
action: 'leave_room',
|
||||||
room_id: this.props.member.roomId,
|
room_id: this.props.member.roomId,
|
||||||
});
|
});
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -166,6 +166,21 @@ module.exports = React.createClass({
|
|||||||
});
|
});
|
||||||
}, 500),
|
}, 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) {
|
onInvite: function(inputText) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
|
||||||
@ -514,6 +529,7 @@ module.exports = React.createClass({
|
|||||||
inviteMemberListSection = (
|
inviteMemberListSection = (
|
||||||
<InviteMemberList roomId={this.props.roomId}
|
<InviteMemberList roomId={this.props.roomId}
|
||||||
onSearchQueryChanged={this.onSearchQueryChanged}
|
onSearchQueryChanged={this.onSearchQueryChanged}
|
||||||
|
onThirdPartyInvite={this.onThirdPartyInvite}
|
||||||
onInvite={this.onInvite} />
|
onInvite={this.onInvite} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ var SearchableEntityList = React.createClass({
|
|||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
query: "",
|
query: "",
|
||||||
|
focused: false,
|
||||||
truncateAt: this.props.truncateAt,
|
truncateAt: this.props.truncateAt,
|
||||||
results: this.getSearchResults("", this.props.entities)
|
results: this.getSearchResults("", this.props.entities)
|
||||||
};
|
};
|
||||||
@ -101,7 +102,7 @@ var SearchableEntityList = React.createClass({
|
|||||||
|
|
||||||
getSearchResults: function(query, entities) {
|
getSearchResults: function(query, entities) {
|
||||||
if (!query || query.length === 0) {
|
if (!query || query.length === 0) {
|
||||||
return this.props.emptyQueryShowsAll ? entities : []
|
return this.props.emptyQueryShowsAll ? entities : [ entities[0] ]
|
||||||
}
|
}
|
||||||
return entities.filter(function(e) {
|
return entities.filter(function(e) {
|
||||||
return e.matches(query);
|
return e.matches(query);
|
||||||
@ -128,19 +129,21 @@ var SearchableEntityList = React.createClass({
|
|||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var inputBox;
|
var inputBox;
|
||||||
|
|
||||||
if (this.props.showInputBox) {
|
if (this.props.showInputBox) {
|
||||||
inputBox = (
|
inputBox = (
|
||||||
<form onSubmit={this.onQuerySubmit} autoComplete="off">
|
<form onSubmit={this.onQuerySubmit} autoComplete="off">
|
||||||
<input className="mx_SearchableEntityList_query" id="mx_SearchableEntityList_query" type="text"
|
<input className="mx_SearchableEntityList_query" id="mx_SearchableEntityList_query" type="text"
|
||||||
onChange={this.onQueryChanged} value={this.state.query}
|
onChange={this.onQueryChanged} value={this.state.query}
|
||||||
|
onFocus={ ()=>{ this.setState({ focused: true }) } }
|
||||||
|
onBlur={ ()=>{ this.setState({ focused: false }) } }
|
||||||
placeholder={this.props.searchPlaceholderText} />
|
placeholder={this.props.searchPlaceholderText} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var list;
|
var list;
|
||||||
if (this.state.results.length) {
|
if (this.state.results.length > 1 || this.state.focused) {
|
||||||
if (this.props.truncateAt) { // caller wants list truncated
|
if (this.props.truncateAt) { // caller wants list truncated
|
||||||
var TruncatedList = sdk.getComponent("elements.TruncatedList");
|
var TruncatedList = sdk.getComponent("elements.TruncatedList");
|
||||||
list = (
|
list = (
|
||||||
@ -172,10 +175,10 @@ var SearchableEntityList = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ "mx_SearchableEntityList " + (this.state.query.length ? "mx_SearchableEntityList_expanded" : "") }>
|
<div className={ "mx_SearchableEntityList " + (list ? "mx_SearchableEntityList_expanded" : "") }>
|
||||||
{ inputBox }
|
{ inputBox }
|
||||||
{ list }
|
{ list }
|
||||||
{ this.state.query.length ? <div className="mx_SearchableEntityList_hrWrapper"><hr/></div> : '' }
|
{ list ? <div className="mx_SearchableEntityList_hrWrapper"><hr/></div> : '' }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user