Convert PasswordLogin to Typescript
This commit is contained in:
parent
85fbc6d89f
commit
7397cebbea
2 changed files with 106 additions and 124 deletions
|
@ -1,7 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016, 2017, 2019 New Vector Ltd.
|
||||||
Copyright 2017 Vector Creations Ltd
|
|
||||||
Copyright 2019 New Vector Ltd.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,9 +15,8 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
||||||
|
@ -27,78 +24,78 @@ import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
import withValidation from "../elements/Validation";
|
import withValidation from "../elements/Validation";
|
||||||
import * as Email from "../../../email";
|
import * as Email from "../../../email";
|
||||||
|
import Field from "../elements/Field";
|
||||||
|
import CountryDropdown from "./CountryDropdown";
|
||||||
|
import SignInToText from "./SignInToText";
|
||||||
|
|
||||||
// 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]*$/;
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
username: string; // also used for email address
|
||||||
|
phoneCountry: string;
|
||||||
|
phoneNumber: string;
|
||||||
|
|
||||||
|
serverConfig: ValidatedServerConfig;
|
||||||
|
loginIncorrect?: boolean;
|
||||||
|
disableSubmit?: boolean;
|
||||||
|
busy?: boolean;
|
||||||
|
|
||||||
|
onSubmit(username: string, phoneCountry: void, phoneNumber: void, password: string): void;
|
||||||
|
onSubmit(username: void, phoneCountry: string, phoneNumber: string, password: string): void;
|
||||||
|
onUsernameChanged?(username: string): void;
|
||||||
|
onUsernameBlur?(username: string): void;
|
||||||
|
onPhoneCountryChanged?(phoneCountry: string): void;
|
||||||
|
onPhoneNumberChanged?(phoneNumber: string): void;
|
||||||
|
onEditServerDetailsClick?(): void;
|
||||||
|
onForgotPasswordClick?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
fieldValid: Partial<Record<LoginField, boolean>>;
|
||||||
|
loginType: LoginField.Email | LoginField.MatrixId | LoginField.Phone,
|
||||||
|
password: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LoginField {
|
||||||
|
Email = "login_field_email",
|
||||||
|
MatrixId = "login_field_mxid",
|
||||||
|
Phone = "login_field_phone",
|
||||||
|
Password = "login_field_phone",
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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.
|
* 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.PureComponent<IProps, IState> {
|
||||||
static propTypes = {
|
|
||||||
onSubmit: PropTypes.func.isRequired, // fn(username, password)
|
|
||||||
onEditServerDetailsClick: PropTypes.func,
|
|
||||||
onForgotPasswordClick: PropTypes.func, // fn()
|
|
||||||
username: PropTypes.string,
|
|
||||||
phoneCountry: PropTypes.string,
|
|
||||||
phoneNumber: PropTypes.string,
|
|
||||||
onUsernameChanged: PropTypes.func,
|
|
||||||
onPhoneCountryChanged: PropTypes.func,
|
|
||||||
onPhoneNumberChanged: PropTypes.func,
|
|
||||||
loginIncorrect: PropTypes.bool,
|
|
||||||
disableSubmit: PropTypes.bool,
|
|
||||||
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
|
|
||||||
busy: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
onEditServerDetailsClick: null,
|
onEditServerDetailsClick: null,
|
||||||
onUsernameChanged: function() {},
|
onUsernameChanged: function() {},
|
||||||
onUsernameBlur: function() {},
|
onUsernameBlur: function() {},
|
||||||
onPhoneCountryChanged: function() {},
|
onPhoneCountryChanged: function() {},
|
||||||
onPhoneNumberChanged: function() {},
|
onPhoneNumberChanged: function() {},
|
||||||
username: "",
|
|
||||||
phoneCountry: "",
|
|
||||||
phoneNumber: "",
|
|
||||||
loginIncorrect: false,
|
loginIncorrect: false,
|
||||||
disableSubmit: false,
|
disableSubmit: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static LOGIN_FIELD_EMAIL = "login_field_email";
|
|
||||||
static LOGIN_FIELD_MXID = "login_field_mxid";
|
|
||||||
static LOGIN_FIELD_PHONE = "login_field_phone";
|
|
||||||
static LOGIN_FIELD_PASSWORD = "login_field_password";
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
// Field error codes by field ID
|
// Field error codes by field ID
|
||||||
fieldValid: {},
|
fieldValid: {},
|
||||||
loginType: PasswordLogin.LOGIN_FIELD_MXID,
|
loginType: LoginField.MatrixId,
|
||||||
password: "",
|
password: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onForgotPasswordClick = this.onForgotPasswordClick.bind(this);
|
|
||||||
this.onSubmitForm = this.onSubmitForm.bind(this);
|
|
||||||
this.onUsernameFocus = this.onUsernameFocus.bind(this);
|
|
||||||
this.onUsernameChanged = this.onUsernameChanged.bind(this);
|
|
||||||
this.onUsernameBlur = this.onUsernameBlur.bind(this);
|
|
||||||
this.onLoginTypeChange = this.onLoginTypeChange.bind(this);
|
|
||||||
this.onPhoneCountryChanged = this.onPhoneCountryChanged.bind(this);
|
|
||||||
this.onPhoneNumberChanged = this.onPhoneNumberChanged.bind(this);
|
|
||||||
this.onPhoneNumberBlur = this.onPhoneNumberBlur.bind(this);
|
|
||||||
this.onPasswordChanged = this.onPasswordChanged.bind(this);
|
|
||||||
this.isLoginEmpty = this.isLoginEmpty.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onForgotPasswordClick(ev) {
|
private onForgotPasswordClick = ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.props.onForgotPasswordClick();
|
this.props.onForgotPasswordClick();
|
||||||
}
|
};
|
||||||
|
|
||||||
async onSubmitForm(ev) {
|
private onSubmitForm = async ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
const allFieldsValid = await this.verifyFieldsBeforeSubmit();
|
const allFieldsValid = await this.verifyFieldsBeforeSubmit();
|
||||||
|
@ -112,83 +109,78 @@ export default class PasswordLogin extends React.Component {
|
||||||
let phoneNumber = null;
|
let phoneNumber = null;
|
||||||
|
|
||||||
switch (this.state.loginType) {
|
switch (this.state.loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case LoginField.Email:
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case LoginField.MatrixId:
|
||||||
username = this.props.username;
|
username = this.props.username;
|
||||||
break;
|
break;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE:
|
case LoginField.Phone:
|
||||||
phoneCountry = this.props.phoneCountry;
|
phoneCountry = this.props.phoneCountry;
|
||||||
phoneNumber = this.props.phoneNumber;
|
phoneNumber = this.props.phoneNumber;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onSubmit(
|
this.props.onSubmit(username, phoneCountry, phoneNumber, this.state.password);
|
||||||
username,
|
};
|
||||||
phoneCountry,
|
|
||||||
phoneNumber,
|
|
||||||
this.state.password,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onUsernameChanged(ev) {
|
private onUsernameChanged = ev => {
|
||||||
this.props.onUsernameChanged(ev.target.value);
|
this.props.onUsernameChanged(ev.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
onUsernameFocus() {
|
private onUsernameFocus = () => {
|
||||||
if (this.state.loginType === PasswordLogin.LOGIN_FIELD_MXID) {
|
if (this.state.loginType === LoginField.MatrixId) {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_mxid_focus");
|
CountlyAnalytics.instance.track("onboarding_login_mxid_focus");
|
||||||
} else {
|
} else {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_email_focus");
|
CountlyAnalytics.instance.track("onboarding_login_email_focus");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onUsernameBlur(ev) {
|
private onUsernameBlur = ev => {
|
||||||
if (this.state.loginType === PasswordLogin.LOGIN_FIELD_MXID) {
|
if (this.state.loginType === LoginField.MatrixId) {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_mxid_blur");
|
CountlyAnalytics.instance.track("onboarding_login_mxid_blur");
|
||||||
} else {
|
} else {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_email_blur");
|
CountlyAnalytics.instance.track("onboarding_login_email_blur");
|
||||||
}
|
}
|
||||||
this.props.onUsernameBlur(ev.target.value);
|
this.props.onUsernameBlur(ev.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
onLoginTypeChange(ev) {
|
private onLoginTypeChange = ev => {
|
||||||
const loginType = ev.target.value;
|
const loginType = ev.target.value;
|
||||||
this.setState({ loginType });
|
this.setState({ loginType });
|
||||||
this.props.onUsernameChanged(""); // Reset because email and username use the same state
|
this.props.onUsernameChanged(""); // 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) {
|
private onPhoneCountryChanged = country => {
|
||||||
this.props.onPhoneCountryChanged(country.iso2);
|
this.props.onPhoneCountryChanged(country.iso2);
|
||||||
}
|
};
|
||||||
|
|
||||||
onPhoneNumberChanged(ev) {
|
private onPhoneNumberChanged = ev => {
|
||||||
this.props.onPhoneNumberChanged(ev.target.value);
|
this.props.onPhoneNumberChanged(ev.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
onPhoneNumberFocus() {
|
private onPhoneNumberFocus = () => {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_phone_number_focus");
|
CountlyAnalytics.instance.track("onboarding_login_phone_number_focus");
|
||||||
}
|
};
|
||||||
|
|
||||||
onPhoneNumberBlur(ev) {
|
private onPhoneNumberBlur = ev => {
|
||||||
CountlyAnalytics.instance.track("onboarding_login_phone_number_blur");
|
CountlyAnalytics.instance.track("onboarding_login_phone_number_blur");
|
||||||
}
|
};
|
||||||
|
|
||||||
onPasswordChanged(ev) {
|
private onPasswordChanged = ev => {
|
||||||
this.setState({password: ev.target.value});
|
this.setState({password: ev.target.value});
|
||||||
}
|
};
|
||||||
|
|
||||||
async verifyFieldsBeforeSubmit() {
|
private async verifyFieldsBeforeSubmit() {
|
||||||
// Blur the active element if any, so we first run its blur validation,
|
// Blur the active element if any, so we first run its blur validation,
|
||||||
// which is less strict than the pass we're about to do below for all fields.
|
// which is less strict than the pass we're about to do below for all fields.
|
||||||
const activeElement = document.activeElement;
|
const activeElement = document.activeElement as HTMLElement;
|
||||||
if (activeElement) {
|
if (activeElement) {
|
||||||
activeElement.blur();
|
activeElement.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldIDsInDisplayOrder = [
|
const fieldIDsInDisplayOrder = [
|
||||||
this.state.loginType,
|
this.state.loginType,
|
||||||
PasswordLogin.LOGIN_FIELD_PASSWORD,
|
LoginField.Password,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Run all fields with stricter validation that no longer allows empty
|
// Run all fields with stricter validation that no longer allows empty
|
||||||
|
@ -226,7 +218,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
allFieldsValid() {
|
private allFieldsValid() {
|
||||||
const keys = Object.keys(this.state.fieldValid);
|
const keys = Object.keys(this.state.fieldValid);
|
||||||
for (let i = 0; i < keys.length; ++i) {
|
for (let i = 0; i < keys.length; ++i) {
|
||||||
if (!this.state.fieldValid[keys[i]]) {
|
if (!this.state.fieldValid[keys[i]]) {
|
||||||
|
@ -236,7 +228,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
findFirstInvalidField(fieldIDs) {
|
private findFirstInvalidField(fieldIDs: LoginField[]) {
|
||||||
for (const fieldID of fieldIDs) {
|
for (const fieldID of fieldIDs) {
|
||||||
if (!this.state.fieldValid[fieldID] && this[fieldID]) {
|
if (!this.state.fieldValid[fieldID] && this[fieldID]) {
|
||||||
return this[fieldID];
|
return this[fieldID];
|
||||||
|
@ -245,7 +237,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
markFieldValid(fieldID, valid) {
|
private markFieldValid(fieldID: LoginField, valid: boolean) {
|
||||||
const { fieldValid } = this.state;
|
const { fieldValid } = this.state;
|
||||||
fieldValid[fieldID] = valid;
|
fieldValid[fieldID] = valid;
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -253,7 +245,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
validateUsernameRules = withValidation({
|
private validateUsernameRules = withValidation({
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
key: "required",
|
key: "required",
|
||||||
|
@ -265,13 +257,13 @@ export default class PasswordLogin extends React.Component {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
onUsernameValidate = async (fieldState) => {
|
private onUsernameValidate = async (fieldState) => {
|
||||||
const result = await this.validateUsernameRules(fieldState);
|
const result = await this.validateUsernameRules(fieldState);
|
||||||
this.markFieldValid(PasswordLogin.LOGIN_FIELD_MXID, result.valid);
|
this.markFieldValid(LoginField.MatrixId, result.valid);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
validateEmailRules = withValidation({
|
private validateEmailRules = withValidation({
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
key: "required",
|
key: "required",
|
||||||
|
@ -287,13 +279,13 @@ export default class PasswordLogin extends React.Component {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
onEmailValidate = async (fieldState) => {
|
private onEmailValidate = async (fieldState) => {
|
||||||
const result = await this.validateEmailRules(fieldState);
|
const result = await this.validateEmailRules(fieldState);
|
||||||
this.markFieldValid(PasswordLogin.LOGIN_FIELD_EMAIL, result.valid);
|
this.markFieldValid(LoginField.Email, result.valid);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
validatePhoneNumberRules = withValidation({
|
private validatePhoneNumberRules = withValidation({
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
key: "required",
|
key: "required",
|
||||||
|
@ -309,13 +301,13 @@ export default class PasswordLogin extends React.Component {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
onPhoneNumberValidate = async (fieldState) => {
|
private onPhoneNumberValidate = async (fieldState) => {
|
||||||
const result = await this.validatePhoneNumberRules(fieldState);
|
const result = await this.validatePhoneNumberRules(fieldState);
|
||||||
this.markFieldValid(PasswordLogin.LOGIN_FIELD_PHONE, result.valid);
|
this.markFieldValid(LoginField.Password, result.valid);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
validatePasswordRules = withValidation({
|
private validatePasswordRules = withValidation({
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
key: "required",
|
key: "required",
|
||||||
|
@ -327,19 +319,19 @@ export default class PasswordLogin extends React.Component {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
onPasswordValidate = async (fieldState) => {
|
private onPasswordValidate = async (fieldState) => {
|
||||||
const result = await this.validatePasswordRules(fieldState);
|
const result = await this.validatePasswordRules(fieldState);
|
||||||
this.markFieldValid(PasswordLogin.LOGIN_FIELD_PASSWORD, result.valid);
|
this.markFieldValid(LoginField.Password, result.valid);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoginField(loginType, autoFocus) {
|
private renderLoginField(loginType: IState["loginType"], autoFocus: boolean) {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
const classes = {
|
||||||
|
error: false,
|
||||||
const classes = {};
|
};
|
||||||
|
|
||||||
switch (loginType) {
|
switch (loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case LoginField.Email:
|
||||||
classes.error = this.props.loginIncorrect && !this.props.username;
|
classes.error = this.props.loginIncorrect && !this.props.username;
|
||||||
return <Field
|
return <Field
|
||||||
className={classNames(classes)}
|
className={classNames(classes)}
|
||||||
|
@ -355,9 +347,9 @@ export default class PasswordLogin extends React.Component {
|
||||||
disabled={this.props.disableSubmit}
|
disabled={this.props.disableSubmit}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
onValidate={this.onEmailValidate}
|
onValidate={this.onEmailValidate}
|
||||||
ref={field => this[PasswordLogin.LOGIN_FIELD_EMAIL] = field}
|
ref={field => this[LoginField.Email] = field}
|
||||||
/>;
|
/>;
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case LoginField.MatrixId:
|
||||||
classes.error = this.props.loginIncorrect && !this.props.username;
|
classes.error = this.props.loginIncorrect && !this.props.username;
|
||||||
return <Field
|
return <Field
|
||||||
className={classNames(classes)}
|
className={classNames(classes)}
|
||||||
|
@ -372,10 +364,9 @@ export default class PasswordLogin extends React.Component {
|
||||||
disabled={this.props.disableSubmit}
|
disabled={this.props.disableSubmit}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
onValidate={this.onUsernameValidate}
|
onValidate={this.onUsernameValidate}
|
||||||
ref={field => this[PasswordLogin.LOGIN_FIELD_MXID] = field}
|
ref={field => this[LoginField.MatrixId] = field}
|
||||||
/>;
|
/>;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE: {
|
case LoginField.Phone: {
|
||||||
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
|
||||||
classes.error = this.props.loginIncorrect && !this.props.phoneNumber;
|
classes.error = this.props.loginIncorrect && !this.props.phoneNumber;
|
||||||
|
|
||||||
const phoneCountry = <CountryDropdown
|
const phoneCountry = <CountryDropdown
|
||||||
|
@ -399,26 +390,23 @@ export default class PasswordLogin extends React.Component {
|
||||||
disabled={this.props.disableSubmit}
|
disabled={this.props.disableSubmit}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
onValidate={this.onPhoneNumberValidate}
|
onValidate={this.onPhoneNumberValidate}
|
||||||
ref={field => this[PasswordLogin.LOGIN_FIELD_PHONE] = field}
|
ref={field => this[LoginField.Password] = field}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoginEmpty() {
|
private isLoginEmpty() {
|
||||||
switch (this.state.loginType) {
|
switch (this.state.loginType) {
|
||||||
case PasswordLogin.LOGIN_FIELD_EMAIL:
|
case LoginField.Email:
|
||||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
case LoginField.MatrixId:
|
||||||
return !this.props.username;
|
return !this.props.username;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE:
|
case LoginField.Phone:
|
||||||
return !this.props.phoneCountry || !this.props.phoneNumber;
|
return !this.props.phoneCountry || !this.props.phoneNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
const SignInToText = sdk.getComponent('views.auth.SignInToText');
|
|
||||||
|
|
||||||
let forgotPasswordJsx;
|
let forgotPasswordJsx;
|
||||||
|
|
||||||
if (this.props.onForgotPasswordClick) {
|
if (this.props.onForgotPasswordClick) {
|
||||||
|
@ -458,22 +446,16 @@ export default class PasswordLogin extends React.Component {
|
||||||
onChange={this.onLoginTypeChange}
|
onChange={this.onLoginTypeChange}
|
||||||
disabled={this.props.disableSubmit}
|
disabled={this.props.disableSubmit}
|
||||||
>
|
>
|
||||||
<option
|
<option key={LoginField.MatrixId} value={LoginField.MatrixId}>
|
||||||
key={PasswordLogin.LOGIN_FIELD_MXID}
|
|
||||||
value={PasswordLogin.LOGIN_FIELD_MXID}
|
|
||||||
>
|
|
||||||
{_t('Username')}
|
{_t('Username')}
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
key={PasswordLogin.LOGIN_FIELD_EMAIL}
|
key={LoginField.Email}
|
||||||
value={PasswordLogin.LOGIN_FIELD_EMAIL}
|
value={LoginField.Email}
|
||||||
>
|
>
|
||||||
{_t('Email address')}
|
{_t('Email address')}
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option key={LoginField.Password} value={LoginField.Password}>
|
||||||
key={PasswordLogin.LOGIN_FIELD_PHONE}
|
|
||||||
value={PasswordLogin.LOGIN_FIELD_PHONE}
|
|
||||||
>
|
|
||||||
{_t('Phone')}
|
{_t('Phone')}
|
||||||
</option>
|
</option>
|
||||||
</Field>
|
</Field>
|
||||||
|
@ -498,7 +480,7 @@ export default class PasswordLogin extends React.Component {
|
||||||
disabled={this.props.disableSubmit}
|
disabled={this.props.disableSubmit}
|
||||||
autoFocus={autoFocusPassword}
|
autoFocus={autoFocusPassword}
|
||||||
onValidate={this.onPasswordValidate}
|
onValidate={this.onPasswordValidate}
|
||||||
ref={field => this[PasswordLogin.LOGIN_FIELD_PASSWORD] = field}
|
ref={field => this[LoginField.Password] = field}
|
||||||
/>
|
/>
|
||||||
{forgotPasswordJsx}
|
{forgotPasswordJsx}
|
||||||
{ !this.props.busy && <input className="mx_Login_submit"
|
{ !this.props.busy && <input className="mx_Login_submit"
|
|
@ -32,7 +32,7 @@ interface IRule<T, D = void> {
|
||||||
|
|
||||||
interface IArgs<T, D = void> {
|
interface IArgs<T, D = void> {
|
||||||
rules: IRule<T, D>[];
|
rules: IRule<T, D>[];
|
||||||
description(this: T, derivedData: D): React.ReactChild;
|
description?(this: T, derivedData: D): React.ReactChild;
|
||||||
hideDescriptionIfValid?: boolean;
|
hideDescriptionIfValid?: boolean;
|
||||||
deriveData?(data: Data): Promise<D>;
|
deriveData?(data: Data): Promise<D>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue