Improve no email warning during registration
This commit is contained in:
parent
6f6e850075
commit
2263280035
6 changed files with 159 additions and 31 deletions
|
@ -78,6 +78,7 @@
|
||||||
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
|
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
|
||||||
@import "./views/dialogs/_ModalWidgetDialog.scss";
|
@import "./views/dialogs/_ModalWidgetDialog.scss";
|
||||||
@import "./views/dialogs/_NewSessionReviewDialog.scss";
|
@import "./views/dialogs/_NewSessionReviewDialog.scss";
|
||||||
|
@import "./views/dialogs/_RegistrationEmailPromptDialog.scss";
|
||||||
@import "./views/dialogs/_RoomSettingsDialog.scss";
|
@import "./views/dialogs/_RoomSettingsDialog.scss";
|
||||||
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
|
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
|
||||||
@import "./views/dialogs/_RoomUpgradeDialog.scss";
|
@import "./views/dialogs/_RoomUpgradeDialog.scss";
|
||||||
|
|
28
res/css/views/dialogs/_RegistrationEmailPromptDialog.scss
Normal file
28
res/css/views/dialogs/_RegistrationEmailPromptDialog.scss
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.mx_RegistrationEmailPromptDialog {
|
||||||
|
width: 417px;
|
||||||
|
|
||||||
|
.mx_Dialog_content {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
color: $tertiary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_Dialog_primary {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,9 @@ import withValidation from '../elements/Validation';
|
||||||
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
|
||||||
import PassphraseField from "./PassphraseField";
|
import PassphraseField from "./PassphraseField";
|
||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
|
import Field from '../elements/Field';
|
||||||
|
import RegistrationEmailPromptDialog from '../dialogs/RegistrationEmailPromptDialog';
|
||||||
|
import QuestionDialog from '../dialogs/QuestionDialog';
|
||||||
|
|
||||||
enum RegistrationField {
|
enum RegistrationField {
|
||||||
Email = "field_email",
|
Email = "field_email",
|
||||||
|
@ -104,6 +107,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
|
|
||||||
private onSubmit = async ev => {
|
private onSubmit = async ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
ev.persist();
|
||||||
|
|
||||||
if (!this.props.canSubmit) return;
|
if (!this.props.canSubmit) return;
|
||||||
|
|
||||||
|
@ -116,36 +120,36 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
if (this.state.email === '') {
|
if (this.state.email === '') {
|
||||||
const haveIs = Boolean(this.props.serverConfig.isUrl);
|
const haveIs = Boolean(this.props.serverConfig.isUrl);
|
||||||
|
|
||||||
let desc;
|
|
||||||
if (this.props.serverRequiresIdServer && !haveIs) {
|
if (this.props.serverRequiresIdServer && !haveIs) {
|
||||||
desc = _t(
|
Modal.createTrackedDialog("No identity server no email", '', QuestionDialog, {
|
||||||
"No identity server is configured so you cannot add an email address in order to " +
|
title: _t("Warning!"),
|
||||||
"reset your password in the future.",
|
description: _t(
|
||||||
);
|
"No identity server is configured so you cannot add an email address in order to " +
|
||||||
|
"reset your password in the future.",
|
||||||
|
),
|
||||||
|
button: _t("Continue"),
|
||||||
|
onFinished: async (confirmed) => {
|
||||||
|
if (confirmed) this.doSubmit(ev);
|
||||||
|
},
|
||||||
|
});
|
||||||
} else if (this.showEmail()) {
|
} else if (this.showEmail()) {
|
||||||
desc = _t(
|
CountlyAnalytics.instance.track("onboarding_registration_submit_warn");
|
||||||
"If you don't specify an email address, you won't be able to reset your password. " +
|
Modal.createTrackedDialog("Email prompt dialog", '', RegistrationEmailPromptDialog, {
|
||||||
"Are you sure?",
|
onFinished: async (confirmed: boolean, email?: string) => {
|
||||||
);
|
if (confirmed) {
|
||||||
|
this.setState({
|
||||||
|
email,
|
||||||
|
}, () => {
|
||||||
|
this.doSubmit(ev);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// user can't set an e-mail so don't prompt them to
|
// user can't set an e-mail so don't prompt them to
|
||||||
this.doSubmit(ev);
|
this.doSubmit(ev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CountlyAnalytics.instance.track("onboarding_registration_submit_warn");
|
|
||||||
|
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
||||||
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
|
||||||
title: _t("Warning!"),
|
|
||||||
description: desc,
|
|
||||||
button: _t("Continue"),
|
|
||||||
onFinished: (confirmed) => {
|
|
||||||
if (confirmed) {
|
|
||||||
this.doSubmit(ev);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.doSubmit(ev);
|
this.doSubmit(ev);
|
||||||
}
|
}
|
||||||
|
@ -443,7 +447,6 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
if (!this.showEmail()) {
|
if (!this.showEmail()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
const emailPlaceholder = this.authStepIsRequired('m.login.email.identity') ?
|
const emailPlaceholder = this.authStepIsRequired('m.login.email.identity') ?
|
||||||
_t("Email") :
|
_t("Email") :
|
||||||
_t("Email (optional)");
|
_t("Email (optional)");
|
||||||
|
@ -473,7 +476,6 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPasswordConfirm() {
|
renderPasswordConfirm() {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
return <Field
|
return <Field
|
||||||
id="mx_RegistrationForm_passwordConfirm"
|
id="mx_RegistrationForm_passwordConfirm"
|
||||||
ref={field => this[RegistrationField.PasswordConfirm] = field}
|
ref={field => this[RegistrationField.PasswordConfirm] = field}
|
||||||
|
@ -493,7 +495,6 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
const phoneLabel = this.authStepIsRequired('m.login.msisdn') ?
|
const phoneLabel = this.authStepIsRequired('m.login.msisdn') ?
|
||||||
_t("Phone") :
|
_t("Phone") :
|
||||||
_t("Phone (optional)");
|
_t("Phone (optional)");
|
||||||
|
@ -515,7 +516,6 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUsername() {
|
renderUsername() {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
return <Field
|
return <Field
|
||||||
id="mx_RegistrationForm_username"
|
id="mx_RegistrationForm_username"
|
||||||
ref={field => this[RegistrationField.Username] = field}
|
ref={field => this[RegistrationField.Username] = field}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { _t } from '../../../languageHandler';
|
||||||
|
import { IDialogProps } from "./IDialogProps";
|
||||||
|
import {useRef, useState} from "react";
|
||||||
|
import Field from "../elements/Field";
|
||||||
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
|
import withValidation from "../elements/Validation";
|
||||||
|
import * as Email from "../../../email";
|
||||||
|
import BaseDialog from "./BaseDialog";
|
||||||
|
import DialogButtons from "../elements/DialogButtons";
|
||||||
|
|
||||||
|
interface IProps extends IDialogProps {
|
||||||
|
onFinished(continued: boolean, email?: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validation = withValidation({
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
key: "email",
|
||||||
|
test: ({ value }) => !value || Email.looksValid(value),
|
||||||
|
invalid: () => _t("Doesn't look like a valid email address"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const RegistrationEmailPromptDialog: React.FC<IProps> = ({onFinished}) => {
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const fieldRef = useRef<Field>();
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (email) {
|
||||||
|
const valid = await fieldRef.current.validate({ allowEmpty: false });
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
fieldRef.current.focus();
|
||||||
|
fieldRef.current.validate({ allowEmpty: false, focused: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFinished(true, email);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <BaseDialog
|
||||||
|
title={_t("Continuing without email")}
|
||||||
|
className="mx_RegistrationEmailPromptDialog"
|
||||||
|
contentId="mx_RegistrationEmailPromptDialog"
|
||||||
|
onFinished={() => onFinished(false)}
|
||||||
|
fixedWidth={false}
|
||||||
|
>
|
||||||
|
<div className="mx_Dialog_content" id="mx_RegistrationEmailPromptDialog">
|
||||||
|
<p>{_t("Just a heads up, if you don't add an email and forget your password, you could " +
|
||||||
|
"<b>permanently lose access to your account.</b>", {}, {
|
||||||
|
b: sub => <b>{sub}</b>,
|
||||||
|
})}</p>
|
||||||
|
<form onSubmit={onSubmit}>
|
||||||
|
<Field
|
||||||
|
ref={fieldRef}
|
||||||
|
type="text"
|
||||||
|
label={_t("Email (optional)")}
|
||||||
|
value={email}
|
||||||
|
onChange={ev => {
|
||||||
|
setEmail(ev.target.value);
|
||||||
|
}}
|
||||||
|
onValidate={async fieldState => await validation(fieldState)}
|
||||||
|
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_email2_focus")}
|
||||||
|
onBlur={() => CountlyAnalytics.instance.track("onboarding_registration_email2_blur")}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<DialogButtons
|
||||||
|
primaryButton={_t("Continue")}
|
||||||
|
onPrimaryButtonClick={onSubmit}
|
||||||
|
hasCancel={false}
|
||||||
|
/>
|
||||||
|
</BaseDialog>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RegistrationEmailPromptDialog;
|
|
@ -167,7 +167,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private async validate({ focused, allowEmpty = true }: {focused: boolean, allowEmpty?: boolean}) {
|
public async validate({ focused, allowEmpty = true }: {focused?: boolean, allowEmpty?: boolean}) {
|
||||||
if (!this.props.onValidate) {
|
if (!this.props.onValidate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,8 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
||||||
feedbackVisible: false,
|
feedbackVisible: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
|
|
@ -2045,6 +2045,10 @@
|
||||||
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
|
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
|
||||||
"If you didn’t sign in to this session, your account may be compromised.": "If you didn’t sign in to this session, your account may be compromised.",
|
"If you didn’t sign in to this session, your account may be compromised.": "If you didn’t sign in to this session, your account may be compromised.",
|
||||||
"This wasn't me": "This wasn't me",
|
"This wasn't me": "This wasn't me",
|
||||||
|
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
|
||||||
|
"Continuing without email": "Continuing without email",
|
||||||
|
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account.</b>": "Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account.</b>",
|
||||||
|
"Email (optional)": "Email (optional)",
|
||||||
"Please fill why you're reporting.": "Please fill why you're reporting.",
|
"Please fill why you're reporting.": "Please fill why you're reporting.",
|
||||||
"Report Content to Your Homeserver Administrator": "Report Content to Your Homeserver Administrator",
|
"Report Content to Your Homeserver Administrator": "Report Content to Your Homeserver Administrator",
|
||||||
"Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.",
|
"Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.",
|
||||||
|
@ -2226,7 +2230,6 @@
|
||||||
"Keep going...": "Keep going...",
|
"Keep going...": "Keep going...",
|
||||||
"Enter username": "Enter username",
|
"Enter username": "Enter username",
|
||||||
"Enter email address": "Enter email address",
|
"Enter email address": "Enter email address",
|
||||||
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
|
|
||||||
"Enter phone number": "Enter phone number",
|
"Enter phone number": "Enter phone number",
|
||||||
"Doesn't look like a valid phone number": "Doesn't look like a valid phone number",
|
"Doesn't look like a valid phone number": "Doesn't look like a valid phone number",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
|
@ -2236,14 +2239,12 @@
|
||||||
"Sign in with": "Sign in with",
|
"Sign in with": "Sign in with",
|
||||||
"Sign in": "Sign in",
|
"Sign in": "Sign in",
|
||||||
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "No identity server is configured so you cannot add an email address in order to reset your password in the future.",
|
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "No identity server is configured so you cannot add an email address in order to reset your password in the future.",
|
||||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
|
|
||||||
"Use an email address to recover your account": "Use an email address to recover your account",
|
"Use an email address to recover your account": "Use an email address to recover your account",
|
||||||
"Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)",
|
"Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)",
|
||||||
"Passwords don't match": "Passwords don't match",
|
"Passwords don't match": "Passwords don't match",
|
||||||
"Other users can invite you to rooms using your contact details": "Other users can invite you to rooms using your contact details",
|
"Other users can invite you to rooms using your contact details": "Other users can invite you to rooms using your contact details",
|
||||||
"Enter phone number (required on this homeserver)": "Enter phone number (required on this homeserver)",
|
"Enter phone number (required on this homeserver)": "Enter phone number (required on this homeserver)",
|
||||||
"Use lowercase letters, numbers, dashes and underscores only": "Use lowercase letters, numbers, dashes and underscores only",
|
"Use lowercase letters, numbers, dashes and underscores only": "Use lowercase letters, numbers, dashes and underscores only",
|
||||||
"Email (optional)": "Email (optional)",
|
|
||||||
"Phone (optional)": "Phone (optional)",
|
"Phone (optional)": "Phone (optional)",
|
||||||
"Register": "Register",
|
"Register": "Register",
|
||||||
"Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.",
|
"Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.",
|
||||||
|
|
Loading…
Reference in a new issue