Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion core/lib/presentation/extensions/color_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ extension AppColor on Color {
static const colorFilterMessageButton = Color(0xFFEBEDF0);
static const colorFilterMessageIcon = Color(0xFF686E76);
static const colorFilterMessageTitle = Color(0xFF686E76);
static const colorStarredSearchFilterIcon = Color(0xFFFFCC00);
static const colorMobileSearchFilterButton = Color(0xFFEBEDF0);
static const colorContactViewClearFilterButton = Color(0x001C3D0D);
static const steelGrayA540 = Color(0xFF55687D);
Expand Down
4 changes: 3 additions & 1 deletion core/lib/presentation/views/checkbox/labeled_checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class LabeledCheckbox extends StatelessWidget {
children: <Widget>[
buildCheckboxWidget,
buildGapWidget,
buildLabelWidget,
Flexible(child: buildLabelWidget),
],
),
);
Expand All @@ -53,5 +53,7 @@ class LabeledCheckbox extends StatelessWidget {
Widget get buildLabelWidget => Text(
label,
style: textStyle ?? ThemeUtils.textStyleM3BodyMedium3,
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:model/model.dart';
import 'package:super_tag_editor/tag_editor.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
Expand Down Expand Up @@ -33,6 +34,8 @@ class AdvancedFilterController extends BaseController {

final receiveTimeType = EmailReceiveTimeType.allTime.obs;
final hasAttachment = false.obs;
final isStarred = false.obs;
final isUnread = false.obs;
final startDate = Rxn<DateTime>();
final endDate = Rxn<DateTime>();
final sortOrderType = SearchEmailFilter.defaultSortOrder.obs;
Expand Down Expand Up @@ -115,10 +118,12 @@ class AdvancedFilterController extends BaseController {
Option<Set<String>>? toOption,
Option<SearchQuery>? textOption,
Option<String>? subjectOption,
Option<Set<String>>? hasKeywordOption,
Option<Set<String>>? notKeywordOption,
Option<PresentationMailbox>? mailboxOption,
Option<EmailReceiveTimeType>? emailReceiveTimeTypeOption,
Option<bool>? hasAttachmentOption,
Option<bool>? unreadOption,
Option<UTCDate>? beforeOption,
Option<UTCDate>? startDateOption,
Option<UTCDate>? endDateOption,
Expand All @@ -130,10 +135,12 @@ class AdvancedFilterController extends BaseController {
toOption: toOption,
textOption: textOption,
subjectOption: subjectOption,
hasKeywordOption: hasKeywordOption,
notKeywordOption: notKeywordOption,
mailboxOption: mailboxOption,
emailReceiveTimeTypeOption: emailReceiveTimeTypeOption,
hasAttachmentOption: hasAttachmentOption,
unreadOption: unreadOption,
beforeOption: beforeOption,
startDateOption: startDateOption,
endDateOption: endDateOption,
Expand Down Expand Up @@ -174,6 +181,13 @@ class AdvancedFilterController extends BaseController {

final endDateOption = optionOf(endDate.value?.toUTCDate());

final unreadOption = Some(isUnread.value);

final hasKeywordOption = option(
isStarred.isTrue,
{KeyWordIdentifier.emailFlagged.value},
);

_updateMemorySearchFilter(
textOption: textOption,
notKeywordOption: notKeywordsOption,
Expand All @@ -184,6 +198,8 @@ class AdvancedFilterController extends BaseController {
subjectOption: subjectOption,
emailReceiveTimeTypeOption: emailReceiveTimeTypeOption,
hasAttachmentOption: hasAttachmentOption,
unreadOption: unreadOption,
hasKeywordOption: hasKeywordOption,
startDateOption: startDateOption,
endDateOption: endDateOption
);
Expand Down Expand Up @@ -267,6 +283,11 @@ class AdvancedFilterController extends BaseController {

hasAttachment.value = _memorySearchFilter.hasAttachment;

isUnread.value = _memorySearchFilter.unread;

isStarred.value = _memorySearchFilter.hasKeyword
.contains(KeyWordIdentifier.emailFlagged.value);

if (_memorySearchFilter.from.isEmpty) {
listFromEmailAddress.clear();
} else {
Expand Down Expand Up @@ -453,6 +474,8 @@ class AdvancedFilterController extends BaseController {
endDate.value = null;
receiveTimeType.value = EmailReceiveTimeType.allTime;
hasAttachment.value = false;
isUnread.value = false;
isStarred.value = false;
selectedFolderName.value = null;
listFromEmailAddress.clear();
listToEmailAddress.clear();
Expand Down Expand Up @@ -532,6 +555,26 @@ class AdvancedFilterController extends BaseController {
_updateMemorySearchFilter(hasAttachmentOption: Some(hasAttachment.value));
}

void onStarredCheckboxChanged(bool? isChecked) {
isStarred.value = isChecked ?? false;
final listHasKeywordFiltered = _memorySearchFilter.hasKeyword;
if (isStarred.isTrue) {
listHasKeywordFiltered.add(KeyWordIdentifier.emailFlagged.value);
} else {
listHasKeywordFiltered.remove(KeyWordIdentifier.emailFlagged.value);
}
_updateMemorySearchFilter(
hasKeywordOption: Some(listHasKeywordFiltered),
);
}

void onUnreadCheckboxChanged(bool? isChecked) {
isUnread.value = isChecked ?? false;
_updateMemorySearchFilter(
unreadOption: isStarred.isTrue ? const Some(true) : const None(),
);
}

void onTextChanged(FilterField filterField, String value) {
switch (filterField) {
case FilterField.subject:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class InputFieldFocusManager {
late FocusNode notKeywordFieldFocusNode;
late FocusNode mailboxFieldFocusNode;
late FocusNode attachmentCheckboxFocusNode;
late FocusNode starredCheckboxFocusNode;
late FocusNode unreadCheckboxFocusNode;

InputFieldFocusManager() {
fromFieldFocusNode = FocusNode();
Expand All @@ -19,6 +21,8 @@ class InputFieldFocusManager {
notKeywordFieldFocusNode = FocusNode();
mailboxFieldFocusNode = FocusNode();
attachmentCheckboxFocusNode = FocusNode();
starredCheckboxFocusNode = FocusNode();
unreadCheckboxFocusNode = FocusNode();
}

factory InputFieldFocusManager.initial() {
Expand All @@ -33,5 +37,7 @@ class InputFieldFocusManager {
notKeywordFieldFocusNode.dispose();
mailboxFieldFocusNode.dispose();
attachmentCheckboxFocusNode.dispose();
starredCheckboxFocusNode.dispose();
unreadCheckboxFocusNode.dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/notify_thread_detail_setting_updated.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/reopen_composer_cache_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/select_search_filter_action_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/set_error_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/update_current_emails_flags_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_paywall_extension.dart';
Expand Down Expand Up @@ -2246,6 +2247,12 @@ class MailboxDashBoardController extends ReloadableController
case QuickSearchFilter.folder:
_deleteFolderSearchFilter();
break;
case QuickSearchFilter.starred:
deleteStarredSearchFilter();
break;
case QuickSearchFilter.unread:
deleteUnreadSearchFilter();
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
Option<PresentationMailbox>? mailboxOption,
Option<EmailReceiveTimeType>? emailReceiveTimeTypeOption,
Option<bool>? hasAttachmentOption,
Option<bool>? unreadOption,
Option<UTCDate>? beforeOption,
Option<UTCDate>? startDateOption,
Option<UTCDate>? endDateOption,
Expand All @@ -200,6 +201,7 @@ class SearchController extends BaseController with DateRangePickerMixin {
mailboxOption: mailboxOption,
emailReceiveTimeTypeOption: emailReceiveTimeTypeOption,
hasAttachmentOption: hasAttachmentOption,
unreadOption: unreadOption,
beforeOption: beforeOption,
startDateOption: startDateOption,
endDateOption: endDateOption,
Expand All @@ -221,6 +223,10 @@ class SearchController extends BaseController with DateRangePickerMixin {

Set<String> get listAddressOfFromFiltered => searchEmailFilter.value.from;

Set<String> get listHasKeywordFiltered => searchEmailFilter.value.hasKeyword;

bool get unreadFiltered => searchEmailFilter.value.unread;

EmailSortOrderType get sortOrderFiltered => searchEmailFilter.value.sortOrderType;

bool isSearchActive() =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';

extension SelectSearchFilterActionExtension on MailboxDashBoardController {
void selectStarredSearchFilter() {
final listHasKeywordFiltered = searchController.listHasKeywordFiltered;
listHasKeywordFiltered.add(KeyWordIdentifier.emailFlagged.value);
searchController.updateFilterEmail(
hasKeywordOption: Some(listHasKeywordFiltered),
);
dispatchAction(StartSearchEmailAction());
}

void selectUnreadSearchFilter() {
searchController.updateFilterEmail(unreadOption: const Some(true));
dispatchAction(StartSearchEmailAction());
}

void deleteStarredSearchFilter() {
final listHasKeywordFiltered = searchController.listHasKeywordFiltered;
listHasKeywordFiltered.remove(KeyWordIdentifier.emailFlagged.value);
searchController.updateFilterEmail(
hasKeywordOption: Some(listHasKeywordFiltered),
);
dispatchAction(StartSearchEmailAction());
}

void deleteUnreadSearchFilter() {
searchController.updateFilterEmail(unreadOption: const None());
dispatchAction(StartSearchEmailAction());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/base/widget/clean_messages_banner.dart';
Expand All @@ -22,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/base_mailb
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_profile_setting_action_type_click_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/select_search_filter_action_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/profile_setting/profile_setting_action_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
Expand Down Expand Up @@ -452,13 +454,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.colorFilterMessageButton.withValues(alpha: 0.6),
shadowColor: Colors.transparent,
padding: const EdgeInsetsDirectional.symmetric(horizontal: 12, vertical: 8),
padding: const EdgeInsetsDirectional.symmetric(horizontal: 12),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
elevation: 0.0,
foregroundColor: AppColor.colorTextButtonHeaderThread,
maximumSize: const Size.fromWidth(250),
fixedSize: const Size.fromHeight(34),
textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith(
fontSize: 13,
fontWeight: FontWeight.normal,
Expand All @@ -473,7 +476,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
Obx(() {
final filterMessageCurrent = controller.filterMessageOption.value;

if (controller.validateNoEmailsInTrashAndSpamFolder()) {
if (controller.validateNoEmailsInTrashAndSpamFolder() ||
controller.searchController.isSearchEmailRunning) {
return const SizedBox.shrink();
} else {
return Padding(
Expand Down Expand Up @@ -503,11 +507,16 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
return const SizedBox.shrink();
}
}),
const Spacer(),
Obx(() {
if (controller.searchController.isSearchEmailRunning &&
controller.dashboardRoute.value == DashboardRoutes.thread) {
return _buildQuickSearchFilterButton(context, QuickSearchFilter.sortBy);
return Padding(
padding: const EdgeInsetsDirectional.only(start: 16),
child: _buildQuickSearchFilterButton(
context,
QuickSearchFilter.sortBy,
),
);
} else {
return const SizedBox.shrink();
}
Expand Down Expand Up @@ -654,6 +663,10 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
_buildQuickSearchFilterButton(context, QuickSearchFilter.dateTime),
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
_buildQuickSearchFilterButton(context, QuickSearchFilter.hasAttachment),
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
_buildQuickSearchFilterButton(context, QuickSearchFilter.starred),
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
_buildQuickSearchFilterButton(context, QuickSearchFilter.unread),
],
),
),
Expand Down Expand Up @@ -704,6 +717,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
final receiveTimeType = controller.searchController.receiveTimeFiltered;
final mailbox = controller.searchController.mailboxFiltered;
final listAddressOfTo = controller.searchController.listAddressOfToFiltered;
final listHasKeywordFiltered = controller.searchController.listHasKeywordFiltered;
final unreadFiltered = controller.searchController.unreadFiltered;

final isSelected = searchFilter.isSelected(
context,
Expand All @@ -721,7 +736,9 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
startDate != null ||
endDate != null ||
receiveTimeType != EmailReceiveTimeType.allTime ||
mailbox != null;
mailbox != null ||
listHasKeywordFiltered.contains(KeyWordIdentifier.emailFlagged.value) ||
unreadFiltered;

return SearchFilterButton(
key: Key('${searchFilter.name}_search_filter_button'),
Expand All @@ -737,8 +754,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
listAddressOfTo: listAddressOfTo,
mailbox: mailbox,
buttonPadding: buttonPadding,
isContextMenuAlignEndButton: isFilterApplied ||
searchFilter == QuickSearchFilter.sortBy,
backgroundColor: searchFilter == QuickSearchFilter.sortBy
? isSelected
? AppColor.primaryColor.withValues(alpha: 0.06)
: AppColor.colorFilterMessageButton.withValues(alpha: 0.6)
: null,
isContextMenuAlignEndButton: isFilterApplied,
onSelectSearchFilterAction: _onSelectSearchFilterAction,
onDeleteSearchFilterAction: controller.onDeleteSearchFilterAction,
);
Expand Down Expand Up @@ -777,6 +798,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
case QuickSearchFilter.folder:
controller.selectFolderSearchFilter();
break;
case QuickSearchFilter.starred:
controller.selectStarredSearchFilter();
break;
case QuickSearchFilter.unread:
controller.selectUnreadSearchFilter();
break;
default:
break;
}
Expand Down
Loading
Loading