From 9f393a7ce5a33159aff13d5efdd7b4d8ccbe36d8 Mon Sep 17 00:00:00 2001 From: Lukas Mirbt Date: Fri, 26 Jul 2024 07:07:37 +0200 Subject: [PATCH] refactor(flutter_login): use `context.select` instead of BlocBuilders (#4212) Co-authored-by: Felix Angelov --- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 8 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../lib/home/view/home_page.dart | 48 ++++++----- .../lib/login/view/login_form.dart | 80 +++++++++---------- .../lib/login/view/login_page.dart | 9 +-- 6 files changed, 77 insertions(+), 72 deletions(-) diff --git a/examples/flutter_login/ios/Flutter/AppFrameworkInfo.plist b/examples/flutter_login/ios/Flutter/AppFrameworkInfo.plist index 9625e105df3..7c569640062 100644 --- a/examples/flutter_login/ios/Flutter/AppFrameworkInfo.plist +++ b/examples/flutter_login/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/examples/flutter_login/ios/Runner.xcodeproj/project.pbxproj b/examples/flutter_login/ios/Runner.xcodeproj/project.pbxproj index 7d9f6857d38..48a9cdaeff2 100644 --- a/examples/flutter_login/ios/Runner.xcodeproj/project.pbxproj +++ b/examples/flutter_login/ios/Runner.xcodeproj/project.pbxproj @@ -168,7 +168,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C8080294A63A400263BE5 = { @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -471,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -520,7 +520,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/examples/flutter_login/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/flutter_login/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index e42adcb34c2..8e3ca5dfe19 100644 --- a/examples/flutter_login/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/examples/flutter_login/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ [ - Builder( - builder: (context) { - final userId = context.select( - (AuthenticationBloc bloc) => bloc.state.user.id, - ); - return Text('UserID: $userId'); - }, - ), - ElevatedButton( - child: const Text('Logout'), - onPressed: () { - context - .read() - .add(AuthenticationLogoutRequested()); - }, - ), - ], + children: [_UserId(), _LogoutButton()], ), ), ); } } + +class _LogoutButton extends StatelessWidget { + const _LogoutButton(); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + child: const Text('Logout'), + onPressed: () { + context.read().add(AuthenticationLogoutRequested()); + }, + ); + } +} + +class _UserId extends StatelessWidget { + const _UserId(); + + @override + Widget build(BuildContext context) { + final userId = context.select( + (AuthenticationBloc bloc) => bloc.state.user.id, + ); + + return Text('UserID: $userId'); + } +} diff --git a/examples/flutter_login/lib/login/view/login_form.dart b/examples/flutter_login/lib/login/view/login_form.dart index 8118604034c..a2f67abcb4d 100644 --- a/examples/flutter_login/lib/login/view/login_form.dart +++ b/examples/flutter_login/lib/login/view/login_form.dart @@ -38,20 +38,19 @@ class LoginForm extends StatelessWidget { class _UsernameInput extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - buildWhen: (previous, current) => previous.username != current.username, - builder: (context, state) { - return TextField( - key: const Key('loginForm_usernameInput_textField'), - onChanged: (username) => - context.read().add(LoginUsernameChanged(username)), - decoration: InputDecoration( - labelText: 'username', - errorText: - state.username.displayError != null ? 'invalid username' : null, - ), - ); + final displayError = context.select( + (LoginBloc bloc) => bloc.state.username.displayError, + ); + + return TextField( + key: const Key('loginForm_usernameInput_textField'), + onChanged: (username) { + context.read().add(LoginUsernameChanged(username)); }, + decoration: InputDecoration( + labelText: 'username', + errorText: displayError != null ? 'invalid username' : null, + ), ); } } @@ -59,21 +58,20 @@ class _UsernameInput 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().add(LoginPasswordChanged(password)), - obscureText: true, - decoration: InputDecoration( - labelText: 'password', - errorText: - state.password.displayError != null ? 'invalid password' : null, - ), - ); + final displayError = context.select( + (LoginBloc bloc) => bloc.state.password.displayError, + ); + + return TextField( + key: const Key('loginForm_passwordInput_textField'), + onChanged: (password) { + context.read().add(LoginPasswordChanged(password)); }, + obscureText: true, + decoration: InputDecoration( + labelText: 'password', + errorText: displayError != null ? 'invalid password' : null, + ), ); } } @@ -81,20 +79,20 @@ 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'), - onPressed: state.isValid - ? () { - context.read().add(const LoginSubmitted()); - } - : null, - child: const Text('Login'), - ); - }, + final isInProgress = context.select( + (LoginBloc bloc) => bloc.state.status.isInProgress, + ); + + if (isInProgress) return const CircularProgressIndicator(); + + final isValid = context.select((LoginBloc bloc) => bloc.state.isValid); + + return ElevatedButton( + key: const Key('loginForm_continue_raisedButton'), + onPressed: isValid + ? () => context.read().add(const LoginSubmitted()) + : null, + child: const Text('Login'), ); } } diff --git a/examples/flutter_login/lib/login/view/login_page.dart b/examples/flutter_login/lib/login/view/login_page.dart index d8e7c102bf2..529a946d6dc 100644 --- a/examples/flutter_login/lib/login/view/login_page.dart +++ b/examples/flutter_login/lib/login/view/login_page.dart @@ -16,12 +16,9 @@ class LoginPage extends StatelessWidget { body: Padding( padding: const EdgeInsets.all(12), child: BlocProvider( - create: (context) { - return LoginBloc( - authenticationRepository: - RepositoryProvider.of(context), - ); - }, + create: (context) => LoginBloc( + authenticationRepository: context.read(), + ), child: const LoginForm(), ), ),