From f64a269cccb1df05afb7aa9bab4e86afbdfe54ec Mon Sep 17 00:00:00 2001 From: Pankaj Basnet <165250380+pankaj-basnet@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:23:01 +0545 Subject: [PATCH 1/5] disable email verification button after initial click in UserProfileForm - Added `_isVerifying` state to track asynchronous verification process - Disabled OutlinedButton during active requests to prevent duplicate API calls - Added CircularProgressIndicator for visual feedback during loading - Included `mounted` checks to prevent memory leaks/crashes on post-await setState - Removed redundant verification check inside the onPressed callback --- lib/widgets/user/forms.dart | 54 ++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/widgets/user/forms.dart b/lib/widgets/user/forms.dart index 1ed19191e..be1f2e995 100644 --- a/lib/widgets/user/forms.dart +++ b/lib/widgets/user/forms.dart @@ -38,6 +38,7 @@ class _UserProfileFormState extends State { final _form = GlobalKey(); final emailController = TextEditingController(); + bool _isVerifying = false; @override void initState() { @@ -101,23 +102,44 @@ class _UserProfileFormState extends State { ), if (!widget._profile.emailVerified) OutlinedButton( - onPressed: () async { - // Email is already verified - if (widget._profile.emailVerified) { - return; - } + // If _isVerifying is true, setting onPressed to null disables the button + onPressed: _isVerifying + ? null + : () async { + setState(() { + _isVerifying = true; + }); - // Verify - await context.read().verifyEmail(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).verifiedEmailInfo(widget._profile.email), - ), - ), - ); - }, - child: Text(AppLocalizations.of(context).verify), + try { + // Verify + await context.read().verifyEmail(); + if (!context.mounted) return; + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of( + context, + ).verifiedEmailInfo(widget._profile.email), + ), + ), + ); + } + } catch (e) { + setState(() { + _isVerifying = false; + }); + } + }, + child: _isVerifying + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + : Text(AppLocalizations.of(context).verify), ), ElevatedButton( onPressed: () async { From 6d32ee613deafcddbe7895085d427daca36c065e Mon Sep 17 00:00:00 2001 From: Pankaj Basnet <165250380+pankaj-basnet@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:42:36 +0545 Subject: [PATCH 2/5] button disabled updated in UserProfileForm after verification email sent - Button becomes disabled immediately after click - Stays disabled after request succeeds - Re-enables only if request fails --- lib/widgets/user/forms.dart | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/widgets/user/forms.dart b/lib/widgets/user/forms.dart index be1f2e995..4b863a8e0 100644 --- a/lib/widgets/user/forms.dart +++ b/lib/widgets/user/forms.dart @@ -102,6 +102,13 @@ class _UserProfileFormState extends State { ), if (!widget._profile.emailVerified) OutlinedButton( + style: OutlinedButton.styleFrom( + // Applying the "Darker background" when disabled + disabledBackgroundColor: Colors.grey.shade300, + side: BorderSide( + color: _isVerifying ? Colors.grey : Colors.green, + ), + ), // If _isVerifying is true, setting onPressed to null disables the button onPressed: _isVerifying ? null @@ -131,15 +138,7 @@ class _UserProfileFormState extends State { }); } }, - child: _isVerifying - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - ), - ) - : Text(AppLocalizations.of(context).verify), + child: _isVerifying ? const Text("Email sent") : Text(AppLocalizations.of(context).verify), ), ElevatedButton( onPressed: () async { From 306df5dd918867d2e237592c4ad8bd53a93c9b05 Mon Sep 17 00:00:00 2001 From: Pankaj Basnet <165250380+pankaj-basnet@users.noreply.github.com> Date: Sun, 29 Mar 2026 03:57:31 +0545 Subject: [PATCH 3/5] Update app_en.arb , verifiedEmailSent for Email Sent --- lib/l10n/app_en.arb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d07fa2765..895888917 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -896,6 +896,7 @@ "unVerifiedEmail": "Unverified email", "verifiedEmailReason": "You need to verify your email to contribute exercises", "verifiedEmailInfo": "A verification email was sent to {email}", + "verifiedEmailSent": "Email Sent", "@verifiedEmailInfo": { "placeholders": { "email": { From 799663d672af306c8b4820433b12a21a5130fa39 Mon Sep 17 00:00:00 2001 From: Pankaj Basnet <165250380+pankaj-basnet@users.noreply.github.com> Date: Sun, 29 Mar 2026 04:09:39 +0545 Subject: [PATCH 4/5] Update UserProfileForm , removed disabled button style - Improve Verify button state handling in UserProfileScreen - Disable "Verify" button after user clicks it - Keep it disabled for the lifetime of the screen - Re-enable on request failure - Reset state when navigating away and back --- lib/widgets/user/forms.dart | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/widgets/user/forms.dart b/lib/widgets/user/forms.dart index 4b863a8e0..1157dac03 100644 --- a/lib/widgets/user/forms.dart +++ b/lib/widgets/user/forms.dart @@ -102,13 +102,6 @@ class _UserProfileFormState extends State { ), if (!widget._profile.emailVerified) OutlinedButton( - style: OutlinedButton.styleFrom( - // Applying the "Darker background" when disabled - disabledBackgroundColor: Colors.grey.shade300, - side: BorderSide( - color: _isVerifying ? Colors.grey : Colors.green, - ), - ), // If _isVerifying is true, setting onPressed to null disables the button onPressed: _isVerifying ? null @@ -133,12 +126,15 @@ class _UserProfileFormState extends State { ); } } catch (e) { + // 'verify' button is enabled if error occurs setState(() { _isVerifying = false; }); } }, - child: _isVerifying ? const Text("Email sent") : Text(AppLocalizations.of(context).verify), + child: _isVerifying + ? const Text(AppLocalizations.of(context).verifiedEmailSent) + : Text(AppLocalizations.of(context).verify), ), ElevatedButton( onPressed: () async { From e3619ca4b6bc3272a297bad8492c409d43c3ef4d Mon Sep 17 00:00:00 2001 From: pankaj-basnet <165250380+pankaj-basnet@users.noreply.github.com> Date: Mon, 30 Mar 2026 00:06:29 +0545 Subject: [PATCH 5/5] remove const from Text widget which has AppLocalizations.of code --- lib/widgets/user/forms.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/user/forms.dart b/lib/widgets/user/forms.dart index 1157dac03..dceb862ed 100644 --- a/lib/widgets/user/forms.dart +++ b/lib/widgets/user/forms.dart @@ -133,7 +133,7 @@ class _UserProfileFormState extends State { } }, child: _isVerifying - ? const Text(AppLocalizations.of(context).verifiedEmailSent) + ? Text(AppLocalizations.of(context).verifiedEmailSent) : Text(AppLocalizations.of(context).verify), ), ElevatedButton(