TF-1477 Improve UX for advanced and quick search
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/utils/app_toast.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_date_range_picker/multiple_view_date_range_picker.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
|
|
||||||
|
mixin DateRangePickerMixin {
|
||||||
|
|
||||||
|
void showMultipleViewDateRangePicker(
|
||||||
|
BuildContext context,
|
||||||
|
DateTime? initStartDate,
|
||||||
|
DateTime? initEndDate,
|
||||||
|
{Function(DateTime? startDate, DateTime? endDate)? onCallbackAction}
|
||||||
|
) {
|
||||||
|
showGeneralDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true,
|
||||||
|
barrierLabel: '',
|
||||||
|
barrierColor: Colors.black54,
|
||||||
|
pageBuilder: (context, _, __) {
|
||||||
|
return Dialog(
|
||||||
|
elevation: 0,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.0)),
|
||||||
|
child: PointerInterceptor(child: MultipleViewDateRangePicker(
|
||||||
|
confirmText: AppLocalizations.of(context).setDate,
|
||||||
|
cancelText: AppLocalizations.of(context).cancel,
|
||||||
|
last7daysTitle: AppLocalizations.of(context).last7Days,
|
||||||
|
last30daysTitle: AppLocalizations.of(context).last30Days,
|
||||||
|
last6monthsTitle: AppLocalizations.of(context).last6Months,
|
||||||
|
lastYearTitle: AppLocalizations.of(context).lastYears,
|
||||||
|
startDate: initStartDate,
|
||||||
|
endDate: initEndDate,
|
||||||
|
setDateActionCallback: ({startDate, endDate}) =>
|
||||||
|
_handleSelectDateRangeResult(
|
||||||
|
context,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
onCallbackAction: onCallbackAction
|
||||||
|
)
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleSelectDateRangeResult(
|
||||||
|
BuildContext context,
|
||||||
|
DateTime? startDate,
|
||||||
|
DateTime? endDate,
|
||||||
|
{Function(DateTime? startDate, DateTime? endDate)? onCallbackAction}
|
||||||
|
) {
|
||||||
|
final _appToast = Get.find<AppToast>();
|
||||||
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
|
|
||||||
|
if (startDate == null) {
|
||||||
|
_appToast.showToastWithIcon(
|
||||||
|
context,
|
||||||
|
textColor: Colors.black,
|
||||||
|
message: AppLocalizations.of(context).toastMessageErrorWhenSelectStartDateIsEmpty,
|
||||||
|
icon: _imagePaths.icNotConnection
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endDate == null) {
|
||||||
|
_appToast.showToastWithIcon(
|
||||||
|
context,
|
||||||
|
textColor: Colors.black,
|
||||||
|
message: AppLocalizations.of(context).toastMessageErrorWhenSelectEndDateIsEmpty,
|
||||||
|
icon: _imagePaths.icNotConnection
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endDate.isBefore(startDate)) {
|
||||||
|
_appToast.showToastWithIcon(
|
||||||
|
context,
|
||||||
|
textColor: Colors.black,
|
||||||
|
message: AppLocalizations.of(context).toastMessageErrorWhenSelectDateIsInValid,
|
||||||
|
icon: _imagePaths.icNotConnection
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
popBack();
|
||||||
|
onCallbackAction?.call(startDate, endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
|||||||
final double radiusButton;
|
final double radiusButton;
|
||||||
final double opacity;
|
final double opacity;
|
||||||
final Widget? iconArrowDown;
|
final Widget? iconArrowDown;
|
||||||
final Color? colorButton;
|
final Color colorButton;
|
||||||
final String tooltip;
|
final String tooltip;
|
||||||
final double? dropdownWidth;
|
final double? dropdownWidth;
|
||||||
final double? dropdownMaxHeight;
|
final double? dropdownMaxHeight;
|
||||||
@@ -36,7 +36,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
|||||||
const DropDownButtonWidget({
|
const DropDownButtonWidget({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.items,
|
required this.items,
|
||||||
required this.itemSelected,
|
this.itemSelected,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
this.onMenuStateChange,
|
this.onMenuStateChange,
|
||||||
this.supportHint = false,
|
this.supportHint = false,
|
||||||
@@ -112,7 +112,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
|||||||
color: AppColor.colorInputBorderCreateMailbox,
|
color: AppColor.colorInputBorderCreateMailbox,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
color: colorButton ?? AppColor.colorInputBackgroundCreateMailbox,
|
color: colorButton,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.only(left: 12, right: 10),
|
padding: const EdgeInsets.only(left: 12, right: 10),
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
@@ -139,7 +139,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
|||||||
color: AppColor.colorInputBorderCreateMailbox,
|
color: AppColor.colorInputBorderCreateMailbox,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
color: colorButton ?? AppColor.colorInputBackgroundCreateMailbox,
|
color: colorButton,
|
||||||
),
|
),
|
||||||
itemHeight: heightItem,
|
itemHeight: heightItem,
|
||||||
buttonHeight: heightItem,
|
buttonHeight: heightItem,
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
|
|
||||||
|
class PopupItemNoIconWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
final String _nameAction;
|
||||||
|
final String? svgIconSelected;
|
||||||
|
final bool isSelected;
|
||||||
|
final double? maxWidth;
|
||||||
|
final TextStyle? styleName;
|
||||||
|
final EdgeInsets? padding;
|
||||||
|
final VoidCallback? onCallbackAction;
|
||||||
|
|
||||||
|
const PopupItemNoIconWidget(
|
||||||
|
this._nameAction,
|
||||||
|
{
|
||||||
|
Key? key,
|
||||||
|
this.isSelected = false,
|
||||||
|
this.svgIconSelected,
|
||||||
|
this.maxWidth,
|
||||||
|
this.styleName,
|
||||||
|
this.padding,
|
||||||
|
this.onCallbackAction
|
||||||
|
}
|
||||||
|
) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PointerInterceptor(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onCallbackAction,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||||
|
child: SizedBox(
|
||||||
|
width: maxWidth,
|
||||||
|
child: Row(children: [
|
||||||
|
Expanded(child: Text(
|
||||||
|
_nameAction,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.normal
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
if (isSelected && svgIconSelected != null)
|
||||||
|
...[
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
SvgPicture.asset(
|
||||||
|
svgIconSelected!,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fit: BoxFit.fill
|
||||||
|
),
|
||||||
|
]
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import 'package:model/email/email_action_type.dart';
|
|||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
|
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
|
||||||
|
|
||||||
@@ -134,4 +135,25 @@ class OpenMailboxAction extends DashBoardAction {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [context, presentationMailbox];
|
List<Object?> get props => [context, presentationMailbox];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectDateRangeToAdvancedSearch extends DashBoardAction {
|
||||||
|
|
||||||
|
final DateTime? startDate;
|
||||||
|
final DateTime? endDate;
|
||||||
|
|
||||||
|
SelectDateRangeToAdvancedSearch(this.startDate, this.endDate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [startDate, endDate];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClearDateRangeToAdvancedSearch extends DashBoardAction {
|
||||||
|
|
||||||
|
final EmailReceiveTimeType receiveTime;
|
||||||
|
|
||||||
|
ClearDateRangeToAdvancedSearch(this.receiveTime);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [receiveTime];
|
||||||
}
|
}
|
||||||
+67
-125
@@ -2,14 +2,12 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_date_range_picker/multiple_view_date_range_picker.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/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.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/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:pointer_interceptor/pointer_interceptor.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/composer/domain/model/contact_suggestion_source.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_autocomplete_state.dart';
|
||||||
@@ -37,28 +35,24 @@ class AdvancedFilterController extends BaseController {
|
|||||||
final hasAttachment = false.obs;
|
final hasAttachment = false.obs;
|
||||||
final lastTextForm = ''.obs;
|
final lastTextForm = ''.obs;
|
||||||
final lastTextTo = ''.obs;
|
final lastTextTo = ''.obs;
|
||||||
|
final startDate = Rxn<DateTime>();
|
||||||
|
final endDate = Rxn<DateTime>();
|
||||||
|
|
||||||
TextEditingController subjectFilterInputController = TextEditingController();
|
TextEditingController subjectFilterInputController = TextEditingController();
|
||||||
TextEditingController hasKeyWordFilterInputController = TextEditingController();
|
TextEditingController hasKeyWordFilterInputController = TextEditingController();
|
||||||
TextEditingController notKeyWordFilterInputController = TextEditingController();
|
TextEditingController notKeyWordFilterInputController = TextEditingController();
|
||||||
TextEditingController dateFilterInputController = TextEditingController();
|
|
||||||
TextEditingController mailBoxFilterInputController = TextEditingController();
|
TextEditingController mailBoxFilterInputController = TextEditingController();
|
||||||
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
|
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
|
||||||
|
|
||||||
final SearchController searchController = Get.find<SearchController>();
|
final SearchController searchController = Get.find<SearchController>();
|
||||||
final MailboxDashBoardController _mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
final MailboxDashBoardController _mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||||
final _appToast = Get.find<AppToast>();
|
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
|
||||||
|
|
||||||
SearchEmailFilter get searchEmailFilter =>
|
SearchEmailFilter get searchEmailFilter =>
|
||||||
searchController.searchEmailFilter.value;
|
searchController.searchEmailFilter.value;
|
||||||
|
|
||||||
final focusManager = InputFieldFocusManager.initial();
|
final focusManager = InputFieldFocusManager.initial();
|
||||||
|
|
||||||
DateTime? _startDate, _endDate;
|
PresentationMailbox? _destinationMailboxSelected;
|
||||||
|
|
||||||
DateTime? get startDate => _startDate;
|
|
||||||
|
|
||||||
DateTime? get endDate => _endDate;
|
|
||||||
|
|
||||||
late Worker _dashboardActionWorker;
|
late Worker _dashboardActionWorker;
|
||||||
|
|
||||||
@@ -83,17 +77,15 @@ class AdvancedFilterController extends BaseController {
|
|||||||
|
|
||||||
void cleanSearchFilter(BuildContext context) {
|
void cleanSearchFilter(BuildContext context) {
|
||||||
searchController.clearSearchFilter();
|
searchController.clearSearchFilter();
|
||||||
dateFilterSelectedFormAdvancedSearch.value = EmailReceiveTimeType.allTime;
|
_updateDateRangeTime(EmailReceiveTimeType.allTime);
|
||||||
clearDateRangeOfFilter();
|
|
||||||
subjectFilterInputController.text = '';
|
subjectFilterInputController.text = '';
|
||||||
hasKeyWordFilterInputController.text = '';
|
hasKeyWordFilterInputController.text = '';
|
||||||
notKeyWordFilterInputController.text = '';
|
notKeyWordFilterInputController.text = '';
|
||||||
dateFilterInputController.text = '';
|
|
||||||
hasAttachment.value = false;
|
hasAttachment.value = false;
|
||||||
|
_destinationMailboxSelected = null;
|
||||||
searchController.deactivateAdvancedSearch();
|
searchController.deactivateAdvancedSearch();
|
||||||
searchController.isAdvancedSearchViewOpen.toggle();
|
searchController.isAdvancedSearchViewOpen.toggle();
|
||||||
_mailboxDashBoardController.searchEmail(
|
_mailboxDashBoardController.searchEmail(context, StringConvert.writeNullToEmpty(searchEmailFilter.text?.value));
|
||||||
context, StringConvert.writeNullToEmpty(searchEmailFilter.text?.value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateFilterEmailFromAdvancedSearchView() {
|
void _updateFilterEmailFromAdvancedSearchView() {
|
||||||
@@ -127,11 +119,12 @@ class AdvancedFilterController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchController.updateFilterEmail(
|
searchController.updateFilterEmail(
|
||||||
|
mailbox: _destinationMailboxSelected,
|
||||||
subjectOption: optionOf(subjectFilterInputController.text),
|
subjectOption: optionOf(subjectFilterInputController.text),
|
||||||
emailReceiveTimeType: dateFilterSelectedFormAdvancedSearch.value,
|
emailReceiveTimeType: dateFilterSelectedFormAdvancedSearch.value,
|
||||||
hasAttachment: hasAttachment.value,
|
hasAttachment: hasAttachment.value,
|
||||||
endDate: _endDate.toUTCDate(),
|
startDateOption: optionOf(startDate.value?.toUTCDate()),
|
||||||
startDate: _startDate.toUTCDate()
|
endDateOption: optionOf(endDate.value?.toUTCDate())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +143,9 @@ class AdvancedFilterController extends BaseController {
|
|||||||
context: context,
|
context: context,
|
||||||
arguments: arguments,
|
arguments: arguments,
|
||||||
onSelectedMailbox: (destinationMailbox) {
|
onSelectedMailbox: (destinationMailbox) {
|
||||||
searchController.updateFilterEmail(mailbox: destinationMailbox);
|
_destinationMailboxSelected = destinationMailbox;
|
||||||
mailBoxFilterInputController.text =
|
final mailboxName = destinationMailbox.name?.name;
|
||||||
StringConvert.writeNullToEmpty(destinationMailbox.name?.name);
|
mailBoxFilterInputController.text = StringConvert.writeNullToEmpty(mailboxName);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
final destinationMailbox = await push(
|
final destinationMailbox = await push(
|
||||||
@@ -160,9 +153,9 @@ class AdvancedFilterController extends BaseController {
|
|||||||
arguments: arguments);
|
arguments: arguments);
|
||||||
|
|
||||||
if (destinationMailbox is PresentationMailbox) {
|
if (destinationMailbox is PresentationMailbox) {
|
||||||
searchController.updateFilterEmail(mailbox: destinationMailbox);
|
_destinationMailboxSelected = destinationMailbox;
|
||||||
mailBoxFilterInputController.text =
|
final mailboxName = destinationMailbox.name?.name;
|
||||||
StringConvert.writeNullToEmpty(destinationMailbox.name?.name);
|
mailBoxFilterInputController.text = StringConvert.writeNullToEmpty(mailboxName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,8 +169,7 @@ class AdvancedFilterController extends BaseController {
|
|||||||
searchController.deactivateAdvancedSearch();
|
searchController.deactivateAdvancedSearch();
|
||||||
}
|
}
|
||||||
if (!isAdvancedSearchHasApplied) {
|
if (!isAdvancedSearchHasApplied) {
|
||||||
final newSearchEmailFilter = searchController.searchEmailFilter.value.clearBeforeDate();
|
searchController.updateFilterEmail(beforeOption: const None());
|
||||||
searchController.searchEmailFilter.value = newSearchEmailFilter;
|
|
||||||
}
|
}
|
||||||
searchController.isAdvancedSearchViewOpen.toggle();
|
searchController.isAdvancedSearchViewOpen.toggle();
|
||||||
_mailboxDashBoardController.searchEmail(
|
_mailboxDashBoardController.searchEmail(
|
||||||
@@ -259,111 +251,55 @@ class AdvancedFilterController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initSearchFilterField(BuildContext context) {
|
void initSearchFilterField(BuildContext context) {
|
||||||
searchController.updateFilterEmail(
|
subjectFilterInputController.text = StringConvert.writeNullToEmpty(searchEmailFilter.subject);
|
||||||
mailbox: PresentationMailbox.unifiedMailbox);
|
hasKeyWordFilterInputController.text = StringConvert.writeNullToEmpty(searchEmailFilter.text?.value);
|
||||||
subjectFilterInputController.text =
|
notKeyWordFilterInputController.text = StringConvert.writeNullToEmpty(searchEmailFilter.notKeyword.firstOrNull);
|
||||||
StringConvert.writeNullToEmpty(searchEmailFilter.subject);
|
dateFilterSelectedFormAdvancedSearch.value = searchEmailFilter.emailReceiveTimeType;
|
||||||
hasKeyWordFilterInputController.text = StringConvert.writeNullToEmpty(
|
_destinationMailboxSelected = searchEmailFilter.mailbox;
|
||||||
searchEmailFilter.text?.value);
|
if (searchEmailFilter.mailbox == null) {
|
||||||
notKeyWordFilterInputController.text = StringConvert.writeNullToEmpty(
|
mailBoxFilterInputController.text = AppLocalizations.of(context).allMailboxes;
|
||||||
searchEmailFilter.notKeyword.firstOrNull);
|
} else {
|
||||||
dateFilterInputController.text = StringConvert.writeNullToEmpty(
|
mailBoxFilterInputController.text = StringConvert.writeNullToEmpty(searchEmailFilter.mailbox?.name?.name);
|
||||||
searchEmailFilter.emailReceiveTimeType.getTitle(
|
}
|
||||||
context,
|
|
||||||
startDate: _startDate,
|
|
||||||
endDate: _endDate));
|
|
||||||
mailBoxFilterInputController.text =
|
|
||||||
StringConvert.writeNullToEmpty(searchEmailFilter.mailbox?.name?.name);
|
|
||||||
dateFilterSelectedFormAdvancedSearch.value =
|
|
||||||
searchEmailFilter.emailReceiveTimeType;
|
|
||||||
hasAttachment.value = searchEmailFilter.hasAttachment;
|
hasAttachment.value = searchEmailFilter.hasAttachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectDateRange(BuildContext context) {
|
void selectDateRange(BuildContext context) {
|
||||||
showGeneralDialog(
|
searchController.showMultipleViewDateRangePicker(
|
||||||
context: context,
|
context,
|
||||||
barrierDismissible: true,
|
startDate.value,
|
||||||
barrierLabel: '',
|
endDate.value,
|
||||||
barrierColor: Colors.black54,
|
onCallbackAction: (startDate, endDate) =>
|
||||||
pageBuilder: (context, animation, secondaryAnimation) {
|
_updateDateRangeTime(
|
||||||
return Dialog(
|
EmailReceiveTimeType.customRange,
|
||||||
elevation: 0,
|
newStartDate: startDate,
|
||||||
backgroundColor: Colors.white,
|
newEndDate: endDate
|
||||||
shape: RoundedRectangleBorder(
|
)
|
||||||
borderRadius: BorderRadius.circular(18.0)),
|
|
||||||
child: PointerInterceptor(
|
|
||||||
child: MultipleViewDateRangePicker(
|
|
||||||
confirmText: AppLocalizations.of(context).setDate,
|
|
||||||
cancelText: AppLocalizations.of(context).cancel,
|
|
||||||
last7daysTitle: AppLocalizations.of(context).last7Days,
|
|
||||||
last30daysTitle: AppLocalizations.of(context).last30Days,
|
|
||||||
last6monthsTitle: AppLocalizations.of(context).last6Months,
|
|
||||||
lastYearTitle: AppLocalizations.of(context).lastYears,
|
|
||||||
startDate: _startDate,
|
|
||||||
endDate: _endDate,
|
|
||||||
setDateActionCallback: ({startDate, endDate}) {
|
|
||||||
_handleSelectDateRangeResult(context, startDate, endDate);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleSelectDateRangeResult(
|
void _updateDateRangeTime(EmailReceiveTimeType receiveTime, {DateTime? newStartDate, DateTime? newEndDate}) {
|
||||||
BuildContext context,
|
startDate.value = newStartDate;
|
||||||
DateTime? startDate,
|
endDate.value = newEndDate;
|
||||||
DateTime? endDate
|
dateFilterSelectedFormAdvancedSearch.value = receiveTime;
|
||||||
) {
|
|
||||||
log('AdvancedFilterController::_handleSelectDateRangeResult(): startDate: $startDate');
|
|
||||||
log('AdvancedFilterController::_handleSelectDateRangeResult(): endDate: $endDate');
|
|
||||||
if (startDate == null) {
|
|
||||||
_appToast.showToastWithIcon(
|
|
||||||
context,
|
|
||||||
textColor: Colors.black,
|
|
||||||
message: AppLocalizations.of(context).toastMessageErrorWhenSelectStartDateIsEmpty,
|
|
||||||
icon: _imagePaths.icNotConnection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (endDate == null) {
|
|
||||||
_appToast.showToastWithIcon(
|
|
||||||
context,
|
|
||||||
textColor: Colors.black,
|
|
||||||
message: AppLocalizations.of(context).toastMessageErrorWhenSelectEndDateIsEmpty,
|
|
||||||
icon: _imagePaths.icNotConnection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endDate.isBefore(startDate)) {
|
|
||||||
_appToast.showToastWithIcon(
|
|
||||||
context,
|
|
||||||
textColor: Colors.black,
|
|
||||||
message: AppLocalizations.of(context).toastMessageErrorWhenSelectDateIsInValid,
|
|
||||||
icon: _imagePaths.icNotConnection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_startDate = startDate;
|
|
||||||
_endDate = endDate;
|
|
||||||
dateFilterSelectedFormAdvancedSearch.value = EmailReceiveTimeType.customRange;
|
|
||||||
dateFilterInputController.text = EmailReceiveTimeType.customRange.getTitle(
|
|
||||||
context,
|
|
||||||
startDate: startDate,
|
|
||||||
endDate: endDate);
|
|
||||||
dateFilterSelectedFormAdvancedSearch.refresh();
|
|
||||||
|
|
||||||
popBack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearDateRangeOfFilter() {
|
void updateReceiveDateSearchFilter(BuildContext context, EmailReceiveTimeType receiveTime) {
|
||||||
_startDate = null;
|
if (receiveTime == EmailReceiveTimeType.customRange) {
|
||||||
_endDate = null;
|
searchController.showMultipleViewDateRangePicker(
|
||||||
|
context,
|
||||||
searchController.searchEmailFilter.value =
|
startDate.value,
|
||||||
searchController.searchEmailFilter.value.withDateRange(
|
endDate.value,
|
||||||
startDate: _startDate.toUTCDate(),
|
onCallbackAction: (startDate, endDate) =>
|
||||||
endDate: _endDate.toUTCDate());
|
_updateDateRangeTime(
|
||||||
|
EmailReceiveTimeType.customRange,
|
||||||
|
newStartDate: startDate,
|
||||||
|
newEndDate: endDate
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_updateDateRangeTime(receiveTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resetAllToOriginalValue() {
|
void _resetAllToOriginalValue() {
|
||||||
@@ -371,15 +307,14 @@ class AdvancedFilterController extends BaseController {
|
|||||||
hasAttachment.value = false;
|
hasAttachment.value = false;
|
||||||
lastTextForm.value = '';
|
lastTextForm.value = '';
|
||||||
lastTextTo.value = '';
|
lastTextTo.value = '';
|
||||||
_startDate = null;
|
startDate.value = null;
|
||||||
_endDate = null;
|
endDate.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _clearAllTextFieldInput() {
|
void _clearAllTextFieldInput() {
|
||||||
subjectFilterInputController.clear();
|
subjectFilterInputController.clear();
|
||||||
hasKeyWordFilterInputController.clear();
|
hasKeyWordFilterInputController.clear();
|
||||||
notKeyWordFilterInputController.clear();
|
notKeyWordFilterInputController.clear();
|
||||||
dateFilterInputController.clear();
|
|
||||||
mailBoxFilterInputController.clear();
|
mailBoxFilterInputController.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,6 +324,14 @@ class AdvancedFilterController extends BaseController {
|
|||||||
(action) {
|
(action) {
|
||||||
if (action is ClearAllFieldOfAdvancedSearchAction) {
|
if (action is ClearAllFieldOfAdvancedSearchAction) {
|
||||||
_handleClearAllFieldOfAdvancedSearch();
|
_handleClearAllFieldOfAdvancedSearch();
|
||||||
|
} else if (action is SelectDateRangeToAdvancedSearch) {
|
||||||
|
_updateDateRangeTime(
|
||||||
|
EmailReceiveTimeType.customRange,
|
||||||
|
newStartDate: action.startDate,
|
||||||
|
newEndDate: action.endDate
|
||||||
|
);
|
||||||
|
} else if (action is ClearDateRangeToAdvancedSearch) {
|
||||||
|
_updateDateRangeTime(action.receiveTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -410,7 +353,6 @@ class AdvancedFilterController extends BaseController {
|
|||||||
hasKeyWordFilterInputController.dispose();
|
hasKeyWordFilterInputController.dispose();
|
||||||
notKeyWordFilterInputController.dispose();
|
notKeyWordFilterInputController.dispose();
|
||||||
mailBoxFilterInputController.dispose();
|
mailBoxFilterInputController.dispose();
|
||||||
dateFilterInputController.dispose();
|
|
||||||
_unregisterWorkerListener();
|
_unregisterWorkerListener();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-30
@@ -73,6 +73,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/state/update_vacati
|
|||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart';
|
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/datetime_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
|
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
|
||||||
@@ -535,9 +536,6 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
if (_searchInsideEmailDetailedViewIsActive(context)) {
|
if (_searchInsideEmailDetailedViewIsActive(context)) {
|
||||||
_closeEmailDetailedView();
|
_closeEmailDetailedView();
|
||||||
}
|
}
|
||||||
if (value.isEmpty){
|
|
||||||
searchController.setEmailReceiveTimeType(null);
|
|
||||||
}
|
|
||||||
_unSelectedMailbox();
|
_unSelectedMailbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1281,23 +1279,13 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectQuickSearchFilter({
|
void selectQuickSearchFilter(QuickSearchFilter filter) {
|
||||||
required QuickSearchFilter quickSearchFilter,
|
return searchController.selectQuickSearchFilter(filter, userProfile.value!);
|
||||||
bool fromSuggestionBox = false,
|
}
|
||||||
}) => searchController.selectQuickSearchFilter(
|
|
||||||
quickSearchFilter: quickSearchFilter,
|
|
||||||
userProfile: userProfile.value!,
|
|
||||||
fromSuggestionBox: fromSuggestionBox,
|
|
||||||
);
|
|
||||||
|
|
||||||
bool checkQuickSearchFilterSelected({
|
void addFilterToSuggestionForm(QuickSearchFilter filter) {
|
||||||
required QuickSearchFilter quickSearchFilter,
|
searchController.addFilterToSuggestionForm(filter);
|
||||||
bool fromSuggestionBox = false,
|
}
|
||||||
}) => searchController.checkQuickSearchFilterSelected(
|
|
||||||
quickSearchFilter: quickSearchFilter,
|
|
||||||
userProfile: userProfile.value!,
|
|
||||||
fromSuggestionBox: fromSuggestionBox,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<List<PresentationEmail>> quickSearchEmails() => searchController.quickSearchEmails(accountId: accountId.value!);
|
Future<List<PresentationEmail>> quickSearchEmails() => searchController.quickSearchEmails(accountId: accountId.value!);
|
||||||
|
|
||||||
@@ -1353,26 +1341,44 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
|
|
||||||
void selectQuickSearchFilterAction(QuickSearchFilter filter) {
|
void selectQuickSearchFilterAction(QuickSearchFilter filter) {
|
||||||
log('MailboxDashBoardController::selectQuickSearchFilterAction(): filter: $filter');
|
log('MailboxDashBoardController::selectQuickSearchFilterAction(): filter: $filter');
|
||||||
selectQuickSearchFilter(quickSearchFilter: filter);
|
selectQuickSearchFilter(filter);
|
||||||
dispatchAction(StartSearchEmailAction());
|
dispatchAction(StartSearchEmailAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectReceiveTimeQuickSearchFilter(EmailReceiveTimeType? emailReceiveTimeType) {
|
void selectReceiveTimeQuickSearchFilter(BuildContext context, EmailReceiveTimeType receiveTime) {
|
||||||
|
log('MailboxDashBoardController::selectReceiveTimeQuickSearchFilter():receiveTime: $receiveTime');
|
||||||
popBack();
|
popBack();
|
||||||
|
|
||||||
if (emailReceiveTimeType != null) {
|
if (receiveTime == EmailReceiveTimeType.customRange) {
|
||||||
searchController.updateFilterEmail(emailReceiveTimeType: emailReceiveTimeType);
|
searchController.showMultipleViewDateRangePicker(
|
||||||
|
context,
|
||||||
|
searchController.startDateFiltered,
|
||||||
|
searchController.endDateFiltered,
|
||||||
|
onCallbackAction: (startDate, endDate) {
|
||||||
|
dispatchAction(SelectDateRangeToAdvancedSearch(startDate, endDate));
|
||||||
|
searchController.updateFilterEmail(
|
||||||
|
emailReceiveTimeType: receiveTime,
|
||||||
|
startDateOption: optionOf(startDate?.toUTCDate()),
|
||||||
|
endDateOption: optionOf(startDate?.toUTCDate()),
|
||||||
|
beforeOption: const None()
|
||||||
|
);
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
searchController.updateFilterEmail(emailReceiveTimeType: EmailReceiveTimeType.allTime);
|
dispatchAction(ClearDateRangeToAdvancedSearch(receiveTime));
|
||||||
|
searchController.updateFilterEmail(
|
||||||
|
emailReceiveTimeType: receiveTime,
|
||||||
|
startDateOption: const None(),
|
||||||
|
endDateOption: const None(),
|
||||||
|
beforeOption: const None()
|
||||||
|
);
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
}
|
}
|
||||||
searchController.setEmailReceiveTimeType(emailReceiveTimeType);
|
|
||||||
searchController.updateFilterEmail();
|
|
||||||
if (searchController.searchQuery == null){
|
|
||||||
searchController.updateFilterEmail(text: SearchQuery.initial());
|
|
||||||
}
|
|
||||||
dispatchAction(StartSearchEmailAction());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool get isMailboxTrash => selectedMailbox.value?.isTrash == true;
|
bool get isMailboxTrash => selectedMailbox.value?.isTrash == true;
|
||||||
|
|
||||||
void emptyTrashAction(BuildContext context) {
|
void emptyTrashAction(BuildContext context) {
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/filter/filter_operator.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart';
|
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:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||||
|
import 'package:model/email/presentation_email.dart';
|
||||||
|
import 'package:model/extensions/email_filter_condition_extension.dart';
|
||||||
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
|
import 'package:model/user/user_profile.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/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';
|
||||||
@@ -27,7 +36,7 @@ import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
|||||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
|
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart';
|
import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart';
|
||||||
|
|
||||||
class SearchController extends BaseController {
|
class SearchController extends BaseController with DateRangePickerMixin {
|
||||||
final QuickSearchEmailInteractor _quickSearchEmailInteractor;
|
final QuickSearchEmailInteractor _quickSearchEmailInteractor;
|
||||||
final SaveRecentSearchInteractor _saveRecentSearchInteractor;
|
final SaveRecentSearchInteractor _saveRecentSearchInteractor;
|
||||||
final GetAllRecentSearchLatestInteractor _getAllRecentSearchLatestInteractor;
|
final GetAllRecentSearchLatestInteractor _getAllRecentSearchLatestInteractor;
|
||||||
@@ -38,7 +47,7 @@ class SearchController extends BaseController {
|
|||||||
final searchEmailFilter = SearchEmailFilter.initial().obs;
|
final searchEmailFilter = SearchEmailFilter.initial().obs;
|
||||||
final searchState = SearchState.initial().obs;
|
final searchState = SearchState.initial().obs;
|
||||||
final isAdvancedSearchViewOpen = false.obs;
|
final isAdvancedSearchViewOpen = false.obs;
|
||||||
final emailReceiveTimeType = Rxn<EmailReceiveTimeType>();
|
final listFilterOnSuggestionForm = RxList<QuickSearchFilter>();
|
||||||
final simpleSearchIsActivated = RxBool(false);
|
final simpleSearchIsActivated = RxBool(false);
|
||||||
final advancedSearchIsActivated = RxBool(false);
|
final advancedSearchIsActivated = RxBool(false);
|
||||||
final autoFocus = RxBool(true);
|
final autoFocus = RxBool(true);
|
||||||
@@ -67,53 +76,78 @@ class SearchController extends BaseController {
|
|||||||
searchEmailFilter.value = SearchEmailFilter.initial();
|
searchEmailFilter.value = SearchEmailFilter.initial();
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectQuickSearchFilter({
|
void selectQuickSearchFilter(QuickSearchFilter quickSearchFilter, UserProfile userProfile) {
|
||||||
required QuickSearchFilter quickSearchFilter,
|
final isFilterSelected = quickSearchFilter.isSelected(searchEmailFilter.value, userProfile);
|
||||||
required UserProfile userProfile,
|
|
||||||
bool fromSuggestionBox = false,
|
|
||||||
}) {
|
|
||||||
final quickSearchFilterSelected = checkQuickSearchFilterSelected(
|
|
||||||
userProfile: userProfile,
|
|
||||||
quickSearchFilter: quickSearchFilter,
|
|
||||||
fromSuggestionBox: fromSuggestionBox,
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (quickSearchFilter) {
|
switch (quickSearchFilter) {
|
||||||
case QuickSearchFilter.hasAttachment:
|
case QuickSearchFilter.hasAttachment:
|
||||||
updateFilterEmail(hasAttachment: !quickSearchFilterSelected);
|
updateFilterEmail(hasAttachment: !isFilterSelected);
|
||||||
return;
|
return;
|
||||||
case QuickSearchFilter.last7Days:
|
case QuickSearchFilter.last7Days:
|
||||||
if (quickSearchFilterSelected) {
|
updateFilterEmail(emailReceiveTimeType: EmailReceiveTimeType.allTime);
|
||||||
setEmailReceiveTimeType(null);
|
|
||||||
updateFilterEmail(emailReceiveTimeType: EmailReceiveTimeType.allTime);
|
|
||||||
} else {
|
|
||||||
setEmailReceiveTimeType(EmailReceiveTimeType.last7Days);
|
|
||||||
updateFilterEmail(emailReceiveTimeType: EmailReceiveTimeType.last7Days);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case QuickSearchFilter.fromMe:
|
case QuickSearchFilter.fromMe:
|
||||||
quickSearchFilterSelected
|
isFilterSelected
|
||||||
? searchEmailFilter.value.from.removeWhere((e) => e == userProfile.email)
|
? searchEmailFilter.value.from.removeWhere((e) => e == userProfile.email)
|
||||||
: searchEmailFilter.value.from.add(userProfile.email);
|
: searchEmailFilter.value.from.add(userProfile.email);
|
||||||
updateFilterEmail(from: searchEmailFilter.value.from);
|
updateFilterEmail(from: searchEmailFilter.value.from);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<PresentationEmail>> quickSearchEmails({required AccountId accountId}) async {
|
void addFilterToSuggestionForm(QuickSearchFilter filter) {
|
||||||
return await _quickSearchEmailInteractor
|
if (listFilterOnSuggestionForm.contains(filter)) {
|
||||||
.execute(accountId,
|
listFilterOnSuggestionForm.remove(filter);
|
||||||
limit: UnsignedInt(5),
|
} else {
|
||||||
sort: <Comparator>{}..add(
|
listFilterOnSuggestionForm.add(filter);
|
||||||
EmailComparator(EmailComparatorProperty.receivedAt)
|
}
|
||||||
..setIsAscending(false)),
|
}
|
||||||
filter: searchEmailFilter.value.mappingToEmailFilterCondition(),
|
|
||||||
properties: ThreadConstants.propertiesQuickSearch)
|
Future<List<PresentationEmail>> quickSearchEmails({
|
||||||
.then((result) => result.fold(
|
required AccountId accountId,
|
||||||
(failure) => <PresentationEmail>[],
|
UserProfile? userProfile
|
||||||
(success) => success is QuickSearchEmailSuccess
|
}) async {
|
||||||
? success.emailList
|
return await _quickSearchEmailInteractor.execute(
|
||||||
: <PresentationEmail>[]));
|
accountId,
|
||||||
|
limit: UnsignedInt(5),
|
||||||
|
sort: <Comparator>{}..add(
|
||||||
|
EmailComparator(EmailComparatorProperty.receivedAt)
|
||||||
|
..setIsAscending(false)),
|
||||||
|
filter: _mappingToFilterOnSuggestionForm(userProfile),
|
||||||
|
properties: ThreadConstants.propertiesQuickSearch
|
||||||
|
).then((result) => result.fold(
|
||||||
|
(failure) => <PresentationEmail>[],
|
||||||
|
(success) => success is QuickSearchEmailSuccess
|
||||||
|
? success.emailList
|
||||||
|
: <PresentationEmail>[]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter? _mappingToFilterOnSuggestionForm(UserProfile? userProfile) {
|
||||||
|
final searchText = searchEmailFilter.value.text?.value.trim();
|
||||||
|
|
||||||
|
final filterCondition = EmailFilterCondition(
|
||||||
|
text: searchText?.isNotEmpty == true ? searchText : null,
|
||||||
|
after: listFilterOnSuggestionForm.contains(QuickSearchFilter.last7Days)
|
||||||
|
? EmailReceiveTimeType.last7Days.toOldestUTCDate()
|
||||||
|
: null,
|
||||||
|
before: listFilterOnSuggestionForm.contains(QuickSearchFilter.last7Days)
|
||||||
|
? EmailReceiveTimeType.last7Days.toLatestUTCDate()
|
||||||
|
: null,
|
||||||
|
hasAttachment: listFilterOnSuggestionForm.contains(QuickSearchFilter.hasAttachment)
|
||||||
|
? true
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
|
||||||
|
final listEmailCondition = {
|
||||||
|
if (filterCondition.hasCondition) filterCondition,
|
||||||
|
if (listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe) && userProfile != null)
|
||||||
|
LogicFilterOperator(Operator.AND, {EmailFilterCondition(from: userProfile.email)})
|
||||||
|
};
|
||||||
|
|
||||||
|
return listEmailCondition.isNotEmpty
|
||||||
|
? LogicFilterOperator(Operator.AND, listEmailCondition)
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateFilterEmail({
|
void updateFilterEmail({
|
||||||
@@ -125,9 +159,9 @@ class SearchController extends BaseController {
|
|||||||
PresentationMailbox? mailbox,
|
PresentationMailbox? mailbox,
|
||||||
EmailReceiveTimeType? emailReceiveTimeType,
|
EmailReceiveTimeType? emailReceiveTimeType,
|
||||||
bool? hasAttachment,
|
bool? hasAttachment,
|
||||||
UTCDate? before,
|
Option<UTCDate>? beforeOption,
|
||||||
UTCDate? startDate,
|
Option<UTCDate>? startDateOption,
|
||||||
UTCDate? endDate,
|
Option<UTCDate>? endDateOption
|
||||||
}) {
|
}) {
|
||||||
searchEmailFilter.value = searchEmailFilter.value.copyWith(
|
searchEmailFilter.value = searchEmailFilter.value.copyWith(
|
||||||
from: from,
|
from: from,
|
||||||
@@ -138,9 +172,9 @@ class SearchController extends BaseController {
|
|||||||
mailbox: mailbox,
|
mailbox: mailbox,
|
||||||
emailReceiveTimeType: emailReceiveTimeType,
|
emailReceiveTimeType: emailReceiveTimeType,
|
||||||
hasAttachment: hasAttachment,
|
hasAttachment: hasAttachment,
|
||||||
before: before,
|
beforeOption: beforeOption,
|
||||||
startDate: startDate,
|
startDateOption: startDateOption,
|
||||||
endDate: endDate,
|
endDateOption: endDateOption,
|
||||||
);
|
);
|
||||||
searchEmailFilter.refresh();
|
searchEmailFilter.refresh();
|
||||||
}
|
}
|
||||||
@@ -159,6 +193,12 @@ class SearchController extends BaseController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmailReceiveTimeType get receiveTimeFiltered => searchEmailFilter.value.emailReceiveTimeType;
|
||||||
|
|
||||||
|
DateTime? get startDateFiltered => searchEmailFilter.value.startDate?.value.toLocal();
|
||||||
|
|
||||||
|
DateTime? get endDateFiltered => searchEmailFilter.value.endDate?.value.toLocal();
|
||||||
|
|
||||||
bool isSearchActive() =>
|
bool isSearchActive() =>
|
||||||
searchState.value.searchStatus == SearchStatus.ACTIVE;
|
searchState.value.searchStatus == SearchStatus.ACTIVE;
|
||||||
|
|
||||||
@@ -188,21 +228,15 @@ class SearchController extends BaseController {
|
|||||||
searchInputController.text = value;
|
searchInputController.text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkQuickSearchFilterSelected({
|
bool checkQuickSearchFilterSelected(QuickSearchFilter quickSearchFilter, UserProfile userProfile) {
|
||||||
required QuickSearchFilter quickSearchFilter,
|
|
||||||
required UserProfile userProfile,
|
|
||||||
bool fromSuggestionBox = false,
|
|
||||||
}) {
|
|
||||||
switch (quickSearchFilter) {
|
switch (quickSearchFilter) {
|
||||||
case QuickSearchFilter.hasAttachment:
|
case QuickSearchFilter.hasAttachment:
|
||||||
return searchEmailFilter.value.hasAttachment == true;
|
return searchEmailFilter.value.hasAttachment == true;
|
||||||
case QuickSearchFilter.last7Days:
|
case QuickSearchFilter.last7Days:
|
||||||
if (emailReceiveTimeType.value != null) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return searchEmailFilter.value.emailReceiveTimeType == EmailReceiveTimeType.last7Days;
|
|
||||||
case QuickSearchFilter.fromMe:
|
case QuickSearchFilter.fromMe:
|
||||||
return searchEmailFilter.value.from.contains( userProfile.email) && searchEmailFilter.value.from.length == 1;
|
return searchEmailFilter.value.from.contains(userProfile.email) &&
|
||||||
|
searchEmailFilter.value.from.length == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,11 +254,7 @@ class SearchController extends BaseController {
|
|||||||
: <RecentSearch>[]));
|
: <RecentSearch>[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEmailReceiveTimeType(EmailReceiveTimeType? receiveTimeType) {
|
void showAdvancedFilterView(BuildContext context) async {
|
||||||
emailReceiveTimeType.value = receiveTimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
showAdvancedFilterView(BuildContext context) async {
|
|
||||||
selectOpenAdvanceSearch();
|
selectOpenAdvanceSearch();
|
||||||
if (_responsiveUtils.isMobile(context)) {
|
if (_responsiveUtils.isMobile(context)) {
|
||||||
await showAdvancedSearchFilterBottomSheet(context);
|
await showAdvancedSearchFilterBottomSheet(context);
|
||||||
@@ -259,7 +289,6 @@ class SearchController extends BaseController {
|
|||||||
void _clearAllTextInputSimpleSearch() {
|
void _clearAllTextInputSimpleSearch() {
|
||||||
searchInputController.clear();
|
searchInputController.clear();
|
||||||
searchFocus.unfocus();
|
searchFocus.unfocus();
|
||||||
emailReceiveTimeType.value = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableAllSearchEmail() {
|
void disableAllSearchEmail() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter_portal/flutter_portal.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:pointer_interceptor/pointer_interceptor.dart';
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||||
@@ -541,8 +542,9 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
QuickSearchFilter filter
|
QuickSearchFilter filter
|
||||||
) {
|
) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final quickSearchFilterSelected = controller.checkQuickSearchFilterSelected(
|
final isFilterSelected = filter.isSelected(
|
||||||
quickSearchFilter: filter,
|
controller.searchController.searchEmailFilter.value,
|
||||||
|
controller.userProfile.value
|
||||||
);
|
);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
@@ -563,35 +565,40 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
screenSize.width - offset.dx,
|
screenSize.width - offset.dx,
|
||||||
screenSize.height - offset.dy,
|
screenSize.height - offset.dy,
|
||||||
);
|
);
|
||||||
controller.openPopupMenuAction(context, position,
|
controller.openPopupMenuAction(
|
||||||
popupMenuEmailReceiveTimeType(context,
|
context,
|
||||||
controller.searchController.emailReceiveTimeType.value,
|
position,
|
||||||
(receiveTime) => controller.selectReceiveTimeQuickSearchFilter(receiveTime)));
|
popupMenuEmailReceiveTimeType(
|
||||||
|
context,
|
||||||
|
controller.searchController.receiveTimeFiltered,
|
||||||
|
onCallBack: (receiveTime) => controller.selectReceiveTimeQuickSearchFilter(context, receiveTime)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
color: filter.getBackgroundColor(quickSearchFilterSelected: quickSearchFilterSelected)),
|
color: filter.getBackgroundColor(isFilterSelected: isFilterSelected)),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
filter.getIcon(
|
filter.getIcon(imagePaths, isFilterSelected: isFilterSelected),
|
||||||
imagePaths,
|
|
||||||
quickSearchFilterSelected: quickSearchFilterSelected),
|
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
fit: BoxFit.fill),
|
fit: BoxFit.fill),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
filter.getTitle(
|
filter.getTitle(
|
||||||
context,
|
context,
|
||||||
receiveTimeType: controller.searchController.emailReceiveTimeType.value),
|
receiveTimeType: controller.searchController.receiveTimeFiltered,
|
||||||
|
startDate: controller.searchController.startDateFiltered,
|
||||||
|
endDate: controller.searchController.endDateFiltered
|
||||||
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: filter.getTextStyle(
|
style: filter.getTextStyle(isFilterSelected: isFilterSelected),
|
||||||
quickSearchFilterSelected: quickSearchFilterSelected),
|
|
||||||
),
|
),
|
||||||
if (filter == QuickSearchFilter.last7Days)
|
if (filter == QuickSearchFilter.last7Days)
|
||||||
... [
|
... [
|
||||||
@@ -609,55 +616,21 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<PopupMenuEntry> popupMenuEmailReceiveTimeType(
|
List<PopupMenuEntry> popupMenuEmailReceiveTimeType(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
EmailReceiveTimeType? receiveTimeSelected,
|
EmailReceiveTimeType? receiveTimeSelected,
|
||||||
Function(EmailReceiveTimeType?)? onCallBack
|
{Function(EmailReceiveTimeType)? onCallBack}
|
||||||
) {
|
) {
|
||||||
return EmailReceiveTimeType.values
|
return EmailReceiveTimeType.values
|
||||||
.map((timeType) => PopupMenuItem(
|
.map((receiveTime) => PopupMenuItem(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
child: _receiveTimeTileAction(
|
child: PopupItemNoIconWidget(
|
||||||
context,
|
receiveTime.getTitle(context),
|
||||||
receiveTimeSelected,
|
svgIconSelected: imagePaths.icFilterSelected,
|
||||||
timeType,
|
maxWidth: 320,
|
||||||
onCallBack)))
|
isSelected: receiveTimeSelected == receiveTime,
|
||||||
.toList();
|
onCallbackAction: () => onCallBack?.call(receiveTime),
|
||||||
}
|
)))
|
||||||
|
.toList();
|
||||||
Widget _receiveTimeTileAction(
|
|
||||||
BuildContext context,
|
|
||||||
EmailReceiveTimeType? receiveTimeSelected,
|
|
||||||
EmailReceiveTimeType receiveTimeType,
|
|
||||||
Function(EmailReceiveTimeType?)? onCallBack
|
|
||||||
) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: () => onCallBack?.call(receiveTimeType == receiveTimeSelected
|
|
||||||
? null
|
|
||||||
: receiveTimeType),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
|
||||||
child: SizedBox(
|
|
||||||
width: 320,
|
|
||||||
child: Row(children: [
|
|
||||||
Expanded(child: Text(
|
|
||||||
receiveTimeType.getTitle(context),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 17,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.normal))),
|
|
||||||
if (receiveTimeType == receiveTimeSelected)
|
|
||||||
...[
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
SvgPicture.asset(
|
|
||||||
imagePaths.icFilterSelected,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
]
|
|
||||||
])
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportEmptyTrash(BuildContext context) {
|
bool supportEmptyTrash(BuildContext context) {
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ enum AdvancedSearchFilterField {
|
|||||||
case AdvancedSearchFilterField.notKeyword:
|
case AdvancedSearchFilterField.notKeyword:
|
||||||
return AppLocalizations.of(context).enterSearchTerm;
|
return AppLocalizations.of(context).enterSearchTerm;
|
||||||
case AdvancedSearchFilterField.mailBox:
|
case AdvancedSearchFilterField.mailBox:
|
||||||
return AppLocalizations.of(context).allMails;
|
return AppLocalizations.of(context).allMailboxes;
|
||||||
case AdvancedSearchFilterField.date:
|
case AdvancedSearchFilterField.date:
|
||||||
return AppLocalizations.of(context).allTime;
|
return AppLocalizations.of(context).allTime;
|
||||||
case AdvancedSearchFilterField.hasAttachment:
|
case AdvancedSearchFilterField.hasAttachment:
|
||||||
|
|||||||
+43
-4
@@ -37,10 +37,8 @@ enum EmailReceiveTimeType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UTCDate? toUTCDate() {
|
UTCDate? toOldestUTCDate() {
|
||||||
switch(this) {
|
switch(this) {
|
||||||
case EmailReceiveTimeType.allTime:
|
|
||||||
return null;
|
|
||||||
case EmailReceiveTimeType.last7Days:
|
case EmailReceiveTimeType.last7Days:
|
||||||
final today = DateTime.now();
|
final today = DateTime.now();
|
||||||
final last7Days = today.subtract(const Duration(days: 7));
|
final last7Days = today.subtract(const Duration(days: 7));
|
||||||
@@ -57,8 +55,49 @@ enum EmailReceiveTimeType {
|
|||||||
final today = DateTime.now();
|
final today = DateTime.now();
|
||||||
final lastYear = DateTime(today.year - 1, today.month, today.day);
|
final lastYear = DateTime(today.year - 1, today.month, today.day);
|
||||||
return lastYear.toUTCDate();
|
return lastYear.toUTCDate();
|
||||||
case EmailReceiveTimeType.customRange:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTCDate? toLatestUTCDate() {
|
||||||
|
switch(this) {
|
||||||
|
case EmailReceiveTimeType.last7Days:
|
||||||
|
case EmailReceiveTimeType.last30Days:
|
||||||
|
case EmailReceiveTimeType.last6Months:
|
||||||
|
case EmailReceiveTimeType.lastYear:
|
||||||
|
return DateTime.now().toUTCDate();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UTCDate? getAfterDate(UTCDate? startDate) {
|
||||||
|
if (startDate != null) {
|
||||||
|
return startDate;
|
||||||
|
} else {
|
||||||
|
return toOldestUTCDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UTCDate? getBeforeDate(UTCDate? endDate, UTCDate? loadMoreDate) {
|
||||||
|
if (endDate != null) {
|
||||||
|
if (loadMoreDate != null && loadMoreDate.value.isBefore(endDate.value)) {
|
||||||
|
return loadMoreDate;
|
||||||
|
} else {
|
||||||
|
return endDate;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final latestDate = toLatestUTCDate();
|
||||||
|
if (latestDate != null) {
|
||||||
|
if (loadMoreDate != null && loadMoreDate.value.isBefore(latestDate.value)) {
|
||||||
|
return loadMoreDate;
|
||||||
|
} else {
|
||||||
|
return latestDate;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return loadMoreDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:model/user/user_profile.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
enum QuickSearchFilter {
|
enum QuickSearchFilter {
|
||||||
@@ -9,22 +12,36 @@ enum QuickSearchFilter {
|
|||||||
last7Days,
|
last7Days,
|
||||||
fromMe;
|
fromMe;
|
||||||
|
|
||||||
String getTitle(BuildContext context, {EmailReceiveTimeType? receiveTimeType}) {
|
String getName(BuildContext context) {
|
||||||
switch(this) {
|
switch(this) {
|
||||||
case QuickSearchFilter.hasAttachment:
|
case QuickSearchFilter.hasAttachment:
|
||||||
return AppLocalizations.of(context).hasAttachment;
|
return AppLocalizations.of(context).hasAttachment;
|
||||||
case QuickSearchFilter.last7Days:
|
case QuickSearchFilter.last7Days:
|
||||||
if (receiveTimeType != null) {
|
|
||||||
return receiveTimeType.getTitle(context);
|
|
||||||
}
|
|
||||||
return AppLocalizations.of(context).last7Days;
|
return AppLocalizations.of(context).last7Days;
|
||||||
case QuickSearchFilter.fromMe:
|
case QuickSearchFilter.fromMe:
|
||||||
return AppLocalizations.of(context).fromMe;
|
return AppLocalizations.of(context).fromMe;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getIcon(ImagePaths imagePaths, {required bool quickSearchFilterSelected}) {
|
String getTitle(
|
||||||
if (quickSearchFilterSelected) {
|
BuildContext context, {
|
||||||
|
EmailReceiveTimeType? receiveTimeType,
|
||||||
|
DateTime? startDate,
|
||||||
|
DateTime? endDate,
|
||||||
|
}) {
|
||||||
|
switch(this) {
|
||||||
|
case QuickSearchFilter.hasAttachment:
|
||||||
|
return AppLocalizations.of(context).hasAttachment;
|
||||||
|
case QuickSearchFilter.last7Days:
|
||||||
|
return receiveTimeType?.getTitle(context, startDate: startDate, endDate: endDate)
|
||||||
|
?? AppLocalizations.of(context).allTime;
|
||||||
|
case QuickSearchFilter.fromMe:
|
||||||
|
return AppLocalizations.of(context).fromMe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getIcon(ImagePaths imagePaths, {required bool isFilterSelected}) {
|
||||||
|
if (isFilterSelected) {
|
||||||
return imagePaths.icSelectedSB;
|
return imagePaths.icSelectedSB;
|
||||||
} else {
|
} else {
|
||||||
switch(this) {
|
switch(this) {
|
||||||
@@ -38,16 +55,16 @@ enum QuickSearchFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color getBackgroundColor({required bool quickSearchFilterSelected}) {
|
Color getBackgroundColor({required bool isFilterSelected}) {
|
||||||
if (quickSearchFilterSelected) {
|
if (isFilterSelected) {
|
||||||
return AppColor.colorItemEmailSelectedDesktop;
|
return AppColor.colorItemEmailSelectedDesktop;
|
||||||
} else {
|
} else {
|
||||||
return AppColor.colorButtonHeaderThread;
|
return AppColor.colorButtonHeaderThread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextStyle getTextStyle({required bool quickSearchFilterSelected}) {
|
TextStyle getTextStyle({required bool isFilterSelected}) {
|
||||||
if (quickSearchFilterSelected) {
|
if (isFilterSelected) {
|
||||||
return const TextStyle(
|
return const TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -59,4 +76,19 @@ enum QuickSearchFilter {
|
|||||||
color: AppColor.colorTextButtonHeaderThread);
|
color: AppColor.colorTextButtonHeaderThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isApplied(List<QuickSearchFilter> listFilter) => listFilter.contains(this);
|
||||||
|
|
||||||
|
bool isSelected(SearchEmailFilter filter, UserProfile? userProfile) {
|
||||||
|
switch (this) {
|
||||||
|
case QuickSearchFilter.hasAttachment:
|
||||||
|
return filter.hasAttachment == true;
|
||||||
|
case QuickSearchFilter.last7Days:
|
||||||
|
return true;
|
||||||
|
case QuickSearchFilter.fromMe:
|
||||||
|
return userProfile != null &&
|
||||||
|
filter.from.contains(userProfile.email) &&
|
||||||
|
filter.from.length == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,8 @@ import 'package:jmap_dart_client/jmap/core/filter/filter_operator.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart';
|
import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/extensions/email_filter_condition_extension.dart';
|
||||||
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||||
|
|
||||||
@@ -52,9 +53,9 @@ class SearchEmailFilter with EquatableMixin {
|
|||||||
PresentationMailbox? mailbox,
|
PresentationMailbox? mailbox,
|
||||||
EmailReceiveTimeType? emailReceiveTimeType,
|
EmailReceiveTimeType? emailReceiveTimeType,
|
||||||
bool? hasAttachment,
|
bool? hasAttachment,
|
||||||
UTCDate? before,
|
Option<UTCDate>? beforeOption,
|
||||||
UTCDate? startDate,
|
Option<UTCDate>? startDateOption,
|
||||||
UTCDate? endDate,
|
Option<UTCDate>? endDateOption,
|
||||||
}) {
|
}) {
|
||||||
return SearchEmailFilter(
|
return SearchEmailFilter(
|
||||||
from: from ?? this.from,
|
from: from ?? this.from,
|
||||||
@@ -65,9 +66,9 @@ class SearchEmailFilter with EquatableMixin {
|
|||||||
mailbox: mailbox ?? this.mailbox,
|
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: _getOptionParam(beforeOption, before),
|
||||||
startDate: startDate ?? this.startDate,
|
startDate: _getOptionParam(startDateOption, startDate),
|
||||||
endDate: endDate ?? this.endDate,
|
endDate: _getOptionParam(endDateOption, endDate),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,17 +85,13 @@ class SearchEmailFilter with EquatableMixin {
|
|||||||
text: text?.value.trim().isNotEmpty == true
|
text: text?.value.trim().isNotEmpty == true
|
||||||
? text?.value
|
? text?.value
|
||||||
: null,
|
: null,
|
||||||
inMailbox: mailbox == PresentationMailbox.unifiedMailbox
|
inMailbox: mailbox?.mailboxId,
|
||||||
? null
|
after: emailReceiveTimeType.getAfterDate(startDate),
|
||||||
: mailbox?.id,
|
|
||||||
after: emailReceiveTimeType == EmailReceiveTimeType.customRange
|
|
||||||
? startDate
|
|
||||||
: emailReceiveTimeType.toUTCDate(),
|
|
||||||
hasAttachment: hasAttachment == false ? null : hasAttachment,
|
hasAttachment: hasAttachment == false ? null : hasAttachment,
|
||||||
subject: subject,
|
subject: subject?.trim().isNotEmpty == true
|
||||||
before: emailReceiveTimeType == EmailReceiveTimeType.customRange
|
? subject
|
||||||
? endDate
|
: null,
|
||||||
: before,
|
before: emailReceiveTimeType.getBeforeDate(endDate, before)
|
||||||
);
|
);
|
||||||
|
|
||||||
final listEmailCondition = {
|
final listEmailCondition = {
|
||||||
@@ -135,39 +132,4 @@ class SearchEmailFilter with EquatableMixin {
|
|||||||
startDate,
|
startDate,
|
||||||
endDate
|
endDate
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
extension SearchEmailFilterExtension on SearchEmailFilter {
|
|
||||||
|
|
||||||
SearchEmailFilter clearBeforeDate() {
|
|
||||||
return SearchEmailFilter(
|
|
||||||
from: from,
|
|
||||||
to: to,
|
|
||||||
text: text,
|
|
||||||
subject: subject,
|
|
||||||
notKeyword: notKeyword,
|
|
||||||
mailbox: mailbox,
|
|
||||||
emailReceiveTimeType: emailReceiveTimeType,
|
|
||||||
hasAttachment: hasAttachment,
|
|
||||||
before: null,
|
|
||||||
startDate: startDate,
|
|
||||||
endDate: endDate,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchEmailFilter withDateRange({UTCDate? startDate, UTCDate? endDate}) {
|
|
||||||
return SearchEmailFilter(
|
|
||||||
from: from,
|
|
||||||
to: to,
|
|
||||||
text: text,
|
|
||||||
subject: subject,
|
|
||||||
notKeyword: notKeyword,
|
|
||||||
mailbox: mailbox,
|
|
||||||
emailReceiveTimeType: emailReceiveTimeType,
|
|
||||||
hasAttachment: hasAttachment,
|
|
||||||
before: before,
|
|
||||||
startDate: startDate,
|
|
||||||
endDate: endDate,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+29
-47
@@ -4,11 +4,12 @@ import 'package:flutter/services.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:tmail_ui_user/features/base/mixin/popup_context_menu_action_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/popup_context_menu_action_mixin.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/popup_item_no_icon_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.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/model/search/advanced_search_filter.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/advanced_search_filter_form_bottom_view.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/advanced_search_filter_form_bottom_view.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/drop_down_button_filter_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/date_drop_down_button.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_auto_complete_email_adress.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/text_field_auto_complete_email_adress.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
@@ -73,7 +74,6 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
onTap: () => controller.selectedMailBox(context)),
|
onTap: () => controller.selectedMailBox(context)),
|
||||||
Row(children: [
|
Row(children: [
|
||||||
Expanded(child: _buildFilterField(
|
Expanded(child: _buildFilterField(
|
||||||
textEditingController: controller.dateFilterInputController,
|
|
||||||
context: context,
|
context: context,
|
||||||
advancedSearchFilterField: AdvancedSearchFilterField.date,
|
advancedSearchFilterField: AdvancedSearchFilterField.date,
|
||||||
isSelectFormList: true,
|
isSelectFormList: true,
|
||||||
@@ -102,52 +102,22 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
|
|
||||||
List<Widget> _buildEmailReceiveTimeTypeActionTiles(BuildContext context) {
|
List<Widget> _buildEmailReceiveTimeTypeActionTiles(BuildContext context) {
|
||||||
return EmailReceiveTimeType.values
|
return EmailReceiveTimeType.values
|
||||||
.map(
|
.map((receiveTime) => PopupMenuItem(
|
||||||
(e) => Material(
|
padding: EdgeInsets.zero,
|
||||||
child: PopupMenuItem(
|
child: PopupItemNoIconWidget(
|
||||||
child: Row(children: [
|
receiveTime.getTitle(context),
|
||||||
const SizedBox(width: 12),
|
svgIconSelected: _imagePaths.icFilterSelected,
|
||||||
Expanded(
|
maxWidth: 320,
|
||||||
child: Text(
|
isSelected: controller.dateFilterSelectedFormAdvancedSearch.value == receiveTime,
|
||||||
e.getTitle(
|
onCallbackAction: () => controller.updateReceiveDateSearchFilter(context, receiveTime),
|
||||||
context,
|
)))
|
||||||
startDate: controller.startDate,
|
.toList();
|
||||||
endDate: controller.endDate),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.w500))),
|
|
||||||
if (e == controller.dateFilterSelectedFormAdvancedSearch.value)
|
|
||||||
...[
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
SvgPicture.asset(
|
|
||||||
_imagePaths.icFilterSelected,
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
]),
|
|
||||||
onTap: () {
|
|
||||||
if (e != EmailReceiveTimeType.customRange) {
|
|
||||||
controller.clearDateRangeOfFilter();
|
|
||||||
}
|
|
||||||
controller.dateFilterSelectedFormAdvancedSearch.value = e;
|
|
||||||
controller.dateFilterInputController.text = e.getTitle(
|
|
||||||
context,
|
|
||||||
startDate: controller.startDate,
|
|
||||||
endDate: controller.endDate);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFilterField({
|
Widget _buildFilterField({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required AdvancedSearchFilterField advancedSearchFilterField,
|
required AdvancedSearchFilterField advancedSearchFilterField,
|
||||||
required TextEditingController textEditingController,
|
TextEditingController? textEditingController,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
bool isSelectFormList = false,
|
bool isSelectFormList = false,
|
||||||
MouseCursor? mouseCursor,
|
MouseCursor? mouseCursor,
|
||||||
@@ -180,7 +150,13 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
)
|
)
|
||||||
else if (_responsiveUtils.landscapeTabletSupported(context))
|
else if (_responsiveUtils.landscapeTabletSupported(context))
|
||||||
if (advancedSearchFilterField == AdvancedSearchFilterField.date)
|
if (advancedSearchFilterField == AdvancedSearchFilterField.date)
|
||||||
const DateDropDownButton()
|
Obx(() => DateDropDownButton(
|
||||||
|
_imagePaths,
|
||||||
|
startDate: controller.startDate.value,
|
||||||
|
endDate: controller.endDate.value,
|
||||||
|
receiveTimeSelected: controller.dateFilterSelectedFormAdvancedSearch.value,
|
||||||
|
onReceiveTimeSelected: (receiveTime) => controller.updateReceiveDateSearchFilter(context, receiveTime),
|
||||||
|
))
|
||||||
else
|
else
|
||||||
_buildTextField(
|
_buildTextField(
|
||||||
isSelectFormList: isSelectFormList,
|
isSelectFormList: isSelectFormList,
|
||||||
@@ -222,7 +198,7 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
Widget _buildTextFieldFilterForWeb({
|
Widget _buildTextFieldFilterForWeb({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required AdvancedSearchFilterField advancedSearchFilterField,
|
required AdvancedSearchFilterField advancedSearchFilterField,
|
||||||
required TextEditingController textEditingController,
|
TextEditingController? textEditingController,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
bool isSelectFormList = false,
|
bool isSelectFormList = false,
|
||||||
MouseCursor? mouseCursor,
|
MouseCursor? mouseCursor,
|
||||||
@@ -231,7 +207,13 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
}) {
|
}) {
|
||||||
switch (advancedSearchFilterField) {
|
switch (advancedSearchFilterField) {
|
||||||
case AdvancedSearchFilterField.date:
|
case AdvancedSearchFilterField.date:
|
||||||
return const DateDropDownButton();
|
return Obx(() => DateDropDownButton(
|
||||||
|
_imagePaths,
|
||||||
|
startDate: controller.startDate.value,
|
||||||
|
endDate: controller.endDate.value,
|
||||||
|
receiveTimeSelected: controller.dateFilterSelectedFormAdvancedSearch.value,
|
||||||
|
onReceiveTimeSelected: (receiveTime) => controller.updateReceiveDateSearchFilter(context, receiveTime),
|
||||||
|
));
|
||||||
default:
|
default:
|
||||||
return _buildTextField(
|
return _buildTextField(
|
||||||
isSelectFormList: isSelectFormList,
|
isSelectFormList: isSelectFormList,
|
||||||
@@ -357,7 +339,7 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
|
|||||||
Widget _buildTextField({
|
Widget _buildTextField({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required AdvancedSearchFilterField advancedSearchFilterField,
|
required AdvancedSearchFilterField advancedSearchFilterField,
|
||||||
required TextEditingController textEditingController,
|
TextEditingController? textEditingController,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
bool isSelectFormList = false,
|
bool isSelectFormList = false,
|
||||||
MouseCursor? mouseCursor,
|
MouseCursor? mouseCursor,
|
||||||
|
|||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/utils/style_utils.dart';
|
||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
|
|
||||||
|
class DateDropDownButton extends StatelessWidget {
|
||||||
|
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final DateTime? startDate;
|
||||||
|
final DateTime? endDate;
|
||||||
|
final EmailReceiveTimeType? receiveTimeSelected;
|
||||||
|
final Function(EmailReceiveTimeType)? onReceiveTimeSelected;
|
||||||
|
|
||||||
|
const DateDropDownButton(
|
||||||
|
this.imagePaths, {
|
||||||
|
Key? key,
|
||||||
|
this.startDate,
|
||||||
|
this.endDate,
|
||||||
|
this.receiveTimeSelected,
|
||||||
|
this.onReceiveTimeSelected,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DropdownButtonHideUnderline(
|
||||||
|
child: PointerInterceptor(
|
||||||
|
child: DropdownButton2<EmailReceiveTimeType>(
|
||||||
|
isExpanded: true,
|
||||||
|
items: EmailReceiveTimeType.values
|
||||||
|
.map((item) => _buildItemMenu(context, item))
|
||||||
|
.toList(),
|
||||||
|
value: receiveTimeSelected,
|
||||||
|
customButton: Container(
|
||||||
|
height: 44,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.colorInputBorderCreateMailbox,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
color: AppColor.colorInputBackgroundCreateMailbox
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(left: 12, right: 10),
|
||||||
|
child: Row(children: [
|
||||||
|
Expanded(child: Text(
|
||||||
|
receiveTimeSelected?.getTitle(context, startDate: startDate, endDate: endDate) ?? '',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
)),
|
||||||
|
SvgPicture.asset(imagePaths.icDropDown)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
onReceiveTimeSelected?.call(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: SvgPicture.asset(imagePaths.icDropDown),
|
||||||
|
buttonPadding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
buttonDecoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.colorInputBorderCreateMailbox,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
color: AppColor.colorInputBackgroundCreateMailbox,
|
||||||
|
),
|
||||||
|
itemHeight: 44,
|
||||||
|
buttonHeight: 44,
|
||||||
|
selectedItemHighlightColor: Colors.white,
|
||||||
|
itemPadding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
dropdownMaxHeight: 200,
|
||||||
|
dropdownDecoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
offset: const Offset(0.0, -8.0),
|
||||||
|
dropdownElevation: 4,
|
||||||
|
scrollbarRadius: const Radius.circular(40),
|
||||||
|
scrollbarThickness: 6
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DropdownMenuItem<EmailReceiveTimeType> _buildItemMenu(
|
||||||
|
BuildContext context,
|
||||||
|
EmailReceiveTimeType receiveTime
|
||||||
|
) {
|
||||||
|
return DropdownMenuItem<EmailReceiveTimeType>(
|
||||||
|
value: receiveTime,
|
||||||
|
child: PointerInterceptor(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
height: 44,
|
||||||
|
child: Row(children: [
|
||||||
|
Expanded(child: Text(
|
||||||
|
receiveTime.getTitle(context),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: Colors.black
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
)),
|
||||||
|
if (receiveTime == receiveTimeSelected)
|
||||||
|
SvgPicture.asset(
|
||||||
|
imagePaths.icChecked,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
fit: BoxFit.fill
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,6 +1,7 @@
|
|||||||
import 'package:core/presentation/extensions/color_extension.dart';
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
import 'package:core/presentation/resources/image_paths.dart';
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||||
|
import 'package:core/utils/app_logger.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';
|
||||||
@@ -34,9 +35,8 @@ class IconOpenAdvancedSearchWidget extends StatelessWidget {
|
|||||||
width: 16,
|
width: 16,
|
||||||
height: 16),
|
height: 16),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if(searchController.isAdvancedSearchViewOpen.isFalse && searchController.advancedSearchIsActivated.isFalse){
|
log('IconOpenAdvancedSearchWidget::build(): clicked');
|
||||||
advancedFilterController.initSearchFilterField(context);
|
advancedFilterController.initSearchFilterField(context);
|
||||||
}
|
|
||||||
searchController.showAdvancedFilterView(_parentContext);
|
searchController.showAdvancedFilterView(_parentContext);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -128,10 +128,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
},
|
},
|
||||||
buttonActionCallback: (filterAction) {
|
buttonActionCallback: (filterAction) {
|
||||||
if (filterAction is QuickSearchFilter) {
|
if (filterAction is QuickSearchFilter) {
|
||||||
dashBoardController.selectQuickSearchFilter(
|
dashBoardController.addFilterToSuggestionForm(filterAction);
|
||||||
quickSearchFilter: filterAction,
|
|
||||||
fromSuggestionBox: true,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
listActionPadding: const EdgeInsets.only(
|
listActionPadding: const EdgeInsets.only(
|
||||||
@@ -210,43 +207,31 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildListButtonForQuickSearchForm(BuildContext context, QuickSearchFilter filter) {
|
Widget buildListButtonForQuickSearchForm(BuildContext context, QuickSearchFilter filter) {
|
||||||
final controller = dashBoardController.searchController;
|
|
||||||
|
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final isFilterSelected = dashBoardController.checkQuickSearchFilterSelected(
|
final isFilterSelected = filter.isApplied(dashBoardController.searchController.listFilterOnSuggestionForm);
|
||||||
quickSearchFilter: filter);
|
|
||||||
|
|
||||||
return Chip(
|
return Chip(
|
||||||
labelPadding: const EdgeInsets.only(
|
labelPadding: const EdgeInsets.only(
|
||||||
top: 2,
|
top: 2,
|
||||||
bottom: 2,
|
bottom: 2,
|
||||||
right: 10),
|
right: 10),
|
||||||
label: Text(
|
label: Text(
|
||||||
filter.getTitle(
|
filter.getName(context),
|
||||||
context,
|
|
||||||
receiveTimeType: controller.emailReceiveTimeType.value),
|
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
style: filter.getTextStyle(
|
style: filter.getTextStyle(isFilterSelected: isFilterSelected),
|
||||||
quickSearchFilterSelected: isFilterSelected),
|
|
||||||
),
|
),
|
||||||
avatar: SvgPicture.asset(
|
avatar: SvgPicture.asset(
|
||||||
filter.getIcon(
|
filter.getIcon(imagePaths, isFilterSelected: isFilterSelected),
|
||||||
imagePaths,
|
width: 16,
|
||||||
quickSearchFilterSelected: isFilterSelected),
|
height: 16,
|
||||||
width: 16,
|
fit: BoxFit.fill),
|
||||||
height: 16,
|
labelStyle: filter.getTextStyle(isFilterSelected: isFilterSelected),
|
||||||
fit: BoxFit.fill),
|
backgroundColor: filter.getBackgroundColor(isFilterSelected: isFilterSelected),
|
||||||
labelStyle: filter.getTextStyle(
|
|
||||||
quickSearchFilterSelected: isFilterSelected),
|
|
||||||
backgroundColor: filter.getBackgroundColor(
|
|
||||||
quickSearchFilterSelected: isFilterSelected),
|
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
side: BorderSide(
|
side: BorderSide(color: filter.getBackgroundColor(isFilterSelected: isFilterSelected)),
|
||||||
color: filter.getBackgroundColor(
|
|
||||||
quickSearchFilterSelected: isFilterSelected)),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
newState.fold(
|
newState.fold(
|
||||||
(failure) {
|
(failure) {
|
||||||
if (failure is SearchEmailFailure) {
|
if (failure is SearchEmailFailure) {
|
||||||
|
canSearchMore = false;
|
||||||
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
||||||
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
|
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
|
||||||
_isLoadingMore = false;
|
_isLoadingMore = false;
|
||||||
@@ -197,7 +198,7 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
if (_currentMailboxId != mailbox.id) {
|
if (_currentMailboxId != mailbox.id) {
|
||||||
_currentMailboxId = mailbox.id;
|
_currentMailboxId = mailbox.id;
|
||||||
_resetToOriginalValue();
|
_resetToOriginalValue();
|
||||||
_getAllEmail();
|
_getAllEmailAction();
|
||||||
}
|
}
|
||||||
} else if (mailbox == null) { // disable current mailbox when search active
|
} else if (mailbox == null) { // disable current mailbox when search active
|
||||||
_currentMailboxId = null;
|
_currentMailboxId = null;
|
||||||
@@ -262,6 +263,12 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
_navigationRouter = action.navigationRouter;
|
_navigationRouter = action.navigationRouter;
|
||||||
_activateSearchFromRouter();
|
_activateSearchFromRouter();
|
||||||
mailboxDashBoardController.clearDashBoardAction();
|
mailboxDashBoardController.clearDashBoardAction();
|
||||||
|
} else if (action is SelectDateRangeToAdvancedSearch || action is ClearDateRangeToAdvancedSearch) {
|
||||||
|
if (listEmailController.hasClients) {
|
||||||
|
listEmailController.jumpTo(0);
|
||||||
|
}
|
||||||
|
canSearchMore = true;
|
||||||
|
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -335,18 +342,12 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
|
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
|
||||||
if (error is CannotCalculateChangesMethodResponseException) {
|
if (error is CannotCalculateChangesMethodResponseException) {
|
||||||
await _cachingManager.clearEmailCache();
|
await _cachingManager.clearEmailCache();
|
||||||
_getAllEmail();
|
_getAllEmailAction();
|
||||||
} else {
|
} else {
|
||||||
super.onError(error);
|
super.onError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getAllEmail() {
|
|
||||||
if (_accountId != null) {
|
|
||||||
_getAllEmailAction(_accountId!, mailboxId: _currentMailboxId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _resetToOriginalValue() {
|
void _resetToOriginalValue() {
|
||||||
dispatchState(Right(LoadingState()));
|
dispatchState(Right(LoadingState()));
|
||||||
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
||||||
@@ -389,48 +390,47 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getAllEmailAction(AccountId accountId, {MailboxId? mailboxId}) {
|
void _getAllEmailAction() {
|
||||||
consumeState(_getEmailsInMailboxInteractor.execute(
|
if (_accountId != null) {
|
||||||
accountId,
|
consumeState(_getEmailsInMailboxInteractor.execute(
|
||||||
limit: ThreadConstants.defaultLimit,
|
_accountId!,
|
||||||
sort: _sortOrder,
|
limit: ThreadConstants.defaultLimit,
|
||||||
emailFilter: EmailFilter(
|
sort: _sortOrder,
|
||||||
filter: _getFilterCondition(),
|
emailFilter: EmailFilter(
|
||||||
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
filter: _getFilterCondition(mailboxIdSelected: _currentMailboxId),
|
||||||
mailboxId: mailboxId ?? _currentMailboxId),
|
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
||||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
mailboxId: _currentMailboxId
|
||||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
),
|
||||||
));
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmailFilterCondition _getFilterCondition({bool isLoadMore = false}) {
|
EmailFilterCondition _getFilterCondition({PresentationEmail? oldestEmail, MailboxId? mailboxIdSelected}) {
|
||||||
final lastEmail = mailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty
|
|
||||||
? mailboxDashBoardController.emailsInCurrentMailbox.last
|
|
||||||
: null;
|
|
||||||
final mailboxIdSelected = mailboxDashBoardController.selectedMailbox.value?.id;
|
|
||||||
switch(mailboxDashBoardController.filterMessageOption.value) {
|
switch(mailboxDashBoardController.filterMessageOption.value) {
|
||||||
case FilterMessageOption.all:
|
case FilterMessageOption.all:
|
||||||
return EmailFilterCondition(
|
return EmailFilterCondition(
|
||||||
inMailbox: mailboxIdSelected,
|
inMailbox: mailboxIdSelected,
|
||||||
before: isLoadMore ? lastEmail?.receivedAt : null
|
before: oldestEmail?.receivedAt
|
||||||
);
|
);
|
||||||
case FilterMessageOption.unread:
|
case FilterMessageOption.unread:
|
||||||
return EmailFilterCondition(
|
return EmailFilterCondition(
|
||||||
inMailbox: mailboxIdSelected,
|
inMailbox: mailboxIdSelected,
|
||||||
notKeyword: KeyWordIdentifier.emailSeen.value,
|
notKeyword: KeyWordIdentifier.emailSeen.value,
|
||||||
before: isLoadMore ? lastEmail?.receivedAt : null
|
before: oldestEmail?.receivedAt
|
||||||
);
|
);
|
||||||
case FilterMessageOption.attachments:
|
case FilterMessageOption.attachments:
|
||||||
return EmailFilterCondition(
|
return EmailFilterCondition(
|
||||||
inMailbox: mailboxIdSelected,
|
inMailbox: mailboxIdSelected,
|
||||||
hasAttachment: true,
|
hasAttachment: true,
|
||||||
before: isLoadMore ? lastEmail?.receivedAt : null
|
before: oldestEmail?.receivedAt
|
||||||
);
|
);
|
||||||
case FilterMessageOption.starred:
|
case FilterMessageOption.starred:
|
||||||
return EmailFilterCondition(
|
return EmailFilterCondition(
|
||||||
inMailbox: mailboxIdSelected,
|
inMailbox: mailboxIdSelected,
|
||||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||||
before: isLoadMore ? lastEmail?.receivedAt : null
|
before: oldestEmail?.receivedAt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,10 +441,9 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
cancelSelectEmail();
|
cancelSelectEmail();
|
||||||
|
|
||||||
if (searchController.isSearchEmailRunning) {
|
if (searchController.isSearchEmailRunning) {
|
||||||
searchController.searchEmailFilter.value = _searchEmailFilter.clearBeforeDate();
|
|
||||||
_searchEmail(limit: limitEmailFetched);
|
_searchEmail(limit: limitEmailFetched);
|
||||||
} else {
|
} else {
|
||||||
_getAllEmail();
|
_getAllEmailAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,22 +458,22 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
void _refreshEmailChanges({jmap.State? currentEmailState}) {
|
void _refreshEmailChanges({jmap.State? currentEmailState}) {
|
||||||
log('ThreadController::_refreshEmailChanges(): currentEmailState: $currentEmailState');
|
log('ThreadController::_refreshEmailChanges(): currentEmailState: $currentEmailState');
|
||||||
if (searchController.isSearchEmailRunning) {
|
if (searchController.isSearchEmailRunning) {
|
||||||
searchController.searchEmailFilter.value = _searchEmailFilter.clearBeforeDate();
|
|
||||||
_searchEmail(limit: limitEmailFetched);
|
_searchEmail(limit: limitEmailFetched);
|
||||||
} else {
|
} else {
|
||||||
final newEmailState = currentEmailState ?? _currentEmailState;
|
final newEmailState = currentEmailState ?? _currentEmailState;
|
||||||
log('ThreadController::_refreshEmailChanges(): newEmailState: $newEmailState');
|
log('ThreadController::_refreshEmailChanges(): newEmailState: $newEmailState');
|
||||||
if (_accountId != null && newEmailState != null) {
|
if (_accountId != null && newEmailState != null) {
|
||||||
consumeState(_refreshChangesEmailsInMailboxInteractor.execute(
|
consumeState(_refreshChangesEmailsInMailboxInteractor.execute(
|
||||||
_accountId!,
|
_accountId!,
|
||||||
newEmailState,
|
newEmailState,
|
||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||||
emailFilter: EmailFilter(
|
emailFilter: EmailFilter(
|
||||||
filter: _getFilterCondition(),
|
filter: _getFilterCondition(mailboxIdSelected: _currentMailboxId),
|
||||||
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
||||||
mailboxId: _currentMailboxId),
|
mailboxId: _currentMailboxId
|
||||||
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,15 +482,19 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
void loadMoreEmails() {
|
void loadMoreEmails() {
|
||||||
log('ThreadController::loadMoreEmails()');
|
log('ThreadController::loadMoreEmails()');
|
||||||
if (canLoadMore && _accountId != null) {
|
if (canLoadMore && _accountId != null) {
|
||||||
|
final oldestEmail = mailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty
|
||||||
|
? mailboxDashBoardController.emailsInCurrentMailbox.last
|
||||||
|
: null;
|
||||||
consumeState(_loadMoreEmailsInMailboxInteractor.execute(
|
consumeState(_loadMoreEmailsInMailboxInteractor.execute(
|
||||||
GetEmailRequest(
|
GetEmailRequest(
|
||||||
_accountId!,
|
_accountId!,
|
||||||
limit: ThreadConstants.defaultLimit,
|
limit: ThreadConstants.defaultLimit,
|
||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
||||||
filter: _getFilterCondition(isLoadMore: true),
|
filter: _getFilterCondition(oldestEmail: oldestEmail),
|
||||||
properties: ThreadConstants.propertiesDefault,
|
properties: ThreadConstants.propertiesDefault,
|
||||||
lastEmailId: mailboxDashBoardController.emailsInCurrentMailbox.last.id)
|
lastEmailId: oldestEmail?.id
|
||||||
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,7 +652,7 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
icon: newFilterOption.getIconToast(_imagePaths));
|
icon: newFilterOption.getIconToast(_imagePaths));
|
||||||
|
|
||||||
if (searchController.isSearchEmailRunning) {
|
if (searchController.isSearchEmailRunning) {
|
||||||
_searchEmail(filterCondition: _getFilterCondition());
|
_searchEmail();
|
||||||
} else {
|
} else {
|
||||||
refreshAllEmail();
|
refreshAllEmail();
|
||||||
}
|
}
|
||||||
@@ -664,21 +667,22 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
searchController.clearTextSearch();
|
searchController.clearTextSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _searchEmail({UnsignedInt? limit, EmailFilterCondition? filterCondition}) {
|
void _searchEmail({UnsignedInt? limit}) {
|
||||||
if (_accountId != null) {
|
if (_accountId != null) {
|
||||||
searchController.activateSimpleSearch();
|
if (listEmailController.hasClients) {
|
||||||
|
listEmailController.jumpTo(0);
|
||||||
|
}
|
||||||
|
mailboxDashBoardController.emailsInCurrentMailbox.clear();
|
||||||
|
canSearchMore = true;
|
||||||
|
searchController.updateFilterEmail(beforeOption: const None());
|
||||||
|
|
||||||
filterCondition = EmailFilterCondition(
|
searchController.activateSimpleSearch();
|
||||||
notKeyword: filterCondition?.notKeyword,
|
|
||||||
hasKeyword: filterCondition?.hasKeyword,
|
|
||||||
hasAttachment: filterCondition?.hasAttachment,
|
|
||||||
);
|
|
||||||
|
|
||||||
consumeState(_searchEmailInteractor.execute(
|
consumeState(_searchEmailInteractor.execute(
|
||||||
_accountId!,
|
_accountId!,
|
||||||
limit: limit ?? ThreadConstants.defaultLimit,
|
limit: limit ?? ThreadConstants.defaultLimit,
|
||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
filter: _searchEmailFilter.mappingToEmailFilterCondition(moreFilterCondition: filterCondition),
|
filter: _searchEmailFilter.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()),
|
||||||
properties: ThreadConstants.propertiesDefault,
|
properties: ThreadConstants.propertiesDefault,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -697,6 +701,7 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _searchEmailsSuccess(SearchEmailSuccess success) {
|
void _searchEmailsSuccess(SearchEmailSuccess success) {
|
||||||
|
canSearchMore = true;
|
||||||
final resultEmailSearchList = success.emailList
|
final resultEmailSearchList = success.emailList
|
||||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById))
|
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById))
|
||||||
.toList();
|
.toList();
|
||||||
@@ -716,21 +721,24 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
|
|
||||||
void searchMoreEmails() {
|
void searchMoreEmails() {
|
||||||
if (canSearchMore && _accountId != null) {
|
if (canSearchMore && _accountId != null) {
|
||||||
final lastEmail = mailboxDashBoardController.emailsInCurrentMailbox.last;
|
final oldestEmail = mailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty
|
||||||
searchController.updateFilterEmail(before: lastEmail.receivedAt);
|
? mailboxDashBoardController.emailsInCurrentMailbox.last
|
||||||
|
: null;
|
||||||
|
searchController.updateFilterEmail(beforeOption: optionOf(oldestEmail?.receivedAt));
|
||||||
consumeState(_searchMoreEmailInteractor.execute(
|
consumeState(_searchMoreEmailInteractor.execute(
|
||||||
_accountId!,
|
_accountId!,
|
||||||
limit: ThreadConstants.defaultLimit,
|
limit: ThreadConstants.defaultLimit,
|
||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
filter: searchController.searchEmailFilter.value.mappingToEmailFilterCondition(),
|
filter: searchController.searchEmailFilter.value.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()),
|
||||||
properties: ThreadConstants.propertiesDefault,
|
properties: ThreadConstants.propertiesDefault,
|
||||||
lastEmailId: lastEmail.id
|
lastEmailId: oldestEmail?.id
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _searchMoreEmailsSuccess(SearchMoreEmailSuccess success) {
|
void _searchMoreEmailsSuccess(SearchMoreEmailSuccess success) {
|
||||||
if (success.emailList.isNotEmpty) {
|
if (success.emailList.isNotEmpty) {
|
||||||
|
canSearchMore = true;
|
||||||
final resultEmailSearchList = success.emailList
|
final resultEmailSearchList = success.emailList
|
||||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById))
|
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById))
|
||||||
.where((email) => !mailboxDashBoardController.emailsInCurrentMailbox.contains(email))
|
.where((email) => !mailboxDashBoardController.emailsInCurrentMailbox.contains(email))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2023-02-24T11:57:26.810965",
|
"@@last_modified": "2023-03-02T21:08:14.879842",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1488,12 +1488,6 @@
|
|||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
},
|
},
|
||||||
"allMails": "All mails",
|
|
||||||
"@allMails": {
|
|
||||||
"type": "text",
|
|
||||||
"placeholders_order": [],
|
|
||||||
"placeholders": {}
|
|
||||||
},
|
|
||||||
"allTime": "All time",
|
"allTime": "All time",
|
||||||
"@allTime": {
|
"@allTime": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
|||||||
@@ -1515,13 +1515,6 @@ class AppLocalizations {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String get allMails {
|
|
||||||
return Intl.message(
|
|
||||||
'All mails',
|
|
||||||
name: 'allMails',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String get allTime {
|
String get allTime {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'All time',
|
'All time',
|
||||||
|
|||||||
@@ -107,6 +107,14 @@ class PresentationMailbox with EquatableMixin {
|
|||||||
|
|
||||||
bool get allowedToDisplay => isSubscribedMailbox || isDefault;
|
bool get allowedToDisplay => isSubscribedMailbox || isDefault;
|
||||||
|
|
||||||
|
MailboxId? get mailboxId {
|
||||||
|
if (id == unifiedMailbox.id) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
id,
|
id,
|
||||||
|
|||||||
Reference in New Issue
Block a user