diff --git a/lib/features/login/presentation/base_login_view.dart b/lib/features/login/presentation/base_login_view.dart index 5036c6a65..f91cd79e6 100644 --- a/lib/features/login/presentation/base_login_view.dart +++ b/lib/features/login/presentation/base_login_view.dart @@ -94,11 +94,13 @@ abstract class BaseLoginView extends GetWidget { } Widget buildInputCredentialForm(BuildContext context) { - return Column( - children: [ - buildUserNameInput(context), - buildPasswordInput(context) - ], + return AutofillGroup( + child: Column( + children: [ + buildUserNameInput(context), + buildPasswordInput(context) + ], + ), ); } @@ -111,6 +113,8 @@ abstract class BaseLoginView extends GetWidget { controller: loginController.usernameInputController, onChanged: (value) => loginController.setUserNameText(value), textInputAction: TextInputAction.next, + autocorrect: false, + autofillHints: [AutofillHints.email], keyboardType: TextInputType.emailAddress, decoration: (LoginInputDecorationBuilder() ..setLabelText(AppLocalizations.of(context).email) @@ -141,16 +145,21 @@ abstract class BaseLoginView extends GetWidget { return Padding( padding: const EdgeInsets.only(bottom: 40, right: 24, left: 24), child: Container( - child: (LoginTextInputBuilder(context, imagePaths) - ..setOnSubmitted((value) => loginController.handleLoginPressed()) - ..passwordInput(true) - ..key(const Key('login_password_input')) - ..obscureText(true) - ..onChange((value) => loginController.setPasswordText(value)) - ..textInputAction(TextInputAction.done) - ..hintText(AppLocalizations.of(context).password) - ..setFocusNode(passFocusNode)) - .build())); + child: (LoginTextInputBuilder( + context, + imagePaths, + autocorrect: false, + autofillHints: [AutofillHints.password] + ) + ..setOnSubmitted((value) => loginController.handleLoginPressed()) + ..passwordInput(true) + ..key(const Key('login_password_input')) + ..obscureText(true) + ..onChange(loginController.setPasswordText) + ..textInputAction(TextInputAction.done) + ..hintText(AppLocalizations.of(context).password) + ..setFocusNode(passFocusNode)) + .build())); } Widget buildLoadingCircularProgress() { diff --git a/lib/features/login/presentation/login_controller.dart b/lib/features/login/presentation/login_controller.dart index 0db67a368..db3a0f3a1 100644 --- a/lib/features/login/presentation/login_controller.dart +++ b/lib/features/login/presentation/login_controller.dart @@ -7,6 +7,7 @@ import 'package:core/utils/build_utils.dart'; import 'package:dartz/dartz.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:model/account/password.dart'; @@ -241,6 +242,8 @@ class LoginController extends ReloadableController { } void handleLoginPressed() { + TextInput.finishAutofillContext(); + _saveRecentLoginUsername(); log('LoginController::handleLoginPressed(): ${loginFormType.value}'); if (loginFormType.value == LoginFormType.ssoForm) { diff --git a/lib/features/login/presentation/widgets/login_text_input_builder.dart b/lib/features/login/presentation/widgets/login_text_input_builder.dart index d35bf9622..25785f66e 100644 --- a/lib/features/login/presentation/widgets/login_text_input_builder.dart +++ b/lib/features/login/presentation/widgets/login_text_input_builder.dart @@ -24,11 +24,19 @@ class LoginTextInputBuilder { bool? _passwordInput; OnSubmitted? _onSubmitted; FocusNode? _focusNode; - + final List? autofillHints; + final bool autocorrect; final BuildContext context; final ImagePaths imagePaths; - LoginTextInputBuilder(this.context, this.imagePaths); + LoginTextInputBuilder( + this.context, + this.imagePaths, + { + this.autocorrect = true, + this.autofillHints + } + ); void key(Key key) { _key = key; @@ -119,6 +127,8 @@ class LoginTextInputBuilder { onChanged: (value) => _onTextChanged(value, setState), obscureText: _obscureText ?? false, textInputAction: _textInputAction, + autofillHints: autofillHints, + autocorrect: autocorrect, controller: _textEditingController, cursorColor: AppColor.primaryColor, style: const TextStyle(color: AppColor.loginTextFieldHintColor, fontSize: 16, fontWeight: FontWeight.normal), diff --git a/pubspec.lock b/pubspec.lock index 69506d8b2..4c48f0c8b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -772,11 +772,12 @@ packages: flutter_typeahead: dependency: "direct main" description: - name: flutter_typeahead - sha256: "3f7509bc1d43e245e0bfdc180f206508bc5ab0e0d84ce1b891cb0e4176b7802f" - url: "https://pub.dev" - source: hosted - version: "4.3.6" + path: "." + ref: support-autofillhint + resolved-ref: "121707e2c283dae5299dc22974850d65f6c97b83" + url: "https://github.com/dab246/flutter_typeahead.git" + source: git + version: "4.3.7" flutter_web_plugins: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 7676a5362..8d6a57358 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -81,6 +81,11 @@ dependencies: url: https://github.com/linagora/flutter-date-range-picker.git ref: master + flutter_typeahead: + git: + url: https://github.com/dab246/flutter_typeahead.git + ref: support-autofillhint + ### Dependencies from pub.dev ### cupertino_icons: 1.0.5 @@ -100,8 +105,6 @@ dependencies: flutter_dotenv: 5.0.2 - flutter_typeahead: 4.3.6 - built_collection: 5.1.1 textfield_tags: 2.0.2