TF-1694 Use KeyboardUtils to centralized management show/hide keyboard

(cherry picked from commit e2598476ecdc8c5d16a17dc3c777a34620013c64)
This commit is contained in:
dab246
2023-04-07 07:33:53 +07:00
committed by Dat Vu
parent ee686f2400
commit 84438efc89
18 changed files with 89 additions and 54 deletions
@@ -1,10 +1,12 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
class KeyboardUtils {
void hideKeyboard(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
static void hideKeyboard(BuildContext context) {
FocusScope.of(context).unfocus();
}
static void hideSystemKeyboardMobile() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
}
@@ -1,4 +1,15 @@
import 'package:core/core.dart';
import 'package:core/presentation/extensions/capitalize_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/html_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/context_menu/simple_context_menu_action_builder.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:core/presentation/views/list/sliver_grid_delegate_fixed_height.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:file_picker/file_picker.dart';
import 'package:filesize/filesize.dart';
@@ -7,7 +18,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/model.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/prefix_email_address.dart';
import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
@@ -27,7 +41,6 @@ class ComposerView extends GetWidget<ComposerController>
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
final keyboardUtils = Get.find<KeyboardUtils>();
ComposerView({Key? key}) : super(key: key);
@@ -1,4 +1,16 @@
import 'package:core/core.dart';
import 'package:core/presentation/extensions/capitalize_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/html_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/html_transformer/html_template.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:file_picker/file_picker.dart';
import 'package:filesize/filesize.dart';
@@ -7,7 +19,10 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:html_editor_enhanced/html_editor.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/model.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/prefix_email_address.dart';
import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
@@ -29,7 +44,6 @@ class ComposerView extends GetWidget<ComposerController>
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
final appToast = Get.find<AppToast>();
final keyboardUtils = Get.find<KeyboardUtils>();
ComposerView({Key? key}) : super(key: key);
@@ -1,4 +1,5 @@
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart';
@@ -171,7 +172,7 @@ class ContactController extends BaseController {
}
void selectContact(BuildContext context, EmailAddress emailAddress) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
onSelectedContactCallback?.call(emailAddress);
@@ -182,7 +183,7 @@ class ContactController extends BaseController {
void closeContactView(BuildContext context) {
clearAllTextInputSearchForm();
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
onDismissContactView?.call();
@@ -2,6 +2,7 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -265,7 +266,7 @@ class DestinationPickerController extends BaseMailboxController {
searchState.value = searchState.value.disableSearchState();
searchQuery.value = SearchQuery.initial();
searchInputController?.clear();
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
}
void clearSearchText() {
@@ -368,7 +369,7 @@ class DestinationPickerController extends BaseMailboxController {
}
void dispatchSelectMailboxDestination(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (mailboxDestination.value == null) {
_appToast.showToastErrorMessage(
@@ -385,7 +386,7 @@ class DestinationPickerController extends BaseMailboxController {
}
void createNewMailboxAction(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
final nameMailbox = newNameMailbox.value;
if (nameMailbox != null && nameMailbox.isNotEmpty) {
@@ -408,7 +409,7 @@ class DestinationPickerController extends BaseMailboxController {
void backToDestinationScreen(BuildContext context) {
nameInputController?.clear();
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
destinationScreenType.value = DestinationScreenType.destinationPicker;
}
@@ -424,7 +425,7 @@ class DestinationPickerController extends BaseMailboxController {
}
void closeDestinationPicker(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
onDismissDestinationPicker?.call();
@@ -1,10 +1,10 @@
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:get/get_core/get_core.dart';
import 'package:get/get_instance/get_instance.dart';
import 'package:get/get_rx/get_rx.dart';
@@ -17,7 +17,9 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/identity_extension.dart';
import 'package:model/user/user_profile.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
@@ -426,9 +428,9 @@ class IdentityCreatorController extends BaseController {
void clearFocusEditor(BuildContext context) {
if (!BuildUtils.isWeb) {
keyboardRichTextController.htmlEditorApi?.unfocus();
KeyboardUtils.hideSystemKeyboardMobile();
}
SystemChannels.textInput.invokeMethod('TextInput.hide');
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
}
void closeView(BuildContext context) {
@@ -1,4 +1,4 @@
import 'package:core/core.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
@@ -14,8 +14,6 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class LoginView extends BaseLoginView {
final keyboardUtils = Get.find<KeyboardUtils>();
LoginView({Key? key}) : super(key: key);
@override
@@ -439,7 +439,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
PresentationMailbox presentationMailboxSelected
) {
log('MailboxController::_handleOpenMailbox(): ');
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
mailboxDashBoardController.clearSelectedEmail();
if (presentationMailboxSelected.id != mailboxDashBoardController.selectedMailbox.value?.id) {
@@ -134,7 +134,7 @@ class MailboxCreatorController extends BaseController {
}
void selectMailboxLocation(BuildContext context) async {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (accountId != null) {
final arguments = DestinationPickerArguments(
@@ -180,7 +180,7 @@ class MailboxCreatorController extends BaseController {
}
void createNewMailbox(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
final nameMailbox = newNameMailbox.value;
final nameValidated = getErrorInputNameString(context);
@@ -203,7 +203,7 @@ class MailboxCreatorController extends BaseController {
}
void closeMailboxCreator(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
onDismissMailboxCreator?.call();
@@ -531,7 +531,7 @@ class MailboxDashBoardController extends ReloadableController {
clearFilterMessageOption();
searchController.updateFilterEmail(text: SearchQuery(value));
dispatchAction(StartSearchEmailAction());
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (_searchInsideEmailDetailedViewIsActive(context)) {
_closeEmailDetailedView();
}
@@ -3,6 +3,7 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -233,7 +234,7 @@ class ForwardController extends BaseController {
}
void addRecipientAction(BuildContext context, List<EmailAddress> listRecipientsSelected) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
final accountId = accountDashBoardController.accountId.value;
if (accountId != null) {
@@ -239,7 +239,7 @@ class VacationController extends BaseController {
}
void saveVacation(BuildContext context) async {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (vacationPresentation.value.isEnabled) {
final fromDate = vacationPresentation.value.fromDate;
@@ -346,7 +346,7 @@ class VacationController extends BaseController {
if (!BuildUtils.isWeb) {
richTextControllerForMobile.htmlEditorApi?.unfocus();
}
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
}
void backToUniversalSettings(BuildContext context) {
@@ -445,7 +445,7 @@ class VacationView extends GetWidget<VacationController> with RichTextButtonMixi
}, onChangeContent: (String? changed) {
controller.updateMessageHtmlText(changed);
}, onFocus: () {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
Future.delayed(const Duration(milliseconds: 500), () {
controller.richTextControllerForWeb.editorController.setFocus();
});
@@ -1,6 +1,7 @@
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/cupertino.dart';
@@ -248,7 +249,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
}
void createNewRuleFilter(BuildContext context) async {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
final errorName = _getErrorStringByInputValue(context, _newRuleName);
if (errorName?.isNotEmpty == true) {
@@ -341,7 +342,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
void closeView(BuildContext context) {
_clearAll();
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
onDismissRuleFilterCreator?.call();
@@ -230,7 +230,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
value: controller.mailboxSelected.value,
borderColor: _getBorderColorMailboxSelected(),
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.selectMailbox(context);
}))),
])
@@ -390,7 +390,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
value: controller.mailboxSelected.value,
borderColor: _getBorderColorMailboxSelected(),
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.selectMailbox(context);
}))),
])
@@ -493,7 +493,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
return RuleFilterButtonField<rule_condition.Field>(
value: controller.ruleConditionFieldSelected.value,
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.openContextMenuAction(
context,
_bottomSheetRuleConditionFieldActionTiles(
@@ -508,7 +508,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
return RuleFilterButtonField<rule_condition.Comparator>(
value: controller.ruleConditionComparatorSelected.value,
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.openContextMenuAction(
context,
_bottomSheetRuleConditionComparatorActionTiles(
@@ -553,7 +553,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
return RuleFilterButtonField<EmailRuleFilterAction>(
value: controller.emailRuleFilterActionSelected.value,
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.openContextMenuAction(
context,
_bottomSheetActionRuleFilterActionTiles(
@@ -579,7 +579,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
value: controller.mailboxSelected.value,
borderColor: _getBorderColorMailboxSelected(),
tapActionCallback: (value) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
controller.selectMailbox(context);
}))
])
@@ -1,6 +1,7 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:dartz/dartz.dart';
@@ -282,7 +283,7 @@ class SearchEmailController extends BaseController
}
void _searchEmailAction(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (session != null && accountId != null) {
canSearchMore = true;
@@ -665,7 +666,7 @@ class SearchEmailController extends BaseController
log('SearchEmailController::closeSearchView(): ');
clearAllTextInputSearchForm();
clearAllResultSearch();
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
mailboxDashBoardController.searchController.disableAllSearchEmail();
mailboxDashBoardController.dispatchMailboxUIAction(SelectMailboxDefaultAction());
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
@@ -4,6 +4,7 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/keyboard_utils.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
@@ -189,7 +190,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
}
void handleSearchButtonPressed(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
searchMailboxAction();
}
@@ -211,7 +212,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
}
void submitSearchAction(BuildContext context, String query) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
currentSearchQuery.value = query;
searchMailboxAction();
}
@@ -429,7 +430,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
}
void openMailboxAction(BuildContext context, PresentationMailbox mailbox) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
dashboardController.openMailboxAction(context, mailbox);
if (!responsiveUtils.isWebDesktop(context)) {
@@ -602,7 +603,7 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
}
void closeSearchView(BuildContext context) {
FocusScope.of(context).unfocus();
KeyboardUtils.hideKeyboard(context);
if (BuildUtils.isWeb) {
dashboardController.searchMailboxActivated.value = false;
clearAllTextInputSearchForm();
+6 -6
View File
@@ -1,4 +1,9 @@
import 'package:core/core.dart';
import 'package:core/data/utils/compress_file_utils.dart';
import 'package:core/data/utils/device_manager.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/config/app_config_loader.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
@@ -14,7 +19,6 @@ class CoreBindings extends Bindings {
await _bindingSharePreference();
_bindingAppImagePaths();
_bindingResponsiveManager();
_bindingKeyboardManager();
_bindingTransformer();
_bindingToast();
_bindingDeviceManager();
@@ -34,10 +38,6 @@ class CoreBindings extends Bindings {
await Get.putAsync(() async => await SharedPreferences.getInstance(), permanent: true);
}
void _bindingKeyboardManager() {
Get.put(KeyboardUtils());
}
void _bindingTransformer() {
Get.put(HtmlAnalyzer());
}