TF-933 Add search filter by mailbox in new search view for mobile/tablet

This commit is contained in:
dab246
2022-09-19 20:53:26 +07:00
committed by Dat H. Pham
parent 639ac62bad
commit 5d0a6e8e15
9 changed files with 222 additions and 30 deletions
@@ -27,11 +27,11 @@ class DestinationPickerController extends BaseMailboxController {
final mailboxAction = Rxn<MailboxActions>(); final mailboxAction = Rxn<MailboxActions>();
final listMailboxSearched = <PresentationMailbox>[].obs; final listMailboxSearched = <PresentationMailbox>[].obs;
final mailboxIdSelected = Rxn<MailboxId>();
final searchState = SearchState.initial().obs; final searchState = SearchState.initial().obs;
final searchQuery = SearchQuery.initial().obs; final searchQuery = SearchQuery.initial().obs;
final mailboxCategoriesExpandMode = MailboxCategoriesExpandMode.initial().obs; final mailboxCategoriesExpandMode = MailboxCategoriesExpandMode.initial().obs;
MailboxId? mailboxIdSelected;
AccountId? accountId; AccountId? accountId;
final searchInputController = TextEditingController(); final searchInputController = TextEditingController();
final searchFocus = FocusNode(); final searchFocus = FocusNode();
@@ -48,7 +48,7 @@ class DestinationPickerController extends BaseMailboxController {
final arguments = Get.arguments; final arguments = Get.arguments;
if (arguments != null && arguments is DestinationPickerArguments) { if (arguments != null && arguments is DestinationPickerArguments) {
mailboxAction.value = arguments.mailboxAction; mailboxAction.value = arguments.mailboxAction;
mailboxIdSelected = arguments.mailboxIdSelected; mailboxIdSelected.value = arguments.mailboxIdSelected;
accountId = arguments.accountId; accountId = arguments.accountId;
getAllMailboxAction(); getAllMailboxAction();
} }
@@ -59,9 +59,9 @@ class DestinationPickerController extends BaseMailboxController {
super.onData(newState); super.onData(newState);
newState.map((success) { newState.map((success) {
if (success is GetAllMailboxSuccess) { if (success is GetAllMailboxSuccess) {
if (mailboxAction.value == MailboxActions.move && mailboxIdSelected != null) { if (mailboxAction.value == MailboxActions.move && mailboxIdSelected.value != null) {
final newMailboxList = success.mailboxList final newMailboxList = success.mailboxList
.where((mailbox) => mailbox.id != mailboxIdSelected) .where((mailbox) => mailbox.id != mailboxIdSelected.value)
.toList(); .toList();
buildTree(newMailboxList); buildTree(newMailboxList);
} else { } else {
@@ -243,7 +243,7 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
color: AppColor.primaryColor, color: AppColor.primaryColor,
onRefresh: () async => controller.getAllMailboxAction(), onRefresh: () async => controller.getAllMailboxAction(),
child: Obx(() => controller.isSearchActive() child: Obx(() => controller.isSearchActive()
? _buildListMailboxSearched(context) ? _buildListMailboxSearched(context, actions)
: _buildListMailbox(context, actions))); : _buildListMailbox(context, actions)));
} }
@@ -350,7 +350,11 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
padding: _paddingMailboxList(context, actions), padding: _paddingMailboxList(context, actions),
child: TreeView( child: TreeView(
key: Key('${categories.keyValue}_mailbox_list'), key: Key('${categories.keyValue}_mailbox_list'),
children: _buildListChildTileWidget(context, mailboxNode, lastNode: lastNode))); children: _buildListChildTileWidget(
context,
mailboxNode,
lastNode: lastNode,
actions: actions)));
} }
EdgeInsets _marginMailboxList(BuildContext context, MailboxActions? actions) { EdgeInsets _marginMailboxList(BuildContext context, MailboxActions? actions) {
@@ -379,29 +383,47 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
} }
} }
List<Widget> _buildListChildTileWidget(BuildContext context, MailboxNode parentNode, {MailboxNode? lastNode}) { List<Widget> _buildListChildTileWidget(
BuildContext context,
MailboxNode parentNode,
{
MailboxNode? lastNode,
MailboxActions? actions
}
) {
return parentNode.childrenItems return parentNode.childrenItems
?.map((mailboxNode) => mailboxNode.hasChildren() ?.map((mailboxNode) => mailboxNode.hasChildren()
? TreeViewChild( ? TreeViewChild(
context, context,
key: const Key('children_tree_mailbox_child'), key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND, isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, parent: (MailBoxFolderTileBuilder(
context,
_imagePaths,
mailboxNode,
lastNode: lastNode, lastNode: lastNode,
mailboxActions: actions,
mailboxIdSelected: controller.mailboxIdSelected.value,
mailboxDisplayed: MailboxDisplayed.destinationPicker) mailboxDisplayed: MailboxDisplayed.destinationPicker)
..addOnOpenMailboxFolderClick(_handleOpenMailboxClick) ..addOnOpenMailboxFolderClick(_handleOpenMailboxClick)
..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))) ..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode)))
.build(), .build(),
children: _buildListChildTileWidget(context, mailboxNode) children: _buildListChildTileWidget(context, mailboxNode, actions: actions)
).build() ).build()
: (MailBoxFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode, : (MailBoxFolderTileBuilder(
mailboxDisplayed: MailboxDisplayed.destinationPicker) context,
_imagePaths,
mailboxNode,
lastNode: lastNode,
mailboxDisplayed: MailboxDisplayed.destinationPicker,
mailboxIdSelected: controller.mailboxIdSelected.value,
mailboxActions: actions)
..addOnOpenMailboxFolderClick(_handleOpenMailboxClick)) ..addOnOpenMailboxFolderClick(_handleOpenMailboxClick))
.build()) .build())
.toList() ?? <Widget>[]; .toList() ?? <Widget>[];
} }
Widget _buildListMailboxSearched(BuildContext context) { Widget _buildListMailboxSearched(BuildContext context, MailboxActions? actions) {
return Obx(() => Container( return Obx(() => Container(
margin: const EdgeInsets.only( margin: const EdgeInsets.only(
right: 8, right: 8,
@@ -424,6 +446,8 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
_imagePaths, _imagePaths,
_responsiveUtils, _responsiveUtils,
controller.listMailboxSearched[index], controller.listMailboxSearched[index],
mailboxActions: actions,
mailboxIdSelected: controller.mailboxIdSelected.value,
mailboxDisplayed: MailboxDisplayed.destinationPicker, mailboxDisplayed: MailboxDisplayed.destinationPicker,
lastMailbox: controller.listMailboxSearched.last) lastMailbox: controller.listMailboxSearched.last)
..addOnOpenMailboxAction((mailbox) => controller.selectMailboxAction(mailbox))) ..addOnOpenMailboxAction((mailbox) => controller.selectMailboxAction(mailbox)))
@@ -473,6 +497,21 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
fontWeight: FontWeight.normal), fontWeight: FontWeight.normal),
)), )),
const SizedBox(width: 8), const SizedBox(width: 8),
Obx(() {
if (actions == MailboxActions.select &&
(controller.mailboxIdSelected.value == null ||
controller.mailboxIdSelected.value == PresentationMailbox.unifiedMailbox.id)) {
return Padding(
padding: const EdgeInsets.only(right: 30.0),
child: SvgPicture.asset(
_imagePaths.icFilterSelected,
width: 20,
height: 20,
fit: BoxFit.fill),
);
}
return const SizedBox.shrink();
})
]) ])
), ),
), ),
@@ -2,8 +2,10 @@ import 'package:core/core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -24,6 +26,8 @@ class MailBoxFolderTileBuilder {
final MailboxDisplayed mailboxDisplayed; final MailboxDisplayed mailboxDisplayed;
final MailboxNode? lastNode; final MailboxNode? lastNode;
final PresentationMailbox? mailboxNodeSelected; final PresentationMailbox? mailboxNodeSelected;
final MailboxActions? mailboxActions;
final MailboxId? mailboxIdSelected;
OnExpandFolderActionClick? _onExpandFolderActionClick; OnExpandFolderActionClick? _onExpandFolderActionClick;
OnOpenMailboxFolderClick? _onOpenMailboxFolderClick; OnOpenMailboxFolderClick? _onOpenMailboxFolderClick;
@@ -41,6 +45,8 @@ class MailBoxFolderTileBuilder {
this.mailboxDisplayed = MailboxDisplayed.mailbox, this.mailboxDisplayed = MailboxDisplayed.mailbox,
this.lastNode, this.lastNode,
this.mailboxNodeSelected, this.mailboxNodeSelected,
this.mailboxActions,
this.mailboxIdSelected,
} }
); );
@@ -105,6 +111,7 @@ class MailBoxFolderTileBuilder {
_buildLeadingMailboxItem(), _buildLeadingMailboxItem(),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded(child: _buildTitleFolderItem()), Expanded(child: _buildTitleFolderItem()),
_buildSelectedIcon(),
const SizedBox(width: 8), const SizedBox(width: 8),
_buildTrailingMailboxItem() _buildTrailingMailboxItem()
]) ])
@@ -132,6 +139,7 @@ class MailBoxFolderTileBuilder {
_buildLeadingMailboxItem(), _buildLeadingMailboxItem(),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded(child: _buildTitleFolderItem()), Expanded(child: _buildTitleFolderItem()),
_buildSelectedIcon(),
const SizedBox(width: 8), const SizedBox(width: 8),
_buildTrailingMailboxItem() _buildTrailingMailboxItem()
]), ]),
@@ -365,4 +373,18 @@ class MailBoxFolderTileBuilder {
} }
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
Widget _buildSelectedIcon() {
if (_mailboxNode.item.id == mailboxIdSelected &&
mailboxDisplayed == MailboxDisplayed.destinationPicker &&
mailboxActions == MailboxActions.select) {
return SvgPicture.asset(
_imagePaths.icFilterSelected,
width: 20,
height: 20,
fit: BoxFit.fill);
} else {
return const SizedBox.shrink();
}
}
} }
@@ -1,8 +1,10 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart';
typedef OnOpenMailboxActionClick = void Function(PresentationMailbox); typedef OnOpenMailboxActionClick = void Function(PresentationMailbox);
@@ -18,6 +20,8 @@ class MailboxSearchTileBuilder {
final ResponsiveUtils _responsiveUtils; final ResponsiveUtils _responsiveUtils;
final BuildContext _context; final BuildContext _context;
final MailboxDisplayed mailboxDisplayed; final MailboxDisplayed mailboxDisplayed;
final MailboxActions? mailboxActions;
final MailboxId? mailboxIdSelected;
bool isHoverItem = false; bool isHoverItem = false;
@@ -34,6 +38,8 @@ class MailboxSearchTileBuilder {
this.allSelectMode = SelectMode.INACTIVE, this.allSelectMode = SelectMode.INACTIVE,
this.lastMailbox, this.lastMailbox,
this.mailboxDisplayed = MailboxDisplayed.mailbox, this.mailboxDisplayed = MailboxDisplayed.mailbox,
this.mailboxActions,
this.mailboxIdSelected,
} }
); );
@@ -90,6 +96,7 @@ class MailboxSearchTileBuilder {
leading: _buildLeadingIcon(), leading: _buildLeadingIcon(),
title: _buildTitleItem(), title: _buildTitleItem(),
subtitle: _buildSubtitleItem(), subtitle: _buildSubtitleItem(),
trailing: _buildSelectedIcon(),
), ),
if (lastMailbox?.id != _presentationMailbox.id) if (lastMailbox?.id != _presentationMailbox.id)
Padding( Padding(
@@ -183,8 +190,9 @@ class MailboxSearchTileBuilder {
height: 20, height: 20,
fit: BoxFit.fill)), fit: BoxFit.fill)),
); );
} else {
return _buildSelectedIcon();
} }
return null;
} }
Color get backgroundColorItem { Color get backgroundColorItem {
@@ -200,4 +208,21 @@ class MailboxSearchTileBuilder {
} }
} }
} }
Widget? _buildSelectedIcon() {
if (_presentationMailbox.id == mailboxIdSelected &&
mailboxDisplayed == MailboxDisplayed.destinationPicker &&
mailboxActions == MailboxActions.select) {
return Padding(
padding: const EdgeInsets.only(right: 8),
child: SvgPicture.asset(
_imagePaths.icFilterSelected,
width: 20,
height: 20,
fit: BoxFit.fill),
);
} else {
return null;
}
}
} }
@@ -118,7 +118,8 @@ class AdvancedFilterController extends GetxController {
AppRoutes.DESTINATION_PICKER, AppRoutes.DESTINATION_PICKER,
arguments: DestinationPickerArguments( arguments: DestinationPickerArguments(
_mailboxDashBoardController.accountId.value!, _mailboxDashBoardController.accountId.value!,
MailboxActions.select)); MailboxActions.select,
mailboxIdSelected: searchController.searchEmailFilter.value.mailbox?.id));
if (destinationMailbox is PresentationMailbox) { if (destinationMailbox is PresentationMailbox) {
searchController.updateFilterEmail(mailbox: destinationMailbox); searchController.updateFilterEmail(mailbox: destinationMailbox);
@@ -24,7 +24,6 @@ enum QuickSearchFilter {
} }
String getIcon(ImagePaths imagePaths, {required bool quickSearchFilterSelected}) { String getIcon(ImagePaths imagePaths, {required bool quickSearchFilterSelected}) {
if (quickSearchFilterSelected) { if (quickSearchFilterSelected) {
return imagePaths.icSelectedSB; return imagePaths.icSelectedSB;
} else { } else {
@@ -40,7 +39,6 @@ enum QuickSearchFilter {
} }
Color getBackgroundColor({required bool quickSearchFilterSelected}) { Color getBackgroundColor({required bool quickSearchFilterSelected}) {
if (quickSearchFilterSelected) { if (quickSearchFilterSelected) {
return AppColor.colorItemEmailSelectedDesktop; return AppColor.colorItemEmailSelectedDesktop;
} else { } else {
@@ -49,7 +47,6 @@ enum QuickSearchFilter {
} }
TextStyle getTextStyle({required bool quickSearchFilterSelected}) { TextStyle getTextStyle({required bool quickSearchFilterSelected}) {
if (quickSearchFilterSelected) { if (quickSearchFilterSelected) {
return const TextStyle( return const TextStyle(
fontSize: 13, fontSize: 13,
@@ -11,6 +11,7 @@ import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
class SimpleSearchFilter with EquatableMixin { class SimpleSearchFilter with EquatableMixin {
final Set<String> from; final Set<String> from;
final SearchQuery? text; final SearchQuery? text;
final PresentationMailbox? mailbox;
final EmailReceiveTimeType emailReceiveTimeType; final EmailReceiveTimeType emailReceiveTimeType;
final bool hasAttachment; final bool hasAttachment;
final UTCDate? before; final UTCDate? before;
@@ -21,13 +22,15 @@ class SimpleSearchFilter with EquatableMixin {
bool? hasAttachment, bool? hasAttachment,
this.text, this.text,
this.before, this.before,
this.mailbox,
}) : from = from ?? <String>{}, }) : from = from ?? <String>{},
hasAttachment = hasAttachment ?? false, hasAttachment = hasAttachment ?? false,
emailReceiveTimeType =emailReceiveTimeType ?? EmailReceiveTimeType.allTime; emailReceiveTimeType = emailReceiveTimeType ?? EmailReceiveTimeType.allTime;
SimpleSearchFilter copyWith({ SimpleSearchFilter copyWith({
Set<String>? from, Set<String>? from,
SearchQuery? text, SearchQuery? text,
PresentationMailbox? mailbox,
EmailReceiveTimeType? emailReceiveTimeType, EmailReceiveTimeType? emailReceiveTimeType,
bool? hasAttachment, bool? hasAttachment,
UTCDate? before, UTCDate? before,
@@ -35,6 +38,7 @@ class SimpleSearchFilter with EquatableMixin {
return SimpleSearchFilter( return SimpleSearchFilter(
from: from ?? this.from, from: from ?? this.from,
text: text ?? this.text, text: text ?? this.text,
mailbox: mailbox ?? this.mailbox,
emailReceiveTimeType: emailReceiveTimeType ?? this.emailReceiveTimeType, emailReceiveTimeType: emailReceiveTimeType ?? this.emailReceiveTimeType,
hasAttachment: hasAttachment ?? this.hasAttachment, hasAttachment: hasAttachment ?? this.hasAttachment,
before: before ?? this.before, before: before ?? this.before,
@@ -46,6 +50,7 @@ class SimpleSearchFilter with EquatableMixin {
text: text?.value.trim().isNotEmpty == true text: text?.value.trim().isNotEmpty == true
? text?.value ? text?.value
: null, : null,
inMailbox: mailbox?.id,
after: emailReceiveTimeType.toUTCDate(), after: emailReceiveTimeType.toUTCDate(),
hasAttachment: hasAttachment == false ? null : hasAttachment, hasAttachment: hasAttachment == false ? null : hasAttachment,
before: before, before: before,
@@ -66,18 +71,34 @@ class SimpleSearchFilter with EquatableMixin {
} }
@override @override
List<Object?> get props => [from, text, emailReceiveTimeType, hasAttachment, before]; List<Object?> get props => [from, text, mailbox, emailReceiveTimeType, hasAttachment, before];
} }
extension SearchEmailFilterExtension on SimpleSearchFilter { extension SearchEmailFilterExtension on SimpleSearchFilter {
SimpleSearchFilter toSimpleSearchFilter({UTCDate? newBefore}) { SimpleSearchFilter toSimpleSearchFilterByBefore({UTCDate? newBefore}) {
return SimpleSearchFilter( return SimpleSearchFilter(
from: from, from: from,
text: text, text: text,
mailbox: mailbox,
emailReceiveTimeType: emailReceiveTimeType, emailReceiveTimeType: emailReceiveTimeType,
hasAttachment: hasAttachment, hasAttachment: hasAttachment,
before: newBefore, before: newBefore,
); );
} }
SimpleSearchFilter toSimpleSearchFilterByMailbox({PresentationMailbox? newMailbox}) {
return SimpleSearchFilter(
from: from,
text: text,
mailbox: newMailbox,
emailReceiveTimeType: emailReceiveTimeType,
hasAttachment: hasAttachment,
before: before,
);
}
bool get searchFilterByMailboxApplied => mailbox != null;
String get mailboxName => mailbox?.name?.name ?? '';
} }
@@ -14,11 +14,13 @@ import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart';
import 'package:model/model.dart'; import 'package:model/model.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/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/quick_search_email_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/quick_search_email_state.dart';
@@ -197,7 +199,7 @@ class SearchEmailController extends BaseController
final limit = listResultSearch.isNotEmpty final limit = listResultSearch.isNotEmpty
? UnsignedInt(listResultSearch.length) ? UnsignedInt(listResultSearch.length)
: ThreadConstants.defaultLimit; : ThreadConstants.defaultLimit;
simpleSearchFilter.value = simpleSearchFilter.value.toSimpleSearchFilter(newBefore: null); simpleSearchFilter.value = simpleSearchFilter.value.toSimpleSearchFilterByBefore(newBefore: null);
consumeState(_refreshChangesSearchEmailInteractor.execute( consumeState(_refreshChangesSearchEmailInteractor.execute(
accountId!, accountId!,
@@ -353,6 +355,9 @@ class SearchEmailController extends BaseController
} }
bool checkQuickSearchFilterSelected(QuickSearchFilter filter) { bool checkQuickSearchFilterSelected(QuickSearchFilter filter) {
log('SearchEmailController::checkQuickSearchFilterSelected(): filter: $filter');
log('SearchEmailController::checkQuickSearchFilterSelected(): simpleSearchFilter: ${simpleSearchFilter.value.from}');
log('SearchEmailController::checkQuickSearchFilterSelected(): userProfile: ${userProfile!.email}');
switch (filter) { switch (filter) {
case QuickSearchFilter.hasAttachment: case QuickSearchFilter.hasAttachment:
return simpleSearchFilter.value.hasAttachment == true; return simpleSearchFilter.value.hasAttachment == true;
@@ -370,7 +375,7 @@ class SearchEmailController extends BaseController
void _selectQuickSearchFilter(QuickSearchFilter filter) { void _selectQuickSearchFilter(QuickSearchFilter filter) {
final filterSelected = checkQuickSearchFilterSelected(filter); final filterSelected = checkQuickSearchFilterSelected(filter);
log('SearchEmailController::_selectQuickSearchFilter(): filterSelected: $filterSelected');
switch (filter) { switch (filter) {
case QuickSearchFilter.hasAttachment: case QuickSearchFilter.hasAttachment:
_updateSimpleSearchFilter(hasAttachment: !filterSelected); _updateSimpleSearchFilter(hasAttachment: !filterSelected);
@@ -389,6 +394,7 @@ class SearchEmailController extends BaseController
filterSelected filterSelected
? simpleSearchFilter.value.from.removeWhere((e) => e == userProfile!.email) ? simpleSearchFilter.value.from.removeWhere((e) => e == userProfile!.email)
: simpleSearchFilter.value.from.add(userProfile!.email); : simpleSearchFilter.value.from.add(userProfile!.email);
log('SearchEmailController::_selectQuickSearchFilter(): from: ${simpleSearchFilter.value.from}');
_updateSimpleSearchFilter(from: simpleSearchFilter.value.from); _updateSimpleSearchFilter(from: simpleSearchFilter.value.from);
} }
break; break;
@@ -415,9 +421,30 @@ class SearchEmailController extends BaseController
_searchEmailAction(context); _searchEmailAction(context);
} }
void selectMailboxForSearchFilter(BuildContext context, PresentationMailbox? mailbox) async {
final destinationMailbox = await push(
AppRoutes.DESTINATION_PICKER,
arguments: DestinationPickerArguments(
mailboxDashBoardController.accountId.value!,
MailboxActions.select,
mailboxIdSelected: mailbox?.id));
if (destinationMailbox is PresentationMailbox) {
final mailboxSelected = destinationMailbox == PresentationMailbox.unifiedMailbox
? null
: destinationMailbox;
if (mailbox?.id != mailboxSelected?.id) {
simpleSearchFilter.value = simpleSearchFilter.value
.toSimpleSearchFilterByMailbox(newMailbox: mailboxSelected);
_searchEmailAction(context);
}
}
}
void _updateSimpleSearchFilter({ void _updateSimpleSearchFilter({
Set<String>? from, Set<String>? from,
SearchQuery? text, SearchQuery? text,
PresentationMailbox? mailbox,
EmailReceiveTimeType? emailReceiveTimeType, EmailReceiveTimeType? emailReceiveTimeType,
bool? hasAttachment, bool? hasAttachment,
UTCDate? before, UTCDate? before,
@@ -425,10 +452,12 @@ class SearchEmailController extends BaseController
simpleSearchFilter.value = simpleSearchFilter.value.copyWith( simpleSearchFilter.value = simpleSearchFilter.value.copyWith(
from: from, from: from,
text: text, text: text,
mailbox: mailbox,
emailReceiveTimeType: emailReceiveTimeType, emailReceiveTimeType: emailReceiveTimeType,
hasAttachment: hasAttachment, hasAttachment: hasAttachment,
before: before, before: before,
); );
simpleSearchFilter.refresh();
} }
void onTextSearchChange(String text) { void onTextSearchChange(String text) {
@@ -6,6 +6,7 @@ import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/background/background_widget_builder.dart'; import 'package:core/presentation/views/background/background_widget_builder.dart';
import 'package:core/presentation/views/button/icon_button_web.dart'; import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/text/text_field_builder.dart'; import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart'; import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@@ -19,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/sear
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/search/presentation/model/search_more_state.dart'; import 'package:tmail_ui_user/features/search/presentation/model/search_more_state.dart';
import 'package:tmail_ui_user/features/search/presentation/model/simple_search_filter.dart';
import 'package:tmail_ui_user/features/search/presentation/search_email_controller.dart'; import 'package:tmail_ui_user/features/search/presentation/search_email_controller.dart';
import 'package:tmail_ui_user/features/search/presentation/utils/search_email_utils.dart'; import 'package:tmail_ui_user/features/search/presentation/utils/search_email_utils.dart';
import 'package:tmail_ui_user/features/search/presentation/widgets/app_bar_selection_mode.dart'; import 'package:tmail_ui_user/features/search/presentation/widgets/app_bar_selection_mode.dart';
@@ -158,14 +160,16 @@ class SearchEmailView extends GetWidget<SearchEmailController>
margin: SearchEmailUtils.getMarginSearchFilterButton(context, _responsiveUtils), margin: SearchEmailUtils.getMarginSearchFilterButton(context, _responsiveUtils),
padding: SearchEmailUtils.getPaddingSearchFilterButton(context, _responsiveUtils), padding: SearchEmailUtils.getPaddingSearchFilterButton(context, _responsiveUtils),
height: 60, height: 60,
child: ListView.builder( child: ListView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: QuickSearchFilter.values.length, children: [
itemBuilder: (context, index) { ...[
return _buildQuickSearchFilterButton( QuickSearchFilter.fromMe,
context, QuickSearchFilter.hasAttachment,
QuickSearchFilter.values[index]); QuickSearchFilter.last7Days
} ].map((filter) => _buildQuickSearchFilterButton(context, filter)),
_buildSearchFilterByMailboxButton(context),
],
), ),
); );
} }
@@ -173,7 +177,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
Widget _buildQuickSearchFilterButton(BuildContext context, QuickSearchFilter filter) { Widget _buildQuickSearchFilterButton(BuildContext context, QuickSearchFilter filter) {
return Obx(() { return Obx(() {
final filterSelected = controller.checkQuickSearchFilterSelected(filter); final filterSelected = controller.checkQuickSearchFilterSelected(filter);
log('SearchEmailView::_buildQuickSearchFilterButton(): filterSelected: $filterSelected');
return Padding( return Padding(
padding: const EdgeInsets.only(right: 8), padding: const EdgeInsets.only(right: 8),
child: InkWell( child: InkWell(
@@ -505,4 +509,58 @@ class SearchEmailView extends GetWidget<SearchEmailController>
: const SizedBox.shrink(); : const SizedBox.shrink();
})); }));
} }
Widget _buildSearchFilterByMailboxButton(BuildContext context) {
return Obx(() {
final filterSelected = controller.simpleSearchFilter.value.searchFilterByMailboxApplied;
return Padding(
padding: const EdgeInsets.only(right: 8),
child: InkWell(
onTap: () => controller.selectMailboxForSearchFilter(
context,
controller.simpleSearchFilter.value.mailbox),
borderRadius: const BorderRadius.all(Radius.circular(10)),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: filterSelected
? AppColor.colorItemEmailSelectedDesktop
: AppColor.colorButtonHeaderThread),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
SvgPicture.asset(
filterSelected ? _imagePaths.icSelectedSB : _imagePaths.icFolderMailbox,
width: 16,
height: 16,
fit: BoxFit.fill),
const SizedBox(width: 4),
Text(
filterSelected
? controller.simpleSearchFilter.value.mailboxName
: AppLocalizations.of(context).mailbox,
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: filterSelected
? const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
color: AppColor.colorTextButton)
: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.normal,
color: AppColor.colorTextButtonHeaderThread)
),
const SizedBox(width: 4),
SvgPicture.asset(
_imagePaths.icChevronDown,
width: 16,
height: 16,
fit: BoxFit.fill),
])
),
),
);
});
}
} }