TF-2101 Update email_recovery controller to fit text input fields
(cherry picked from commit 155450df2877ff9fb74b25e27b5947c09a749f26)
This commit is contained in:
@@ -1,15 +1,33 @@
|
|||||||
import 'package:core/presentation/utils/keyboard_utils.dart';
|
import 'package:core/presentation/utils/keyboard_utils.dart';
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
|
import 'package:model/autocomplete/auto_complete_pattern.dart';
|
||||||
|
import 'package:model/mailbox/expand_mode.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:super_tag_editor/tag_editor.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/date_range_picker_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/date_range_picker_mixin.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/state/get_autocomplete_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/state/get_device_contact_suggestions_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_all_autocomplete_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_autocomplete_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/get_device_contact_suggestions_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/email_recovery/presentation/controller/input_field_focus_manager.dart';
|
import 'package:tmail_ui_user/features/email_recovery/presentation/controller/input_field_focus_manager.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_time_type.dart';
|
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_time_type.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
|
|
||||||
class EmailRecoveryController extends BaseController with DateRangePickerMixin {
|
class EmailRecoveryController extends BaseController with DateRangePickerMixin {
|
||||||
|
GetAllAutoCompleteInteractor? _getAllAutoCompleteInteractor;
|
||||||
|
GetAutoCompleteInteractor? _getAutoCompleteInteractor;
|
||||||
|
GetDeviceContactSuggestionsInteractor? _getDeviceContactSuggestionsInteractor;
|
||||||
|
|
||||||
final deletionDateFieldSelected = EmailRecoveryTimeType.last1Year.obs;
|
final deletionDateFieldSelected = EmailRecoveryTimeType.last1Year.obs;
|
||||||
final receptionDateFieldSelected = EmailRecoveryTimeType.allTime.obs;
|
final receptionDateFieldSelected = EmailRecoveryTimeType.allTime.obs;
|
||||||
@@ -17,13 +35,106 @@ class EmailRecoveryController extends BaseController with DateRangePickerMixin {
|
|||||||
final endDeletionDate = Rxn<DateTime>();
|
final endDeletionDate = Rxn<DateTime>();
|
||||||
final startReceptionDate = Rxn<DateTime>();
|
final startReceptionDate = Rxn<DateTime>();
|
||||||
final endReceptionDate = Rxn<DateTime>();
|
final endReceptionDate = Rxn<DateTime>();
|
||||||
|
final recipientsExpandMode = ExpandMode.EXPAND.obs;
|
||||||
|
final senderExpandMode = ExpandMode.EXPAND.obs;
|
||||||
|
|
||||||
final focusManager = InputFieldFocusManager.initial();
|
final focusManager = InputFieldFocusManager.initial();
|
||||||
|
|
||||||
List<EmailAddress> listRecipients = <EmailAddress>[];
|
List<EmailAddress> listRecipients = <EmailAddress>[];
|
||||||
List<EmailAddress> listSenders = <EmailAddress>[];
|
List<EmailAddress> listSenders = <EmailAddress>[];
|
||||||
|
|
||||||
|
TextEditingController subjectFieldInputController = TextEditingController();
|
||||||
|
TextEditingController recipientsFieldInputController = TextEditingController();
|
||||||
|
TextEditingController senderFieldInputController = TextEditingController();
|
||||||
|
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
|
||||||
|
|
||||||
|
final GlobalKey<TagsEditorState> recipientsFieldKey = GlobalKey<TagsEditorState>();
|
||||||
|
final GlobalKey<TagsEditorState> senderFieldKey = GlobalKey<TagsEditorState>();
|
||||||
|
|
||||||
|
EmailRecoveryArguments? arguments;
|
||||||
|
AccountId? _accountId;
|
||||||
|
Session? _session;
|
||||||
|
|
||||||
EmailRecoveryController();
|
EmailRecoveryController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
_registerFocusListener();
|
||||||
|
log('EmailRecoveryController::onInit():arguments: ${Get.arguments}');
|
||||||
|
arguments = Get.arguments;
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
log('EmailRecoveryController::onReady():');
|
||||||
|
if (arguments != null) {
|
||||||
|
_accountId = arguments!.accountId;
|
||||||
|
_session = arguments!.session;
|
||||||
|
}
|
||||||
|
if (PlatformInfo.isMobile) {
|
||||||
|
Future.delayed(
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
|
() => _checkContactPermission(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
injectAutoCompleteBindings(_session, _accountId);
|
||||||
|
super.onReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _checkContactPermission() async {
|
||||||
|
final permissionStatus = await Permission.contacts.status;
|
||||||
|
if (permissionStatus.isGranted) {
|
||||||
|
_contactSuggestionSource = ContactSuggestionSource.all;
|
||||||
|
} else if (!permissionStatus.isPermanentlyDenied) {
|
||||||
|
final requestedPermission = await Permission.contacts.request();
|
||||||
|
_contactSuggestionSource =
|
||||||
|
requestedPermission == PermissionStatus.granted
|
||||||
|
? ContactSuggestionSource.all
|
||||||
|
: _contactSuggestionSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _registerFocusListener() {
|
||||||
|
focusManager.subjectFieldFocusNode.addListener(_onSubjectFieldFocusChanged);
|
||||||
|
focusManager.recipientsFieldFocusNode.addListener(_onRecipientsFieldFocusChanged);
|
||||||
|
focusManager.senderFieldFocusNode.addListener(_onSenderFieldFocusChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSubjectFieldFocusChanged() {
|
||||||
|
if (focusManager.subjectFieldFocusNode.hasFocus) {
|
||||||
|
senderExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
recipientsExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
_closeSuggestionBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onRecipientsFieldFocusChanged() {
|
||||||
|
if (focusManager.recipientsFieldFocusNode.hasFocus) {
|
||||||
|
recipientsExpandMode.value = ExpandMode.EXPAND;
|
||||||
|
senderExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
_closeSuggestionBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSenderFieldFocusChanged() {
|
||||||
|
if (focusManager.senderFieldFocusNode.hasFocus) {
|
||||||
|
senderExpandMode.value = ExpandMode.EXPAND;
|
||||||
|
recipientsExpandMode.value = ExpandMode.COLLAPSE;
|
||||||
|
_closeSuggestionBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _closeSuggestionBox() {
|
||||||
|
if (recipientsFieldInputController.text.isNotEmpty) {
|
||||||
|
recipientsFieldKey.currentState?.closeSuggestionBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (senderFieldInputController.text.isNotEmpty) {
|
||||||
|
senderFieldKey.currentState?.closeSuggestionBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onSelectDeletionDateRange(BuildContext context) {
|
void onSelectDeletionDateRange(BuildContext context) {
|
||||||
showMultipleViewDateRangePicker(
|
showMultipleViewDateRangePicker(
|
||||||
context,
|
context,
|
||||||
@@ -99,8 +210,92 @@ class EmailRecoveryController extends BaseController with DateRangePickerMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<EmailAddress>> getAutoCompleteSuggestion(String word) async {
|
||||||
|
log('EmailRecoveryController::getAutoCompleteSuggestion(): $word | $_contactSuggestionSource');
|
||||||
|
_getAllAutoCompleteInteractor = getBinding<GetAllAutoCompleteInteractor>();
|
||||||
|
_getAutoCompleteInteractor = getBinding<GetAutoCompleteInteractor>();
|
||||||
|
_getDeviceContactSuggestionsInteractor = getBinding<GetDeviceContactSuggestionsInteractor>();
|
||||||
|
|
||||||
|
if (_contactSuggestionSource == ContactSuggestionSource.all) {
|
||||||
|
if (_getAllAutoCompleteInteractor != null) {
|
||||||
|
return await _getAllAutoCompleteInteractor!
|
||||||
|
.execute(AutoCompletePattern(word: word, accountId: _accountId))
|
||||||
|
.then((value) => value.fold(
|
||||||
|
(failure) => <EmailAddress>[],
|
||||||
|
(success) => success is GetAutoCompleteSuccess
|
||||||
|
? success.listEmailAddress
|
||||||
|
: <EmailAddress>[]
|
||||||
|
));
|
||||||
|
} else if (_getDeviceContactSuggestionsInteractor != null) {
|
||||||
|
return await _getDeviceContactSuggestionsInteractor!
|
||||||
|
.execute(AutoCompletePattern(word: word, accountId: _accountId))
|
||||||
|
.then((value) => value.fold(
|
||||||
|
(failure) => <EmailAddress>[],
|
||||||
|
(success) => success is GetDeviceContactSuggestionsSuccess
|
||||||
|
? success.listEmailAddress
|
||||||
|
: <EmailAddress>[]
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return <EmailAddress>[];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_getAutoCompleteInteractor == null) {
|
||||||
|
return <EmailAddress>[];
|
||||||
|
} else {
|
||||||
|
return await _getAutoCompleteInteractor!
|
||||||
|
.execute(AutoCompletePattern(word: word, accountId: _accountId))
|
||||||
|
.then((value) => value.fold(
|
||||||
|
(failure) => <EmailAddress>[],
|
||||||
|
(success) => success is GetAutoCompleteSuccess
|
||||||
|
? success.listEmailAddress
|
||||||
|
: <EmailAddress>[]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFullEmailAddress(EmailRecoveryField field) {
|
||||||
|
switch (field) {
|
||||||
|
case EmailRecoveryField.recipients:
|
||||||
|
recipientsExpandMode.value = ExpandMode.EXPAND;
|
||||||
|
break;
|
||||||
|
case EmailRecoveryField.sender:
|
||||||
|
senderExpandMode.value = ExpandMode.EXPAND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateListEmailAddress(
|
||||||
|
EmailRecoveryField field,
|
||||||
|
List<EmailAddress> listEmailAddress,
|
||||||
|
) {
|
||||||
|
switch (field) {
|
||||||
|
case EmailRecoveryField.recipients:
|
||||||
|
listRecipients = List.from(listEmailAddress);
|
||||||
|
log('EmailRecoveryController::updateListEmailAddress(): listRecipients: ${listRecipients.first}');
|
||||||
|
break;
|
||||||
|
case EmailRecoveryField.sender:
|
||||||
|
listSenders = List.from(listEmailAddress);
|
||||||
|
log('EmailRecoveryController::updateListEmailAddress(): listSenders: ${listSenders.first}');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void closeView(BuildContext context) {
|
void closeView(BuildContext context) {
|
||||||
KeyboardUtils.hideKeyboard(context);
|
KeyboardUtils.hideKeyboard(context);
|
||||||
popBack();
|
popBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
focusManager.subjectFieldFocusNode.removeListener(_onSubjectFieldFocusChanged);
|
||||||
|
focusManager.recipientsFieldFocusNode.removeListener(_onRecipientsFieldFocusChanged);
|
||||||
|
focusManager.senderFieldFocusNode.removeListener(_onSenderFieldFocusChanged);
|
||||||
|
focusManager.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user