Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
1990a4d39f
12 changed files with 143 additions and 150 deletions
|
@ -36,7 +36,7 @@ limitations under the License.
|
||||||
color: $primary-fg-color;
|
color: $primary-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_editServerDetails {
|
.mx_AuthBody_editServerDetails {
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -47,21 +47,21 @@ limitations under the License.
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_fieldRow {
|
.mx_AuthBody_fieldRow {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_fieldRow > * {
|
.mx_AuthBody_fieldRow > * {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_fieldRow > *:first-child {
|
.mx_AuthBody_fieldRow > *:first-child {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_fieldRow > *:last-child {
|
.mx_AuthBody_fieldRow > *:last-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ limitations under the License.
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_changeFlow {
|
.mx_AuthBody_changeFlow {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_Auth_language {
|
.mx_AuthBody_language {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_language .mx_Dropdown_input {
|
.mx_AuthBody_language .mx_Dropdown_input {
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: $authpage-lang-color;
|
color: $authpage-lang-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Auth_language .mx_Dropdown_arrow {
|
.mx_AuthBody_language .mx_Dropdown_arrow {
|
||||||
background: $authpage-lang-color;
|
background: $authpage-lang-color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 OpenMarket Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions for applying common thematic effects to UI elements.
|
|
||||||
* Ideally this would be themeable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Velocity from 'velocity-vector';
|
|
||||||
import 'velocity-vector/velocity.ui';
|
|
||||||
|
|
||||||
export function fieldInputIncorrect(element) {
|
|
||||||
Velocity(element, "callout.shake", 300);
|
|
||||||
}
|
|
|
@ -1892,7 +1892,6 @@ export default React.createClass({
|
||||||
idSid={this.state.register_id_sid}
|
idSid={this.state.register_id_sid}
|
||||||
email={this.props.startingFragmentQueryParams.email}
|
email={this.props.startingFragmentQueryParams.email}
|
||||||
referrer={this.props.startingFragmentQueryParams.referrer}
|
referrer={this.props.startingFragmentQueryParams.referrer}
|
||||||
defaultServerName={this.getDefaultServerName()}
|
|
||||||
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
|
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
|
||||||
defaultHsUrl={this.getDefaultHsUrl()}
|
defaultHsUrl={this.getDefaultHsUrl()}
|
||||||
defaultIsUrl={this.getDefaultIsUrl()}
|
defaultIsUrl={this.getDefaultIsUrl()}
|
||||||
|
@ -1932,7 +1931,6 @@ export default React.createClass({
|
||||||
<Login
|
<Login
|
||||||
onLoggedIn={Lifecycle.setLoggedIn}
|
onLoggedIn={Lifecycle.setLoggedIn}
|
||||||
onRegisterClick={this.onRegisterClick}
|
onRegisterClick={this.onRegisterClick}
|
||||||
defaultServerName={this.getDefaultServerName()}
|
|
||||||
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
|
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
|
||||||
defaultHsUrl={this.getDefaultHsUrl()}
|
defaultHsUrl={this.getDefaultHsUrl()}
|
||||||
defaultIsUrl={this.getDefaultIsUrl()}
|
defaultIsUrl={this.getDefaultIsUrl()}
|
||||||
|
|
|
@ -255,7 +255,7 @@ module.exports = React.createClass({
|
||||||
</form>
|
</form>
|
||||||
{ serverConfigSection }
|
{ serverConfigSection }
|
||||||
{ errorText }
|
{ errorText }
|
||||||
<a className="mx_Auth_changeFlow" onClick={this.onLoginClick} href="#">
|
<a className="mx_AuthBody_changeFlow" onClick={this.onLoginClick} href="#">
|
||||||
{ _t('Sign in instead') }
|
{ _t('Sign in instead') }
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -66,10 +66,6 @@ module.exports = React.createClass({
|
||||||
// different home server without confusing users.
|
// different home server without confusing users.
|
||||||
fallbackHsUrl: PropTypes.string,
|
fallbackHsUrl: PropTypes.string,
|
||||||
|
|
||||||
// The default server name to use when the user hasn't specified
|
|
||||||
// one. This is used when displaying the defaultHsUrl in the UI.
|
|
||||||
defaultServerName: PropTypes.string,
|
|
||||||
|
|
||||||
// An error passed along from higher up explaining that something
|
// An error passed along from higher up explaining that something
|
||||||
// went wrong when finding the defaultHsUrl.
|
// went wrong when finding the defaultHsUrl.
|
||||||
defaultServerDiscoveryError: PropTypes.string,
|
defaultServerDiscoveryError: PropTypes.string,
|
||||||
|
@ -265,7 +261,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onUsernameBlur: function(username) {
|
onUsernameBlur: function(username) {
|
||||||
this.setState({ username: username });
|
this.setState({
|
||||||
|
username: username,
|
||||||
|
discoveryError: null,
|
||||||
|
});
|
||||||
if (username[0] === "@") {
|
if (username[0] === "@") {
|
||||||
const serverName = username.split(':').slice(1).join(':');
|
const serverName = username.split(':').slice(1).join(':');
|
||||||
try {
|
try {
|
||||||
|
@ -285,16 +284,22 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onPhoneNumberChanged: function(phoneNumber) {
|
onPhoneNumberChanged: function(phoneNumber) {
|
||||||
// Validate the phone number entered
|
|
||||||
if (!PHONE_NUMBER_REGEX.test(phoneNumber)) {
|
|
||||||
this.setState({ errorText: _t('The phone number entered looks invalid') });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
phoneNumber: phoneNumber,
|
phoneNumber: phoneNumber,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onPhoneNumberBlur: function(phoneNumber) {
|
||||||
|
this.setState({
|
||||||
errorText: null,
|
errorText: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Validate the phone number entered
|
||||||
|
if (!PHONE_NUMBER_REGEX.test(phoneNumber)) {
|
||||||
|
this.setState({
|
||||||
|
errorText: _t('The phone number entered looks invalid'),
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onServerConfigChange: function(config) {
|
onServerConfigChange: function(config) {
|
||||||
|
@ -571,7 +576,7 @@ module.exports = React.createClass({
|
||||||
defaultHsUrl={this.props.defaultHsUrl}
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
defaultIsUrl={this.props.defaultIsUrl}
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onServerConfigChange={this.onServerConfigChange}
|
onServerConfigChange={this.onServerConfigChange}
|
||||||
delayTimeMs={1000}
|
delayTimeMs={250}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
case ServerType.ADVANCED:
|
case ServerType.ADVANCED:
|
||||||
|
@ -581,7 +586,7 @@ module.exports = React.createClass({
|
||||||
defaultHsUrl={this.props.defaultHsUrl}
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
defaultIsUrl={this.props.defaultIsUrl}
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onServerConfigChange={this.onServerConfigChange}
|
onServerConfigChange={this.onServerConfigChange}
|
||||||
delayTimeMs={1000}
|
delayTimeMs={250}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -649,10 +654,10 @@ module.exports = React.createClass({
|
||||||
onUsernameBlur={this.onUsernameBlur}
|
onUsernameBlur={this.onUsernameBlur}
|
||||||
onPhoneCountryChanged={this.onPhoneCountryChanged}
|
onPhoneCountryChanged={this.onPhoneCountryChanged}
|
||||||
onPhoneNumberChanged={this.onPhoneNumberChanged}
|
onPhoneNumberChanged={this.onPhoneNumberChanged}
|
||||||
|
onPhoneNumberBlur={this.onPhoneNumberBlur}
|
||||||
onForgotPasswordClick={this.props.onForgotPasswordClick}
|
onForgotPasswordClick={this.props.onForgotPasswordClick}
|
||||||
loginIncorrect={this.state.loginIncorrect}
|
loginIncorrect={this.state.loginIncorrect}
|
||||||
hsUrl={this.state.enteredHomeserverUrl}
|
hsUrl={this.state.enteredHomeserverUrl}
|
||||||
hsName={this.props.defaultServerName}
|
|
||||||
disableSubmit={this.state.findingHomeserver}
|
disableSubmit={this.state.findingHomeserver}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -684,7 +689,7 @@ module.exports = React.createClass({
|
||||||
let loginAsGuestJsx;
|
let loginAsGuestJsx;
|
||||||
if (this.props.enableGuest) {
|
if (this.props.enableGuest) {
|
||||||
loginAsGuestJsx =
|
loginAsGuestJsx =
|
||||||
<a className="mx_Auth_changeFlow" onClick={this._onLoginAsGuestClick} href="#">
|
<a className="mx_AuthBody_changeFlow" onClick={this._onLoginAsGuestClick} href="#">
|
||||||
{ _t('Try the app first') }
|
{ _t('Try the app first') }
|
||||||
</a>;
|
</a>;
|
||||||
}
|
}
|
||||||
|
@ -709,7 +714,7 @@ module.exports = React.createClass({
|
||||||
{ errorTextSection }
|
{ errorTextSection }
|
||||||
{ this.renderServerComponentForStep() }
|
{ this.renderServerComponentForStep() }
|
||||||
{ this.renderLoginComponentForStep() }
|
{ this.renderLoginComponentForStep() }
|
||||||
<a className="mx_Auth_changeFlow" onClick={this.onRegisterClick} href="#">
|
<a className="mx_AuthBody_changeFlow" onClick={this.onRegisterClick} href="#">
|
||||||
{ _t('Create account') }
|
{ _t('Create account') }
|
||||||
</a>
|
</a>
|
||||||
{ loginAsGuestJsx }
|
{ loginAsGuestJsx }
|
||||||
|
|
|
@ -56,10 +56,6 @@ module.exports = React.createClass({
|
||||||
email: PropTypes.string,
|
email: PropTypes.string,
|
||||||
referrer: PropTypes.string,
|
referrer: PropTypes.string,
|
||||||
|
|
||||||
// The default server name to use when the user hasn't specified
|
|
||||||
// one. This is used when displaying the defaultHsUrl in the UI.
|
|
||||||
defaultServerName: PropTypes.string,
|
|
||||||
|
|
||||||
// An error passed along from higher up explaining that something
|
// An error passed along from higher up explaining that something
|
||||||
// went wrong when finding the defaultHsUrl.
|
// went wrong when finding the defaultHsUrl.
|
||||||
defaultServerDiscoveryError: PropTypes.string,
|
defaultServerDiscoveryError: PropTypes.string,
|
||||||
|
@ -151,6 +147,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_replaceClient: async function() {
|
_replaceClient: async function() {
|
||||||
|
this.setState({
|
||||||
|
errorText: null,
|
||||||
|
});
|
||||||
this._matrixClient = Matrix.createClient({
|
this._matrixClient = Matrix.createClient({
|
||||||
baseUrl: this.state.hsUrl,
|
baseUrl: this.state.hsUrl,
|
||||||
idBaseUrl: this.state.isUrl,
|
idBaseUrl: this.state.isUrl,
|
||||||
|
@ -390,7 +389,7 @@ module.exports = React.createClass({
|
||||||
defaultHsUrl={this.props.defaultHsUrl}
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
defaultIsUrl={this.props.defaultIsUrl}
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onServerConfigChange={this.onServerConfigChange}
|
onServerConfigChange={this.onServerConfigChange}
|
||||||
delayTimeMs={1000}
|
delayTimeMs={250}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
case ServerType.ADVANCED:
|
case ServerType.ADVANCED:
|
||||||
|
@ -400,7 +399,7 @@ module.exports = React.createClass({
|
||||||
defaultHsUrl={this.props.defaultHsUrl}
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
defaultIsUrl={this.props.defaultIsUrl}
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onServerConfigChange={this.onServerConfigChange}
|
onServerConfigChange={this.onServerConfigChange}
|
||||||
delayTimeMs={1000}
|
delayTimeMs={250}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -470,7 +469,6 @@ module.exports = React.createClass({
|
||||||
onEditServerDetailsClick={onEditServerDetailsClick}
|
onEditServerDetailsClick={onEditServerDetailsClick}
|
||||||
flows={this.state.flows}
|
flows={this.state.flows}
|
||||||
hsUrl={this.state.hsUrl}
|
hsUrl={this.state.hsUrl}
|
||||||
hsName={this.props.defaultServerName}
|
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -489,7 +487,7 @@ module.exports = React.createClass({
|
||||||
let signIn;
|
let signIn;
|
||||||
if (!this.state.doingUIAuth) {
|
if (!this.state.doingUIAuth) {
|
||||||
signIn = (
|
signIn = (
|
||||||
<a className="mx_Auth_changeFlow" onClick={this.onLoginClick} href="#">
|
<a className="mx_AuthBody_changeFlow" onClick={this.onLoginClick} href="#">
|
||||||
{ _t('Sign in instead') }
|
{ _t('Sign in instead') }
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default function LanguageSelector() {
|
||||||
if (SdkConfig.get()['disable_login_language_selector']) return <div />;
|
if (SdkConfig.get()['disable_login_language_selector']) return <div />;
|
||||||
|
|
||||||
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown');
|
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown');
|
||||||
return <LanguageDropdown className="mx_Auth_language"
|
return <LanguageDropdown className="mx_AuthBody_language"
|
||||||
onOptionChange={onChange}
|
onOptionChange={onChange}
|
||||||
value={getCurrentLanguage()}
|
value={getCurrentLanguage()}
|
||||||
/>;
|
/>;
|
||||||
|
|
|
@ -77,17 +77,18 @@ export default class ModularServerConfig extends React.PureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onHomeserverChanged = (ev) => {
|
onHomeserverBlur = (ev) => {
|
||||||
this.setState({hsUrl: ev.target.value}, () => {
|
|
||||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, () => {
|
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, () => {
|
||||||
let hsUrl = this.state.hsUrl.trim().replace(/\/$/, "");
|
|
||||||
if (hsUrl === "") hsUrl = this.props.defaultHsUrl;
|
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hsUrl,
|
hsUrl: this.state.hsUrl,
|
||||||
isUrl: this.props.defaultIsUrl,
|
isUrl: this.props.defaultIsUrl,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
onHomeserverChange = (ev) => {
|
||||||
|
const hsUrl = ev.target.value;
|
||||||
|
this.setState({ hsUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
_waitThenInvoke(existingTimeoutId, fn) {
|
_waitThenInvoke(existingTimeoutId, fn) {
|
||||||
|
@ -117,7 +118,8 @@ export default class ModularServerConfig extends React.PureComponent {
|
||||||
label={_t("Server Name")}
|
label={_t("Server Name")}
|
||||||
placeholder={this.props.defaultHsUrl}
|
placeholder={this.props.defaultHsUrl}
|
||||||
value={this.state.hsUrl}
|
value={this.state.hsUrl}
|
||||||
onChange={this.onHomeserverChanged}
|
onBlur={this.onHomeserverBlur}
|
||||||
|
onChange={this.onHomeserverChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,7 +20,6 @@ import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import {fieldInputIncorrect} from '../../../UiEffects';
|
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,13 +34,13 @@ class PasswordLogin extends React.Component {
|
||||||
onPasswordChanged: function() {},
|
onPasswordChanged: function() {},
|
||||||
onPhoneCountryChanged: function() {},
|
onPhoneCountryChanged: function() {},
|
||||||
onPhoneNumberChanged: function() {},
|
onPhoneNumberChanged: function() {},
|
||||||
|
onPhoneNumberBlur: function() {},
|
||||||
initialUsername: "",
|
initialUsername: "",
|
||||||
initialPhoneCountry: "",
|
initialPhoneCountry: "",
|
||||||
initialPhoneNumber: "",
|
initialPhoneNumber: "",
|
||||||
initialPassword: "",
|
initialPassword: "",
|
||||||
loginIncorrect: false,
|
loginIncorrect: false,
|
||||||
hsUrl: "",
|
hsUrl: "",
|
||||||
hsName: null,
|
|
||||||
disableSubmit: false,
|
disableSubmit: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +60,7 @@ class PasswordLogin extends React.Component {
|
||||||
this.onLoginTypeChange = this.onLoginTypeChange.bind(this);
|
this.onLoginTypeChange = this.onLoginTypeChange.bind(this);
|
||||||
this.onPhoneCountryChanged = this.onPhoneCountryChanged.bind(this);
|
this.onPhoneCountryChanged = this.onPhoneCountryChanged.bind(this);
|
||||||
this.onPhoneNumberChanged = this.onPhoneNumberChanged.bind(this);
|
this.onPhoneNumberChanged = this.onPhoneNumberChanged.bind(this);
|
||||||
|
this.onPhoneNumberBlur = this.onPhoneNumberBlur.bind(this);
|
||||||
this.onPasswordChanged = this.onPasswordChanged.bind(this);
|
this.onPasswordChanged = this.onPasswordChanged.bind(this);
|
||||||
this.isLoginEmpty = this.isLoginEmpty.bind(this);
|
this.isLoginEmpty = this.isLoginEmpty.bind(this);
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,6 @@ class PasswordLogin extends React.Component {
|
||||||
this._loginField = null;
|
this._loginField = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if (!this.props.loginIncorrect && nextProps.loginIncorrect) {
|
|
||||||
fieldInputIncorrect(this.isLoginEmpty() ? this._loginField : this._passwordField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmitForm(ev) {
|
onSubmitForm(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
|
@ -130,7 +124,7 @@ class PasswordLogin extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onUsernameBlur(ev) {
|
onUsernameBlur(ev) {
|
||||||
this.props.onUsernameBlur(this.state.username);
|
this.props.onUsernameBlur(ev.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoginTypeChange(loginType) {
|
onLoginTypeChange(loginType) {
|
||||||
|
@ -154,6 +148,10 @@ class PasswordLogin extends React.Component {
|
||||||
this.props.onPhoneNumberChanged(ev.target.value);
|
this.props.onPhoneNumberChanged(ev.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPhoneNumberBlur(ev) {
|
||||||
|
this.props.onPhoneNumberBlur(ev.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
onPasswordChanged(ev) {
|
onPasswordChanged(ev) {
|
||||||
this.setState({password: ev.target.value});
|
this.setState({password: ev.target.value});
|
||||||
this.props.onPasswordChanged(ev.target.value);
|
this.props.onPasswordChanged(ev.target.value);
|
||||||
|
@ -215,6 +213,7 @@ class PasswordLogin extends React.Component {
|
||||||
type="text"
|
type="text"
|
||||||
name="phoneNumber"
|
name="phoneNumber"
|
||||||
onChange={this.onPhoneNumberChanged}
|
onChange={this.onPhoneNumberChanged}
|
||||||
|
onBlur={this.onPhoneNumberBlur}
|
||||||
placeholder={_t("Mobile phone number")}
|
placeholder={_t("Mobile phone number")}
|
||||||
value={this.state.phoneNumber}
|
value={this.state.phoneNumber}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
@ -251,20 +250,18 @@ class PasswordLogin extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
let yourMatrixAccountText = _t('Your account');
|
let yourMatrixAccountText = _t('Your account');
|
||||||
if (this.props.hsName) {
|
|
||||||
yourMatrixAccountText = _t('Your %(serverName)s account', {serverName: this.props.hsName});
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
const parsedHsUrl = new URL(this.props.hsUrl);
|
const parsedHsUrl = new URL(this.props.hsUrl);
|
||||||
yourMatrixAccountText = _t('Your %(serverName)s account', {serverName: parsedHsUrl.hostname});
|
yourMatrixAccountText = _t('Your %(serverName)s account', {
|
||||||
|
serverName: parsedHsUrl.hostname,
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let editLink = null;
|
let editLink = null;
|
||||||
if (this.props.onEditServerDetailsClick) {
|
if (this.props.onEditServerDetailsClick) {
|
||||||
editLink = <a className="mx_Auth_editServerDetails"
|
editLink = <a className="mx_AuthBody_editServerDetails"
|
||||||
href="#" onClick={this.props.onEditServerDetailsClick}
|
href="#" onClick={this.props.onEditServerDetailsClick}
|
||||||
>
|
>
|
||||||
{_t('Edit')}
|
{_t('Edit')}
|
||||||
|
@ -341,7 +338,6 @@ PasswordLogin.propTypes = {
|
||||||
onPhoneNumberChanged: PropTypes.func,
|
onPhoneNumberChanged: PropTypes.func,
|
||||||
onPasswordChanged: PropTypes.func,
|
onPasswordChanged: PropTypes.func,
|
||||||
loginIncorrect: PropTypes.bool,
|
loginIncorrect: PropTypes.bool,
|
||||||
hsName: PropTypes.string,
|
|
||||||
disableSubmit: PropTypes.bool,
|
disableSubmit: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { fieldInputIncorrect } from '../../../UiEffects';
|
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import Email from '../../../email';
|
import Email from '../../../email';
|
||||||
import { looksValid as phoneNumberLooksValid } from '../../../phonenumber';
|
import { looksValid as phoneNumberLooksValid } from '../../../phonenumber';
|
||||||
|
@ -51,6 +50,7 @@ module.exports = React.createClass({
|
||||||
onRegisterClick: PropTypes.func.isRequired, // onRegisterClick(Object) => ?Promise
|
onRegisterClick: PropTypes.func.isRequired, // onRegisterClick(Object) => ?Promise
|
||||||
onEditServerDetailsClick: PropTypes.func,
|
onEditServerDetailsClick: PropTypes.func,
|
||||||
flows: PropTypes.arrayOf(PropTypes.object).isRequired,
|
flows: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
hsUrl: PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -78,11 +78,11 @@ module.exports = React.createClass({
|
||||||
// is the one from the first invalid field.
|
// is the one from the first invalid field.
|
||||||
// It's not super ideal that this just calls
|
// It's not super ideal that this just calls
|
||||||
// onError once for each invalid field.
|
// onError once for each invalid field.
|
||||||
this.validateField(FIELD_PASSWORD_CONFIRM);
|
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
||||||
this.validateField(FIELD_PASSWORD);
|
this.validateField(FIELD_PASSWORD, ev.type);
|
||||||
this.validateField(FIELD_USERNAME);
|
this.validateField(FIELD_USERNAME, ev.type);
|
||||||
this.validateField(FIELD_PHONE_NUMBER);
|
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||||
this.validateField(FIELD_EMAIL);
|
this.validateField(FIELD_EMAIL, ev.type);
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.allFieldsValid()) {
|
if (this.allFieldsValid()) {
|
||||||
|
@ -139,9 +139,10 @@ module.exports = React.createClass({
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateField: function(fieldID) {
|
validateField: function(fieldID, eventType) {
|
||||||
const pwd1 = this.refs.password.value.trim();
|
const pwd1 = this.refs.password.value.trim();
|
||||||
const pwd2 = this.refs.passwordConfirm.value.trim();
|
const pwd2 = this.refs.passwordConfirm.value.trim();
|
||||||
|
const allowEmpty = eventType === "blur";
|
||||||
|
|
||||||
switch (fieldID) {
|
switch (fieldID) {
|
||||||
case FIELD_EMAIL: {
|
case FIELD_EMAIL: {
|
||||||
|
@ -162,7 +163,9 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
case FIELD_USERNAME: {
|
case FIELD_USERNAME: {
|
||||||
const username = this.refs.username.value.trim();
|
const username = this.refs.username.value.trim();
|
||||||
if (!SAFE_LOCALPART_REGEX.test(username)) {
|
if (allowEmpty && username === '') {
|
||||||
|
this.markFieldValid(fieldID, true);
|
||||||
|
} else if (!SAFE_LOCALPART_REGEX.test(username)) {
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
fieldID,
|
fieldID,
|
||||||
false,
|
false,
|
||||||
|
@ -180,7 +183,9 @@ module.exports = React.createClass({
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FIELD_PASSWORD:
|
case FIELD_PASSWORD:
|
||||||
if (pwd1 == '') {
|
if (allowEmpty && pwd1 === "") {
|
||||||
|
this.markFieldValid(fieldID, true);
|
||||||
|
} else if (pwd1 == '') {
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
fieldID,
|
fieldID,
|
||||||
false,
|
false,
|
||||||
|
@ -210,7 +215,6 @@ module.exports = React.createClass({
|
||||||
fieldValid[fieldID] = val;
|
fieldValid[fieldID] = val;
|
||||||
this.setState({fieldValid: fieldValid});
|
this.setState({fieldValid: fieldValid});
|
||||||
if (!val) {
|
if (!val) {
|
||||||
fieldInputIncorrect(this.fieldElementById(fieldID));
|
|
||||||
this.props.onError(errorCode);
|
this.props.onError(errorCode);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -239,13 +243,33 @@ module.exports = React.createClass({
|
||||||
return cls;
|
return cls;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPhoneCountryChange(newVal) {
|
onEmailBlur(ev) {
|
||||||
|
this.validateField(FIELD_EMAIL, ev.type);
|
||||||
|
},
|
||||||
|
|
||||||
|
onPasswordBlur(ev) {
|
||||||
|
this.validateField(FIELD_PASSWORD, ev.type);
|
||||||
|
},
|
||||||
|
|
||||||
|
onPasswordConfirmBlur(ev) {
|
||||||
|
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
|
||||||
|
},
|
||||||
|
|
||||||
|
onPhoneCountryChange(newVal) {
|
||||||
this.setState({
|
this.setState({
|
||||||
phoneCountry: newVal.iso2,
|
phoneCountry: newVal.iso2,
|
||||||
phonePrefix: newVal.prefix,
|
phonePrefix: newVal.prefix,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onPhoneNumberBlur(ev) {
|
||||||
|
this.validateField(FIELD_PHONE_NUMBER, ev.type);
|
||||||
|
},
|
||||||
|
|
||||||
|
onUsernameBlur(ev) {
|
||||||
|
this.validateField(FIELD_USERNAME, ev.type);
|
||||||
|
},
|
||||||
|
|
||||||
_authStepIsRequired(step) {
|
_authStepIsRequired(step) {
|
||||||
// A step is required if no flow exists which does not include that step
|
// A step is required if no flow exists which does not include that step
|
||||||
// (Notwithstanding setups like either email or msisdn being required)
|
// (Notwithstanding setups like either email or msisdn being required)
|
||||||
|
@ -255,14 +279,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const self = this;
|
|
||||||
|
|
||||||
let yourMatrixAccountText = _t('Create your account');
|
let yourMatrixAccountText = _t('Create your account');
|
||||||
if (this.props.hsName) {
|
|
||||||
yourMatrixAccountText = _t('Create your %(serverName)s account', {
|
|
||||||
serverName: this.props.hsName,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
const parsedHsUrl = new URL(this.props.hsUrl);
|
const parsedHsUrl = new URL(this.props.hsUrl);
|
||||||
yourMatrixAccountText = _t('Create your %(serverName)s account', {
|
yourMatrixAccountText = _t('Create your %(serverName)s account', {
|
||||||
|
@ -271,11 +288,10 @@ module.exports = React.createClass({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let editLink = null;
|
let editLink = null;
|
||||||
if (this.props.onEditServerDetailsClick) {
|
if (this.props.onEditServerDetailsClick) {
|
||||||
editLink = <a className="mx_Auth_editServerDetails"
|
editLink = <a className="mx_AuthBody_editServerDetails"
|
||||||
href="#" onClick={this.props.onEditServerDetailsClick}
|
href="#" onClick={this.props.onEditServerDetailsClick}
|
||||||
>
|
>
|
||||||
{_t('Edit')}
|
{_t('Edit')}
|
||||||
|
@ -292,8 +308,8 @@ module.exports = React.createClass({
|
||||||
autoFocus={true} placeholder={emailPlaceholder}
|
autoFocus={true} placeholder={emailPlaceholder}
|
||||||
defaultValue={this.props.defaultEmail}
|
defaultValue={this.props.defaultEmail}
|
||||||
className={this._classForField(FIELD_EMAIL, 'mx_Login_field')}
|
className={this._classForField(FIELD_EMAIL, 'mx_Login_field')}
|
||||||
onBlur={function() {self.validateField(FIELD_EMAIL);}}
|
onBlur={this.onEmailBlur}
|
||||||
value={self.state.email} />
|
value={this.state.email} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -305,11 +321,12 @@ module.exports = React.createClass({
|
||||||
_t("Phone (optional)");
|
_t("Phone (optional)");
|
||||||
phoneSection = (
|
phoneSection = (
|
||||||
<div className="mx_Login_phoneSection">
|
<div className="mx_Login_phoneSection">
|
||||||
<CountryDropdown ref="phone_country" onOptionChange={this._onPhoneCountryChange}
|
<CountryDropdown ref="phone_country"
|
||||||
className="mx_Login_phoneCountry mx_Login_field_prefix"
|
className="mx_Login_phoneCountry mx_Login_field_prefix"
|
||||||
value={this.state.phoneCountry}
|
value={this.state.phoneCountry}
|
||||||
isSmall={true}
|
isSmall={true}
|
||||||
showPrefix={true}
|
showPrefix={true}
|
||||||
|
onOptionChange={this.onPhoneCountryChange}
|
||||||
/>
|
/>
|
||||||
<input type="text" ref="phoneNumber"
|
<input type="text" ref="phoneNumber"
|
||||||
placeholder={phonePlaceholder}
|
placeholder={phonePlaceholder}
|
||||||
|
@ -320,8 +337,8 @@ module.exports = React.createClass({
|
||||||
'mx_Login_field',
|
'mx_Login_field',
|
||||||
'mx_Login_field_has_prefix',
|
'mx_Login_field_has_prefix',
|
||||||
)}
|
)}
|
||||||
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
onBlur={this.onPhoneNumberBlur}
|
||||||
value={self.state.phoneNumber}
|
value={this.state.phoneNumber}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -340,24 +357,24 @@ module.exports = React.createClass({
|
||||||
{editLink}
|
{editLink}
|
||||||
</h3>
|
</h3>
|
||||||
<form onSubmit={this.onSubmit}>
|
<form onSubmit={this.onSubmit}>
|
||||||
<div className="mx_Auth_fieldRow">
|
<div className="mx_AuthBody_fieldRow">
|
||||||
<input type="text" ref="username"
|
<input type="text" ref="username"
|
||||||
placeholder={placeholderUsername} defaultValue={this.props.defaultUsername}
|
placeholder={placeholderUsername} defaultValue={this.props.defaultUsername}
|
||||||
className={this._classForField(FIELD_USERNAME, 'mx_Login_field')}
|
className={this._classForField(FIELD_USERNAME, 'mx_Login_field')}
|
||||||
onBlur={function() {self.validateField(FIELD_USERNAME);}} />
|
onBlur={this.onUsernameBlur} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Auth_fieldRow">
|
<div className="mx_AuthBody_fieldRow">
|
||||||
<input type="password" ref="password"
|
<input type="password" ref="password"
|
||||||
className={this._classForField(FIELD_PASSWORD, 'mx_Login_field')}
|
className={this._classForField(FIELD_PASSWORD, 'mx_Login_field')}
|
||||||
onBlur={function() {self.validateField(FIELD_PASSWORD);}}
|
onBlur={this.onPasswordBlur}
|
||||||
placeholder={_t("Password")} defaultValue={this.props.defaultPassword} />
|
placeholder={_t("Password")} defaultValue={this.props.defaultPassword} />
|
||||||
<input type="password" ref="passwordConfirm"
|
<input type="password" ref="passwordConfirm"
|
||||||
placeholder={_t("Confirm")}
|
placeholder={_t("Confirm")}
|
||||||
className={this._classForField(FIELD_PASSWORD_CONFIRM, 'mx_Login_field')}
|
className={this._classForField(FIELD_PASSWORD_CONFIRM, 'mx_Login_field')}
|
||||||
onBlur={function() {self.validateField(FIELD_PASSWORD_CONFIRM);}}
|
onBlur={this.onPasswordConfirmBlur}
|
||||||
defaultValue={this.props.defaultPassword} />
|
defaultValue={this.props.defaultPassword} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Auth_fieldRow">
|
<div className="mx_AuthBody_fieldRow">
|
||||||
{ emailSection }
|
{ emailSection }
|
||||||
{ phoneSection }
|
{ phoneSection }
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -76,30 +76,32 @@ export default class ServerConfig extends React.PureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onHomeserverChanged = (ev) => {
|
onHomeserverBlur = (ev) => {
|
||||||
this.setState({hsUrl: ev.target.value}, () => {
|
|
||||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, () => {
|
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, () => {
|
||||||
let hsUrl = this.state.hsUrl.trim().replace(/\/$/, "");
|
|
||||||
if (hsUrl === "") hsUrl = this.props.defaultHsUrl;
|
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hsUrl,
|
hsUrl: this.state.hsUrl,
|
||||||
isUrl: this.state.isUrl,
|
isUrl: this.state.isUrl,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onIdentityServerChanged = (ev) => {
|
onHomeserverChange = (ev) => {
|
||||||
this.setState({isUrl: ev.target.value}, () => {
|
const hsUrl = ev.target.value;
|
||||||
|
this.setState({ hsUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
onIdentityServerBlur = (ev) => {
|
||||||
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, () => {
|
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, () => {
|
||||||
let isUrl = this.state.isUrl.trim().replace(/\/$/, "");
|
|
||||||
if (isUrl === "") isUrl = this.props.defaultIsUrl;
|
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hsUrl,
|
hsUrl: this.state.hsUrl,
|
||||||
isUrl: this.state.isUrl,
|
isUrl: this.state.isUrl,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
onIdentityServerChange = (ev) => {
|
||||||
|
const isUrl = ev.target.value;
|
||||||
|
this.setState({ isUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
_waitThenInvoke(existingTimeoutId, fn) {
|
_waitThenInvoke(existingTimeoutId, fn) {
|
||||||
|
@ -130,13 +132,15 @@ export default class ServerConfig extends React.PureComponent {
|
||||||
label={_t("Homeserver URL")}
|
label={_t("Homeserver URL")}
|
||||||
placeholder={this.props.defaultHsUrl}
|
placeholder={this.props.defaultHsUrl}
|
||||||
value={this.state.hsUrl}
|
value={this.state.hsUrl}
|
||||||
onChange={this.onHomeserverChanged}
|
onBlur={this.onHomeserverBlur}
|
||||||
|
onChange={this.onHomeserverChange}
|
||||||
/>
|
/>
|
||||||
<Field id="mx_ServerConfig_isUrl"
|
<Field id="mx_ServerConfig_isUrl"
|
||||||
label={_t("Identity Server URL")}
|
label={_t("Identity Server URL")}
|
||||||
placeholder={this.props.defaultIsUrl}
|
placeholder={this.props.defaultIsUrl}
|
||||||
value={this.state.isUrl}
|
value={this.state.isUrl}
|
||||||
onChange={this.onIdentityServerChanged}
|
onBlur={this.onIdentityServerBlur}
|
||||||
|
onChange={this.onIdentityServerChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue