From b9604d1fb5a9babeda29ab2153b633eb2081c83a Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Thu, 19 Aug 2021 09:12:22 +0200 Subject: [PATCH 1/4] Make ForgotPassword UX slightly more user friendly --- res/css/structures/auth/_Login.scss | 7 +++++ .../structures/auth/ForgotPassword.tsx | 27 ++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/res/css/structures/auth/_Login.scss b/res/css/structures/auth/_Login.scss index 9c98ca3a1c..390e091289 100644 --- a/res/css/structures/auth/_Login.scss +++ b/res/css/structures/auth/_Login.scss @@ -96,3 +96,10 @@ div.mx_AccessibleButton_kind_link.mx_Login_forgot { cursor: not-allowed; } } +.mx_Login--spinner { + display: flex; + justify-content: center; + align-items: center; + align-content: center; + padding: 14px; +} diff --git a/src/components/structures/auth/ForgotPassword.tsx b/src/components/structures/auth/ForgotPassword.tsx index f978a6cded..45ef86d793 100644 --- a/src/components/structures/auth/ForgotPassword.tsx +++ b/src/components/structures/auth/ForgotPassword.tsx @@ -31,6 +31,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent"; import { PASSWORD_MIN_SCORE } from '../../views/auth/RegistrationForm'; import { IValidationResult } from "../../views/elements/Validation"; +import InlineSpinner from '../../views/elements/InlineSpinner'; enum Phase { // Show the forgot password inputs @@ -66,13 +67,14 @@ interface IState { serverDeadError: string; passwordFieldValid: boolean; + currentHttpRequest?: Promise; } @replaceableComponent("structures.auth.ForgotPassword") export default class ForgotPassword extends React.Component { private reset: PasswordReset; - state = { + state: IState = { phase: Phase.Forgot, email: "", password: "", @@ -148,8 +150,10 @@ export default class ForgotPassword extends React.Component { console.error("onVerify called before submitPasswordReset!"); return; } + if (this.state.currentHttpRequest) return; + try { - await this.reset.checkEmailLinkClicked(); + await this.handleHttpRequest(this.reset.checkEmailLinkClicked()); this.setState({ phase: Phase.Done }); } catch (err) { this.showErrorDialog(err.message); @@ -158,9 +162,10 @@ export default class ForgotPassword extends React.Component { private onSubmitForm = async (ev: React.FormEvent): Promise => { ev.preventDefault(); + if (this.state.currentHttpRequest) return; // refresh the server errors, just in case the server came back online - await this.checkServerLiveliness(this.props.serverConfig); + await this.handleHttpRequest(this.checkServerLiveliness(this.props.serverConfig)); await this['password_field'].validate({ allowEmpty: false }); @@ -221,6 +226,17 @@ export default class ForgotPassword extends React.Component { }); } + private handleHttpRequest(request: Promise): Promise { + this.setState({ + currentHttpRequest: request, + }); + return request.finally(() => { + this.setState({ + currentHttpRequest: undefined, + }); + }); + } + renderForgot() { const Field = sdk.getComponent('elements.Field'); @@ -320,6 +336,9 @@ export default class ForgotPassword extends React.Component { type="button" onClick={this.onVerify} value={_t('I have verified my email address')} /> + { this.state.currentHttpRequest && ( +
) + } ; } @@ -357,6 +376,8 @@ export default class ForgotPassword extends React.Component { case Phase.Done: resetPasswordJsx = this.renderDone(); break; + default: + resetPasswordJsx =
; } return ( From 8fe28fe8648352ae6f1a2aa91b416025a6c29fd0 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk <3636685+Palid@users.noreply.github.com> Date: Thu, 19 Aug 2021 09:19:02 +0200 Subject: [PATCH 2/4] Update res/css/structures/auth/_Login.scss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Šimon Brandner --- res/css/structures/auth/_Login.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/structures/auth/_Login.scss b/res/css/structures/auth/_Login.scss index 390e091289..c4aaaca1d0 100644 --- a/res/css/structures/auth/_Login.scss +++ b/res/css/structures/auth/_Login.scss @@ -96,7 +96,7 @@ div.mx_AccessibleButton_kind_link.mx_Login_forgot { cursor: not-allowed; } } -.mx_Login--spinner { +.mx_Login_spinner { display: flex; justify-content: center; align-items: center; From 01ecdd2e6ba05a56a951b41bd94d51a161634433 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk <3636685+Palid@users.noreply.github.com> Date: Thu, 19 Aug 2021 10:08:37 +0200 Subject: [PATCH 3/4] Update src/components/structures/auth/ForgotPassword.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Šimon Brandner --- src/components/structures/auth/ForgotPassword.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/auth/ForgotPassword.tsx b/src/components/structures/auth/ForgotPassword.tsx index 45ef86d793..1ebc5303d6 100644 --- a/src/components/structures/auth/ForgotPassword.tsx +++ b/src/components/structures/auth/ForgotPassword.tsx @@ -377,7 +377,7 @@ export default class ForgotPassword extends React.Component { resetPasswordJsx = this.renderDone(); break; default: - resetPasswordJsx =
; + resetPasswordJsx =
; } return ( From f50d9b729f909b1829de134261b37a8d2d552a76 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk <3636685+Palid@users.noreply.github.com> Date: Thu, 19 Aug 2021 10:08:42 +0200 Subject: [PATCH 4/4] Update src/components/structures/auth/ForgotPassword.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Šimon Brandner --- src/components/structures/auth/ForgotPassword.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/auth/ForgotPassword.tsx b/src/components/structures/auth/ForgotPassword.tsx index 1ebc5303d6..24b47bfa03 100644 --- a/src/components/structures/auth/ForgotPassword.tsx +++ b/src/components/structures/auth/ForgotPassword.tsx @@ -337,7 +337,7 @@ export default class ForgotPassword extends React.Component { onClick={this.onVerify} value={_t('I have verified my email address')} /> { this.state.currentHttpRequest && ( -
) +
) } ; }