From 33aa83df4e0cae0f9f8e513d0628c7952cc769e7 Mon Sep 17 00:00:00 2001 From: pohuing <24683548+pohuing@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:54:23 +0100 Subject: [PATCH 1/3] Fix autofill not opening when tapping on email field in SupaEmailAuth --- lib/src/components/supa_email_auth.dart | 294 ++++++++++++------------ 1 file changed, 148 insertions(+), 146 deletions(-) diff --git a/lib/src/components/supa_email_auth.dart b/lib/src/components/supa_email_auth.dart index d540902..ea9f743 100644 --- a/lib/src/components/supa_email_auth.dart +++ b/lib/src/components/supa_email_auth.dart @@ -133,177 +133,179 @@ class _SupaEmailAuthState extends State { @override Widget build(BuildContext context) { final localization = widget.localization; - return Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - TextFormField( - keyboardType: TextInputType.emailAddress, - autofillHints: const [AutofillHints.email], - validator: (value) { - if (value == null || - value.isEmpty || - !EmailValidator.validate(_emailController.text)) { - return localization.validEmailError; - } - return null; - }, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.email), - label: Text(localization.enterEmail), - ), - controller: _emailController, - ), - if (!_forgotPassword) ...[ - spacer(16), + return AutofillGroup( + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ TextFormField( - autofillHints: _isSigningIn - ? [AutofillHints.password] - : [AutofillHints.newPassword], + keyboardType: TextInputType.emailAddress, + autofillHints: const [AutofillHints.email], validator: (value) { - if (value == null || value.isEmpty || value.length < 6) { - return localization.passwordLengthError; + if (value == null || + value.isEmpty || + !EmailValidator.validate(_emailController.text)) { + return localization.validEmailError; } return null; }, decoration: InputDecoration( - prefixIcon: const Icon(Icons.lock), - label: Text(localization.enterPassword), + prefixIcon: const Icon(Icons.email), + label: Text(localization.enterEmail), ), - obscureText: true, - controller: _passwordController, + controller: _emailController, ), - spacer(16), - if (widget.metadataFields != null && !_isSigningIn) - ...widget.metadataFields! - .map((metadataField) => [ - TextFormField( - controller: _metadataControllers[metadataField], - decoration: InputDecoration( - label: Text(metadataField.label), - prefixIcon: metadataField.prefixIcon, + if (!_forgotPassword) ...[ + spacer(16), + TextFormField( + autofillHints: _isSigningIn + ? [AutofillHints.password] + : [AutofillHints.newPassword], + validator: (value) { + if (value == null || value.isEmpty || value.length < 6) { + return localization.passwordLengthError; + } + return null; + }, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.lock), + label: Text(localization.enterPassword), + ), + obscureText: true, + controller: _passwordController, + ), + spacer(16), + if (widget.metadataFields != null && !_isSigningIn) + ...widget.metadataFields! + .map((metadataField) => [ + TextFormField( + controller: _metadataControllers[metadataField], + decoration: InputDecoration( + label: Text(metadataField.label), + prefixIcon: metadataField.prefixIcon, + ), + validator: metadataField.validator, ), - validator: metadataField.validator, + spacer(16), + ]) + .expand((element) => element), + ElevatedButton( + child: (_isLoading) + ? SizedBox( + height: 16, + width: 16, + child: CircularProgressIndicator( + color: Theme.of(context).colorScheme.onPrimary, + strokeWidth: 1.5, ), - spacer(16), - ]) - .expand((element) => element), - ElevatedButton( - child: (_isLoading) - ? SizedBox( - height: 16, - width: 16, - child: CircularProgressIndicator( - color: Theme.of(context).colorScheme.onPrimary, - strokeWidth: 1.5, - ), - ) - : Text( - _isSigningIn ? localization.signIn : localization.signUp), - onPressed: () async { - if (!_formKey.currentState!.validate()) { - return; - } - setState(() { - _isLoading = true; - }); - try { - if (_isSigningIn) { - final response = await supabase.auth.signInWithPassword( - email: _emailController.text.trim(), - password: _passwordController.text.trim(), - ); - widget.onSignInComplete.call(response); - } else { - final response = await supabase.auth.signUp( - email: _emailController.text.trim(), - password: _passwordController.text.trim(), - emailRedirectTo: widget.redirectTo, - data: _resolveData(), - ); - widget.onSignUpComplete.call(response); - } - } on AuthException catch (error) { - if (widget.onError == null && context.mounted) { - context.showErrorSnackBar(error.message); - } else { - widget.onError?.call(error); - } - } catch (error) { - if (widget.onError == null && context.mounted) { - context.showErrorSnackBar( - '${localization.unexpectedError}: $error'); - } else { - widget.onError?.call(error); + ) + : Text( + _isSigningIn ? localization.signIn : localization.signUp), + onPressed: () async { + if (!_formKey.currentState!.validate()) { + return; } - } - if (mounted) { setState(() { - _isLoading = false; + _isLoading = true; }); - } - }, - ), - spacer(16), - if (_isSigningIn) ...[ + try { + if (_isSigningIn) { + final response = await supabase.auth.signInWithPassword( + email: _emailController.text.trim(), + password: _passwordController.text.trim(), + ); + widget.onSignInComplete.call(response); + } else { + final response = await supabase.auth.signUp( + email: _emailController.text.trim(), + password: _passwordController.text.trim(), + emailRedirectTo: widget.redirectTo, + data: _resolveData(), + ); + widget.onSignUpComplete.call(response); + } + } on AuthException catch (error) { + if (widget.onError == null && context.mounted) { + context.showErrorSnackBar(error.message); + } else { + widget.onError?.call(error); + } + } catch (error) { + if (widget.onError == null && context.mounted) { + context.showErrorSnackBar( + '${localization.unexpectedError}: $error'); + } else { + widget.onError?.call(error); + } + } + if (mounted) { + setState(() { + _isLoading = false; + }); + } + }, + ), + spacer(16), + if (_isSigningIn) ...[ + TextButton( + onPressed: () { + setState(() { + _forgotPassword = true; + }); + }, + child: Text(localization.forgotPassword), + ), + ], TextButton( + key: const ValueKey('toggleSignInButton'), onPressed: () { setState(() { - _forgotPassword = true; + _forgotPassword = false; + _isSigningIn = !_isSigningIn; }); }, - child: Text(localization.forgotPassword), + child: Text(_isSigningIn + ? localization.dontHaveAccount + : localization.haveAccount), ), ], - TextButton( - key: const ValueKey('toggleSignInButton'), - onPressed: () { - setState(() { - _forgotPassword = false; - _isSigningIn = !_isSigningIn; - }); - }, - child: Text(_isSigningIn - ? localization.dontHaveAccount - : localization.haveAccount), - ), - ], - if (_isSigningIn && _forgotPassword) ...[ - spacer(16), - ElevatedButton( - onPressed: () async { - try { - if (!_formKey.currentState!.validate()) { - return; + if (_isSigningIn && _forgotPassword) ...[ + spacer(16), + ElevatedButton( + onPressed: () async { + try { + if (!_formKey.currentState!.validate()) { + return; + } + setState(() { + _isLoading = true; + }); + + final email = _emailController.text.trim(); + await supabase.auth.resetPasswordForEmail(email); + widget.onPasswordResetEmailSent?.call(); + } on AuthException catch (error) { + widget.onError?.call(error); + } catch (error) { + widget.onError?.call(error); } + }, + child: Text(localization.sendPasswordReset), + ), + spacer(16), + TextButton( + onPressed: () { setState(() { - _isLoading = true; + _forgotPassword = false; }); - - final email = _emailController.text.trim(); - await supabase.auth.resetPasswordForEmail(email); - widget.onPasswordResetEmailSent?.call(); - } on AuthException catch (error) { - widget.onError?.call(error); - } catch (error) { - widget.onError?.call(error); - } - }, - child: Text(localization.sendPasswordReset), - ), + }, + child: Text(localization.backToSignIn), + ), + ], spacer(16), - TextButton( - onPressed: () { - setState(() { - _forgotPassword = false; - }); - }, - child: Text(localization.backToSignIn), - ), ], - spacer(16), - ], + ), ), ); } From a4d9aac5d83c728b9c8b32245bd39705d1252753 Mon Sep 17 00:00:00 2001 From: pohuing <24683548+pohuing@users.noreply.github.com> Date: Sun, 31 Mar 2024 17:17:07 +0200 Subject: [PATCH 2/3] Fix autofill not opening when tapping on phone number field in SupaPhoneAuth --- lib/src/components/supa_phone_auth.dart | 158 ++++++++++++------------ 1 file changed, 80 insertions(+), 78 deletions(-) diff --git a/lib/src/components/supa_phone_auth.dart b/lib/src/components/supa_phone_auth.dart index 06fc7c8..0f25100 100644 --- a/lib/src/components/supa_phone_auth.dart +++ b/lib/src/components/supa_phone_auth.dart @@ -49,88 +49,90 @@ class _SupaPhoneAuthState extends State { Widget build(BuildContext context) { final localization = widget.localization; final isSigningIn = widget.authAction == SupaAuthAction.signIn; - return Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - TextFormField( - autofillHints: const [AutofillHints.telephoneNumber], - validator: (value) { - if (value == null || value.isEmpty) { - return localization.validPhoneNumberError; - } - return null; - }, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.phone), - label: Text(localization.enterPhoneNumber), - ), - controller: _phone, - ), - spacer(16), - TextFormField( - autofillHints: isSigningIn - ? [AutofillHints.password] - : [AutofillHints.newPassword], - validator: (value) { - if (value == null || value.isEmpty || value.length < 6) { - return localization.passwordLengthError; - } - return null; - }, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.lock), - label: Text(localization.enterPassword), - ), - obscureText: true, - controller: _password, - ), - spacer(16), - ElevatedButton( - child: Text( - isSigningIn ? localization.signIn : localization.signUp, - style: const TextStyle(fontWeight: FontWeight.bold), + return AutofillGroup( + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + autofillHints: const [AutofillHints.telephoneNumber], + validator: (value) { + if (value == null || value.isEmpty) { + return localization.validPhoneNumberError; + } + return null; + }, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.phone), + label: Text(localization.enterPhoneNumber), + ), + controller: _phone, ), - onPressed: () async { - if (!_formKey.currentState!.validate()) { - return; - } - try { - if (isSigningIn) { - final response = await supabase.auth.signInWithPassword( - phone: _phone.text, - password: _password.text, - ); - widget.onSuccess(response); - } else { - final response = await supabase.auth - .signUp(phone: _phone.text, password: _password.text); - if (!mounted) return; - widget.onSuccess(response); + spacer(16), + TextFormField( + autofillHints: isSigningIn + ? [AutofillHints.password] + : [AutofillHints.newPassword], + validator: (value) { + if (value == null || value.isEmpty || value.length < 6) { + return localization.passwordLengthError; } - } on AuthException catch (error) { - if (widget.onError == null && context.mounted) { - context.showErrorSnackBar(error.message); - } else { - widget.onError?.call(error); + return null; + }, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.lock), + label: Text(localization.enterPassword), + ), + obscureText: true, + controller: _password, + ), + spacer(16), + ElevatedButton( + child: Text( + isSigningIn ? localization.signIn : localization.signUp, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + onPressed: () async { + if (!_formKey.currentState!.validate()) { + return; } - } catch (error) { - if (widget.onError == null && context.mounted) { - context.showErrorSnackBar( - '${localization.unexpectedError}: $error'); - } else { - widget.onError?.call(error); + try { + if (isSigningIn) { + final response = await supabase.auth.signInWithPassword( + phone: _phone.text, + password: _password.text, + ); + widget.onSuccess(response); + } else { + final response = await supabase.auth + .signUp(phone: _phone.text, password: _password.text); + if (!mounted) return; + widget.onSuccess(response); + } + } on AuthException catch (error) { + if (widget.onError == null && context.mounted) { + context.showErrorSnackBar(error.message); + } else { + widget.onError?.call(error); + } + } catch (error) { + if (widget.onError == null && context.mounted) { + context.showErrorSnackBar( + '${localization.unexpectedError}: $error'); + } else { + widget.onError?.call(error); + } } - } - setState(() { - _phone.text = ''; - _password.text = ''; - }); - }, - ), - spacer(10), - ], + setState(() { + _phone.text = ''; + _password.text = ''; + }); + }, + ), + spacer(10), + ], + ), ), ); } From aee0e783b14f2c20f492fe949617acf173ee56a3 Mon Sep 17 00:00:00 2001 From: pohuing <24683548+pohuing@users.noreply.github.com> Date: Sun, 31 Mar 2024 17:18:56 +0200 Subject: [PATCH 3/3] Fix Formatter issue in EmailAuth --- lib/src/components/supa_email_auth.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/components/supa_email_auth.dart b/lib/src/components/supa_email_auth.dart index ea9f743..ec0d23e 100644 --- a/lib/src/components/supa_email_auth.dart +++ b/lib/src/components/supa_email_auth.dart @@ -200,8 +200,9 @@ class _SupaEmailAuthState extends State { strokeWidth: 1.5, ), ) - : Text( - _isSigningIn ? localization.signIn : localization.signUp), + : Text(_isSigningIn + ? localization.signIn + : localization.signUp), onPressed: () async { if (!_formKey.currentState!.validate()) { return;