enable remove suggestion tag in from field

This commit is contained in:
ManhNTX
2022-07-01 06:49:27 +07:00
committed by Dat H. Pham
parent 0f46a1c899
commit 263ee35a0a
9 changed files with 374 additions and 169 deletions
@@ -2,23 +2,24 @@
import 'package:core/core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
typedef OnOpenSearchViewAction = Function();
class SearchBarView {
OnOpenSearchViewAction? _onOpenSearchViewAction;
OnOpenSearchViewAction? _onOpenSearchViewAction;
final ImagePaths _imagePaths;
final ImagePaths _imagePaths;
double? _heightSearchBar;
EdgeInsets? _padding;
EdgeInsets? _margin;
String? _hintTextSearch;
double? _maxSizeWidth;
Widget? _rightButton;
SearchBarView(this._imagePaths);
SearchBarView(this._imagePaths);
void addOnOpenSearchViewAction(OnOpenSearchViewAction onOpenSearchViewAction) {
_onOpenSearchViewAction = onOpenSearchViewAction;
@@ -32,6 +33,10 @@ class SearchBarView {
_padding = padding;
}
void addRightButton(Widget rightButton) {
_rightButton = rightButton;
}
void addMargin(EdgeInsets margin) {
_margin = margin;
}
@@ -55,26 +60,29 @@ class SearchBarView {
color: AppColor.colorBgSearchBar),
padding: _padding ?? EdgeInsets.zero,
margin: _margin ?? EdgeInsets.zero,
child: InkWell(
onTap: () => _onOpenSearchViewAction?.call(),
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 8),
buildIconWeb(
splashRadius: 15,
minSize: 40,
iconPadding: EdgeInsets.zero,
icon: SvgPicture.asset(_imagePaths.icSearchBar, width: 16, height: 16, fit: BoxFit.fill),
onTap: () => _onOpenSearchViewAction?.call()),
Expanded(child:
Text(
_hintTextSearch ?? '',
maxLines: 1,
style: TextStyle(fontSize: kIsWeb ? 15 : 17, color: AppColor.colorHintSearchBar)))
]
)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 8),
buildIconWeb(
splashRadius: 15,
minSize: 40,
iconPadding: EdgeInsets.zero,
icon: SvgPicture.asset(_imagePaths.icSearchBar, width: 16, height: 16, fit: BoxFit.fill),
onTap: () => _onOpenSearchViewAction?.call()),
Expanded(
child: InkWell(
onTap: () => _onOpenSearchViewAction?.call(),
child: Text(
_hintTextSearch ?? '',
maxLines: 1,
style: TextStyle(fontSize: kIsWeb ? 15 : 17, color: AppColor.colorHintSearchBar)),
),
),
if(_rightButton != null)
_rightButton!
]
),
);
}
}
@@ -27,9 +27,8 @@ class AdvancedFilterController extends GetxController {
final dateFilterSelectedFormAdvancedSearch = EmailReceiveTimeType.allTime.obs;
final hasAttachment = false.obs;
final listEmailAddressInit = RxList<EmailAddress>();
final listTagFromSelected = RxList<String>();
final listTagToSelected = RxList<String>();
final lastTextForm = ''.obs;
final lastTextTo = ''.obs;
TextEditingController subjectFilterInputController = TextEditingController();
TextEditingController hasKeyWordFilterInputController =
TextEditingController();
@@ -40,7 +39,7 @@ class AdvancedFilterController extends GetxController {
ContactSuggestionSource _contactSuggestionSource =
ContactSuggestionSource.tMailContact;
final SearchController _searchController = Get.find<SearchController>();
final SearchController searchController = Get.find<SearchController>();
final MailboxDashBoardController _mailboxDashBoardController =
Get.find<MailboxDashBoardController>();
@@ -52,7 +51,7 @@ class AdvancedFilterController extends GetxController {
}
SearchEmailFilter get searchEmailFilter =>
_searchController.searchEmailFilter.value;
searchController.searchEmailFilter.value;
@override
void onReady() async {
@@ -64,52 +63,55 @@ class AdvancedFilterController extends GetxController {
}
void selectOpenAdvanceSearch() {
_searchController.isAdvancedSearchViewOpen.toggle();
searchController.isAdvancedSearchViewOpen.toggle();
}
void cleanSearchFilter(BuildContext context) {
_searchController.cleanSearchFilter();
searchController.cleanSearchFilter();
dateFilterSelectedFormAdvancedSearch.value = EmailReceiveTimeType.allTime;
listTagFromSelected.clear();
listTagToSelected.clear();
subjectFilterInputController.text = '';
hasKeyWordFilterInputController.text = '';
notKeyWordFilterInputController.text = '';
dateFilterInputController.text = '';
hasAttachment.value = false;
_searchController.isAdvancedSearchHasApply.value = false;
_searchController.isAdvancedSearchViewOpen.toggle();
searchController.isAdvancedSearchHasApply.value = false;
searchController.isAdvancedSearchViewOpen.toggle();
_mailboxDashBoardController.searchEmail(
context, StringConvert.writeNullToEmpty(searchEmailFilter.text?.value));
}
void _updateFilterEmailFromAdvancedSearchView() {
if (listTagFromSelected.isNotEmpty) {
_searchController.updateFilterEmail(
from: listTagFromSelected.toSet());
} else {
_searchController.updateFilterEmail(from: {});
}
if (listTagToSelected.isNotEmpty) {
_searchController.updateFilterEmail(
to: listTagToSelected.toSet());
} else {
_searchController.updateFilterEmail(to: {});
}
if (hasKeyWordFilterInputController.text.isNotEmpty) {
_searchController.updateFilterEmail(
hasKeyword: hasKeyWordFilterInputController.text.split(',').toSet());
searchController.updateFilterEmail(hasKeyword: hasKeyWordFilterInputController.text.split(',').toSet());
} else {
_searchController.updateFilterEmail(hasKeyword: {});
}
if (notKeyWordFilterInputController.text.isNotEmpty) {
_searchController.updateFilterEmail(
notKeyword: notKeyWordFilterInputController.text.split(',').toSet());
} else {
_searchController.updateFilterEmail(notKeyword: {});
searchController.updateFilterEmail(hasKeyword: {});
}
_searchController.updateFilterEmail(
if (notKeyWordFilterInputController.text.isNotEmpty) {
searchController.updateFilterEmail(notKeyword: notKeyWordFilterInputController.text.split(',').toSet());
} else {
searchController.updateFilterEmail(notKeyword: {});
}
if(lastTextForm.isNotEmpty && !searchController.searchEmailFilter.value.from.contains(lastTextForm.value)){
print(lastTextForm);
searchController.updateFilterEmail(
from: searchController.searchEmailFilter.value.from..add(lastTextForm.value),
);
lastTextForm.value = '';
}
if(lastTextTo.isNotEmpty && !searchController.searchEmailFilter.value.to.contains(lastTextTo.value)){
searchController.updateFilterEmail(
to: searchController.searchEmailFilter.value.to..add(lastTextTo.value),
);
lastTextTo.value = '';
}
searchController.updateFilterEmail(
subject:
StringConvert.writeEmptyToNull(subjectFilterInputController.text),
emailReceiveTimeType: dateFilterSelectedFormAdvancedSearch.value,
@@ -123,7 +125,7 @@ class AdvancedFilterController extends GetxController {
arguments: DestinationPickerArguments(
_mailboxDashBoardController.accountId.value!,
MailboxActions.moveEmail));
_searchController.updateFilterEmail(mailbox: destinationMailbox);
searchController.updateFilterEmail(mailbox: destinationMailbox);
mailBoxFilterInputController.text =
StringConvert.writeNullToEmpty(destinationMailbox.name?.name);
}
@@ -132,9 +134,8 @@ class AdvancedFilterController extends GetxController {
_updateFilterEmailFromAdvancedSearchView();
_mailboxDashBoardController.searchEmail(
context, StringConvert.writeNullToEmpty(searchEmailFilter.text?.value));
_searchController.isAdvancedSearchViewOpen.toggle();
_searchController.isAdvancedSearchHasApply.value =
_checkAdvancedSearchHasApply();
searchController.isAdvancedSearchViewOpen.toggle();
searchController.isAdvancedSearchHasApply.value = _checkAdvancedSearchHasApply();
}
void _checkContactPermission() async {
@@ -173,18 +174,18 @@ class AdvancedFilterController extends GetxController {
}
bool _checkAdvancedSearchHasApply() {
return listTagFromSelected.isNotEmpty ||
listTagToSelected.isNotEmpty ||
return searchEmailFilter.from.isNotEmpty ||
searchEmailFilter.to.isNotEmpty ||
subjectFilterInputController.text.isNotEmpty ||
hasKeyWordFilterInputController.text.isNotEmpty ||
notKeyWordFilterInputController.text.isNotEmpty ||
dateFilterInputController.text.isNotEmpty ||
mailBoxFilterInputController.text.isNotEmpty ||
searchEmailFilter.emailReceiveTimeType != EmailReceiveTimeType.allTime ||
searchEmailFilter.mailbox != _mailboxDashBoardController.selectedMailbox.value ||
hasAttachment.isTrue;
}
void initSearchFilterField(BuildContext context) {
_searchController.updateFilterEmail(
searchController.updateFilterEmail(
mailbox: _mailboxDashBoardController.selectedMailbox.value);
subjectFilterInputController.text =
StringConvert.writeNullToEmpty(searchEmailFilter.subject);
@@ -0,0 +1,51 @@
import 'package:textfield_tags/textfield_tags.dart';
class CustomController extends TextfieldTagsController {
CustomController() : super();
late Function(String)? actionRemoveTag;
late Function(String)? actionAddTag;
late Function(String)? actionChangeText;
//create your own methods
void setActionRemoveTag(Function(String) action) {
actionRemoveTag = action;
}
void setActionAddTag(Function(String) action) {
actionAddTag = action;
}
void setActionChangeText(Function(String) action) {
actionChangeText = action;
}
@override
set removeTag(String tag) {
actionRemoveTag?.call(tag);
super.removeTag = tag;
}
@override
void onTagDelete(String tag) {
actionRemoveTag?.call(tag);
super.onTagDelete(tag);
}
@override
void onChanged(String value) {
final ts = [' ', ','];
final separator = ts.cast<String?>().firstWhere(
(element) => value.contains(element!) && value.indexOf(element) != 0,
orElse: () => null);
actionChangeText?.call(value);
if (separator != null) {
final splits = value.split(separator);
final indexer = splits.length > 1 ? splits.length - 2 : splits.length - 1;
final val = splits.elementAt(indexer).trim();
if(val.isNotEmpty){
actionAddTag?.call(val);
}
}
super.onChanged(value);
}
}
@@ -167,11 +167,26 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
Obx(() => !searchController.isSearchActive() ? const Spacer() : const SizedBox.shrink()),
Obx(() => searchController.isSearchActive()
? Expanded(child: _buildSearchForm(context))
: (SearchBarView(imagePaths)
..hintTextSearch(AppLocalizations.of(context).search_emails)
..maxSizeWidth(240)
..addOnOpenSearchViewAction(() => searchController.enableSearch()))
.build()),
: PortalTarget(
visible: controller.searchController.isAdvancedSearchViewOpen.isTrue,
anchor: const Aligned(
follower: Alignment.topRight,
target: Alignment.bottomRight,
widthFactor: 3,
backup: Aligned(
follower: Alignment.topRight,
target: Alignment.bottomRight,
widthFactor: 3,
),
),
portalFollower: responsiveUtils.isMobile(context) ? const SizedBox.shrink() : const AdvancedSearchFilterOverlay(),
child: (SearchBarView(imagePaths)
..hintTextSearch(AppLocalizations.of(context).search_emails)
..maxSizeWidth(240)
..addOnOpenSearchViewAction(() => searchController.enableSearch())
..addRightButton(IconOpenAdvancedSearchWidget(context)))
.build(),
)),
Obx(() => !searchController.isSearchActive() ? const SizedBox(width: 16) : const SizedBox.shrink()),
Obx(() => (AvatarBuilder()
..text(controller.userProfile.value?.getAvatarText() ?? '')
@@ -26,16 +26,16 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
child: Column(
children: [
_buildSuggestionFilterField(
listTagSelected: controller.listTagFromSelected,
context: context,
advancedSearchFilterField: AdvancedSearchFilterField.form,
listTagInitial: controller.searchEmailFilter.from.toList()
listTagSelected: controller.searchEmailFilter.from,
context: context,
advancedSearchFilterField: AdvancedSearchFilterField.form,
listTagInitial: controller.searchEmailFilter.from,
),
_buildSuggestionFilterField(
listTagSelected: controller.listTagToSelected,
context: context,
advancedSearchFilterField: AdvancedSearchFilterField.to,
listTagInitial: controller.searchEmailFilter.to.toList()
listTagSelected: controller.searchEmailFilter.to,
context: context,
advancedSearchFilterField: AdvancedSearchFilterField.to,
listTagInitial: controller.searchEmailFilter.to,
),
_buildFilterField(
textEditingController: controller.subjectFilterInputController,
@@ -91,11 +91,15 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.w500))),
if (e ==
controller.dateFilterSelectedFormAdvancedSearch.value) ...[
if (e == controller.dateFilterSelectedFormAdvancedSearch.value)
...[
const SizedBox(width: 12),
SvgPicture.asset(_imagePaths.icFilterSelected,
width: 16, height: 16, fit: BoxFit.fill),
SvgPicture.asset(
_imagePaths.icFilterSelected,
width: 16,
height: 16,
fit: BoxFit.fill,
),
]
]),
onTap: () {
@@ -182,8 +186,8 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
Widget _buildSuggestionFilterField({
required AdvancedSearchFilterField advancedSearchFilterField,
required BuildContext context,
required List<String> listTagSelected,
required List<String> listTagInitial,
required Set<String> listTagSelected,
required Set<String> listTagInitial,
}) {
final child = [
SizedBox(
@@ -204,7 +208,32 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
},
advancedSearchFilterField: advancedSearchFilterField,
initialTags: listTagInitial,
listTagSelected: listTagSelected,
onAddTag: (value) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.searchEmailFilter.from.add(value);
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.searchEmailFilter.to.add(value);
}
},
onDeleteTag: (tag) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.searchEmailFilter.from.remove(tag);
controller.lastTextForm.value = '';
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.searchEmailFilter.to.remove(tag);
controller.lastTextTo.value = '';
}
},
onChange: (value) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.lastTextForm.value = value;
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.lastTextTo.value = value;
}
},
)
: Expanded(
child: TextFieldAutoCompleteEmailAddress(
@@ -213,7 +242,33 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
},
advancedSearchFilterField: advancedSearchFilterField,
initialTags: listTagInitial,
listTagSelected: listTagSelected,
onAddTag: (value) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.searchEmailFilter.from.add(value.trim());
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.searchEmailFilter.to.add(value.trim());
}
},
onChange: (value) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.lastTextForm.value = value.trim();
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.lastTextTo.value = value.trim();
}
},
onDeleteTag: (tag) {
if (advancedSearchFilterField == AdvancedSearchFilterField.form) {
controller.searchEmailFilter.from.remove(tag);
controller.lastTextForm.value = '';
}
if (advancedSearchFilterField == AdvancedSearchFilterField.to) {
controller.searchEmailFilter.to.remove(tag);
controller.lastTextTo.value = '';
}
},
),
)
];
@@ -267,8 +322,7 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
fontSize: 14,
color: AppColor.colorHintSearchBar,
),
suffixIconConstraints:
const BoxConstraints(minHeight: 24, minWidth: 24),
suffixIconConstraints: const BoxConstraints(minHeight: 24, minWidth: 24),
suffixIcon: isSelectFormList
? buildIconWeb(
icon: SvgPicture.asset(
@@ -7,15 +7,19 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class AdvancedSearchFilterFormBottomView
extends GetWidget<AdvancedFilterController> {
const AdvancedSearchFilterFormBottomView({Key? key}) : super(key: key);
const AdvancedSearchFilterFormBottomView({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final ResponsiveUtils _responsiveUtils = Get.find<ResponsiveUtils>();
return Padding(
padding: EdgeInsets.only(top: _responsiveUtils.isMobile(context) ? 8 : 20),
padding:
EdgeInsets.only(top: _responsiveUtils.isMobile(context) ? 8 : 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_responsiveUtils.isMobile(context))
_buildCheckboxHasAttachment(context),
@@ -26,31 +30,11 @@ class AdvancedSearchFilterFormBottomView
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
if (!_responsiveUtils.isMobile(context))
Expanded(child: _buildCheckboxHasAttachment(context)),
_buildButton(
onAction: () {
controller.cleanSearchFilter(context);
popBack();
},
colorButton: Colors.transparent,
colorText: AppColor.colorMessageConfirmDialog,
text: AppLocalizations.of(context).clearFilter,
context: context,
responsiveUtils: _responsiveUtils,
),
const SizedBox(width: 12),
_buildButton(
onAction: () {
controller.applyAdvancedSearchFilter(context);
popBack();
},
colorButton: AppColor.primaryColor,
colorText: AppColor.primaryLightColor,
text: AppLocalizations.of(context).search,
context: context,
responsiveUtils: _responsiveUtils,
),
if (!_responsiveUtils.isMobile(context))...[
_buildCheckboxHasAttachment(context),
const Spacer(),
],
..._buildListButton(context, _responsiveUtils),
],
),
],
@@ -58,16 +42,80 @@ class AdvancedSearchFilterFormBottomView
);
}
List<Widget> _buildListButton(
BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isMobile(context)) {
return [
Expanded(
child: _buildButton(
onAction: () {
controller.cleanSearchFilter(context);
popBack();
},
colorButton: AppColor.primaryColor.withOpacity(0.06),
colorText: AppColor.primaryColor,
text: AppLocalizations.of(context).clearFilter,
context: context,
responsiveUtils: responsiveUtils,
),
),
const SizedBox(width: 12),
Expanded(
child: _buildButton(
onAction: () {
controller.applyAdvancedSearchFilter(context);
popBack();
},
colorButton: AppColor.primaryColor,
colorText: AppColor.primaryLightColor,
text: AppLocalizations.of(context).search,
context: context,
responsiveUtils: responsiveUtils,
),
),
];
} else {
return [
_buildButton(
onAction: () {
controller.cleanSearchFilter(context);
popBack();
},
colorButton: AppColor.primaryColor.withOpacity(0.06),
colorText: AppColor.primaryColor,
text: AppLocalizations.of(context).clearFilter,
context: context,
responsiveUtils: responsiveUtils,
),
const SizedBox(width: 12),
_buildButton(
onAction: () {
controller.applyAdvancedSearchFilter(context);
popBack();
},
colorButton: AppColor.primaryColor,
colorText: AppColor.primaryLightColor,
text: AppLocalizations.of(context).search,
context: context,
responsiveUtils: responsiveUtils,
),
];
}
}
Widget _buildCheckboxHasAttachment(BuildContext context) {
return Obx(
() => CheckboxListTile(
contentPadding: EdgeInsets.zero,
controlAffinity: ListTileControlAffinity.leading,
value: controller.hasAttachment.value,
onChanged: (value) {
controller.hasAttachment.value = value ?? false;
},
title: Text(AppLocalizations.of(context).hasAttachment),
() => SizedBox(
width: 220,
child: CheckboxListTile(
contentPadding: EdgeInsets.zero,
controlAffinity: ListTileControlAffinity.leading,
value: controller.hasAttachment.value,
onChanged: (value) {
controller.hasAttachment.value = value ?? false;
},
title: Text(AppLocalizations.of(context).hasAttachment),
),
),
);
}
@@ -87,8 +135,11 @@ class AdvancedSearchFilterFormBottomView
},
child: Container(
height: 44,
padding: const EdgeInsets.symmetric(horizontal: 26),
constraints: BoxConstraints(maxWidth: responsiveUtils.isMobile(context) ? double.infinity : 144),
padding: EdgeInsets.symmetric(
horizontal: responsiveUtils.isMobile(context) ? 0 : 26),
constraints: BoxConstraints(
maxWidth:
responsiveUtils.isMobile(context) ? double.infinity : 144),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: colorButton),
@@ -10,18 +10,23 @@ class AdvancedSearchFilterOverlay extends StatelessWidget {
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Container(
constraints: const BoxConstraints(
minWidth: 660,
maxHeight: 568,
),
width: 660,
height: MediaQuery.of(context).size.height,
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5)),
]
),
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1,
blurRadius: 1,
offset: Offset(0, 0.5)),
]),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 12),
@@ -8,20 +8,25 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:textfield_tags/textfield_tags.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/advanced_search_filter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/custom_tf_tag_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class TextFieldAutoCompleteEmailAddress extends StatefulWidget {
const TextFieldAutoCompleteEmailAddress({
const TextFieldAutoCompleteEmailAddress({
Key? key,
required this.advancedSearchFilterField,
required this.listTagSelected,
required this.initialTags,
required this.optionsBuilder,
required this.onChange,
required this.onDeleteTag,
required this.onAddTag,
}) : super(key: key);
final AdvancedSearchFilterField advancedSearchFilterField;
final List<String> listTagSelected;
final List<String> initialTags;
final Set<String> initialTags;
final Future<List<EmailAddress>> Function(String) optionsBuilder;
final Function(String) onChange;
final Function(String) onDeleteTag;
final Function(String) onAddTag;
@override
State<TextFieldAutoCompleteEmailAddress> createState() =>
@@ -32,20 +37,23 @@ class _TextFieldAutoCompleteEmailAddressState
extends State<TextFieldAutoCompleteEmailAddress> {
final double _distanceToField = 380;
final ImagePaths _imagePaths = Get.find<ImagePaths>();
late TextfieldTagsController _controller;
late CustomController _controller;
@override
void initState() {
_controller = TextfieldTagsController();
_controller.addListener(() {
if(_controller.hasTags){
widget.listTagSelected.addAll(_controller.getTags!);
}
_controller = CustomController();
_controller.setActionRemoveTag((tag) {
widget.onDeleteTag.call(tag);
});
_controller.setActionAddTag((tag) {
widget.onAddTag.call(tag);
});
_controller.setActionChangeText((tag) {
widget.onChange.call(tag);
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Autocomplete<EmailAddress>(
@@ -85,7 +93,7 @@ class _TextFieldAutoCompleteEmailAddressState
},
fieldViewBuilder: (context, ttec, tfn, onFieldSubmitted) {
return TextFieldTags(
initialTags: widget.initialTags,
initialTags: widget.initialTags.toList(),
textEditingController: ttec,
focusNode: tfn,
textfieldTagsController: _controller,
@@ -123,28 +131,27 @@ class _TextFieldAutoCompleteEmailAddressState
Radius.circular(10),
),
),
hintText:
widget.advancedSearchFilterField.getHintText(context),
hintText: widget.advancedSearchFilterField.getHintText(context),
hintStyle: const TextStyle(
fontSize: 14,
color: AppColor.colorHintSearchBar,
),
prefixIconConstraints:
BoxConstraints(maxWidth: _distanceToField * 0.74),
prefixIcon: tags.isNotEmpty
? SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 10),
controller: sc,
scrollDirection: Axis.horizontal,
child: Row(
children: tags.map((String tag) {
return _buildTagItem(context, tag, onTagDelete);
}).toList()),
)
prefixIconConstraints: BoxConstraints(maxWidth: _distanceToField * 0.74),
prefixIcon: tags.isNotEmpty ? SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 10),
controller: sc,
scrollDirection: Axis.horizontal,
child: Row(
children: tags.map((String tag) {
return _buildTagItem(context, tag, onTagDelete);
}).toList()),
)
: null,
),
onChanged: onChanged,
onSubmitted: (tag){
onChanged: (value) {
onChanged?.call(value);
},
onSubmitted: (tag) {
onSubmitted?.call(tag);
},
);
@@ -250,9 +257,8 @@ class _TextFieldAutoCompleteEmailAddressState
fontWeight: FontWeight.normal)),
const SizedBox(width: 4),
GestureDetector(
onTap: (){
onTap: () {
onTagDelete.call(tag);
widget.listTagSelected.remove(tag);
},
child: SvgPicture.asset(
_imagePaths.icClose,
@@ -281,6 +287,5 @@ class _TextFieldAutoCompleteEmailAddressState
@override
void dispose() {
super.dispose();
_controller.dispose();
}
}
@@ -165,10 +165,25 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
}
Widget _buildSearchFormInActive(BuildContext context) {
return (SearchBarView(_imagePaths)
..hintTextSearch(AppLocalizations.of(context).search_emails)
..addOnOpenSearchViewAction(() => controller.enableSearch(context)))
.build();
return PortalTarget(
visible: controller.searchController.isAdvancedSearchViewOpen.isTrue,
anchor: const Aligned(
follower: Alignment.topLeft,
target: Alignment.bottomLeft,
widthFactor: 1,
backup: Aligned(
follower: Alignment.topLeft,
target: Alignment.bottomLeft,
widthFactor: 1,
),
),
portalFollower: _responsiveUtils.isMobile(context) ? const SizedBox.shrink() : const AdvancedSearchFilterOverlay(),
child: (SearchBarView(_imagePaths)
..hintTextSearch(AppLocalizations.of(context).search_emails)
..addOnOpenSearchViewAction(() => controller.enableSearch(context))
..addRightButton(IconOpenAdvancedSearchWidget(context)))
.build(),
);
}
Widget _buildSearchFormActive(BuildContext context) {