diff --git a/docs/src/content/docs/tutorials/flutter-firebase-login.mdx b/docs/src/content/docs/tutorials/flutter-firebase-login.mdx index db765d7ad47..3197b3e5484 100644 --- a/docs/src/content/docs/tutorials/flutter-firebase-login.mdx +++ b/docs/src/content/docs/tutorials/flutter-firebase-login.mdx @@ -18,7 +18,6 @@ In the following tutorial, we're going to build a Firebase Login Flow in Flutter ## Key Topics - [BlocProvider](/flutter-bloc-concepts#blocprovider), a Flutter widget which provides a bloc to its children. -- [BlocBuilder](/flutter-bloc-concepts#blocbuilder), a Flutter widget that handles building the widget in response to new states. - Using Cubit instead of Bloc. [What's the difference?](/bloc-concepts#cubit-vs-bloc) - Adding events with [context.read](/flutter-bloc-concepts#contextread). - Prevent unnecessary rebuilds with [Equatable](/faqs#when-to-use-equatable). diff --git a/examples/flutter_firebase_login/lib/login/view/login_form.dart b/examples/flutter_firebase_login/lib/login/view/login_form.dart index 41c7b7a2795..28afaf20430 100644 --- a/examples/flutter_firebase_login/lib/login/view/login_form.dart +++ b/examples/flutter_firebase_login/lib/login/view/login_form.dart @@ -53,21 +53,19 @@ class LoginForm extends StatelessWidget { class _EmailInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.email != current.email, - builder: (context, state) { - return TextField( - key: const Key('loginForm_emailInput_textField'), - onChanged: (email) => context.read().emailChanged(email), - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - labelText: 'email', - helperText: '', - errorText: - state.email.displayError != null ? 'invalid email' : null, - ), - ); - }, + final displayError = context.select( + (LoginCubit cubit) => cubit.state.email.displayError, + ); + + return TextField( + key: const Key('loginForm_emailInput_textField'), + onChanged: (email) => context.read().emailChanged(email), + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + labelText: 'email', + helperText: '', + errorText: displayError != null ? 'invalid email' : null, + ), ); } } @@ -75,22 +73,20 @@ class _EmailInput extends StatelessWidget { class _PasswordInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.password != current.password, - builder: (context, state) { - return TextField( - key: const Key('loginForm_passwordInput_textField'), - onChanged: (password) => - context.read().passwordChanged(password), - obscureText: true, - decoration: InputDecoration( - labelText: 'password', - helperText: '', - errorText: - state.password.displayError != null ? 'invalid password' : null, - ), - ); - }, + final displayError = context.select( + (LoginCubit cubit) => cubit.state.password.displayError, + ); + + return TextField( + key: const Key('loginForm_passwordInput_textField'), + onChanged: (password) => + context.read().passwordChanged(password), + obscureText: true, + decoration: InputDecoration( + labelText: 'password', + helperText: '', + errorText: displayError != null ? 'invalid password' : null, + ), ); } } @@ -98,24 +94,28 @@ class _PasswordInput extends StatelessWidget { class _LoginButton extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - return state.status.isInProgress - ? const CircularProgressIndicator() - : ElevatedButton( - key: const Key('loginForm_continue_raisedButton'), - style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(30), - ), - backgroundColor: const Color(0xFFFFD600), - ), - onPressed: state.isValid - ? () => context.read().logInWithCredentials() - : null, - child: const Text('LOGIN'), - ); - }, + final isInProgress = context.select( + (LoginCubit cubit) => cubit.state.status.isInProgress, + ); + + if (isInProgress) return const CircularProgressIndicator(); + + final isValid = context.select( + (LoginCubit cubit) => cubit.state.isValid, + ); + + return ElevatedButton( + key: const Key('loginForm_continue_raisedButton'), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + backgroundColor: const Color(0xFFFFD600), + ), + onPressed: isValid + ? () => context.read().logInWithCredentials() + : null, + child: const Text('LOGIN'), ); } } diff --git a/examples/flutter_firebase_login/lib/sign_up/view/sign_up_form.dart b/examples/flutter_firebase_login/lib/sign_up/view/sign_up_form.dart index 7dc4ee9b314..62255aada2b 100644 --- a/examples/flutter_firebase_login/lib/sign_up/view/sign_up_form.dart +++ b/examples/flutter_firebase_login/lib/sign_up/view/sign_up_form.dart @@ -42,21 +42,19 @@ class SignUpForm extends StatelessWidget { class _EmailInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.email != current.email, - builder: (context, state) { - return TextField( - key: const Key('signUpForm_emailInput_textField'), - onChanged: (email) => context.read().emailChanged(email), - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - labelText: 'email', - helperText: '', - errorText: - state.email.displayError != null ? 'invalid email' : null, - ), - ); - }, + final displayError = context.select( + (SignUpCubit cubit) => cubit.state.email.displayError, + ); + + return TextField( + key: const Key('signUpForm_emailInput_textField'), + onChanged: (email) => context.read().emailChanged(email), + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + labelText: 'email', + helperText: '', + errorText: displayError != null ? 'invalid email' : null, + ), ); } } @@ -64,22 +62,20 @@ class _EmailInput extends StatelessWidget { class _PasswordInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.password != current.password, - builder: (context, state) { - return TextField( - key: const Key('signUpForm_passwordInput_textField'), - onChanged: (password) => - context.read().passwordChanged(password), - obscureText: true, - decoration: InputDecoration( - labelText: 'password', - helperText: '', - errorText: - state.password.displayError != null ? 'invalid password' : null, - ), - ); - }, + final displayError = context.select( + (SignUpCubit cubit) => cubit.state.password.displayError, + ); + + return TextField( + key: const Key('signUpForm_passwordInput_textField'), + onChanged: (password) => + context.read().passwordChanged(password), + obscureText: true, + decoration: InputDecoration( + labelText: 'password', + helperText: '', + errorText: displayError != null ? 'invalid password' : null, + ), ); } } @@ -87,26 +83,20 @@ class _PasswordInput extends StatelessWidget { class _ConfirmPasswordInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => - previous.password != current.password || - previous.confirmedPassword != current.confirmedPassword, - builder: (context, state) { - return TextField( - key: const Key('signUpForm_confirmedPasswordInput_textField'), - onChanged: (confirmPassword) => context - .read() - .confirmedPasswordChanged(confirmPassword), - obscureText: true, - decoration: InputDecoration( - labelText: 'confirm password', - helperText: '', - errorText: state.confirmedPassword.displayError != null - ? 'passwords do not match' - : null, - ), - ); - }, + final displayError = context.select( + (SignUpCubit cubit) => cubit.state.confirmedPassword.displayError, + ); + + return TextField( + key: const Key('signUpForm_confirmedPasswordInput_textField'), + onChanged: (confirmPassword) => + context.read().confirmedPasswordChanged(confirmPassword), + obscureText: true, + decoration: InputDecoration( + labelText: 'confirm password', + helperText: '', + errorText: displayError != null ? 'passwords do not match' : null, + ), ); } } @@ -114,24 +104,28 @@ class _ConfirmPasswordInput extends StatelessWidget { class _SignUpButton extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - return state.status.isInProgress - ? const CircularProgressIndicator() - : ElevatedButton( - key: const Key('signUpForm_continue_raisedButton'), - style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(30), - ), - backgroundColor: Colors.orangeAccent, - ), - onPressed: state.isValid - ? () => context.read().signUpFormSubmitted() - : null, - child: const Text('SIGN UP'), - ); - }, + final isInProgress = context.select( + (SignUpCubit cubit) => cubit.state.status.isInProgress, + ); + + if (isInProgress) return const CircularProgressIndicator(); + + final isValid = context.select( + (SignUpCubit cubit) => cubit.state.isValid, + ); + + return ElevatedButton( + key: const Key('signUpForm_continue_raisedButton'), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + backgroundColor: Colors.orangeAccent, + ), + onPressed: isValid + ? () => context.read().signUpFormSubmitted() + : null, + child: const Text('SIGN UP'), ); } }