Skip to content

Commit 0c36bc5

Browse files
Copilotmaurovanetti
andcommitted
Add enableAutomaticFormSubmission flag to all auth components
Co-authored-by: maurovanetti <402070+maurovanetti@users.noreply.github.com>
1 parent f28878e commit 0c36bc5

File tree

4 files changed

+163
-3
lines changed

4 files changed

+163
-3
lines changed

lib/src/components/supa_email_auth.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,15 @@ class SupaEmailAuth extends StatefulWidget {
226226
/// Pre-filled password for the form
227227
final String? prefilledPassword;
228228

229+
/// Whether pressing Enter on the on-screen keyboard should automatically
230+
/// submit the form.
231+
///
232+
/// When set to `false`, the user must explicitly click the submit button
233+
/// to proceed with the authentication process.
234+
///
235+
/// Defaults to `true` for backward compatibility.
236+
final bool enableAutomaticFormSubmission;
237+
229238
/// {@macro supa_email_auth}
230239
const SupaEmailAuth({
231240
super.key,
@@ -248,6 +257,7 @@ class SupaEmailAuth extends StatefulWidget {
248257
this.showConfirmPasswordField = false,
249258
this.prefilledEmail,
250259
this.prefilledPassword,
260+
this.enableAutomaticFormSubmission = true,
251261
});
252262

253263
@override
@@ -331,7 +341,8 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
331341
),
332342
controller: _emailController,
333343
onFieldSubmitted: (_) {
334-
if (_isRecoveringPassword) {
344+
if (_isRecoveringPassword &&
345+
widget.enableAutomaticFormSubmission) {
335346
_passwordRecovery();
336347
}
337348
},
@@ -360,7 +371,8 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
360371
obscureText: true,
361372
controller: _passwordController,
362373
onFieldSubmitted: (_) {
363-
if (widget.metadataFields == null || _isSigningIn) {
374+
if ((widget.metadataFields == null || _isSigningIn) &&
375+
widget.enableAutomaticFormSubmission) {
364376
_signInSignUp();
365377
}
366378
},
@@ -463,7 +475,7 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
463475
if (metadataField !=
464476
widget.metadataFields!.last) {
465477
FocusScope.of(context).nextFocus();
466-
} else {
478+
} else if (widget.enableAutomaticFormSubmission) {
467479
_signInSignUp();
468480
}
469481
},

lib/src/components/supa_magic_auth.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,22 @@ class SupaMagicAuth extends StatefulWidget {
2222
/// Localization for the form
2323
final SupaMagicAuthLocalization localization;
2424

25+
/// Whether pressing Enter on the on-screen keyboard should automatically
26+
/// submit the form.
27+
///
28+
/// When set to `false`, the user must explicitly click the submit button
29+
/// to proceed with the authentication process.
30+
///
31+
/// Defaults to `true` for backward compatibility.
32+
final bool enableAutomaticFormSubmission;
33+
2534
const SupaMagicAuth({
2635
super.key,
2736
this.redirectUrl,
2837
required this.onSuccess,
2938
this.onError,
3039
this.localization = const SupaMagicAuthLocalization(),
40+
this.enableAutomaticFormSubmission = true,
3141
});
3242

3343
@override
@@ -84,6 +94,41 @@ class _SupaMagicAuthState extends State<SupaMagicAuth> {
8494
label: Text(localization.enterEmail),
8595
),
8696
controller: _email,
97+
onFieldSubmitted: (_) async {
98+
if (widget.enableAutomaticFormSubmission) {
99+
if (!_formKey.currentState!.validate()) {
100+
return;
101+
}
102+
setState(() {
103+
_isLoading = true;
104+
});
105+
try {
106+
await supabase.auth.signInWithOtp(
107+
email: _email.text,
108+
emailRedirectTo: widget.redirectUrl,
109+
);
110+
if (context.mounted) {
111+
context.showSnackBar(localization.checkYourEmail);
112+
}
113+
} on AuthException catch (error) {
114+
if (widget.onError == null && context.mounted) {
115+
context.showErrorSnackBar(error.message);
116+
} else {
117+
widget.onError?.call(error);
118+
}
119+
} catch (error) {
120+
if (widget.onError == null && context.mounted) {
121+
context.showErrorSnackBar(
122+
'${localization.unexpectedError}: $error');
123+
} else {
124+
widget.onError?.call(error);
125+
}
126+
}
127+
setState(() {
128+
_isLoading = false;
129+
});
130+
}
131+
},
87132
),
88133
spacer(16),
89134
ElevatedButton(

lib/src/components/supa_phone_auth.dart

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,22 @@ class SupaPhoneAuth extends StatefulWidget {
1616
/// Localization for the form
1717
final SupaPhoneAuthLocalization localization;
1818

19+
/// Whether pressing Enter on the on-screen keyboard should automatically
20+
/// submit the form.
21+
///
22+
/// When set to `false`, the user must explicitly click the submit button
23+
/// to proceed with the authentication process.
24+
///
25+
/// Defaults to `true` for backward compatibility.
26+
final bool enableAutomaticFormSubmission;
27+
1928
const SupaPhoneAuth({
2029
super.key,
2130
required this.authAction,
2231
required this.onSuccess,
2332
this.onError,
2433
this.localization = const SupaPhoneAuthLocalization(),
34+
this.enableAutomaticFormSubmission = true,
2535
});
2636

2737
@override
@@ -88,6 +98,58 @@ class _SupaPhoneAuthState extends State<SupaPhoneAuth> {
8898
),
8999
obscureText: true,
90100
controller: _password,
101+
onFieldSubmitted: (_) async {
102+
if (widget.enableAutomaticFormSubmission) {
103+
// Trigger form validation and submission
104+
if (!_formKey.currentState!.validate()) {
105+
return;
106+
}
107+
try {
108+
if (isSigningIn) {
109+
final response = await supabase.auth.signInWithPassword(
110+
phone: _phone.text,
111+
password: _password.text,
112+
);
113+
widget.onSuccess(response);
114+
} else {
115+
late final AuthResponse response;
116+
final user = supabase.auth.currentUser;
117+
if (user?.isAnonymous == true) {
118+
await supabase.auth.updateUser(
119+
UserAttributes(
120+
phone: _phone.text,
121+
password: _password.text,
122+
),
123+
);
124+
} else {
125+
response = await supabase.auth.signUp(
126+
phone: _phone.text,
127+
password: _password.text,
128+
);
129+
}
130+
if (!mounted) return;
131+
widget.onSuccess(response);
132+
}
133+
} on AuthException catch (error) {
134+
if (widget.onError == null && context.mounted) {
135+
context.showErrorSnackBar(error.message);
136+
} else {
137+
widget.onError?.call(error);
138+
}
139+
} catch (error) {
140+
if (widget.onError == null && context.mounted) {
141+
context.showErrorSnackBar(
142+
'${localization.unexpectedError}: $error');
143+
} else {
144+
widget.onError?.call(error);
145+
}
146+
}
147+
setState(() {
148+
_phone.text = '';
149+
_password.text = '';
150+
});
151+
}
152+
},
91153
),
92154
spacer(16),
93155
ElevatedButton(

lib/src/components/supa_reset_password.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,22 @@ class SupaResetPassword extends StatefulWidget {
1717
/// Localization for the form
1818
final SupaResetPasswordLocalization localization;
1919

20+
/// Whether pressing Enter on the on-screen keyboard should automatically
21+
/// submit the form.
22+
///
23+
/// When set to `false`, the user must explicitly click the submit button
24+
/// to proceed with the authentication process.
25+
///
26+
/// Defaults to `true` for backward compatibility.
27+
final bool enableAutomaticFormSubmission;
28+
2029
const SupaResetPassword({
2130
super.key,
2231
this.accessToken,
2332
required this.onSuccess,
2433
this.onError,
2534
this.localization = const SupaResetPasswordLocalization(),
35+
this.enableAutomaticFormSubmission = true,
2636
});
2737

2838
@override
@@ -60,6 +70,37 @@ class _SupaResetPasswordState extends State<SupaResetPassword> {
6070
label: Text(localization.enterPassword),
6171
),
6272
controller: _password,
73+
onFieldSubmitted: (_) async {
74+
if (widget.enableAutomaticFormSubmission) {
75+
if (!_formKey.currentState!.validate()) {
76+
return;
77+
}
78+
try {
79+
final response = await supabase.auth.updateUser(
80+
UserAttributes(
81+
password: _password.text,
82+
),
83+
);
84+
widget.onSuccess.call(response);
85+
// FIX use_build_context_synchronously
86+
if (!context.mounted) return;
87+
context.showSnackBar(localization.passwordResetSent);
88+
} on AuthException catch (error) {
89+
if (widget.onError == null && context.mounted) {
90+
context.showErrorSnackBar(error.message);
91+
} else {
92+
widget.onError?.call(error);
93+
}
94+
} catch (error) {
95+
if (widget.onError == null && context.mounted) {
96+
context.showErrorSnackBar(
97+
'${localization.passwordLengthError}: $error');
98+
} else {
99+
widget.onError?.call(error);
100+
}
101+
}
102+
}
103+
},
63104
),
64105
spacer(16),
65106
ElevatedButton(

0 commit comments

Comments
 (0)