TF-1155 Automatically collapsed and created tags when fields lose focus

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit 6c2ffefca87d26b115bae628e48a0ed356de6b33)
This commit is contained in:
dab246
2023-11-08 13:50:49 +07:00
committed by Dat Vu
parent bfb35a7187
commit a0fede7b8f
4 changed files with 49 additions and 67 deletions
@@ -52,7 +52,6 @@ class AdvancedFilterController extends BaseController {
TextEditingController fromEmailAddressController = TextEditingController();
TextEditingController toEmailAddressController = TextEditingController();
TextEditingController subjectFilterInputController = TextEditingController();
TextEditingController hasKeyWordFilterInputController = TextEditingController();
TextEditingController notKeyWordFilterInputController = TextEditingController();
@@ -74,6 +73,7 @@ class AdvancedFilterController extends BaseController {
@override
void onInit() {
_registerWorkerListener();
_registerFocusListener();
super.onInit();
}
@@ -311,22 +311,25 @@ class AdvancedFilterController extends BaseController {
}
}
void onEmailAddressFocusChange(AdvancedSearchFilterField field, bool hasFocus) {
if (hasFocus) {
switch(field) {
case AdvancedSearchFilterField.form:
fromAddressExpandMode.value = ExpandMode.EXPAND;
toAddressExpandMode.value = ExpandMode.COLLAPSE;
break;
case AdvancedSearchFilterField.to:
fromAddressExpandMode.value = ExpandMode.COLLAPSE;
toAddressExpandMode.value = ExpandMode.EXPAND;
break;
default:
break;
}
void _onFromFieldFocusChange() {
if (focusManager.fromFieldFocusNode.hasFocus) {
fromAddressExpandMode.value = ExpandMode.EXPAND;
toAddressExpandMode.value = ExpandMode.COLLAPSE;
_closeSuggestionBox();
} else {
fromAddressExpandMode.value = ExpandMode.COLLAPSE;
_autoCreateTagFromField();
}
}
void _onToFieldFocusChange() {
if (focusManager.toFieldFocusNode.hasFocus) {
toAddressExpandMode.value = ExpandMode.EXPAND;
fromAddressExpandMode.value = ExpandMode.COLLAPSE;
_closeSuggestionBox();
} else {
toAddressExpandMode.value = ExpandMode.COLLAPSE;
_autoCreateTagToField();
}
}
@@ -342,7 +345,7 @@ class AdvancedFilterController extends BaseController {
void showFullEmailAddress(AdvancedSearchFilterField field) {
switch(field) {
case AdvancedSearchFilterField.form:
case AdvancedSearchFilterField.from:
fromAddressExpandMode.value = ExpandMode.EXPAND;
toAddressExpandMode.value = ExpandMode.COLLAPSE;
focusManager.fromFieldFocusNode.requestFocus();
@@ -364,7 +367,7 @@ class AdvancedFilterController extends BaseController {
List<EmailAddress> listEmailAddress,
) {
switch(field) {
case AdvancedSearchFilterField.form:
case AdvancedSearchFilterField.from:
listFromEmailAddress = List.from(listEmailAddress);
searchEmailFilter.from.addAll(listEmailAddress.map((emailAddress) => emailAddress.emailAddress));
break;
@@ -384,12 +387,15 @@ class AdvancedFilterController extends BaseController {
.contains(inputEmail);
}
void _autoCreateFromEmailTag(String inputEmail) {
void _autoCreateTagFromField() {
final inputEmail = fromEmailAddressController.text;
if (inputEmail.isEmpty) {
return;
}
if (!_isDuplicatedEmailAddress(inputEmail, listFromEmailAddress)) {
final emailAddress = EmailAddress(null, inputEmail);
listFromEmailAddress.add(emailAddress);
log('AdvancedFilterController::_autoCreateFromEmailTag(): STATE: ${keyFromEmailTagEditor.currentState}');
keyFromEmailTagEditor.currentState?.resetTextField();
Future.delayed(const Duration(milliseconds: 300), () {
keyFromEmailTagEditor.currentState?.closeSuggestionBox();
@@ -397,12 +403,15 @@ class AdvancedFilterController extends BaseController {
}
}
void _autoCreateToEmailTag(String inputEmail) {
void _autoCreateTagToField() {
final inputEmail = toEmailAddressController.text;
if (inputEmail.isEmpty) {
return;
}
if (!_isDuplicatedEmailAddress(inputEmail, listToEmailAddress)) {
final emailAddress = EmailAddress(null, inputEmail);
listToEmailAddress.add(emailAddress);
log('AdvancedFilterController::_autoCreateToEmailTag(): STATE: ${keyToEmailTagEditor.currentState}');
keyToEmailTagEditor.currentState?.resetTextField();
Future.delayed(const Duration(milliseconds: 300), () {
keyToEmailTagEditor.currentState?.closeSuggestionBox();
@@ -410,39 +419,6 @@ class AdvancedFilterController extends BaseController {
}
}
void _autoCreateEmailTag() {
final inputFromEmail = fromEmailAddressController.text;
final inputToEmail = toEmailAddressController.text;
if (inputFromEmail.isNotEmpty) {
_autoCreateFromEmailTag(inputFromEmail);
}
if (inputToEmail.isNotEmpty) {
_autoCreateToEmailTag(inputToEmail);
}
}
void handleFocusNextAddressAction() {
_autoCreateEmailTag();
}
void removeEmailAddress(EmailAddress emailAddress, AdvancedSearchFilterField field) {
log('AdvancedFilterController::removeEMailAddress: $emailAddress - $field');
switch(field) {
case AdvancedSearchFilterField.form:
listFromEmailAddress.remove(emailAddress);
fromAddressExpandMode.value = ExpandMode.EXPAND;
break;
case AdvancedSearchFilterField.to:
listToEmailAddress.remove(emailAddress);
toAddressExpandMode.value = ExpandMode.EXPAND;
break;
default:
break;
}
}
void _resetAllToOriginalValue() {
dateFilterSelectedFormAdvancedSearch.value = EmailReceiveTimeType.allTime;
hasAttachment.value = false;
@@ -480,10 +456,20 @@ class AdvancedFilterController extends BaseController {
);
}
void _registerFocusListener() {
focusManager.fromFieldFocusNode.addListener(_onFromFieldFocusChange);
focusManager.toFieldFocusNode.addListener(_onToFieldFocusChange);
}
void _unregisterWorkerListener() {
_dashboardActionWorker.dispose();
}
void _removeFocusListener() {
focusManager.fromFieldFocusNode.removeListener(_onFromFieldFocusChange);
focusManager.toFieldFocusNode.removeListener(_onToFieldFocusChange);
}
void _handleClearAllFieldOfAdvancedSearch() {
_resetAllToOriginalValue();
_clearAllTextFieldInput();
@@ -491,6 +477,7 @@ class AdvancedFilterController extends BaseController {
@override
void onClose() {
_removeFocusListener();
focusManager.dispose();
subjectFilterInputController.dispose();
hasKeyWordFilterInputController.dispose();
@@ -3,7 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum AdvancedSearchFilterField {
form,
from,
to,
subject,
hasKeyword,
@@ -14,7 +14,7 @@ enum AdvancedSearchFilterField {
String getTitle(BuildContext context) {
switch (this) {
case AdvancedSearchFilterField.form:
case AdvancedSearchFilterField.from:
return AppLocalizations.of(context).form;
case AdvancedSearchFilterField.to:
return AppLocalizations.of(context).to;
@@ -35,7 +35,7 @@ enum AdvancedSearchFilterField {
String getHintText(BuildContext context) {
switch (this) {
case AdvancedSearchFilterField.form:
case AdvancedSearchFilterField.from:
case AdvancedSearchFilterField.to:
return AppLocalizations.of(context).nameOrEmailAddress;
case AdvancedSearchFilterField.subject:
@@ -30,7 +30,7 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
child: Obx(() => Column(
children: [
TextFieldAutocompleteEmailAddressWeb(
field: AdvancedSearchFilterField.form,
field: AdvancedSearchFilterField.from,
listEmailAddress: controller.listFromEmailAddress,
expandMode: controller.fromAddressExpandMode.value,
controller: controller.fromEmailAddressController,
@@ -40,7 +40,6 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onRemoveEmailAddressAction: controller.removeEmailAddress,
),
TextFieldAutocompleteEmailAddressWeb(
field: AdvancedSearchFilterField.to,
@@ -53,7 +52,6 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onRemoveEmailAddressAction: controller.removeEmailAddress,
),
_buildFilterField(
textEditingController: controller.subjectFilterInputController,
@@ -21,7 +21,6 @@ typedef OnSuggestionEmailAddress = Future<List<EmailAddress>> Function(String wo
typedef OnUpdateListEmailAddressAction = void Function(AdvancedSearchFilterField field, List<EmailAddress> newData);
typedef OnDeleteEmailAddressTypeAction = void Function(AdvancedSearchFilterField field);
typedef OnShowFullListEmailAddressAction = void Function(AdvancedSearchFilterField field);
typedef OnRemoveEmailAddressAction = void Function(EmailAddress emailAddress, AdvancedSearchFilterField field);
typedef OnDeleteTagAction = void Function(EmailAddress emailAddress);
class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
@@ -39,7 +38,6 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
final OnUpdateListEmailAddressAction? onUpdateListEmailAddressAction;
final OnDeleteEmailAddressTypeAction? onDeleteEmailAddressTypeAction;
final OnShowFullListEmailAddressAction? onShowFullListEmailAddressAction;
final OnRemoveEmailAddressAction? onRemoveEmailAddressAction;
final TextEditingController? controller;
const TextFieldAutocompleteEmailAddressWeb({
@@ -57,7 +55,6 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
this.onUpdateListEmailAddressAction,
this.onDeleteEmailAddressTypeAction,
this.onShowFullListEmailAddressAction,
this.onRemoveEmailAddressAction,
this.controller,
}) : super(key: key);
@@ -113,7 +110,7 @@ class _TextFieldAutocompleteEmailAddressWebState extends State<TextFieldAutocomp
textInputAction: TextInputAction.done,
debounceDuration: TextFieldAutoCompleteEmailAddressWebStyles.debounceDuration,
hasAddButton: false,
autofocus: widget.field == AdvancedSearchFilterField.form && _currentListEmailAddress.isEmpty,
autofocus: widget.field == AdvancedSearchFilterField.from && _currentListEmailAddress.isEmpty,
inputDecoration: InputDecoration(
filled: true,
fillColor: TextFieldAutoCompleteEmailAddressWebStyles.textInputFillColor,