improve login, including checkbox fix for advanced options, rechecking when you change server, avoiding flickering when you change HS, better error/spinner layout, and trimming whitespace

This commit is contained in:
Matthew Hodgson 2015-08-31 19:30:24 +01:00
parent 25a4f1fde0
commit ab068cc372
4 changed files with 43 additions and 30 deletions

View File

@ -82,11 +82,19 @@ limitations under the License.
opacity: 0.8; opacity: 0.8;
} }
.mx_Login_loader {
position: absolute;
left: 50%;
margin-top: 12px;
}
.mx_Login_error { .mx_Login_error {
color: #ff2020; color: #ff2020;
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
margin-bottom: 24px; height: 24px;
margin-top: 12px;
margin-bottom: 12px;
} }
.mx_Login_create:link { .mx_Login_create:link {

View File

@ -74,14 +74,14 @@ module.exports = React.createClass({
*/ */
getFormVals: function() { getFormVals: function() {
return { return {
'username': this.refs.user.getDOMNode().value, 'username': this.refs.user.getDOMNode().value.trim(),
'password': this.refs.pass.getDOMNode().value 'password': this.refs.pass.getDOMNode().value.trim()
}; };
}, },
onHsUrlChanged: function() { onHsUrlChanged: function() {
this.customHsUrl = this.refs.serverConfig.getHsUrl(); this.customHsUrl = this.refs.serverConfig.getHsUrl().trim();
this.customIsUrl = this.refs.serverConfig.getIsUrl(); this.customIsUrl = this.refs.serverConfig.getIsUrl().trim();
MatrixClientPeg.replaceUsingUrls( MatrixClientPeg.replaceUsingUrls(
this.getHsUrl(), this.getHsUrl(),
this.getIsUrl() this.getIsUrl()
@ -93,23 +93,24 @@ module.exports = React.createClass({
// XXX: HSes do not have to offer password auth, so we // XXX: HSes do not have to offer password auth, so we
// need to update and maybe show a different component // need to update and maybe show a different component
// when a new HS is entered. // when a new HS is entered.
/*if (this.updateHsTimeout) { if (this.updateHsTimeout) {
clearTimeout(this.updateHsTimeout); clearTimeout(this.updateHsTimeout);
} }
var self = this; var self = this;
this.updateHsTimeout = setTimeout(function() { this.updateHsTimeout = setTimeout(function() {
self.onHSChosen(); self.onHSChosen();
}, 500);*/ }, 500);
}, },
componentForStep: function(step) { componentForStep: function(step) {
switch (step) { switch (step) {
case 'choose_hs': case 'choose_hs':
case 'fetch_stages':
var serverConfigStyle = {}; var serverConfigStyle = {};
serverConfigStyle.display = this.state.serverConfigVisible ? 'block' : 'none'; serverConfigStyle.display = this.state.serverConfigVisible ? 'block' : 'none';
return ( return (
<div> <div>
<input className="mx_Login_checkbox" id="advanced" type="checkbox" value={this.state.serverConfigVisible} onChange={this.onServerConfigVisibleChange} /> <input className="mx_Login_checkbox" id="advanced" type="checkbox" checked={this.state.serverConfigVisible} onChange={this.onServerConfigVisibleChange} />
<label className="mx_Login_label" htmlFor="advanced">Use custom server options (advanced)</label> <label className="mx_Login_label" htmlFor="advanced">Use custom server options (advanced)</label>
<div style={serverConfigStyle}> <div style={serverConfigStyle}>
<ServerConfig ref="serverConfig" <ServerConfig ref="serverConfig"
@ -126,7 +127,7 @@ module.exports = React.createClass({
<form onSubmit={this.onUserPassEntered}> <form onSubmit={this.onUserPassEntered}>
<input className="mx_Login_field" ref="user" type="text" value={this.state.username} onChange={this.onUsernameChanged} placeholder="Email or user name" /><br /> <input className="mx_Login_field" ref="user" type="text" value={this.state.username} onChange={this.onUsernameChanged} placeholder="Email or user name" /><br />
<input className="mx_Login_field" ref="pass" type="password" value={this.state.password} onChange={this.onPasswordChanged} placeholder="Password" /><br /> <input className="mx_Login_field" ref="pass" type="password" value={this.state.password} onChange={this.onPasswordChanged} placeholder="Password" /><br />
{this.componentForStep('choose_hs')} { this.componentForStep('choose_hs') }
<input className="mx_Login_submit" type="submit" value="Log in" /> <input className="mx_Login_submit" type="submit" value="Log in" />
</form> </form>
</div> </div>
@ -143,20 +144,18 @@ module.exports = React.createClass({
}, },
loginContent: function() { loginContent: function() {
if (this.state.busy) { var loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null;
return (
<Loader />
);
} else {
return ( return (
<div> <div>
<h2>Sign in</h2> <h2>Sign in</h2>
{this.componentForStep(this.state.step)} {this.componentForStep(this.state.step)}
<div className="mx_Login_error">{this.state.errorText}</div> <div className="mx_Login_error">
{ loader }
{this.state.errorText}
</div>
<a className="mx_Login_create" onClick={this.showRegister} href="#">Create a new account</a> <a className="mx_Login_create" onClick={this.showRegister} href="#">Create a new account</a>
</div> </div>
); );
}
}, },
render: function() { render: function() {

View File

@ -46,10 +46,10 @@ module.exports = React.createClass({
getRegFormVals: function() { getRegFormVals: function() {
return { return {
email: this.refs.email.getDOMNode().value, email: this.refs.email.getDOMNode().value.trim(),
username: this.refs.username.getDOMNode().value, username: this.refs.username.getDOMNode().value.trim(),
password: this.refs.password.getDOMNode().value, password: this.refs.password.getDOMNode().value.trim(),
confirmPassword: this.refs.confirmPassword.getDOMNode().value confirmPassword: this.refs.confirmPassword.getDOMNode().value.trim()
}; };
}, },

View File

@ -35,7 +35,7 @@ module.exports = {
}, },
setStep: function(step) { setStep: function(step) {
this.setState({ step: step, errorText: '', busy: false }); this.setState({ step: step, busy: false });
}, },
onHSChosen: function() { onHSChosen: function() {
@ -45,11 +45,14 @@ module.exports = {
); );
this.setState({ this.setState({
hs_url: this.getHsUrl(), hs_url: this.getHsUrl(),
is_url: this.getIsUrl() is_url: this.getIsUrl(),
}); });
this.setStep("fetch_stages"); this.setStep("fetch_stages");
var cli = MatrixClientPeg.get(); var cli = MatrixClientPeg.get();
this.setState({busy: true}); this.setState({
busy: true,
errorText: "",
});
var self = this; var self = this;
cli.loginFlows().done(function(result) { cli.loginFlows().done(function(result) {
self.setState({ self.setState({
@ -66,7 +69,10 @@ module.exports = {
onUserPassEntered: function(ev) { onUserPassEntered: function(ev) {
ev.preventDefault(); ev.preventDefault();
this.setState({busy: true}); this.setState({
busy: true,
errorText: "",
});
var self = this; var self = this;
var formVals = this.getFormVals(); var formVals = this.getFormVals();