@@ -31,6 +31,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
3131import { PASSWORD_MIN_SCORE } from '../../views/auth/RegistrationForm' ;
3232
3333import { IValidationResult } from "../../views/elements/Validation" ;
34+ import InlineSpinner from '../../views/elements/InlineSpinner' ;
3435
3536enum Phase {
3637 // Show the forgot password inputs
@@ -66,13 +67,14 @@ interface IState {
6667 serverDeadError : string ;
6768
6869 passwordFieldValid : boolean ;
70+ currentHttpRequest ?: Promise < any > ;
6971}
7072
7173@replaceableComponent ( "structures.auth.ForgotPassword" )
7274export default class ForgotPassword extends React . Component < IProps , IState > {
7375 private reset : PasswordReset ;
7476
75- state = {
77+ state : IState = {
7678 phase : Phase . Forgot ,
7779 email : "" ,
7880 password : "" ,
@@ -148,8 +150,10 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
148150 console . error ( "onVerify called before submitPasswordReset!" ) ;
149151 return ;
150152 }
153+ if ( this . state . currentHttpRequest ) return ;
154+
151155 try {
152- await this . reset . checkEmailLinkClicked ( ) ;
156+ await this . handleHttpRequest ( this . reset . checkEmailLinkClicked ( ) ) ;
153157 this . setState ( { phase : Phase . Done } ) ;
154158 } catch ( err ) {
155159 this . showErrorDialog ( err . message ) ;
@@ -158,9 +162,10 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
158162
159163 private onSubmitForm = async ( ev : React . FormEvent ) : Promise < void > => {
160164 ev . preventDefault ( ) ;
165+ if ( this . state . currentHttpRequest ) return ;
161166
162167 // refresh the server errors, just in case the server came back online
163- await this . checkServerLiveliness ( this . props . serverConfig ) ;
168+ await this . handleHttpRequest ( this . checkServerLiveliness ( this . props . serverConfig ) ) ;
164169
165170 await this [ 'password_field' ] . validate ( { allowEmpty : false } ) ;
166171
@@ -221,6 +226,17 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
221226 } ) ;
222227 }
223228
229+ private handleHttpRequest < T = unknown > ( request : Promise < T > ) : Promise < T > {
230+ this . setState ( {
231+ currentHttpRequest : request ,
232+ } ) ;
233+ return request . finally ( ( ) => {
234+ this . setState ( {
235+ currentHttpRequest : undefined ,
236+ } ) ;
237+ } ) ;
238+ }
239+
224240 renderForgot ( ) {
225241 const Field = sdk . getComponent ( 'elements.Field' ) ;
226242
@@ -320,6 +336,9 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
320336 type = "button"
321337 onClick = { this . onVerify }
322338 value = { _t ( 'I have verified my email address' ) } />
339+ { this . state . currentHttpRequest && (
340+ < div className = "mx_Login_spinner" > < InlineSpinner w = { 64 } h = { 64 } /> </ div > )
341+ }
323342 </ div > ;
324343 }
325344
@@ -357,6 +376,8 @@ export default class ForgotPassword extends React.Component<IProps, IState> {
357376 case Phase . Done :
358377 resetPasswordJsx = this . renderDone ( ) ;
359378 break ;
379+ default :
380+ resetPasswordJsx = < div className = "mx_Login_spinner" > < InlineSpinner w = { 64 } h = { 64 } /> </ div > ;
360381 }
361382
362383 return (
0 commit comments