Skip to content

Commit

Permalink
refactor(flutter_firebase_login): use context.select (#4222)
Browse files Browse the repository at this point in the history
Co-authored-by: Felix Angelov <[email protected]>
  • Loading branch information
LukasMirbt and felangel authored Aug 17, 2024
1 parent 72e928e commit 3ed67d3
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 119 deletions.
1 change: 0 additions & 1 deletion docs/src/content/docs/tutorials/flutter-firebase-login.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
98 changes: 49 additions & 49 deletions examples/flutter_firebase_login/lib/login/view/login_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,69 +53,69 @@ class LoginForm extends StatelessWidget {
class _EmailInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginCubit, LoginState>(
buildWhen: (previous, current) => previous.email != current.email,
builder: (context, state) {
return TextField(
key: const Key('loginForm_emailInput_textField'),
onChanged: (email) => context.read<LoginCubit>().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<LoginCubit>().emailChanged(email),
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'email',
helperText: '',
errorText: displayError != null ? 'invalid email' : null,
),
);
}
}

class _PasswordInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginCubit, LoginState>(
buildWhen: (previous, current) => previous.password != current.password,
builder: (context, state) {
return TextField(
key: const Key('loginForm_passwordInput_textField'),
onChanged: (password) =>
context.read<LoginCubit>().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<LoginCubit>().passwordChanged(password),
obscureText: true,
decoration: InputDecoration(
labelText: 'password',
helperText: '',
errorText: displayError != null ? 'invalid password' : null,
),
);
}
}

class _LoginButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginCubit, LoginState>(
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<LoginCubit>().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<LoginCubit>().logInWithCredentials()
: null,
child: const Text('LOGIN'),
);
}
}
Expand Down
132 changes: 63 additions & 69 deletions examples/flutter_firebase_login/lib/sign_up/view/sign_up_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,96 +42,90 @@ class SignUpForm extends StatelessWidget {
class _EmailInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpCubit, SignUpState>(
buildWhen: (previous, current) => previous.email != current.email,
builder: (context, state) {
return TextField(
key: const Key('signUpForm_emailInput_textField'),
onChanged: (email) => context.read<SignUpCubit>().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<SignUpCubit>().emailChanged(email),
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'email',
helperText: '',
errorText: displayError != null ? 'invalid email' : null,
),
);
}
}

class _PasswordInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpCubit, SignUpState>(
buildWhen: (previous, current) => previous.password != current.password,
builder: (context, state) {
return TextField(
key: const Key('signUpForm_passwordInput_textField'),
onChanged: (password) =>
context.read<SignUpCubit>().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<SignUpCubit>().passwordChanged(password),
obscureText: true,
decoration: InputDecoration(
labelText: 'password',
helperText: '',
errorText: displayError != null ? 'invalid password' : null,
),
);
}
}

class _ConfirmPasswordInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpCubit, SignUpState>(
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<SignUpCubit>()
.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<SignUpCubit>().confirmedPasswordChanged(confirmPassword),
obscureText: true,
decoration: InputDecoration(
labelText: 'confirm password',
helperText: '',
errorText: displayError != null ? 'passwords do not match' : null,
),
);
}
}

class _SignUpButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpCubit, SignUpState>(
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<SignUpCubit>().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<SignUpCubit>().signUpFormSubmitted()
: null,
child: const Text('SIGN UP'),
);
}
}

0 comments on commit 3ed67d3

Please sign in to comment.