Consolidate PasswordLogin state and input control/ownership
previously data was stored in two places which drifted
This commit is contained in:
parent
0b74d3a0ef
commit
85fbc6d89f
2 changed files with 26 additions and 41 deletions
|
@ -566,9 +566,9 @@ export default class LoginComponent extends React.Component {
|
||||||
<PasswordLogin
|
<PasswordLogin
|
||||||
onSubmit={this.onPasswordLogin}
|
onSubmit={this.onPasswordLogin}
|
||||||
onEditServerDetailsClick={onEditServerDetailsClick}
|
onEditServerDetailsClick={onEditServerDetailsClick}
|
||||||
initialUsername={this.state.username}
|
username={this.state.username}
|
||||||
initialPhoneCountry={this.state.phoneCountry}
|
phoneCountry={this.state.phoneCountry}
|
||||||
initialPhoneNumber={this.state.phoneNumber}
|
phoneNumber={this.state.phoneNumber}
|
||||||
onUsernameChanged={this.onUsernameChanged}
|
onUsernameChanged={this.onUsernameChanged}
|
||||||
onUsernameBlur={this.onUsernameBlur}
|
onUsernameBlur={this.onUsernameBlur}
|
||||||
onPhoneCountryChanged={this.onPhoneCountryChanged}
|
onPhoneCountryChanged={this.onPhoneCountryChanged}
|
||||||
|
|
|
@ -31,22 +31,21 @@ import * as Email from "../../../email";
|
||||||
// For validating phone numbers without country codes
|
// For validating phone numbers without country codes
|
||||||
const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/;
|
const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* A pure UI component which displays a username/password form.
|
* A pure UI component which displays a username/password form.
|
||||||
|
* The email/username/phone fields are fully-controlled, the password field is not.
|
||||||
*/
|
*/
|
||||||
export default class PasswordLogin extends React.Component {
|
export default class PasswordLogin extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onSubmit: PropTypes.func.isRequired, // fn(username, password)
|
onSubmit: PropTypes.func.isRequired, // fn(username, password)
|
||||||
onEditServerDetailsClick: PropTypes.func,
|
onEditServerDetailsClick: PropTypes.func,
|
||||||
onForgotPasswordClick: PropTypes.func, // fn()
|
onForgotPasswordClick: PropTypes.func, // fn()
|
||||||
initialUsername: PropTypes.string,
|
username: PropTypes.string,
|
||||||
initialPhoneCountry: PropTypes.string,
|
phoneCountry: PropTypes.string,
|
||||||
initialPhoneNumber: PropTypes.string,
|
phoneNumber: PropTypes.string,
|
||||||
initialPassword: PropTypes.string,
|
|
||||||
onUsernameChanged: PropTypes.func,
|
onUsernameChanged: PropTypes.func,
|
||||||
onPhoneCountryChanged: PropTypes.func,
|
onPhoneCountryChanged: PropTypes.func,
|
||||||
onPhoneNumberChanged: PropTypes.func,
|
onPhoneNumberChanged: PropTypes.func,
|
||||||
onPasswordChanged: PropTypes.func,
|
|
||||||
loginIncorrect: PropTypes.bool,
|
loginIncorrect: PropTypes.bool,
|
||||||
disableSubmit: PropTypes.bool,
|
disableSubmit: PropTypes.bool,
|
||||||
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
|
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
|
||||||
|
@ -57,13 +56,11 @@ export default class PasswordLogin extends React.Component {
|
||||||
onEditServerDetailsClick: null,
|
onEditServerDetailsClick: null,
|
||||||
onUsernameChanged: function() {},
|
onUsernameChanged: function() {},
|
||||||
onUsernameBlur: function() {},
|
onUsernameBlur: function() {},
|
||||||
onPasswordChanged: function() {},
|
|
||||||
onPhoneCountryChanged: function() {},
|
onPhoneCountryChanged: function() {},
|
||||||
onPhoneNumberChanged: function() {},
|
onPhoneNumberChanged: function() {},
|
||||||
initialUsername: "",
|
username: "",
|
||||||
initialPhoneCountry: "",
|
phoneCountry: "",
|
||||||
initialPhoneNumber: "",
|
phoneNumber: "",
|
||||||
initialPassword: "",
|
|
||||||
loginIncorrect: false,
|
loginIncorrect: false,
|
||||||
disableSubmit: false,
|
disableSubmit: false,
|
||||||
};
|
};
|
||||||
|
@ -78,11 +75,8 @@ export default class PasswordLogin extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
// Field error codes by field ID
|
// Field error codes by field ID
|
||||||
fieldValid: {},
|
fieldValid: {},
|
||||||
username: this.props.initialUsername,
|
|
||||||
password: this.props.initialPassword,
|
|
||||||
phoneCountry: this.props.initialPhoneCountry,
|
|
||||||
phoneNumber: this.props.initialPhoneNumber,
|
|
||||||
loginType: PasswordLogin.LOGIN_FIELD_MXID,
|
loginType: PasswordLogin.LOGIN_FIELD_MXID,
|
||||||
|
password: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onForgotPasswordClick = this.onForgotPasswordClick.bind(this);
|
this.onForgotPasswordClick = this.onForgotPasswordClick.bind(this);
|
||||||
|
@ -120,11 +114,11 @@ export default class PasswordLogin extends React.Component {
|
||||||
switch (this.state.loginType) {
|
switch (this.state.loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case PasswordLogin.LOGIN_FIELD_MXID:
|
||||||
username = this.state.username;
|
username = this.props.username;
|
||||||
break;
|
break;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE:
|
case PasswordLogin.LOGIN_FIELD_PHONE:
|
||||||
phoneCountry = this.state.phoneCountry;
|
phoneCountry = this.props.phoneCountry;
|
||||||
phoneNumber = this.state.phoneNumber;
|
phoneNumber = this.props.phoneNumber;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +131,6 @@ export default class PasswordLogin extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onUsernameChanged(ev) {
|
onUsernameChanged(ev) {
|
||||||
this.setState({username: ev.target.value});
|
|
||||||
this.props.onUsernameChanged(ev.target.value);
|
this.props.onUsernameChanged(ev.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,23 +153,16 @@ export default class PasswordLogin extends React.Component {
|
||||||
|
|
||||||
onLoginTypeChange(ev) {
|
onLoginTypeChange(ev) {
|
||||||
const loginType = ev.target.value;
|
const loginType = ev.target.value;
|
||||||
this.setState({
|
this.setState({ loginType });
|
||||||
loginType: loginType,
|
this.props.onUsernameChanged(""); // Reset because email and username use the same state
|
||||||
username: "", // Reset because email and username use the same state
|
|
||||||
});
|
|
||||||
CountlyAnalytics.instance.track("onboarding_login_type_changed", { loginType });
|
CountlyAnalytics.instance.track("onboarding_login_type_changed", { loginType });
|
||||||
}
|
}
|
||||||
|
|
||||||
onPhoneCountryChanged(country) {
|
onPhoneCountryChanged(country) {
|
||||||
this.setState({
|
|
||||||
phoneCountry: country.iso2,
|
|
||||||
phonePrefix: country.prefix,
|
|
||||||
});
|
|
||||||
this.props.onPhoneCountryChanged(country.iso2);
|
this.props.onPhoneCountryChanged(country.iso2);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPhoneNumberChanged(ev) {
|
onPhoneNumberChanged(ev) {
|
||||||
this.setState({phoneNumber: ev.target.value});
|
|
||||||
this.props.onPhoneNumberChanged(ev.target.value);
|
this.props.onPhoneNumberChanged(ev.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +176,6 @@ export default class PasswordLogin extends React.Component {
|
||||||
|
|
||||||
onPasswordChanged(ev) {
|
onPasswordChanged(ev) {
|
||||||
this.setState({password: ev.target.value});
|
this.setState({password: ev.target.value});
|
||||||
this.props.onPasswordChanged(ev.target.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async verifyFieldsBeforeSubmit() {
|
async verifyFieldsBeforeSubmit() {
|
||||||
|
@ -355,7 +340,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
|
|
||||||
switch (loginType) {
|
switch (loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
||||||
classes.error = this.props.loginIncorrect && !this.state.username;
|
classes.error = this.props.loginIncorrect && !this.props.username;
|
||||||
return <Field
|
return <Field
|
||||||
className={classNames(classes)}
|
className={classNames(classes)}
|
||||||
name="username" // make it a little easier for browser's remember-password
|
name="username" // make it a little easier for browser's remember-password
|
||||||
|
@ -363,7 +348,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
type="text"
|
type="text"
|
||||||
label={_t("Email")}
|
label={_t("Email")}
|
||||||
placeholder="joe@example.com"
|
placeholder="joe@example.com"
|
||||||
value={this.state.username}
|
value={this.props.username}
|
||||||
onChange={this.onUsernameChanged}
|
onChange={this.onUsernameChanged}
|
||||||
onFocus={this.onUsernameFocus}
|
onFocus={this.onUsernameFocus}
|
||||||
onBlur={this.onUsernameBlur}
|
onBlur={this.onUsernameBlur}
|
||||||
|
@ -373,14 +358,14 @@ export default class PasswordLogin extends React.Component {
|
||||||
ref={field => this[PasswordLogin.LOGIN_FIELD_EMAIL] = field}
|
ref={field => this[PasswordLogin.LOGIN_FIELD_EMAIL] = field}
|
||||||
/>;
|
/>;
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case PasswordLogin.LOGIN_FIELD_MXID:
|
||||||
classes.error = this.props.loginIncorrect && !this.state.username;
|
classes.error = this.props.loginIncorrect && !this.props.username;
|
||||||
return <Field
|
return <Field
|
||||||
className={classNames(classes)}
|
className={classNames(classes)}
|
||||||
name="username" // make it a little easier for browser's remember-password
|
name="username" // make it a little easier for browser's remember-password
|
||||||
key="username_input"
|
key="username_input"
|
||||||
type="text"
|
type="text"
|
||||||
label={_t("Username")}
|
label={_t("Username")}
|
||||||
value={this.state.username}
|
value={this.props.username}
|
||||||
onChange={this.onUsernameChanged}
|
onChange={this.onUsernameChanged}
|
||||||
onFocus={this.onUsernameFocus}
|
onFocus={this.onUsernameFocus}
|
||||||
onBlur={this.onUsernameBlur}
|
onBlur={this.onUsernameBlur}
|
||||||
|
@ -391,10 +376,10 @@ export default class PasswordLogin extends React.Component {
|
||||||
/>;
|
/>;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE: {
|
case PasswordLogin.LOGIN_FIELD_PHONE: {
|
||||||
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
||||||
classes.error = this.props.loginIncorrect && !this.state.phoneNumber;
|
classes.error = this.props.loginIncorrect && !this.props.phoneNumber;
|
||||||
|
|
||||||
const phoneCountry = <CountryDropdown
|
const phoneCountry = <CountryDropdown
|
||||||
value={this.state.phoneCountry}
|
value={this.props.phoneCountry}
|
||||||
isSmall={true}
|
isSmall={true}
|
||||||
showPrefix={true}
|
showPrefix={true}
|
||||||
onOptionChange={this.onPhoneCountryChanged}
|
onOptionChange={this.onPhoneCountryChanged}
|
||||||
|
@ -406,7 +391,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
key="phone_input"
|
key="phone_input"
|
||||||
type="text"
|
type="text"
|
||||||
label={_t("Phone")}
|
label={_t("Phone")}
|
||||||
value={this.state.phoneNumber}
|
value={this.props.phoneNumber}
|
||||||
prefixComponent={phoneCountry}
|
prefixComponent={phoneCountry}
|
||||||
onChange={this.onPhoneNumberChanged}
|
onChange={this.onPhoneNumberChanged}
|
||||||
onFocus={this.onPhoneNumberFocus}
|
onFocus={this.onPhoneNumberFocus}
|
||||||
|
@ -424,9 +409,9 @@ export default class PasswordLogin extends React.Component {
|
||||||
switch (this.state.loginType) {
|
switch (this.state.loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case PasswordLogin.LOGIN_FIELD_MXID:
|
||||||
return !this.state.username;
|
return !this.props.username;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE:
|
case PasswordLogin.LOGIN_FIELD_PHONE:
|
||||||
return !this.state.phoneCountry || !this.state.phoneNumber;
|
return !this.props.phoneCountry || !this.props.phoneNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue