TF-524 Apply quick search for mobile and tablet
This commit is contained in:
+1
-1
@@ -62,7 +62,7 @@ export 'presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart';
|
||||
export 'presentation/views/search/search_bar_view.dart';
|
||||
export 'presentation/views/popup_menu/popup_menu_item_widget.dart';
|
||||
export 'presentation/views/tab_bar/custom_tab_indicator.dart';
|
||||
export 'presentation/views/typeahead/typeahead_for_quick_search.dart';
|
||||
export 'presentation/views/quick_search/quick_search_input_form.dart';
|
||||
|
||||
// Resources
|
||||
export 'presentation/resources/assets_paths.dart';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
typedef FutureOr<Iterable<T>> SuggestionsCallback<T>(String pattern);
|
||||
typedef FutureOr<Iterable<R>> FetchRecentActionCallback<R>(String pattern);
|
||||
typedef Widget ItemBuilder<T>(BuildContext context, T itemData);
|
||||
typedef void SuggestionSelectionCallback<T>(T suggestion);
|
||||
typedef void RecentSelectionCallback<R>(R recent);
|
||||
typedef Widget ErrorBuilder(BuildContext context, Object? error);
|
||||
typedef Widget ButtonActionBuilder(BuildContext context, dynamic action);
|
||||
typedef void ButtonActionCallback(dynamic action);
|
||||
|
||||
typedef Widget AnimationTransitionBuilder(
|
||||
BuildContext context, Widget child, AnimationController? controller);
|
||||
@@ -1,5 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
final supportedPlatform = (kIsWeb || Platform.isAndroid || Platform.isIOS);
|
||||
@@ -7,6 +7,10 @@ class RecentSearch with EquatableMixin {
|
||||
|
||||
RecentSearch(this.value, this.creationDate);
|
||||
|
||||
factory RecentSearch.now(String word) {
|
||||
return RecentSearch(word, DateTime.now());
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [value, creationDate];
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/email/email_action_type.dart';
|
||||
import 'package:model/email/filter_message_option.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
||||
|
||||
class DashBoardAction extends UIAction {
|
||||
@@ -97,4 +97,12 @@ class OpenEmailDetailedAction extends DashBoardAction {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [presentationEmail];
|
||||
}
|
||||
|
||||
class DisableSearchEmailAction extends DashBoardAction {
|
||||
|
||||
DisableSearchEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
|
||||
String getName(BuildContext context) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return AppLocalizations.of(context).unread;
|
||||
case FilterMessageOption.attachments:
|
||||
return AppLocalizations.of(context).with_attachments;
|
||||
case FilterMessageOption.starred:
|
||||
return AppLocalizations.of(context).starred;
|
||||
}
|
||||
}
|
||||
|
||||
String getIcon(ImagePaths imagePaths) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return imagePaths.icUnread;
|
||||
case FilterMessageOption.attachments:
|
||||
return imagePaths.icAttachment;
|
||||
case FilterMessageOption.starred:
|
||||
return imagePaths.icStar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/emai
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/quick_search_filter.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
|
||||
@@ -82,7 +83,6 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
final accountId = Rxn<AccountId>();
|
||||
final userProfile = Rxn<UserProfile>();
|
||||
final searchState = SearchState.initial().obs;
|
||||
final suggestionSearch = <String>[].obs;
|
||||
final dashBoardAction = Rxn<UIAction>();
|
||||
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
|
||||
final appInformation = Rxn<PackageInfo>();
|
||||
@@ -286,35 +286,40 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
void disableSearch() {
|
||||
searchState.value = searchState.value.disableSearchState();
|
||||
searchQuery = SearchQuery.initial();
|
||||
clearSuggestionSearch();
|
||||
searchInputController.clear();
|
||||
listFilterQuickSearch.clear();
|
||||
emailReceiveTimeType.value = null;
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
void clearSearchText() {
|
||||
void clearTextSearch() {
|
||||
searchQuery = SearchQuery.initial();
|
||||
clearSuggestionSearch();
|
||||
searchInputController.clear();
|
||||
searchFocus.requestFocus();
|
||||
}
|
||||
|
||||
void clearSuggestionSearch() {
|
||||
suggestionSearch.clear();
|
||||
}
|
||||
|
||||
void addSuggestionSearch(String query) {
|
||||
if (query.trim().isNotEmpty) {
|
||||
suggestionSearch.value = [query];
|
||||
} else {
|
||||
clearSearchText();
|
||||
}
|
||||
void updateTextSearch(String value) {
|
||||
searchInputController.text = value;
|
||||
}
|
||||
|
||||
void searchEmail(BuildContext context, String value) {
|
||||
searchQuery = SearchQuery(value);
|
||||
dispatchState(Right(SearchEmailNewQuery(searchQuery ?? SearchQuery.initial())));
|
||||
clearSuggestionSearch();
|
||||
FocusScope.of(context).unfocus();
|
||||
if (searchInsideEmailDetailedViewIsActive(context)) {
|
||||
closeEmailDetailedView();
|
||||
}
|
||||
}
|
||||
|
||||
bool searchInsideEmailDetailedViewIsActive(BuildContext context) {
|
||||
return BuildUtils.isWeb
|
||||
&& _responsiveUtils.isDesktop(context)
|
||||
&& routePath.value == AppRoutes.EMAIL;
|
||||
}
|
||||
|
||||
void closeEmailDetailedView() {
|
||||
dispatchRoute(AppRoutes.THREAD);
|
||||
clearSelectedEmail();
|
||||
}
|
||||
|
||||
void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) {
|
||||
@@ -472,6 +477,36 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
emailReceiveTimeType.value = receiveTimeType;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForLast7DaysIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.last7Days)
|
||||
&& emailReceiveTimeType.value != null;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForHasAttachmentIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.hasAttachment)
|
||||
|| filterMessageOption.value == FilterMessageOption.attachments;
|
||||
}
|
||||
|
||||
bool quickSearchFilterForFromMeIsActive () {
|
||||
return listFilterQuickSearch.contains(QuickSearchFilter.fromMe);
|
||||
}
|
||||
|
||||
bool filterForHasAttachmentIsActive () {
|
||||
return quickSearchFilterForHasAttachmentIsActive() || filterMessageWithAttachmentIsActive();
|
||||
}
|
||||
|
||||
bool filterMessageWithAttachmentIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.attachments;
|
||||
}
|
||||
|
||||
bool filterMessageUnreadIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.unread;
|
||||
}
|
||||
|
||||
bool filterMessageStarredIsActive () {
|
||||
return filterMessageOption.value == FilterMessageOption.starred;
|
||||
}
|
||||
|
||||
void composeEmailAction() {
|
||||
if (kIsWeb) {
|
||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||
@@ -15,7 +14,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/em
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
@@ -396,17 +395,17 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return Row(
|
||||
children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icBack, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.disableSearch();
|
||||
controller.dispatchAction(CancelSelectionAllEmailAction());
|
||||
}),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icBack,
|
||||
color: AppColor.colorTextButton,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () => controller.dispatchAction(DisableSearchEmailAction())),
|
||||
Expanded(child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar),
|
||||
height: 45,
|
||||
child: TypeAheadFormFieldQuickSearch<PresentationEmail, RecentSearch>(
|
||||
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
||||
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||
controller: controller.searchInputController,
|
||||
autofocus: true,
|
||||
@@ -414,7 +413,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (keyword) {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
},
|
||||
@@ -424,30 +423,43 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
enabledBorder: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
hintText: AppLocalizations.of(context).search_mail,
|
||||
hintStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0),
|
||||
labelStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0)
|
||||
hintStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0),
|
||||
labelStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0)
|
||||
),
|
||||
leftButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icSearchBar, width: 16, height: 16, fit: BoxFit.fill),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icSearchBar,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
final keyword = controller.searchInputController.text;
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
}),
|
||||
clearTextButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(imagePaths.icClearTextSearch, width: 16, height: 16, fit: BoxFit.fill),
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icClearTextSearch,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.searchInputController.clear();
|
||||
controller.clearSearchText();
|
||||
controller.clearTextSearch();
|
||||
})
|
||||
),
|
||||
suggestionsBoxDecoration: QuickSearchSuggestionsBoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: responsiveUtils.isDesktop(context) ? 556 : double.infinity),
|
||||
maxWidth: responsiveUtils.isDesktop(context)
|
||||
? 556
|
||||
: double.infinity),
|
||||
),
|
||||
debounceDuration: const Duration(milliseconds: 500),
|
||||
listActionButton: const [
|
||||
@@ -463,12 +475,18 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
},
|
||||
buttonActionCallback: (filterAction) {
|
||||
if (filterAction is QuickSearchFilter) {
|
||||
controller.selectQuickSearchFilter(filterAction, fromSuggestionBox: true);
|
||||
controller.selectQuickSearchFilter(
|
||||
filterAction,
|
||||
fromSuggestionBox: true);
|
||||
}
|
||||
},
|
||||
listActionPadding: const EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 16),
|
||||
listActionPadding: const EdgeInsets.only(
|
||||
left: 24,
|
||||
top: 24,
|
||||
right: 24,
|
||||
bottom: 16),
|
||||
titleHeaderRecent: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24, bottom: 8, top: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Text(AppLocalizations.of(context).recent,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
@@ -480,12 +498,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
||||
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.searchEmail(context, keyword);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24, top: 14, bottom: 14),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
vertical: 14),
|
||||
child: Row(children: [
|
||||
Text(AppLocalizations.of(context).showingResultsFor,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
@@ -523,10 +543,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
||||
return controller.quickSearchEmailsAction(pattern);
|
||||
},
|
||||
itemBuilder: (context, email) {
|
||||
return EmailQuickSearchItemTileWidget(email, controller.selectedMailbox.value);
|
||||
return EmailQuickSearchItemTileWidget(
|
||||
email, controller.selectedMailbox.value);
|
||||
},
|
||||
onSuggestionSelected: (presentationEmail) async {
|
||||
controller.dispatchAction(OpenEmailDetailedAction(context, presentationEmail));
|
||||
controller.dispatchAction(
|
||||
OpenEmailDetailedAction(context, presentationEmail));
|
||||
}),
|
||||
)),
|
||||
const SizedBox(width: 16),
|
||||
|
||||
+15
-7
@@ -3,8 +3,7 @@ import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
mixin FilterEmailPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -38,15 +37,24 @@ mixin FilterEmailPopupMenuMixin {
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill,
|
||||
color: option != FilterMessageOption.starred ? AppColor.colorTextButton : null),
|
||||
color: option != FilterMessageOption.starred
|
||||
? AppColor.colorTextButton
|
||||
: null),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Text(
|
||||
option.getName(context),
|
||||
style: const TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w500))),
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500))),
|
||||
if (optionSelected == option)
|
||||
const SizedBox(width: 12),
|
||||
if (optionSelected == option)
|
||||
SvgPicture.asset(_imagePaths.icFilterSelected, width: 16, height: 16, fit: BoxFit.fill),
|
||||
... [
|
||||
const SizedBox(width: 12),
|
||||
SvgPicture.asset(_imagePaths.icFilterSelected,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
]
|
||||
])
|
||||
),
|
||||
)
|
||||
|
||||
@@ -6,9 +6,9 @@ import 'package:jmap_dart_client/jmap/core/state.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
abstract class ThreadDataSource {
|
||||
Future<EmailsResponse> getAllEmail(
|
||||
|
||||
@@ -6,11 +6,11 @@ import 'package:jmap_dart_client/jmap/core/state.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
class LocalThreadDataSourceImpl extends ThreadDataSource {
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ import 'package:jmap_dart_client/jmap/core/state.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
class ThreadDataSourceImpl extends ThreadDataSource {
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.da
|
||||
import 'package:tmail_ui_user/features/thread/data/extensions/list_email_cache_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
class EmailCacheManager {
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/email/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
class EmailFilter with EquatableMixin {
|
||||
|
||||
+61
-1
@@ -1,9 +1,17 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
enum FilterMessageOption {
|
||||
all,
|
||||
unread,
|
||||
attachments,
|
||||
starred,
|
||||
}
|
||||
|
||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
|
||||
String getIconToast(ImagePaths imagePaths) {
|
||||
@@ -44,4 +52,56 @@ extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
return AppLocalizations.of(context).with_starred;
|
||||
}
|
||||
}
|
||||
|
||||
bool filterPresentationEmail(PresentationEmail email) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return true;
|
||||
case FilterMessageOption.unread:
|
||||
return !email.hasRead;
|
||||
case FilterMessageOption.attachments:
|
||||
return email.withAttachments;
|
||||
case FilterMessageOption.starred:
|
||||
return email.hasStarred;
|
||||
}
|
||||
}
|
||||
|
||||
bool filterEmail(Email email) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return true;
|
||||
case FilterMessageOption.unread:
|
||||
return !email.hasRead;
|
||||
case FilterMessageOption.attachments:
|
||||
return email.withAttachments;
|
||||
case FilterMessageOption.starred:
|
||||
return email.hasStarred;
|
||||
}
|
||||
}
|
||||
|
||||
String getName(BuildContext context) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return AppLocalizations.of(context).unread;
|
||||
case FilterMessageOption.attachments:
|
||||
return AppLocalizations.of(context).with_attachments;
|
||||
case FilterMessageOption.starred:
|
||||
return AppLocalizations.of(context).starred;
|
||||
}
|
||||
}
|
||||
|
||||
String getIcon(ImagePaths imagePaths) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return imagePaths.icUnread;
|
||||
case FilterMessageOption.attachments:
|
||||
return imagePaths.icAttachment;
|
||||
case FilterMessageOption.starred:
|
||||
return imagePaths.icStar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,9 @@ import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart';
|
||||
|
||||
abstract class ThreadRepository {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart';
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||
|
||||
@@ -42,6 +42,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_da
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/email_receive_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/quick_search_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/empty_trash_folder_state.dart';
|
||||
@@ -62,7 +64,6 @@ import 'package:tmail_ui_user/features/thread/domain/usecases/move_multiple_emai
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/refresh_changes_emails_in_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/search_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/search_more_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.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';
|
||||
@@ -92,7 +93,7 @@ class ThreadController extends BaseController {
|
||||
final MoveToMailboxInteractor _moveToMailboxInteractor;
|
||||
|
||||
final emailList = <PresentationEmail>[].obs;
|
||||
final emailListSearch = <PresentationEmail>[].obs;
|
||||
final searchIsActive = RxBool(false);
|
||||
|
||||
bool canLoadMore = true;
|
||||
bool canSearchMore = true;
|
||||
@@ -113,6 +114,10 @@ class ThreadController extends BaseController {
|
||||
|
||||
PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value;
|
||||
|
||||
TextEditingController get searchController => mailboxDashBoardController.searchInputController;
|
||||
|
||||
String get currentTextSearch => mailboxDashBoardController.searchInputController.text;
|
||||
|
||||
ThreadController(
|
||||
this._getEmailsInMailboxInteractor,
|
||||
this._markAsMultipleEmailReadInteractor,
|
||||
@@ -154,7 +159,7 @@ class ThreadController extends BaseController {
|
||||
newState.fold(
|
||||
(failure) {
|
||||
if (failure is SearchEmailFailure) {
|
||||
emailListSearch.clear();
|
||||
emailList.clear();
|
||||
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
|
||||
_isLoadingMore = false;
|
||||
}
|
||||
@@ -181,7 +186,6 @@ class ThreadController extends BaseController {
|
||||
void onDone() {
|
||||
viewState.value.fold(
|
||||
(failure) {
|
||||
log('ThreadController::onDone(): failure: $failure');
|
||||
if (failure is MarkAsMultipleEmailReadAllFailure
|
||||
|| failure is MarkAsMultipleEmailReadFailure) {
|
||||
_markAsReadSelectedMultipleEmailFailure(failure);
|
||||
@@ -197,7 +201,6 @@ class ThreadController extends BaseController {
|
||||
(success) {
|
||||
if (success is MarkAsMultipleEmailReadAllSuccess
|
||||
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||
log('ThreadController::onDone(): success: $success');
|
||||
_markAsReadSelectedMultipleEmailSuccess(success);
|
||||
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|
||||
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
||||
@@ -239,9 +242,7 @@ class ThreadController extends BaseController {
|
||||
|
||||
searchWorker = ever(mailboxDashBoardController.searchState, (searchState) {
|
||||
if (searchState is SearchState) {
|
||||
if (searchState.searchStatus == SearchStatus.INACTIVE) {
|
||||
emailListSearch.clear();
|
||||
} else if (searchState.searchStatus == SearchStatus.ACTIVE) {
|
||||
if (searchState.searchStatus == SearchStatus.ACTIVE) {
|
||||
cancelSelectEmail();
|
||||
}
|
||||
}
|
||||
@@ -270,6 +271,9 @@ class ThreadController extends BaseController {
|
||||
} if (action is OpenEmailDetailedAction) {
|
||||
pressEmailAction(action.context, EmailActionType.preview, action.presentationEmail);
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} if (action is DisableSearchEmailAction) {
|
||||
closeSearchEmailAction();
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -318,7 +322,6 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _getAllEmailSuccess(GetAllEmailSuccess success) {
|
||||
log('ThreadController::_getAllEmailSuccess(): ${success.emailList.length}');
|
||||
_currentEmailState = success.currentEmailState;
|
||||
emailList.value = success.emailList;
|
||||
if (listEmailController.hasClients) {
|
||||
@@ -327,7 +330,6 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) {
|
||||
log('ThreadController::_refreshChangesAllEmailSuccess(): ${success.emailList.length}');
|
||||
_currentEmailState = success.currentEmailState;
|
||||
|
||||
final emailsBeforeChanges = emailList;
|
||||
@@ -341,7 +343,6 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _getAllEmailAction(AccountId accountId, {MailboxId? mailboxId}) {
|
||||
log('ThreadController::_getAllEmailAction(): mailboxId = $mailboxId');
|
||||
consumeState(_getEmailsInMailboxInteractor.execute(
|
||||
accountId,
|
||||
limit: ThreadConstants.defaultLimit,
|
||||
@@ -394,37 +395,30 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _refreshEmailChanges() {
|
||||
log('ThreadController::_refreshEmailChanges(): ');
|
||||
if (isSearchActive()) {
|
||||
if (_accountId != null && searchQuery != null) {
|
||||
final limit = emailListSearch.isNotEmpty ? UnsignedInt(emailListSearch.length) : ThreadConstants.defaultLimit;
|
||||
consumeState(_searchEmailInteractor.execute(
|
||||
_accountId!,
|
||||
limit: limit,
|
||||
sort: _sortOrder,
|
||||
filter: EmailFilterCondition(
|
||||
text: searchQuery!.value,
|
||||
inMailbox: _currentMailboxId),
|
||||
properties: ThreadConstants.propertiesDefault,
|
||||
final limit = emailList.isNotEmpty
|
||||
? UnsignedInt(emailList.length)
|
||||
: ThreadConstants.defaultLimit;
|
||||
_searchEmail(limit: limit);
|
||||
}
|
||||
} else {
|
||||
if (_accountId != null && _currentEmailState != null) {
|
||||
consumeState(_refreshChangesEmailsInMailboxInteractor.execute(
|
||||
_accountId!,
|
||||
_currentEmailState!,
|
||||
sort: _sortOrder,
|
||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||
inMailboxId: _currentMailboxId,
|
||||
filterOption: mailboxDashBoardController.filterMessageOption.value
|
||||
));
|
||||
}
|
||||
}
|
||||
if (_accountId != null && _currentEmailState != null) {
|
||||
consumeState(_refreshChangesEmailsInMailboxInteractor.execute(
|
||||
_accountId!,
|
||||
_currentEmailState!,
|
||||
sort: _sortOrder,
|
||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||
inMailboxId: _currentMailboxId,
|
||||
filterOption: mailboxDashBoardController.filterMessageOption.value
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void loadMoreEmails() {
|
||||
if (canLoadMore && _accountId != null) {
|
||||
log('ThreadController::loadMoreEmails(): latest: ${emailList.last.receivedAt}');
|
||||
startFpsMeter();
|
||||
consumeState(_loadMoreEmailsInMailboxInteractor.execute(
|
||||
GetEmailRequest(
|
||||
@@ -439,11 +433,8 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) {
|
||||
log('ThreadController::_loadMoreEmailsSuccess(): [BEFORE] totalEmailList = ${emailList.length}');
|
||||
if (success.emailList.isNotEmpty) {
|
||||
log('ThreadController::_loadMoreEmailsSuccess(): add success: ${success.emailList.length}');
|
||||
emailList.addAll(success.emailList);
|
||||
log('ThreadController::_loadMoreEmailsSuccess(): [AFTER] totalEmailList = ${emailList.length}');
|
||||
} else {
|
||||
canLoadMore = false;
|
||||
}
|
||||
@@ -466,15 +457,9 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void selectEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
|
||||
if (isSearchActive()) {
|
||||
emailListSearch.value = emailListSearch
|
||||
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
||||
.toList();
|
||||
} else {
|
||||
emailList.value = emailList
|
||||
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
||||
.toList();
|
||||
}
|
||||
emailList.value = emailList
|
||||
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
||||
.toList();
|
||||
|
||||
if (_isUnSelectedAll()) {
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
||||
@@ -492,41 +477,27 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void setSelectAllEmailAction() {
|
||||
if (isSearchActive()) {
|
||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
||||
} else {
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
||||
}
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
||||
mailboxDashBoardController.listEmailSelected.value = listEmailSelected;
|
||||
}
|
||||
|
||||
List<PresentationEmail> get listEmailSelected {
|
||||
if (isSearchActive()) {
|
||||
return emailListSearch.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
||||
} else {
|
||||
return emailList.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
||||
}
|
||||
return emailList.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
||||
}
|
||||
|
||||
bool _isUnSelectedAll() {
|
||||
if (isSearchActive()) {
|
||||
return emailListSearch.every((email) => email.selectMode == SelectMode.INACTIVE);
|
||||
} else {
|
||||
return emailList.every((email) => email.selectMode == SelectMode.INACTIVE);
|
||||
}
|
||||
return emailList.every((email) => email.selectMode == SelectMode.INACTIVE);
|
||||
}
|
||||
|
||||
void cancelSelectEmail() {
|
||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
||||
mailboxDashBoardController.listEmailSelected.clear();
|
||||
}
|
||||
|
||||
void markAsReadAllEmails() {
|
||||
final listEmail = isSearchActive() ? emailListSearch.allEmailUnread : emailList.allEmailUnread;
|
||||
log('ThreadController::markAsReadAllEmails(): ${listEmail.length}');
|
||||
final listEmail = emailList.allEmailUnread;
|
||||
if (listEmail.isNotEmpty) {
|
||||
markAsReadSelectedMultipleEmail(listEmail);
|
||||
}
|
||||
@@ -534,12 +505,10 @@ class ThreadController extends BaseController {
|
||||
|
||||
void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail) {
|
||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listPresentationEmail: ${listPresentationEmail.length}');
|
||||
final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead;
|
||||
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
|
||||
if (_accountId != null && mailboxCurrent != null) {
|
||||
cancelSelectEmail();
|
||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listEmail: ${listEmail.length}');
|
||||
consumeState(_markAsMultipleEmailReadInteractor.execute(_accountId!, listEmail, readAction));
|
||||
}
|
||||
}
|
||||
@@ -564,7 +533,6 @@ class ThreadController extends BaseController {
|
||||
message: message,
|
||||
icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast);
|
||||
}
|
||||
log('ThreadController::_markAsReadSelectedMultipleEmailSuccess(): _refreshEmailChanges');
|
||||
_refreshEmailChanges();
|
||||
}
|
||||
|
||||
@@ -602,18 +570,18 @@ class ThreadController extends BaseController {
|
||||
? FilterMessageOption.all
|
||||
: filterOption;
|
||||
|
||||
log('ThreadController::filterMessagesAction(): newFilterOption: $newFilterOption');
|
||||
|
||||
mailboxDashBoardController.filterMessageOption.value = newFilterOption;
|
||||
|
||||
log('ThreadController::filterMessagesAction(): filterMessageOption: ${mailboxDashBoardController.filterMessageOption}');
|
||||
|
||||
_appToast.showToastWithIcon(
|
||||
currentOverlayContext!,
|
||||
message: newFilterOption.getMessageToast(context),
|
||||
icon: newFilterOption.getIconToast(_imagePaths));
|
||||
|
||||
refreshAllEmail();
|
||||
if (isSearchActive()) {
|
||||
_searchEmail();
|
||||
} else {
|
||||
refreshAllEmail();
|
||||
}
|
||||
}
|
||||
|
||||
void moveSelectedMultipleEmailToMailbox(List<PresentationEmail> listEmail) async {
|
||||
@@ -839,34 +807,62 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void disableSearch() {
|
||||
emailListSearch.clear();
|
||||
searchIsActive.value = false;
|
||||
mailboxDashBoardController.disableSearch();
|
||||
cancelSelectEmail();
|
||||
}
|
||||
|
||||
void _searchEmail() {
|
||||
emailListSearch.clear();
|
||||
void closeSearchEmailAction() {
|
||||
disableSearch();
|
||||
cancelSelectEmail();
|
||||
refreshAllEmail();
|
||||
}
|
||||
|
||||
void clearTextSearch() {
|
||||
mailboxDashBoardController.clearTextSearch();
|
||||
}
|
||||
|
||||
void _searchEmail({UnsignedInt? limit}) {
|
||||
if (_accountId != null && searchQuery != null) {
|
||||
searchIsActive.value = true;
|
||||
|
||||
UTCDate? afterTime;
|
||||
if (mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.last7Days)
|
||||
&& mailboxDashBoardController.emailReceiveTimeType.value != null) {
|
||||
bool? hasAttachment;
|
||||
String? fromAddress;
|
||||
String? keywordUnread;
|
||||
String? keywordStarred;
|
||||
|
||||
if (mailboxDashBoardController.quickSearchFilterForLast7DaysIsActive()) {
|
||||
afterTime = mailboxDashBoardController.emailReceiveTimeType.value!.toUTCDate();
|
||||
}
|
||||
|
||||
if (mailboxDashBoardController.filterForHasAttachmentIsActive()) {
|
||||
hasAttachment = true;
|
||||
}
|
||||
|
||||
if (mailboxDashBoardController.quickSearchFilterForFromMeIsActive()) {
|
||||
fromAddress = mailboxDashBoardController.userProfile.value?.email;
|
||||
}
|
||||
|
||||
if (mailboxDashBoardController.filterMessageUnreadIsActive()) {
|
||||
keywordUnread = KeyWordIdentifier.emailSeen.value;
|
||||
}
|
||||
|
||||
if (mailboxDashBoardController.filterMessageStarredIsActive()) {
|
||||
keywordStarred = KeyWordIdentifier.emailFlagged.value;
|
||||
}
|
||||
|
||||
final emailFilterCondition = EmailFilterCondition(
|
||||
text: searchQuery!.value,
|
||||
hasAttachment: mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.hasAttachment)
|
||||
? true : null,
|
||||
from: mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.fromMe)
|
||||
? mailboxDashBoardController.userProfile.value!.email
|
||||
: null,
|
||||
hasAttachment: hasAttachment,
|
||||
from: fromAddress,
|
||||
after: afterTime,
|
||||
hasKeyword: keywordStarred,
|
||||
notKeyword: keywordUnread,
|
||||
inMailbox: _currentMailboxId);
|
||||
|
||||
consumeState(_searchEmailInteractor.execute(
|
||||
_accountId!,
|
||||
limit: ThreadConstants.defaultLimit,
|
||||
limit: limit ?? ThreadConstants.defaultLimit,
|
||||
sort: _sortOrder,
|
||||
filter: emailFilterCondition,
|
||||
properties: ThreadConstants.propertiesDefault,
|
||||
@@ -879,10 +875,10 @@ class ThreadController extends BaseController {
|
||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
||||
.toList();
|
||||
|
||||
final emailsSearchBeforeChanges = emailListSearch;
|
||||
final emailsSearchBeforeChanges = emailList;
|
||||
final emailsSearchAfterChanges = resultEmailSearchList;
|
||||
final newListEmailSearch = emailsSearchAfterChanges.combine(emailsSearchBeforeChanges);
|
||||
emailListSearch.value = newListEmailSearch;
|
||||
emailList.value = newListEmailSearch;
|
||||
}
|
||||
|
||||
void searchMoreEmails() {
|
||||
@@ -893,9 +889,9 @@ class ThreadController extends BaseController {
|
||||
sort: _sortOrder,
|
||||
filter: EmailFilterCondition(
|
||||
text: searchQuery!.value,
|
||||
before: emailListSearch.last.receivedAt),
|
||||
before: emailList.last.receivedAt),
|
||||
properties: ThreadConstants.propertiesDefault,
|
||||
lastEmailId: emailListSearch.last.id
|
||||
lastEmailId: emailList.last.id
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -904,9 +900,9 @@ class ThreadController extends BaseController {
|
||||
if (success.emailList.isNotEmpty) {
|
||||
final resultEmailSearchList = success.emailList
|
||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
||||
.where((email) => !emailListSearch.contains(email))
|
||||
.where((email) => !emailList.contains(email))
|
||||
.toList();
|
||||
emailListSearch.addAll(resultEmailSearchList);
|
||||
emailList.addAll(resultEmailSearchList);
|
||||
} else {
|
||||
canSearchMore = false;
|
||||
}
|
||||
@@ -916,7 +912,6 @@ class ThreadController extends BaseController {
|
||||
bool isSelectionEnabled() => mailboxDashBoardController.isSelectionEnabled();
|
||||
|
||||
void pressEmailSelectionAction(BuildContext context, EmailActionType actionType, List<PresentationEmail> selectionEmail) {
|
||||
log('ThreadController::pressEmailSelectionAction(): selectionEmail: ${selectionEmail.length}');
|
||||
switch(actionType) {
|
||||
case EmailActionType.markAsRead:
|
||||
case EmailActionType.markAsUnread:
|
||||
|
||||
@@ -5,8 +5,13 @@ import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/filter_email_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/email_receive_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/quick_search_filter.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
|
||||
@@ -16,11 +21,10 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_th
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
|
||||
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/suggestion_box_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
|
||||
FilterEmailPopupMenuMixin {
|
||||
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -46,50 +50,74 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Obx(() => !controller.isSearchActive()
|
||||
&& ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)
|
||||
? _buildAppBarNormal(context)
|
||||
: const SizedBox.shrink()),
|
||||
_buildSearchInputFormForMobile(context),
|
||||
Container(
|
||||
color: BuildUtils.isWeb ? AppColor.colorBgDesktop : Colors.white,
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildSearchButtonViewForMobile(context)),
|
||||
Obx(() => controller.isMailboxTrash && controller.emailList.isNotEmpty && !controller.isSearchActive()
|
||||
? _buildEmptyTrashButton(context)
|
||||
: const SizedBox.shrink()),
|
||||
Obx(() => controller.isSearchActive() && _responsiveUtils.isDesktop(context) && BuildUtils.isWeb
|
||||
? _buildListButtonQuickSearchFilter(context)
|
||||
: const SizedBox.shrink()),
|
||||
if ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)
|
||||
... [
|
||||
_buildAppBarNormal(context),
|
||||
Obx(() {
|
||||
return Stack(children: [
|
||||
if (!controller.isSearchActive())
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: BuildUtils.isWeb && _responsiveUtils.isTabletLarge(context) ? 8 : 0),
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: !BuildUtils.isWeb ? 16 : 0),
|
||||
child: _buildSearchFormInActive(context))
|
||||
else
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: BuildUtils.isWeb && _responsiveUtils.isTabletLarge(context) ? 8 : 0),
|
||||
margin: const EdgeInsets.only(
|
||||
bottom: !BuildUtils.isWeb ? 16 : 0),
|
||||
child: _buildSearchFormActive(context))
|
||||
]);
|
||||
})
|
||||
]
|
||||
else
|
||||
const SizedBox.shrink(),
|
||||
Obx(() {
|
||||
if (controller.isMailboxTrash && controller.emailList.isNotEmpty
|
||||
&& !controller.isSearchActive()) {
|
||||
return _buildEmptyTrashButton(context);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.isSearchActive()
|
||||
&& controller.searchIsActive.isTrue
|
||||
&& _responsiveUtils.isDesktop(context)
|
||||
&& BuildUtils.isWeb) {
|
||||
return _buildListButtonQuickSearchFilter(context);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Expanded(child: Container(
|
||||
color: BuildUtils.isWeb ? AppColor.colorBgDesktop : Colors.white,
|
||||
padding: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
alignment: Alignment.center,
|
||||
margin: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? const EdgeInsets.only(left: 32, right: 24, top: 16, bottom: 24)
|
||||
: EdgeInsets.zero,
|
||||
child: Stack(children: [
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? BorderRadius.circular(20)
|
||||
: null,
|
||||
border: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? Border.all(color: AppColor.colorBorderBodyThread, width: 1)
|
||||
: null,
|
||||
color: Colors.white),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (_responsiveUtils.isMobile(context))
|
||||
_buildStatusResultSearch(context),
|
||||
_buildLoadingView(),
|
||||
Expanded(child: _buildListEmail(context)),
|
||||
_buildLoadingViewLoadMore(),
|
||||
]
|
||||
)
|
||||
),
|
||||
_buildSuggestionBox(context)
|
||||
]))),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? BorderRadius.circular(20)
|
||||
: null,
|
||||
border: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? Border.all(color: AppColor.colorBorderBodyThread, width: 1)
|
||||
: null,
|
||||
color: Colors.white),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildLoadingView(),
|
||||
Expanded(child: _buildListEmail(context)),
|
||||
_buildLoadingViewLoadMore(),
|
||||
]
|
||||
)
|
||||
)),
|
||||
_buildListButtonSelectionForMobile(context),
|
||||
]
|
||||
)
|
||||
@@ -125,62 +153,189 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchButtonViewForMobile(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (!controller.isSearchActive() &&
|
||||
((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 10),
|
||||
child: (SearchBarView(_imagePaths)
|
||||
..hintTextSearch(BuildUtils.isWeb ? AppLocalizations.of(context).search_emails : AppLocalizations.of(context).hint_search_emails)
|
||||
..addOnOpenSearchViewAction(() => controller.enableSearch(context)))
|
||||
.build());
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
Widget _buildSearchFormInActive(BuildContext context) {
|
||||
return (SearchBarView(_imagePaths)
|
||||
..hintTextSearch(AppLocalizations.of(context).search_emails)
|
||||
..addOnOpenSearchViewAction(() => controller.enableSearch(context)))
|
||||
.build();
|
||||
}
|
||||
|
||||
Widget _buildSearchInputFormForMobile(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.isSearchActive() &&
|
||||
((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)) {
|
||||
return Column(children: [
|
||||
_buildSearchForm(context),
|
||||
const Divider(color: AppColor.lineItemListColor, height: 1, thickness: 0.2),
|
||||
]);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchForm(BuildContext context) {
|
||||
return (SearchAppBarWidget(
|
||||
context,
|
||||
_imagePaths,
|
||||
_responsiveUtils,
|
||||
controller.searchQuery,
|
||||
controller.mailboxDashBoardController.searchFocus,
|
||||
controller.mailboxDashBoardController.searchInputController,
|
||||
suggestionSearch: controller.mailboxDashBoardController.suggestionSearch,)
|
||||
..addDecoration(const BoxDecoration(color: Colors.white))
|
||||
..setMargin(const EdgeInsets.only(right: 10))
|
||||
..setHintText(AppLocalizations.of(context).search_mail)
|
||||
..addOnCancelSearchPressed(() => controller.disableSearch())
|
||||
..addOnClearTextSearchAction(() => controller.mailboxDashBoardController.clearSearchText())
|
||||
..addOnTextChangeSearchAction((query) => controller.mailboxDashBoardController.addSuggestionSearch(query))
|
||||
..addOnSearchTextAction((query) => controller.mailboxDashBoardController.searchEmail(context, query)))
|
||||
.build();
|
||||
Widget _buildSearchFormActive(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
_imagePaths.icBack,
|
||||
color: AppColor.colorTextButton,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () => controller.closeSearchEmailAction()),
|
||||
Expanded(child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar),
|
||||
height: 45,
|
||||
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
||||
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||
controller: controller.searchController,
|
||||
autofocus: true,
|
||||
focusNode: controller.mailboxDashBoardController.searchFocus,
|
||||
textInputAction: TextInputAction.done,
|
||||
onSubmitted: (keyword) {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.mailboxDashBoardController
|
||||
.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.mailboxDashBoardController.searchEmail(context, keyword);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
hintText: AppLocalizations.of(context).search_mail,
|
||||
hintStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0),
|
||||
labelStyle: const TextStyle(
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontSize: 17.0)
|
||||
),
|
||||
leftButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
_imagePaths.icSearchBar,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
final keyword = controller.currentTextSearch;
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.mailboxDashBoardController
|
||||
.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.mailboxDashBoardController.searchEmail(context, keyword);
|
||||
}),
|
||||
clearTextButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
_imagePaths.icClearTextSearch,
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.clearTextSearch();
|
||||
})
|
||||
),
|
||||
suggestionsBoxDecoration: const QuickSearchSuggestionsBoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
debounceDuration: const Duration(milliseconds: 500),
|
||||
hideSuggestionsBox: _responsiveUtils.isScreenWithShortestSide(context),
|
||||
listActionButton: const [
|
||||
QuickSearchFilter.hasAttachment,
|
||||
QuickSearchFilter.last7Days,
|
||||
QuickSearchFilter.fromMe,
|
||||
],
|
||||
actionButtonBuilder: (context, filterAction) {
|
||||
if (filterAction is QuickSearchFilter) {
|
||||
return _buildQuickSearchFilterButtonSuggestionBox(
|
||||
context,
|
||||
filterAction);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
buttonActionCallback: (filterAction) {
|
||||
if (filterAction is QuickSearchFilter) {
|
||||
controller.mailboxDashBoardController
|
||||
.selectQuickSearchFilter(filterAction, fromSuggestionBox: true);
|
||||
}
|
||||
},
|
||||
listActionPadding: const EdgeInsets.only(
|
||||
left: 24,
|
||||
top: 24,
|
||||
right: 24,
|
||||
bottom: 16),
|
||||
titleHeaderRecent: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Text(AppLocalizations.of(context).recent,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
fontWeight: FontWeight.w500)
|
||||
)
|
||||
),
|
||||
buttonShowAllResult: (context, keyword) {
|
||||
if (keyword is String) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (keyword.trim().isNotEmpty) {
|
||||
controller.mailboxDashBoardController
|
||||
.saveRecentSearch(RecentSearch.now(keyword));
|
||||
}
|
||||
controller.mailboxDashBoardController.searchEmail(context, keyword);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
|
||||
child: Row(children: [
|
||||
Text(AppLocalizations.of(context).showingResultsFor,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
fontWeight: FontWeight.w500)
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(child: Text('"$keyword"',
|
||||
style: const TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500)))
|
||||
])
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
loadingBuilder: (context) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: loadingWidget,
|
||||
),
|
||||
fetchRecentActionCallback: (pattern) async {
|
||||
return controller.mailboxDashBoardController
|
||||
.getAllRecentSearchAction(pattern);
|
||||
},
|
||||
itemRecentBuilder: (context, recent) {
|
||||
return RecentSearchItemTileWidget(recent);
|
||||
},
|
||||
onRecentSelected: (recent) {
|
||||
controller.mailboxDashBoardController
|
||||
.updateTextSearch(recent.value);
|
||||
controller.mailboxDashBoardController
|
||||
.searchEmail(context, recent.value);
|
||||
},
|
||||
suggestionsCallback: (pattern) async {
|
||||
return controller.mailboxDashBoardController
|
||||
.quickSearchEmailsAction(pattern);
|
||||
},
|
||||
itemBuilder: (context, email) {
|
||||
return EmailQuickSearchItemTileWidget(
|
||||
email,
|
||||
controller.currentMailbox);
|
||||
},
|
||||
onSuggestionSelected: (presentationEmail) async {
|
||||
controller.pressEmailAction(
|
||||
context,
|
||||
EmailActionType.preview,
|
||||
presentationEmail);
|
||||
}),
|
||||
)),
|
||||
const SizedBox(width: 16),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAppBarNormal(BuildContext context) {
|
||||
return (AppBarThreadWidgetBuilder(
|
||||
return Obx(() {
|
||||
return (AppBarThreadWidgetBuilder(
|
||||
context,
|
||||
_imagePaths,
|
||||
_responsiveUtils,
|
||||
controller.mailboxDashBoardController.selectedMailbox.value,
|
||||
controller.currentMailbox,
|
||||
controller.listEmailSelected,
|
||||
controller.mailboxDashBoardController.currentSelectMode.value,
|
||||
controller.mailboxDashBoardController.filterMessageOption.value)
|
||||
@@ -188,17 +343,24 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
..addOnEditThreadAction(() => controller.enableSelectionEmail())
|
||||
..addOnEmailSelectionAction((actionType, selectionEmail) =>
|
||||
controller.pressEmailSelectionAction(context, actionType, selectionEmail))
|
||||
..addOnFilterEmailAction((filterMessageOption, position) =>
|
||||
_responsiveUtils.isScreenWithShortestSide(context)
|
||||
? controller.openContextMenuAction(
|
||||
context,
|
||||
_filterMessagesCupertinoActionTile(context, filterMessageOption))
|
||||
: controller.openPopupMenuAction(
|
||||
context,
|
||||
position,
|
||||
_popupMenuEmailActionTile(context, filterMessageOption)))
|
||||
..addOnFilterEmailAction((filterMessageOption, position) {
|
||||
if (_responsiveUtils.isScreenWithShortestSide(context)) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
_filterMessagesCupertinoActionTile(context, filterMessageOption));
|
||||
} else {
|
||||
controller.openPopupMenuAction(
|
||||
context,
|
||||
position,
|
||||
popupMenuFilterEmailActionTile(
|
||||
context,
|
||||
filterMessageOption,
|
||||
(option) => controller.filterMessagesAction(context, option)));
|
||||
}
|
||||
})
|
||||
..addOnCancelEditThread(() => controller.cancelSelectEmail()))
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildFloatingButtonCompose(BuildContext context) {
|
||||
@@ -232,75 +394,37 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
}
|
||||
|
||||
List<Widget> _filterMessagesCupertinoActionTile(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
return <Widget>[
|
||||
_filterMessageWithAttachmentsAction(context, optionCurrent),
|
||||
_filterMessagesUnreadAction(context, optionCurrent),
|
||||
_filterMessageStarredAction(context, optionCurrent),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _filterMessageWithAttachmentsAction(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
return (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
const Key('filter_attachment_action'),
|
||||
SvgPicture.asset(_imagePaths.icAttachment, width: 28, height: 28, fit: BoxFit.fill, color: AppColor.colorTextButton),
|
||||
AppLocalizations.of(context).with_attachments,
|
||||
FilterMessageOption.attachments,
|
||||
optionCurrent: optionCurrent,
|
||||
iconLeftPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(_imagePaths.icFilterSelected, fit: BoxFit.fill))
|
||||
..onActionClick((option) => controller.filterMessagesAction(context, option)))
|
||||
.build();
|
||||
}
|
||||
|
||||
Widget _filterMessagesUnreadAction(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
return (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
const Key('filter_unread_action'),
|
||||
SvgPicture.asset(_imagePaths.icUnread, width: 28, height: 28, fit: BoxFit.fill),
|
||||
AppLocalizations.of(context).unread,
|
||||
FilterMessageOption.unread,
|
||||
optionCurrent: optionCurrent,
|
||||
iconLeftPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(_imagePaths.icFilterSelected, fit: BoxFit.fill))
|
||||
..onActionClick((option) => controller.filterMessagesAction(context, option)))
|
||||
.build();
|
||||
}
|
||||
|
||||
Widget _filterMessageStarredAction(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
return (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
const Key('filter_starred_action'),
|
||||
SvgPicture.asset(_imagePaths.icStar, width: 28, height: 28, fit: BoxFit.fill),
|
||||
AppLocalizations.of(context).starred,
|
||||
FilterMessageOption.starred,
|
||||
optionCurrent: optionCurrent,
|
||||
iconLeftPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(_imagePaths.icFilterSelected, fit: BoxFit.fill))
|
||||
..onActionClick((option) => controller.filterMessagesAction(context, option)))
|
||||
.build();
|
||||
}
|
||||
|
||||
List<PopupMenuEntry> _popupMenuEmailActionTile(BuildContext context, FilterMessageOption option) {
|
||||
return [
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _filterMessageWithAttachmentsAction(context, option)),
|
||||
const PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _filterMessagesUnreadAction(context, option)),
|
||||
const PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _filterMessageStarredAction(context, option)),
|
||||
final listFilter = [
|
||||
FilterMessageOption.attachments,
|
||||
FilterMessageOption.unread,
|
||||
FilterMessageOption.starred,
|
||||
];
|
||||
|
||||
return listFilter.map((filter) => (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
Key('filter_email_${filter.name}'),
|
||||
SvgPicture.asset(
|
||||
filter.getIcon(_imagePaths),
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill,
|
||||
color: filter == FilterMessageOption.attachments
|
||||
? AppColor.colorTextButton : null),
|
||||
filter.getName(context),
|
||||
filter,
|
||||
optionCurrent: optionCurrent,
|
||||
iconLeftPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: _responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(
|
||||
_imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((option) => controller.filterMessagesAction(context, option)))
|
||||
.build()).toList();
|
||||
}
|
||||
|
||||
Widget _buildLoadingView() {
|
||||
@@ -344,25 +468,11 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
padding: EdgeInsets.zero,
|
||||
color: Colors.white,
|
||||
child: Obx(() {
|
||||
if (controller.isSearchActive()) {
|
||||
if (controller.mailboxDashBoardController.suggestionSearch.isNotEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return _buildResultSearchEmails(context, controller.emailListSearch);
|
||||
}
|
||||
} else {
|
||||
return _buildResultListEmail(context, controller.emailList);
|
||||
}
|
||||
return _buildResultListEmail(context, controller.emailList);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildResultSearchEmails(BuildContext context, List<PresentationEmail> listPresentationEmail) {
|
||||
return listPresentationEmail.isNotEmpty
|
||||
? _buildListEmailBody(context, listPresentationEmail)
|
||||
: _buildEmptyEmail(context);
|
||||
}
|
||||
|
||||
Widget _buildResultListEmail(BuildContext context, List<PresentationEmail> listPresentationEmail) {
|
||||
if (controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) {
|
||||
return listPresentationEmail.isNotEmpty
|
||||
@@ -433,42 +543,6 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSuggestionBox(BuildContext context) {
|
||||
return Obx(() => controller.mailboxDashBoardController.suggestionSearch.isNotEmpty
|
||||
? (SuggestionBoxWidget(
|
||||
context,
|
||||
_imagePaths,
|
||||
controller.mailboxDashBoardController.suggestionSearch)
|
||||
..addOnSelectedSuggestion((suggestion) =>
|
||||
controller.mailboxDashBoardController.searchEmail(context, suggestion)))
|
||||
.build()
|
||||
: const SizedBox.shrink()
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusResultSearch(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.isSearchActive()) {
|
||||
return controller.emailListSearch.isNotEmpty
|
||||
? Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||
? const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))
|
||||
: null,
|
||||
color: AppColor.bgStatusResultSearch),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).results,
|
||||
style: const TextStyle(color: AppColor.baseTextColor, fontSize: 14, fontWeight: FontWeight.w500),
|
||||
))
|
||||
: const SizedBox.shrink();
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildEmptyTrashButton(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -661,4 +735,30 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildQuickSearchFilterButtonSuggestionBox(
|
||||
BuildContext context, QuickSearchFilter filter) {
|
||||
return Obx(() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: filter.getBackgroundColor(controller.mailboxDashBoardController.listFilterQuickSearch)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
SvgPicture.asset(
|
||||
filter.getIcon(_imagePaths, controller.mailboxDashBoardController.listFilterQuickSearch),
|
||||
width: 16,
|
||||
height: 16,
|
||||
fit: BoxFit.fill),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
filter.getTitle(context,
|
||||
receiveTimeType: controller.mailboxDashBoardController.emailReceiveTimeType.value),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: filter.getTextStyle(controller.mailboxDashBoardController.listFilterQuickSearch),
|
||||
)
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnFilterEmailAction = void Function(FilterMessageOption, RelativeRect? position);
|
||||
@@ -15,6 +15,9 @@ typedef OnCancelEditThread = void Function();
|
||||
typedef OnEmailSelectionAction = void Function(EmailActionType actionType, List<PresentationEmail>);
|
||||
|
||||
class AppBarThreadWidgetBuilder {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
|
||||
OnFilterEmailAction? _onFilterEmailAction;
|
||||
OnOpenMailboxMenuActionClick? _onOpenMailboxMenuActionClick;
|
||||
OnEditThreadAction? _onEditThreadAction;
|
||||
@@ -22,8 +25,6 @@ class AppBarThreadWidgetBuilder {
|
||||
OnEmailSelectionAction? _onEmailSelectionAction;
|
||||
|
||||
final BuildContext _context;
|
||||
final ImagePaths _imagePaths;
|
||||
final ResponsiveUtils _responsiveUtils;
|
||||
final PresentationMailbox? _currentMailbox;
|
||||
final List<PresentationEmail> _listSelectionEmail;
|
||||
final SelectMode _selectMode;
|
||||
@@ -31,8 +32,6 @@ class AppBarThreadWidgetBuilder {
|
||||
|
||||
AppBarThreadWidgetBuilder(
|
||||
this._context,
|
||||
this._imagePaths,
|
||||
this._responsiveUtils,
|
||||
this._currentMailbox,
|
||||
this._listSelectionEmail,
|
||||
this._selectMode,
|
||||
@@ -65,8 +64,11 @@ class AppBarThreadWidgetBuilder {
|
||||
alignment: Alignment.topCenter,
|
||||
color: Colors.white,
|
||||
margin: EdgeInsets.zero,
|
||||
padding: EdgeInsets.only(left: 8, bottom: 8, right: 8,
|
||||
top: (!BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(_context)) ? 0 : 16),
|
||||
padding: EdgeInsets.only(
|
||||
left: 8,
|
||||
bottom: !BuildUtils.isWeb ? 8 : 16,
|
||||
right: 8,
|
||||
top: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(_context) ? 0 : 16),
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(padding: EdgeInsets.zero),
|
||||
child: kIsWeb
|
||||
@@ -211,7 +213,8 @@ class AppBarThreadWidgetBuilder {
|
||||
color: Colors.transparent,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: GestureDetector(
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
onTap: () {
|
||||
if (_onFilterEmailAction != null && _responsiveUtils.isScreenWithShortestSide(_context)) {
|
||||
_onFilterEmailAction!.call(_filterMessageOption, null);
|
||||
|
||||
+3
-2
@@ -3,9 +3,10 @@ import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
|
||||
class FilterMessageCupertinoActionSheetActionBuilder extends CupertinoActionSheetActionBuilder<FilterMessageOption> {
|
||||
class FilterMessageCupertinoActionSheetActionBuilder
|
||||
extends CupertinoActionSheetActionBuilder<FilterMessageOption> {
|
||||
|
||||
final FilterMessageOption option;
|
||||
final FilterMessageOption? optionCurrent;
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnSelectedSuggestion = Function(String);
|
||||
|
||||
class SuggestionBoxWidget {
|
||||
|
||||
OnSelectedSuggestion? _onSelectedSuggestion;
|
||||
|
||||
final BuildContext _context;
|
||||
final ImagePaths _imagePaths;
|
||||
|
||||
double? _suggestionHeight;
|
||||
double? _elevation;
|
||||
final List<String> _listData;
|
||||
|
||||
SuggestionBoxWidget(
|
||||
this._context,
|
||||
this._imagePaths,
|
||||
this._listData,
|
||||
);
|
||||
|
||||
void setSuggestionHeight(double suggestionHeight) {
|
||||
_suggestionHeight = suggestionHeight;
|
||||
}
|
||||
|
||||
void setElevation(double elevation) {
|
||||
_elevation = elevation;
|
||||
}
|
||||
|
||||
void addOnSelectedSuggestion(OnSelectedSuggestion onSelectedSuggestion) {
|
||||
_onSelectedSuggestion = onSelectedSuggestion;
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return Material(
|
||||
elevation: _elevation ?? 3,
|
||||
color: Colors.white,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: _suggestionHeight ?? 60,
|
||||
),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: _listData.length,
|
||||
itemBuilder: (BuildContext context, int index) => ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
onTap: () {
|
||||
if (_onSelectedSuggestion != null) {
|
||||
_onSelectedSuggestion!(_listData[index]);
|
||||
}},
|
||||
leading: IconButton(
|
||||
color: AppColor.baseTextColor,
|
||||
icon: SvgPicture.asset(_imagePaths.icSearch, color: AppColor.baseTextColor, fit: BoxFit.fill),
|
||||
onPressed: () {
|
||||
if (_onSelectedSuggestion != null) {
|
||||
_onSelectedSuggestion!(_listData[index]);
|
||||
}
|
||||
}),
|
||||
title: Transform(
|
||||
transform: Matrix4.translationValues(-12.0, 0.0, 0.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${AppLocalizations.of(_context).prefix_suggestion_search} ',
|
||||
style: const TextStyle(fontSize: 15, color: AppColor.baseTextColor),
|
||||
),
|
||||
Expanded(child: Text(
|
||||
'"${_listData[index]}"',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 15, color: AppColor.colorNameEmail),
|
||||
))
|
||||
],
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/email_extension.dart';
|
||||
|
||||
enum FilterMessageOption {
|
||||
all,
|
||||
unread,
|
||||
attachments,
|
||||
starred,
|
||||
}
|
||||
|
||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
|
||||
bool filterPresentationEmail(PresentationEmail email) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return true;
|
||||
case FilterMessageOption.unread:
|
||||
return !email.hasRead;
|
||||
case FilterMessageOption.attachments:
|
||||
return email.withAttachments;
|
||||
case FilterMessageOption.starred:
|
||||
return email.hasStarred;
|
||||
}
|
||||
}
|
||||
|
||||
bool filterEmail(Email email) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return true;
|
||||
case FilterMessageOption.unread:
|
||||
return !email.hasRead;
|
||||
case FilterMessageOption.attachments:
|
||||
return email.withAttachments;
|
||||
case FilterMessageOption.starred:
|
||||
return email.hasStarred;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,7 @@ export 'email/read_actions.dart';
|
||||
export 'email/attachment.dart';
|
||||
export 'email/mark_star_action.dart';
|
||||
export 'email/email_property.dart';
|
||||
export 'email/email_filter.dart';
|
||||
export 'email/email_content_type.dart';
|
||||
export 'email/filter_message_option.dart';
|
||||
|
||||
// Extensions
|
||||
export 'extensions/email_address_extension.dart';
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
@@ -38,7 +39,7 @@ void main() {
|
||||
when(threadRepository.getAllEmail(
|
||||
AccountFixtures.aliceAccountId,
|
||||
limit: UnsignedInt(20),
|
||||
sort: Set()..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||
sort: {}..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||
emailFilter: EmailFilter(
|
||||
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
||||
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||
@@ -66,7 +67,7 @@ void main() {
|
||||
final streamStates = getEmailsInMailboxInteractor.execute(
|
||||
AccountFixtures.aliceAccountId,
|
||||
limit: UnsignedInt(20),
|
||||
sort: Set()..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||
sort: {}..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||
emailFilter: EmailFilter(
|
||||
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
||||
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||
|
||||
+13
-10
@@ -5,19 +5,22 @@
|
||||
import 'dart:async' as _i3;
|
||||
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart' as _i14;
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart' as _i15;
|
||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart' as _i9;
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart' as _i7;
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart' as _i10;
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart' as _i6;
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart' as _i13;
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart' as _i14;
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart' as _i11;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:model/model.dart' as _i8;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart'
|
||||
as _i8;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'
|
||||
as _i4;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart'
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'
|
||||
as _i12;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart'
|
||||
as _i13;
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
|
||||
as _i2;
|
||||
|
||||
@@ -64,7 +67,7 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
_i9.Properties? propertiesCreated,
|
||||
_i9.Properties? propertiesUpdated,
|
||||
_i11.MailboxId? inMailboxId,
|
||||
_i8.FilterMessageOption? filterOption}) =>
|
||||
_i12.FilterMessageOption? filterOption}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#refreshChanges, [
|
||||
accountId,
|
||||
@@ -80,15 +83,15 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
as _i3.Stream<_i4.EmailsResponse>);
|
||||
@override
|
||||
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
||||
_i12.GetEmailRequest? emailRequest) =>
|
||||
_i13.GetEmailRequest? emailRequest) =>
|
||||
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
||||
returnValue: Stream<_i4.EmailsResponse>.empty())
|
||||
as _i3.Stream<_i4.EmailsResponse>);
|
||||
@override
|
||||
_i3.Future<List<_i13.Email>> searchEmails(_i5.AccountId? accountId,
|
||||
_i3.Future<List<_i14.Email>> searchEmails(_i5.AccountId? accountId,
|
||||
{_i6.UnsignedInt? limit,
|
||||
Set<_i7.Comparator>? sort,
|
||||
_i14.Filter? filter,
|
||||
_i15.Filter? filter,
|
||||
_i9.Properties? properties}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#searchEmails, [
|
||||
@@ -99,8 +102,8 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
#filter: filter,
|
||||
#properties: properties
|
||||
}),
|
||||
returnValue: Future<List<_i13.Email>>.value(<_i13.Email>[]))
|
||||
as _i3.Future<List<_i13.Email>>);
|
||||
returnValue: Future<List<_i14.Email>>.value(<_i14.Email>[]))
|
||||
as _i3.Future<List<_i14.Email>>);
|
||||
@override
|
||||
_i3.Future<bool> emptyTrashFolder(
|
||||
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
||||
|
||||
+13
-10
@@ -5,19 +5,22 @@
|
||||
import 'dart:async' as _i3;
|
||||
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart' as _i14;
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart' as _i15;
|
||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart' as _i9;
|
||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart' as _i7;
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart' as _i10;
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart' as _i6;
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart' as _i13;
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart' as _i14;
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart' as _i11;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:model/model.dart' as _i8;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_filter.dart'
|
||||
as _i8;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'
|
||||
as _i4;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart'
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'
|
||||
as _i12;
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart'
|
||||
as _i13;
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
|
||||
as _i2;
|
||||
|
||||
@@ -64,7 +67,7 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
_i9.Properties? propertiesCreated,
|
||||
_i9.Properties? propertiesUpdated,
|
||||
_i11.MailboxId? inMailboxId,
|
||||
_i8.FilterMessageOption? filterOption}) =>
|
||||
_i12.FilterMessageOption? filterOption}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#refreshChanges, [
|
||||
accountId,
|
||||
@@ -80,15 +83,15 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
as _i3.Stream<_i4.EmailsResponse>);
|
||||
@override
|
||||
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
||||
_i12.GetEmailRequest? emailRequest) =>
|
||||
_i13.GetEmailRequest? emailRequest) =>
|
||||
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
||||
returnValue: Stream<_i4.EmailsResponse>.empty())
|
||||
as _i3.Stream<_i4.EmailsResponse>);
|
||||
@override
|
||||
_i3.Future<List<_i13.Email>> searchEmails(_i5.AccountId? accountId,
|
||||
_i3.Future<List<_i14.Email>> searchEmails(_i5.AccountId? accountId,
|
||||
{_i6.UnsignedInt? limit,
|
||||
Set<_i7.Comparator>? sort,
|
||||
_i14.Filter? filter,
|
||||
_i15.Filter? filter,
|
||||
_i9.Properties? properties}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#searchEmails, [
|
||||
@@ -99,8 +102,8 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
||||
#filter: filter,
|
||||
#properties: properties
|
||||
}),
|
||||
returnValue: Future<List<_i13.Email>>.value(<_i13.Email>[]))
|
||||
as _i3.Future<List<_i13.Email>>);
|
||||
returnValue: Future<List<_i14.Email>>.value(<_i14.Email>[]))
|
||||
as _i3.Future<List<_i14.Email>>);
|
||||
@override
|
||||
_i3.Future<bool> emptyTrashFolder(
|
||||
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
||||
|
||||
Reference in New Issue
Block a user