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/search/search_bar_view.dart';
|
||||||
export 'presentation/views/popup_menu/popup_menu_item_widget.dart';
|
export 'presentation/views/popup_menu/popup_menu_item_widget.dart';
|
||||||
export 'presentation/views/tab_bar/custom_tab_indicator.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
|
// Resources
|
||||||
export 'presentation/resources/assets_paths.dart';
|
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);
|
RecentSearch(this.value, this.creationDate);
|
||||||
|
|
||||||
|
factory RecentSearch.now(String word) {
|
||||||
|
return RecentSearch(word, DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [value, creationDate];
|
List<Object?> get props => [value, creationDate];
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:model/email/email_action_type.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:model/email/presentation_email.dart';
|
||||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
||||||
|
|
||||||
class DashBoardAction extends UIAction {
|
class DashBoardAction extends UIAction {
|
||||||
@@ -97,4 +97,12 @@ class OpenEmailDetailedAction extends DashBoardAction {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [presentationEmail];
|
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/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/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/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/model/search_query.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.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';
|
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 accountId = Rxn<AccountId>();
|
||||||
final userProfile = Rxn<UserProfile>();
|
final userProfile = Rxn<UserProfile>();
|
||||||
final searchState = SearchState.initial().obs;
|
final searchState = SearchState.initial().obs;
|
||||||
final suggestionSearch = <String>[].obs;
|
|
||||||
final dashBoardAction = Rxn<UIAction>();
|
final dashBoardAction = Rxn<UIAction>();
|
||||||
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
|
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
|
||||||
final appInformation = Rxn<PackageInfo>();
|
final appInformation = Rxn<PackageInfo>();
|
||||||
@@ -286,35 +286,40 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
void disableSearch() {
|
void disableSearch() {
|
||||||
searchState.value = searchState.value.disableSearchState();
|
searchState.value = searchState.value.disableSearchState();
|
||||||
searchQuery = SearchQuery.initial();
|
searchQuery = SearchQuery.initial();
|
||||||
clearSuggestionSearch();
|
|
||||||
searchInputController.clear();
|
searchInputController.clear();
|
||||||
listFilterQuickSearch.clear();
|
listFilterQuickSearch.clear();
|
||||||
|
emailReceiveTimeType.value = null;
|
||||||
FocusManager.instance.primaryFocus?.unfocus();
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearSearchText() {
|
void clearTextSearch() {
|
||||||
searchQuery = SearchQuery.initial();
|
searchQuery = SearchQuery.initial();
|
||||||
clearSuggestionSearch();
|
searchInputController.clear();
|
||||||
searchFocus.requestFocus();
|
searchFocus.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearSuggestionSearch() {
|
void updateTextSearch(String value) {
|
||||||
suggestionSearch.clear();
|
searchInputController.text = value;
|
||||||
}
|
|
||||||
|
|
||||||
void addSuggestionSearch(String query) {
|
|
||||||
if (query.trim().isNotEmpty) {
|
|
||||||
suggestionSearch.value = [query];
|
|
||||||
} else {
|
|
||||||
clearSearchText();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void searchEmail(BuildContext context, String value) {
|
void searchEmail(BuildContext context, String value) {
|
||||||
searchQuery = SearchQuery(value);
|
searchQuery = SearchQuery(value);
|
||||||
dispatchState(Right(SearchEmailNewQuery(searchQuery ?? SearchQuery.initial())));
|
dispatchState(Right(SearchEmailNewQuery(searchQuery ?? SearchQuery.initial())));
|
||||||
clearSuggestionSearch();
|
|
||||||
FocusScope.of(context).unfocus();
|
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) {
|
void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) {
|
||||||
@@ -472,6 +477,36 @@ class MailboxDashBoardController extends ReloadableController {
|
|||||||
emailReceiveTimeType.value = receiveTimeType;
|
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() {
|
void composeEmailAction() {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||||
@@ -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/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/app_setting.dart';
|
||||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.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/features/thread/presentation/thread_view.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||||
@@ -396,17 +395,17 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
buildIconWeb(
|
buildIconWeb(
|
||||||
icon: SvgPicture.asset(imagePaths.icBack, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
icon: SvgPicture.asset(
|
||||||
onTap: () {
|
imagePaths.icBack,
|
||||||
controller.disableSearch();
|
color: AppColor.colorTextButton,
|
||||||
controller.dispatchAction(CancelSelectionAllEmailAction());
|
fit: BoxFit.fill),
|
||||||
}),
|
onTap: () => controller.dispatchAction(DisableSearchEmailAction())),
|
||||||
Expanded(child: Container(
|
Expanded(child: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
color: AppColor.colorBgSearchBar),
|
color: AppColor.colorBgSearchBar),
|
||||||
height: 45,
|
height: 45,
|
||||||
child: TypeAheadFormFieldQuickSearch<PresentationEmail, RecentSearch>(
|
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
||||||
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||||
controller: controller.searchInputController,
|
controller: controller.searchInputController,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@@ -414,7 +413,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
textInputAction: TextInputAction.done,
|
textInputAction: TextInputAction.done,
|
||||||
onSubmitted: (keyword) {
|
onSubmitted: (keyword) {
|
||||||
if (keyword.trim().isNotEmpty) {
|
if (keyword.trim().isNotEmpty) {
|
||||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||||
}
|
}
|
||||||
controller.searchEmail(context, keyword);
|
controller.searchEmail(context, keyword);
|
||||||
},
|
},
|
||||||
@@ -424,30 +423,43 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
enabledBorder: InputBorder.none,
|
enabledBorder: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
hintText: AppLocalizations.of(context).search_mail,
|
hintText: AppLocalizations.of(context).search_mail,
|
||||||
hintStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0),
|
hintStyle: const TextStyle(
|
||||||
labelStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0)
|
color: AppColor.colorHintSearchBar,
|
||||||
|
fontSize: 17.0),
|
||||||
|
labelStyle: const TextStyle(
|
||||||
|
color: AppColor.colorHintSearchBar,
|
||||||
|
fontSize: 17.0)
|
||||||
),
|
),
|
||||||
leftButton: buildIconWeb(
|
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: () {
|
onTap: () {
|
||||||
final keyword = controller.searchInputController.text;
|
final keyword = controller.searchInputController.text;
|
||||||
if (keyword.trim().isNotEmpty) {
|
if (keyword.trim().isNotEmpty) {
|
||||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||||
}
|
}
|
||||||
controller.searchEmail(context, keyword);
|
controller.searchEmail(context, keyword);
|
||||||
}),
|
}),
|
||||||
clearTextButton: buildIconWeb(
|
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: () {
|
onTap: () {
|
||||||
controller.searchInputController.clear();
|
controller.clearTextSearch();
|
||||||
controller.clearSearchText();
|
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
suggestionsBoxDecoration: QuickSearchSuggestionsBoxDecoration(
|
suggestionsBoxDecoration: QuickSearchSuggestionsBoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: responsiveUtils.isDesktop(context) ? 556 : double.infinity),
|
maxWidth: responsiveUtils.isDesktop(context)
|
||||||
|
? 556
|
||||||
|
: double.infinity),
|
||||||
),
|
),
|
||||||
debounceDuration: const Duration(milliseconds: 500),
|
debounceDuration: const Duration(milliseconds: 500),
|
||||||
listActionButton: const [
|
listActionButton: const [
|
||||||
@@ -463,12 +475,18 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
},
|
},
|
||||||
buttonActionCallback: (filterAction) {
|
buttonActionCallback: (filterAction) {
|
||||||
if (filterAction is QuickSearchFilter) {
|
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(
|
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,
|
child: Text(AppLocalizations.of(context).recent,
|
||||||
style: const TextStyle(fontSize: 13.0,
|
style: const TextStyle(fontSize: 13.0,
|
||||||
color: AppColor.colorTextButtonHeaderThread,
|
color: AppColor.colorTextButtonHeaderThread,
|
||||||
@@ -480,12 +498,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (keyword.trim().isNotEmpty) {
|
if (keyword.trim().isNotEmpty) {
|
||||||
controller.saveRecentSearch(RecentSearch(keyword, DateTime.now()));
|
controller.saveRecentSearch(RecentSearch.now(keyword));
|
||||||
}
|
}
|
||||||
controller.searchEmail(context, keyword);
|
controller.searchEmail(context, keyword);
|
||||||
},
|
},
|
||||||
child: Padding(
|
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: [
|
child: Row(children: [
|
||||||
Text(AppLocalizations.of(context).showingResultsFor,
|
Text(AppLocalizations.of(context).showingResultsFor,
|
||||||
style: const TextStyle(fontSize: 13.0,
|
style: const TextStyle(fontSize: 13.0,
|
||||||
@@ -523,10 +543,12 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
return controller.quickSearchEmailsAction(pattern);
|
return controller.quickSearchEmailsAction(pattern);
|
||||||
},
|
},
|
||||||
itemBuilder: (context, email) {
|
itemBuilder: (context, email) {
|
||||||
return EmailQuickSearchItemTileWidget(email, controller.selectedMailbox.value);
|
return EmailQuickSearchItemTileWidget(
|
||||||
|
email, controller.selectedMailbox.value);
|
||||||
},
|
},
|
||||||
onSuggestionSelected: (presentationEmail) async {
|
onSuggestionSelected: (presentationEmail) async {
|
||||||
controller.dispatchAction(OpenEmailDetailedAction(context, presentationEmail));
|
controller.dispatchAction(
|
||||||
|
OpenEmailDetailedAction(context, presentationEmail));
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
|
|||||||
+15
-7
@@ -3,8 +3,7 @@ import 'package:core/core.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/filter_message_option_extension.dart';
|
|
||||||
|
|
||||||
mixin FilterEmailPopupMenuMixin {
|
mixin FilterEmailPopupMenuMixin {
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
@@ -38,15 +37,24 @@ mixin FilterEmailPopupMenuMixin {
|
|||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
color: option != FilterMessageOption.starred ? AppColor.colorTextButton : null),
|
color: option != FilterMessageOption.starred
|
||||||
|
? AppColor.colorTextButton
|
||||||
|
: null),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Expanded(child: Text(
|
Expanded(child: Text(
|
||||||
option.getName(context),
|
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)
|
if (optionSelected == option)
|
||||||
const SizedBox(width: 12),
|
... [
|
||||||
if (optionSelected == option)
|
const SizedBox(width: 12),
|
||||||
SvgPicture.asset(_imagePaths.icFilterSelected, width: 16, height: 16, fit: BoxFit.fill),
|
SvgPicture.asset(_imagePaths.icFilterSelected,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
]
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/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/email_response.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
|
|
||||||
abstract class ThreadDataSource {
|
abstract class ThreadDataSource {
|
||||||
Future<EmailsResponse> getAllEmail(
|
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/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/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/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/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/email_response.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
|
|
||||||
class LocalThreadDataSourceImpl extends ThreadDataSource {
|
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/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/datasource/thread_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.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/email_response.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.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 {
|
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/extensions/list_email_cache_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/model/email_cache.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:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||||
|
|
||||||
class EmailCacheManager {
|
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/datasource/thread_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/model/email_change_response.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/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/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/model/get_email_request.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.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:equatable/equatable.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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 {
|
class EmailFilter with EquatableMixin {
|
||||||
|
|
||||||
+61
-1
@@ -1,9 +1,17 @@
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
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:model/model.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
|
enum FilterMessageOption {
|
||||||
|
all,
|
||||||
|
unread,
|
||||||
|
attachments,
|
||||||
|
starred,
|
||||||
|
}
|
||||||
|
|
||||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||||
|
|
||||||
String getIconToast(ImagePaths imagePaths) {
|
String getIconToast(ImagePaths imagePaths) {
|
||||||
@@ -44,4 +52,56 @@ extension FilterMessageOptionExtension on FilterMessageOption {
|
|||||||
return AppLocalizations.of(context).with_starred;
|
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/core/unsigned_int.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/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/model/get_email_request.dart';
|
||||||
|
|
||||||
abstract class ThreadRepository {
|
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/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||||
|
import 'package: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/email_response.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.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';
|
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/core/sort/comparator.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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/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:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
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/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/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/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/get_email_request.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/state/empty_trash_folder_state.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/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_email_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/usecases/search_more_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/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_state.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart';
|
import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart';
|
||||||
@@ -92,7 +93,7 @@ class ThreadController extends BaseController {
|
|||||||
final MoveToMailboxInteractor _moveToMailboxInteractor;
|
final MoveToMailboxInteractor _moveToMailboxInteractor;
|
||||||
|
|
||||||
final emailList = <PresentationEmail>[].obs;
|
final emailList = <PresentationEmail>[].obs;
|
||||||
final emailListSearch = <PresentationEmail>[].obs;
|
final searchIsActive = RxBool(false);
|
||||||
|
|
||||||
bool canLoadMore = true;
|
bool canLoadMore = true;
|
||||||
bool canSearchMore = true;
|
bool canSearchMore = true;
|
||||||
@@ -113,6 +114,10 @@ class ThreadController extends BaseController {
|
|||||||
|
|
||||||
PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value;
|
PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value;
|
||||||
|
|
||||||
|
TextEditingController get searchController => mailboxDashBoardController.searchInputController;
|
||||||
|
|
||||||
|
String get currentTextSearch => mailboxDashBoardController.searchInputController.text;
|
||||||
|
|
||||||
ThreadController(
|
ThreadController(
|
||||||
this._getEmailsInMailboxInteractor,
|
this._getEmailsInMailboxInteractor,
|
||||||
this._markAsMultipleEmailReadInteractor,
|
this._markAsMultipleEmailReadInteractor,
|
||||||
@@ -154,7 +159,7 @@ class ThreadController extends BaseController {
|
|||||||
newState.fold(
|
newState.fold(
|
||||||
(failure) {
|
(failure) {
|
||||||
if (failure is SearchEmailFailure) {
|
if (failure is SearchEmailFailure) {
|
||||||
emailListSearch.clear();
|
emailList.clear();
|
||||||
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
|
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
|
||||||
_isLoadingMore = false;
|
_isLoadingMore = false;
|
||||||
}
|
}
|
||||||
@@ -181,7 +186,6 @@ class ThreadController extends BaseController {
|
|||||||
void onDone() {
|
void onDone() {
|
||||||
viewState.value.fold(
|
viewState.value.fold(
|
||||||
(failure) {
|
(failure) {
|
||||||
log('ThreadController::onDone(): failure: $failure');
|
|
||||||
if (failure is MarkAsMultipleEmailReadAllFailure
|
if (failure is MarkAsMultipleEmailReadAllFailure
|
||||||
|| failure is MarkAsMultipleEmailReadFailure) {
|
|| failure is MarkAsMultipleEmailReadFailure) {
|
||||||
_markAsReadSelectedMultipleEmailFailure(failure);
|
_markAsReadSelectedMultipleEmailFailure(failure);
|
||||||
@@ -197,7 +201,6 @@ class ThreadController extends BaseController {
|
|||||||
(success) {
|
(success) {
|
||||||
if (success is MarkAsMultipleEmailReadAllSuccess
|
if (success is MarkAsMultipleEmailReadAllSuccess
|
||||||
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||||
log('ThreadController::onDone(): success: $success');
|
|
||||||
_markAsReadSelectedMultipleEmailSuccess(success);
|
_markAsReadSelectedMultipleEmailSuccess(success);
|
||||||
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|
||||||
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
||||||
@@ -239,9 +242,7 @@ class ThreadController extends BaseController {
|
|||||||
|
|
||||||
searchWorker = ever(mailboxDashBoardController.searchState, (searchState) {
|
searchWorker = ever(mailboxDashBoardController.searchState, (searchState) {
|
||||||
if (searchState is SearchState) {
|
if (searchState is SearchState) {
|
||||||
if (searchState.searchStatus == SearchStatus.INACTIVE) {
|
if (searchState.searchStatus == SearchStatus.ACTIVE) {
|
||||||
emailListSearch.clear();
|
|
||||||
} else if (searchState.searchStatus == SearchStatus.ACTIVE) {
|
|
||||||
cancelSelectEmail();
|
cancelSelectEmail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,6 +271,9 @@ class ThreadController extends BaseController {
|
|||||||
} if (action is OpenEmailDetailedAction) {
|
} if (action is OpenEmailDetailedAction) {
|
||||||
pressEmailAction(action.context, EmailActionType.preview, action.presentationEmail);
|
pressEmailAction(action.context, EmailActionType.preview, action.presentationEmail);
|
||||||
mailboxDashBoardController.clearDashBoardAction();
|
mailboxDashBoardController.clearDashBoardAction();
|
||||||
|
} if (action is DisableSearchEmailAction) {
|
||||||
|
closeSearchEmailAction();
|
||||||
|
mailboxDashBoardController.clearDashBoardAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -318,7 +322,6 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _getAllEmailSuccess(GetAllEmailSuccess success) {
|
void _getAllEmailSuccess(GetAllEmailSuccess success) {
|
||||||
log('ThreadController::_getAllEmailSuccess(): ${success.emailList.length}');
|
|
||||||
_currentEmailState = success.currentEmailState;
|
_currentEmailState = success.currentEmailState;
|
||||||
emailList.value = success.emailList;
|
emailList.value = success.emailList;
|
||||||
if (listEmailController.hasClients) {
|
if (listEmailController.hasClients) {
|
||||||
@@ -327,7 +330,6 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) {
|
void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) {
|
||||||
log('ThreadController::_refreshChangesAllEmailSuccess(): ${success.emailList.length}');
|
|
||||||
_currentEmailState = success.currentEmailState;
|
_currentEmailState = success.currentEmailState;
|
||||||
|
|
||||||
final emailsBeforeChanges = emailList;
|
final emailsBeforeChanges = emailList;
|
||||||
@@ -341,7 +343,6 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _getAllEmailAction(AccountId accountId, {MailboxId? mailboxId}) {
|
void _getAllEmailAction(AccountId accountId, {MailboxId? mailboxId}) {
|
||||||
log('ThreadController::_getAllEmailAction(): mailboxId = $mailboxId');
|
|
||||||
consumeState(_getEmailsInMailboxInteractor.execute(
|
consumeState(_getEmailsInMailboxInteractor.execute(
|
||||||
accountId,
|
accountId,
|
||||||
limit: ThreadConstants.defaultLimit,
|
limit: ThreadConstants.defaultLimit,
|
||||||
@@ -394,37 +395,30 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _refreshEmailChanges() {
|
void _refreshEmailChanges() {
|
||||||
log('ThreadController::_refreshEmailChanges(): ');
|
|
||||||
if (isSearchActive()) {
|
if (isSearchActive()) {
|
||||||
if (_accountId != null && searchQuery != null) {
|
if (_accountId != null && searchQuery != null) {
|
||||||
final limit = emailListSearch.isNotEmpty ? UnsignedInt(emailListSearch.length) : ThreadConstants.defaultLimit;
|
final limit = emailList.isNotEmpty
|
||||||
consumeState(_searchEmailInteractor.execute(
|
? UnsignedInt(emailList.length)
|
||||||
_accountId!,
|
: ThreadConstants.defaultLimit;
|
||||||
limit: limit,
|
_searchEmail(limit: limit);
|
||||||
sort: _sortOrder,
|
}
|
||||||
filter: EmailFilterCondition(
|
} else {
|
||||||
text: searchQuery!.value,
|
if (_accountId != null && _currentEmailState != null) {
|
||||||
inMailbox: _currentMailboxId),
|
consumeState(_refreshChangesEmailsInMailboxInteractor.execute(
|
||||||
properties: ThreadConstants.propertiesDefault,
|
_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() {
|
void loadMoreEmails() {
|
||||||
if (canLoadMore && _accountId != null) {
|
if (canLoadMore && _accountId != null) {
|
||||||
log('ThreadController::loadMoreEmails(): latest: ${emailList.last.receivedAt}');
|
|
||||||
startFpsMeter();
|
startFpsMeter();
|
||||||
consumeState(_loadMoreEmailsInMailboxInteractor.execute(
|
consumeState(_loadMoreEmailsInMailboxInteractor.execute(
|
||||||
GetEmailRequest(
|
GetEmailRequest(
|
||||||
@@ -439,11 +433,8 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) {
|
void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) {
|
||||||
log('ThreadController::_loadMoreEmailsSuccess(): [BEFORE] totalEmailList = ${emailList.length}');
|
|
||||||
if (success.emailList.isNotEmpty) {
|
if (success.emailList.isNotEmpty) {
|
||||||
log('ThreadController::_loadMoreEmailsSuccess(): add success: ${success.emailList.length}');
|
|
||||||
emailList.addAll(success.emailList);
|
emailList.addAll(success.emailList);
|
||||||
log('ThreadController::_loadMoreEmailsSuccess(): [AFTER] totalEmailList = ${emailList.length}');
|
|
||||||
} else {
|
} else {
|
||||||
canLoadMore = false;
|
canLoadMore = false;
|
||||||
}
|
}
|
||||||
@@ -466,15 +457,9 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void selectEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
|
void selectEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
|
||||||
if (isSearchActive()) {
|
emailList.value = emailList
|
||||||
emailListSearch.value = emailListSearch
|
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
||||||
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
.toList();
|
||||||
.toList();
|
|
||||||
} else {
|
|
||||||
emailList.value = emailList
|
|
||||||
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_isUnSelectedAll()) {
|
if (_isUnSelectedAll()) {
|
||||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
||||||
@@ -492,41 +477,27 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setSelectAllEmailAction() {
|
void setSelectAllEmailAction() {
|
||||||
if (isSearchActive()) {
|
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
||||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
|
||||||
} else {
|
|
||||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
|
||||||
}
|
|
||||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
||||||
mailboxDashBoardController.listEmailSelected.value = listEmailSelected;
|
mailboxDashBoardController.listEmailSelected.value = listEmailSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PresentationEmail> get listEmailSelected {
|
List<PresentationEmail> get listEmailSelected {
|
||||||
if (isSearchActive()) {
|
return emailList.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
||||||
return emailListSearch.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
|
||||||
} else {
|
|
||||||
return emailList.where((email) => email.selectMode == SelectMode.ACTIVE).toList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isUnSelectedAll() {
|
bool _isUnSelectedAll() {
|
||||||
if (isSearchActive()) {
|
return emailList.every((email) => email.selectMode == SelectMode.INACTIVE);
|
||||||
return emailListSearch.every((email) => email.selectMode == SelectMode.INACTIVE);
|
|
||||||
} else {
|
|
||||||
return emailList.every((email) => email.selectMode == SelectMode.INACTIVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cancelSelectEmail() {
|
void cancelSelectEmail() {
|
||||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
|
||||||
emailList.value = emailList.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.currentSelectMode.value = SelectMode.INACTIVE;
|
||||||
mailboxDashBoardController.listEmailSelected.clear();
|
mailboxDashBoardController.listEmailSelected.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void markAsReadAllEmails() {
|
void markAsReadAllEmails() {
|
||||||
final listEmail = isSearchActive() ? emailListSearch.allEmailUnread : emailList.allEmailUnread;
|
final listEmail = emailList.allEmailUnread;
|
||||||
log('ThreadController::markAsReadAllEmails(): ${listEmail.length}');
|
|
||||||
if (listEmail.isNotEmpty) {
|
if (listEmail.isNotEmpty) {
|
||||||
markAsReadSelectedMultipleEmail(listEmail);
|
markAsReadSelectedMultipleEmail(listEmail);
|
||||||
}
|
}
|
||||||
@@ -534,12 +505,10 @@ class ThreadController extends BaseController {
|
|||||||
|
|
||||||
void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail) {
|
void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail) {
|
||||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listPresentationEmail: ${listPresentationEmail.length}');
|
|
||||||
final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead;
|
final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead;
|
||||||
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
|
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
|
||||||
if (_accountId != null && mailboxCurrent != null) {
|
if (_accountId != null && mailboxCurrent != null) {
|
||||||
cancelSelectEmail();
|
cancelSelectEmail();
|
||||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listEmail: ${listEmail.length}');
|
|
||||||
consumeState(_markAsMultipleEmailReadInteractor.execute(_accountId!, listEmail, readAction));
|
consumeState(_markAsMultipleEmailReadInteractor.execute(_accountId!, listEmail, readAction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,7 +533,6 @@ class ThreadController extends BaseController {
|
|||||||
message: message,
|
message: message,
|
||||||
icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast);
|
icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast);
|
||||||
}
|
}
|
||||||
log('ThreadController::_markAsReadSelectedMultipleEmailSuccess(): _refreshEmailChanges');
|
|
||||||
_refreshEmailChanges();
|
_refreshEmailChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,18 +570,18 @@ class ThreadController extends BaseController {
|
|||||||
? FilterMessageOption.all
|
? FilterMessageOption.all
|
||||||
: filterOption;
|
: filterOption;
|
||||||
|
|
||||||
log('ThreadController::filterMessagesAction(): newFilterOption: $newFilterOption');
|
|
||||||
|
|
||||||
mailboxDashBoardController.filterMessageOption.value = newFilterOption;
|
mailboxDashBoardController.filterMessageOption.value = newFilterOption;
|
||||||
|
|
||||||
log('ThreadController::filterMessagesAction(): filterMessageOption: ${mailboxDashBoardController.filterMessageOption}');
|
|
||||||
|
|
||||||
_appToast.showToastWithIcon(
|
_appToast.showToastWithIcon(
|
||||||
currentOverlayContext!,
|
currentOverlayContext!,
|
||||||
message: newFilterOption.getMessageToast(context),
|
message: newFilterOption.getMessageToast(context),
|
||||||
icon: newFilterOption.getIconToast(_imagePaths));
|
icon: newFilterOption.getIconToast(_imagePaths));
|
||||||
|
|
||||||
refreshAllEmail();
|
if (isSearchActive()) {
|
||||||
|
_searchEmail();
|
||||||
|
} else {
|
||||||
|
refreshAllEmail();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveSelectedMultipleEmailToMailbox(List<PresentationEmail> listEmail) async {
|
void moveSelectedMultipleEmailToMailbox(List<PresentationEmail> listEmail) async {
|
||||||
@@ -839,34 +807,62 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void disableSearch() {
|
void disableSearch() {
|
||||||
emailListSearch.clear();
|
searchIsActive.value = false;
|
||||||
mailboxDashBoardController.disableSearch();
|
mailboxDashBoardController.disableSearch();
|
||||||
cancelSelectEmail();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _searchEmail() {
|
void closeSearchEmailAction() {
|
||||||
emailListSearch.clear();
|
disableSearch();
|
||||||
|
cancelSelectEmail();
|
||||||
|
refreshAllEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearTextSearch() {
|
||||||
|
mailboxDashBoardController.clearTextSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _searchEmail({UnsignedInt? limit}) {
|
||||||
if (_accountId != null && searchQuery != null) {
|
if (_accountId != null && searchQuery != null) {
|
||||||
|
searchIsActive.value = true;
|
||||||
|
|
||||||
UTCDate? afterTime;
|
UTCDate? afterTime;
|
||||||
if (mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.last7Days)
|
bool? hasAttachment;
|
||||||
&& mailboxDashBoardController.emailReceiveTimeType.value != null) {
|
String? fromAddress;
|
||||||
|
String? keywordUnread;
|
||||||
|
String? keywordStarred;
|
||||||
|
|
||||||
|
if (mailboxDashBoardController.quickSearchFilterForLast7DaysIsActive()) {
|
||||||
afterTime = mailboxDashBoardController.emailReceiveTimeType.value!.toUTCDate();
|
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(
|
final emailFilterCondition = EmailFilterCondition(
|
||||||
text: searchQuery!.value,
|
text: searchQuery!.value,
|
||||||
hasAttachment: mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.hasAttachment)
|
hasAttachment: hasAttachment,
|
||||||
? true : null,
|
from: fromAddress,
|
||||||
from: mailboxDashBoardController.listFilterQuickSearch.contains(QuickSearchFilter.fromMe)
|
|
||||||
? mailboxDashBoardController.userProfile.value!.email
|
|
||||||
: null,
|
|
||||||
after: afterTime,
|
after: afterTime,
|
||||||
|
hasKeyword: keywordStarred,
|
||||||
|
notKeyword: keywordUnread,
|
||||||
inMailbox: _currentMailboxId);
|
inMailbox: _currentMailboxId);
|
||||||
|
|
||||||
consumeState(_searchEmailInteractor.execute(
|
consumeState(_searchEmailInteractor.execute(
|
||||||
_accountId!,
|
_accountId!,
|
||||||
limit: ThreadConstants.defaultLimit,
|
limit: limit ?? ThreadConstants.defaultLimit,
|
||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
filter: emailFilterCondition,
|
filter: emailFilterCondition,
|
||||||
properties: ThreadConstants.propertiesDefault,
|
properties: ThreadConstants.propertiesDefault,
|
||||||
@@ -879,10 +875,10 @@ class ThreadController extends BaseController {
|
|||||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final emailsSearchBeforeChanges = emailListSearch;
|
final emailsSearchBeforeChanges = emailList;
|
||||||
final emailsSearchAfterChanges = resultEmailSearchList;
|
final emailsSearchAfterChanges = resultEmailSearchList;
|
||||||
final newListEmailSearch = emailsSearchAfterChanges.combine(emailsSearchBeforeChanges);
|
final newListEmailSearch = emailsSearchAfterChanges.combine(emailsSearchBeforeChanges);
|
||||||
emailListSearch.value = newListEmailSearch;
|
emailList.value = newListEmailSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void searchMoreEmails() {
|
void searchMoreEmails() {
|
||||||
@@ -893,9 +889,9 @@ class ThreadController extends BaseController {
|
|||||||
sort: _sortOrder,
|
sort: _sortOrder,
|
||||||
filter: EmailFilterCondition(
|
filter: EmailFilterCondition(
|
||||||
text: searchQuery!.value,
|
text: searchQuery!.value,
|
||||||
before: emailListSearch.last.receivedAt),
|
before: emailList.last.receivedAt),
|
||||||
properties: ThreadConstants.propertiesDefault,
|
properties: ThreadConstants.propertiesDefault,
|
||||||
lastEmailId: emailListSearch.last.id
|
lastEmailId: emailList.last.id
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -904,9 +900,9 @@ class ThreadController extends BaseController {
|
|||||||
if (success.emailList.isNotEmpty) {
|
if (success.emailList.isNotEmpty) {
|
||||||
final resultEmailSearchList = success.emailList
|
final resultEmailSearchList = success.emailList
|
||||||
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailbox))
|
||||||
.where((email) => !emailListSearch.contains(email))
|
.where((email) => !emailList.contains(email))
|
||||||
.toList();
|
.toList();
|
||||||
emailListSearch.addAll(resultEmailSearchList);
|
emailList.addAll(resultEmailSearchList);
|
||||||
} else {
|
} else {
|
||||||
canSearchMore = false;
|
canSearchMore = false;
|
||||||
}
|
}
|
||||||
@@ -916,7 +912,6 @@ class ThreadController extends BaseController {
|
|||||||
bool isSelectionEnabled() => mailboxDashBoardController.isSelectionEnabled();
|
bool isSelectionEnabled() => mailboxDashBoardController.isSelectionEnabled();
|
||||||
|
|
||||||
void pressEmailSelectionAction(BuildContext context, EmailActionType actionType, List<PresentationEmail> selectionEmail) {
|
void pressEmailSelectionAction(BuildContext context, EmailActionType actionType, List<PresentationEmail> selectionEmail) {
|
||||||
log('ThreadController::pressEmailSelectionAction(): selectionEmail: ${selectionEmail.length}');
|
|
||||||
switch(actionType) {
|
switch(actionType) {
|
||||||
case EmailActionType.markAsRead:
|
case EmailActionType.markAsRead:
|
||||||
case EmailActionType.markAsUnread:
|
case EmailActionType.markAsUnread:
|
||||||
|
|||||||
@@ -5,8 +5,13 @@ import 'package:get/get.dart';
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.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/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/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/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_email_state.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/state/search_more_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';
|
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'
|
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';
|
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/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';
|
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 _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
@@ -46,50 +50,74 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Obx(() => !controller.isSearchActive()
|
if ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)
|
||||||
&& ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)
|
... [
|
||||||
? _buildAppBarNormal(context)
|
_buildAppBarNormal(context),
|
||||||
: const SizedBox.shrink()),
|
Obx(() {
|
||||||
_buildSearchInputFormForMobile(context),
|
return Stack(children: [
|
||||||
Container(
|
if (!controller.isSearchActive())
|
||||||
color: BuildUtils.isWeb ? AppColor.colorBgDesktop : Colors.white,
|
Container(
|
||||||
padding: EdgeInsets.zero,
|
color: Colors.white,
|
||||||
child: _buildSearchButtonViewForMobile(context)),
|
padding: EdgeInsets.symmetric(
|
||||||
Obx(() => controller.isMailboxTrash && controller.emailList.isNotEmpty && !controller.isSearchActive()
|
horizontal: 16,
|
||||||
? _buildEmptyTrashButton(context)
|
vertical: BuildUtils.isWeb && _responsiveUtils.isTabletLarge(context) ? 8 : 0),
|
||||||
: const SizedBox.shrink()),
|
margin: const EdgeInsets.only(
|
||||||
Obx(() => controller.isSearchActive() && _responsiveUtils.isDesktop(context) && BuildUtils.isWeb
|
bottom: !BuildUtils.isWeb ? 16 : 0),
|
||||||
? _buildListButtonQuickSearchFilter(context)
|
child: _buildSearchFormInActive(context))
|
||||||
: const SizedBox.shrink()),
|
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(
|
Expanded(child: Container(
|
||||||
color: BuildUtils.isWeb ? AppColor.colorBgDesktop : Colors.white,
|
alignment: Alignment.center,
|
||||||
padding: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
margin: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||||
? const EdgeInsets.only(left: 32, right: 24, top: 16, bottom: 24)
|
? const EdgeInsets.only(left: 32, right: 24, top: 16, bottom: 24)
|
||||||
: EdgeInsets.zero,
|
: EdgeInsets.zero,
|
||||||
child: Stack(children: [
|
decoration: BoxDecoration(
|
||||||
Container(
|
borderRadius: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||||
alignment: Alignment.center,
|
? BorderRadius.circular(20)
|
||||||
decoration: BoxDecoration(
|
: null,
|
||||||
borderRadius: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
border: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
||||||
? BorderRadius.circular(20)
|
? Border.all(color: AppColor.colorBorderBodyThread, width: 1)
|
||||||
: null,
|
: null,
|
||||||
border: BuildUtils.isWeb && _responsiveUtils.isDesktop(context)
|
color: Colors.white),
|
||||||
? Border.all(color: AppColor.colorBorderBodyThread, width: 1)
|
child: Column(
|
||||||
: null,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
color: Colors.white),
|
children: [
|
||||||
child: Column(
|
_buildLoadingView(),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Expanded(child: _buildListEmail(context)),
|
||||||
children: [
|
_buildLoadingViewLoadMore(),
|
||||||
if (_responsiveUtils.isMobile(context))
|
]
|
||||||
_buildStatusResultSearch(context),
|
)
|
||||||
_buildLoadingView(),
|
)),
|
||||||
Expanded(child: _buildListEmail(context)),
|
|
||||||
_buildLoadingViewLoadMore(),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
_buildSuggestionBox(context)
|
|
||||||
]))),
|
|
||||||
_buildListButtonSelectionForMobile(context),
|
_buildListButtonSelectionForMobile(context),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -125,62 +153,189 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSearchButtonViewForMobile(BuildContext context) {
|
Widget _buildSearchFormInActive(BuildContext context) {
|
||||||
return Obx(() {
|
return (SearchBarView(_imagePaths)
|
||||||
if (!controller.isSearchActive() &&
|
..hintTextSearch(AppLocalizations.of(context).search_emails)
|
||||||
((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)) {
|
..addOnOpenSearchViewAction(() => controller.enableSearch(context)))
|
||||||
return Container(
|
.build();
|
||||||
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 _buildSearchInputFormForMobile(BuildContext context) {
|
Widget _buildSearchFormActive(BuildContext context) {
|
||||||
return Obx(() {
|
return Row(
|
||||||
if (controller.isSearchActive() &&
|
children: [
|
||||||
((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)) {
|
buildIconWeb(
|
||||||
return Column(children: [
|
icon: SvgPicture.asset(
|
||||||
_buildSearchForm(context),
|
_imagePaths.icBack,
|
||||||
const Divider(color: AppColor.lineItemListColor, height: 1, thickness: 0.2),
|
color: AppColor.colorTextButton,
|
||||||
]);
|
fit: BoxFit.fill),
|
||||||
} else {
|
onTap: () => controller.closeSearchEmailAction()),
|
||||||
return const SizedBox.shrink();
|
Expanded(child: Container(
|
||||||
}
|
decoration: const BoxDecoration(
|
||||||
});
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
}
|
color: AppColor.colorBgSearchBar),
|
||||||
|
height: 45,
|
||||||
Widget _buildSearchForm(BuildContext context) {
|
child: QuickSearchInputForm<PresentationEmail, RecentSearch>(
|
||||||
return (SearchAppBarWidget(
|
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||||
context,
|
controller: controller.searchController,
|
||||||
_imagePaths,
|
autofocus: true,
|
||||||
_responsiveUtils,
|
focusNode: controller.mailboxDashBoardController.searchFocus,
|
||||||
controller.searchQuery,
|
textInputAction: TextInputAction.done,
|
||||||
controller.mailboxDashBoardController.searchFocus,
|
onSubmitted: (keyword) {
|
||||||
controller.mailboxDashBoardController.searchInputController,
|
if (keyword.trim().isNotEmpty) {
|
||||||
suggestionSearch: controller.mailboxDashBoardController.suggestionSearch,)
|
controller.mailboxDashBoardController
|
||||||
..addDecoration(const BoxDecoration(color: Colors.white))
|
.saveRecentSearch(RecentSearch.now(keyword));
|
||||||
..setMargin(const EdgeInsets.only(right: 10))
|
}
|
||||||
..setHintText(AppLocalizations.of(context).search_mail)
|
controller.mailboxDashBoardController.searchEmail(context, keyword);
|
||||||
..addOnCancelSearchPressed(() => controller.disableSearch())
|
},
|
||||||
..addOnClearTextSearchAction(() => controller.mailboxDashBoardController.clearSearchText())
|
decoration: InputDecoration(
|
||||||
..addOnTextChangeSearchAction((query) => controller.mailboxDashBoardController.addSuggestionSearch(query))
|
border: InputBorder.none,
|
||||||
..addOnSearchTextAction((query) => controller.mailboxDashBoardController.searchEmail(context, query)))
|
focusedBorder: InputBorder.none,
|
||||||
.build();
|
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) {
|
Widget _buildAppBarNormal(BuildContext context) {
|
||||||
return (AppBarThreadWidgetBuilder(
|
return Obx(() {
|
||||||
|
return (AppBarThreadWidgetBuilder(
|
||||||
context,
|
context,
|
||||||
_imagePaths,
|
controller.currentMailbox,
|
||||||
_responsiveUtils,
|
|
||||||
controller.mailboxDashBoardController.selectedMailbox.value,
|
|
||||||
controller.listEmailSelected,
|
controller.listEmailSelected,
|
||||||
controller.mailboxDashBoardController.currentSelectMode.value,
|
controller.mailboxDashBoardController.currentSelectMode.value,
|
||||||
controller.mailboxDashBoardController.filterMessageOption.value)
|
controller.mailboxDashBoardController.filterMessageOption.value)
|
||||||
@@ -188,17 +343,24 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
|||||||
..addOnEditThreadAction(() => controller.enableSelectionEmail())
|
..addOnEditThreadAction(() => controller.enableSelectionEmail())
|
||||||
..addOnEmailSelectionAction((actionType, selectionEmail) =>
|
..addOnEmailSelectionAction((actionType, selectionEmail) =>
|
||||||
controller.pressEmailSelectionAction(context, actionType, selectionEmail))
|
controller.pressEmailSelectionAction(context, actionType, selectionEmail))
|
||||||
..addOnFilterEmailAction((filterMessageOption, position) =>
|
..addOnFilterEmailAction((filterMessageOption, position) {
|
||||||
_responsiveUtils.isScreenWithShortestSide(context)
|
if (_responsiveUtils.isScreenWithShortestSide(context)) {
|
||||||
? controller.openContextMenuAction(
|
controller.openContextMenuAction(
|
||||||
context,
|
context,
|
||||||
_filterMessagesCupertinoActionTile(context, filterMessageOption))
|
_filterMessagesCupertinoActionTile(context, filterMessageOption));
|
||||||
: controller.openPopupMenuAction(
|
} else {
|
||||||
context,
|
controller.openPopupMenuAction(
|
||||||
position,
|
context,
|
||||||
_popupMenuEmailActionTile(context, filterMessageOption)))
|
position,
|
||||||
|
popupMenuFilterEmailActionTile(
|
||||||
|
context,
|
||||||
|
filterMessageOption,
|
||||||
|
(option) => controller.filterMessagesAction(context, option)));
|
||||||
|
}
|
||||||
|
})
|
||||||
..addOnCancelEditThread(() => controller.cancelSelectEmail()))
|
..addOnCancelEditThread(() => controller.cancelSelectEmail()))
|
||||||
.build();
|
.build();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFloatingButtonCompose(BuildContext context) {
|
Widget _buildFloatingButtonCompose(BuildContext context) {
|
||||||
@@ -232,75 +394,37 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _filterMessagesCupertinoActionTile(BuildContext context, FilterMessageOption optionCurrent) {
|
List<Widget> _filterMessagesCupertinoActionTile(BuildContext context, FilterMessageOption optionCurrent) {
|
||||||
return <Widget>[
|
final listFilter = [
|
||||||
_filterMessageWithAttachmentsAction(context, optionCurrent),
|
FilterMessageOption.attachments,
|
||||||
_filterMessagesUnreadAction(context, optionCurrent),
|
FilterMessageOption.unread,
|
||||||
_filterMessageStarredAction(context, optionCurrent),
|
FilterMessageOption.starred,
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
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)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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() {
|
Widget _buildLoadingView() {
|
||||||
@@ -344,25 +468,11 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
|||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
if (controller.isSearchActive()) {
|
return _buildResultListEmail(context, controller.emailList);
|
||||||
if (controller.mailboxDashBoardController.suggestionSearch.isNotEmpty) {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
} else {
|
|
||||||
return _buildResultSearchEmails(context, controller.emailListSearch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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) {
|
Widget _buildResultListEmail(BuildContext context, List<PresentationEmail> listPresentationEmail) {
|
||||||
if (controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) {
|
if (controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) {
|
||||||
return listPresentationEmail.isNotEmpty
|
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) {
|
Widget _buildEmptyTrashButton(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
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:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:model/model.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';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
typedef OnFilterEmailAction = void Function(FilterMessageOption, RelativeRect? position);
|
typedef OnFilterEmailAction = void Function(FilterMessageOption, RelativeRect? position);
|
||||||
@@ -15,6 +15,9 @@ typedef OnCancelEditThread = void Function();
|
|||||||
typedef OnEmailSelectionAction = void Function(EmailActionType actionType, List<PresentationEmail>);
|
typedef OnEmailSelectionAction = void Function(EmailActionType actionType, List<PresentationEmail>);
|
||||||
|
|
||||||
class AppBarThreadWidgetBuilder {
|
class AppBarThreadWidgetBuilder {
|
||||||
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
|
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||||
|
|
||||||
OnFilterEmailAction? _onFilterEmailAction;
|
OnFilterEmailAction? _onFilterEmailAction;
|
||||||
OnOpenMailboxMenuActionClick? _onOpenMailboxMenuActionClick;
|
OnOpenMailboxMenuActionClick? _onOpenMailboxMenuActionClick;
|
||||||
OnEditThreadAction? _onEditThreadAction;
|
OnEditThreadAction? _onEditThreadAction;
|
||||||
@@ -22,8 +25,6 @@ class AppBarThreadWidgetBuilder {
|
|||||||
OnEmailSelectionAction? _onEmailSelectionAction;
|
OnEmailSelectionAction? _onEmailSelectionAction;
|
||||||
|
|
||||||
final BuildContext _context;
|
final BuildContext _context;
|
||||||
final ImagePaths _imagePaths;
|
|
||||||
final ResponsiveUtils _responsiveUtils;
|
|
||||||
final PresentationMailbox? _currentMailbox;
|
final PresentationMailbox? _currentMailbox;
|
||||||
final List<PresentationEmail> _listSelectionEmail;
|
final List<PresentationEmail> _listSelectionEmail;
|
||||||
final SelectMode _selectMode;
|
final SelectMode _selectMode;
|
||||||
@@ -31,8 +32,6 @@ class AppBarThreadWidgetBuilder {
|
|||||||
|
|
||||||
AppBarThreadWidgetBuilder(
|
AppBarThreadWidgetBuilder(
|
||||||
this._context,
|
this._context,
|
||||||
this._imagePaths,
|
|
||||||
this._responsiveUtils,
|
|
||||||
this._currentMailbox,
|
this._currentMailbox,
|
||||||
this._listSelectionEmail,
|
this._listSelectionEmail,
|
||||||
this._selectMode,
|
this._selectMode,
|
||||||
@@ -65,8 +64,11 @@ class AppBarThreadWidgetBuilder {
|
|||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
padding: EdgeInsets.only(left: 8, bottom: 8, right: 8,
|
padding: EdgeInsets.only(
|
||||||
top: (!BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(_context)) ? 0 : 16),
|
left: 8,
|
||||||
|
bottom: !BuildUtils.isWeb ? 8 : 16,
|
||||||
|
right: 8,
|
||||||
|
top: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(_context) ? 0 : 16),
|
||||||
child: MediaQuery(
|
child: MediaQuery(
|
||||||
data: const MediaQueryData(padding: EdgeInsets.zero),
|
data: const MediaQueryData(padding: EdgeInsets.zero),
|
||||||
child: kIsWeb
|
child: kIsWeb
|
||||||
@@ -211,7 +213,8 @@ class AppBarThreadWidgetBuilder {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||||
child: GestureDetector(
|
child: InkWell(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (_onFilterEmailAction != null && _responsiveUtils.isScreenWithShortestSide(_context)) {
|
if (_onFilterEmailAction != null && _responsiveUtils.isScreenWithShortestSide(_context)) {
|
||||||
_onFilterEmailAction!.call(_filterMessageOption, null);
|
_onFilterEmailAction!.call(_filterMessageOption, null);
|
||||||
|
|||||||
+3
-2
@@ -3,9 +3,10 @@ import 'package:core/core.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.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 option;
|
||||||
final FilterMessageOption? optionCurrent;
|
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/attachment.dart';
|
||||||
export 'email/mark_star_action.dart';
|
export 'email/mark_star_action.dart';
|
||||||
export 'email/email_property.dart';
|
export 'email/email_property.dart';
|
||||||
export 'email/email_filter.dart';
|
|
||||||
export 'email/email_content_type.dart';
|
export 'email/email_content_type.dart';
|
||||||
export 'email/filter_message_option.dart';
|
|
||||||
|
|
||||||
// Extensions
|
// Extensions
|
||||||
export 'extensions/email_address_extension.dart';
|
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:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||||
import 'package:mockito/annotations.dart';
|
import 'package:mockito/annotations.dart';
|
||||||
import 'package:mockito/mockito.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/model/email_response.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.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';
|
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||||
@@ -38,7 +39,7 @@ void main() {
|
|||||||
when(threadRepository.getAllEmail(
|
when(threadRepository.getAllEmail(
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
limit: UnsignedInt(20),
|
limit: UnsignedInt(20),
|
||||||
sort: Set()..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
sort: {}..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||||
emailFilter: EmailFilter(
|
emailFilter: EmailFilter(
|
||||||
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
||||||
mailboxId: MailboxFixtures.inboxMailbox.id,
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
@@ -66,7 +67,7 @@ void main() {
|
|||||||
final streamStates = getEmailsInMailboxInteractor.execute(
|
final streamStates = getEmailsInMailboxInteractor.execute(
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
limit: UnsignedInt(20),
|
limit: UnsignedInt(20),
|
||||||
sort: Set()..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
sort: {}..add(EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false)),
|
||||||
emailFilter: EmailFilter(
|
emailFilter: EmailFilter(
|
||||||
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
filter: EmailFilterCondition(inMailbox: MailboxFixtures.inboxMailbox.id),
|
||||||
mailboxId: MailboxFixtures.inboxMailbox.id,
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
|||||||
+13
-10
@@ -5,19 +5,22 @@
|
|||||||
import 'dart:async' as _i3;
|
import 'dart:async' as _i3;
|
||||||
|
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
|
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/properties/properties.dart' as _i9;
|
||||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart' as _i7;
|
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/state.dart' as _i10;
|
||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart' as _i6;
|
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:jmap_dart_client/jmap/mail/mailbox/mailbox.dart' as _i11;
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
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'
|
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'
|
||||||
as _i4;
|
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;
|
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'
|
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
|
||||||
as _i2;
|
as _i2;
|
||||||
|
|
||||||
@@ -64,7 +67,7 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
_i9.Properties? propertiesCreated,
|
_i9.Properties? propertiesCreated,
|
||||||
_i9.Properties? propertiesUpdated,
|
_i9.Properties? propertiesUpdated,
|
||||||
_i11.MailboxId? inMailboxId,
|
_i11.MailboxId? inMailboxId,
|
||||||
_i8.FilterMessageOption? filterOption}) =>
|
_i12.FilterMessageOption? filterOption}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(#refreshChanges, [
|
Invocation.method(#refreshChanges, [
|
||||||
accountId,
|
accountId,
|
||||||
@@ -80,15 +83,15 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
as _i3.Stream<_i4.EmailsResponse>);
|
as _i3.Stream<_i4.EmailsResponse>);
|
||||||
@override
|
@override
|
||||||
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
||||||
_i12.GetEmailRequest? emailRequest) =>
|
_i13.GetEmailRequest? emailRequest) =>
|
||||||
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
||||||
returnValue: Stream<_i4.EmailsResponse>.empty())
|
returnValue: Stream<_i4.EmailsResponse>.empty())
|
||||||
as _i3.Stream<_i4.EmailsResponse>);
|
as _i3.Stream<_i4.EmailsResponse>);
|
||||||
@override
|
@override
|
||||||
_i3.Future<List<_i13.Email>> searchEmails(_i5.AccountId? accountId,
|
_i3.Future<List<_i14.Email>> searchEmails(_i5.AccountId? accountId,
|
||||||
{_i6.UnsignedInt? limit,
|
{_i6.UnsignedInt? limit,
|
||||||
Set<_i7.Comparator>? sort,
|
Set<_i7.Comparator>? sort,
|
||||||
_i14.Filter? filter,
|
_i15.Filter? filter,
|
||||||
_i9.Properties? properties}) =>
|
_i9.Properties? properties}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(#searchEmails, [
|
Invocation.method(#searchEmails, [
|
||||||
@@ -99,8 +102,8 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
#filter: filter,
|
#filter: filter,
|
||||||
#properties: properties
|
#properties: properties
|
||||||
}),
|
}),
|
||||||
returnValue: Future<List<_i13.Email>>.value(<_i13.Email>[]))
|
returnValue: Future<List<_i14.Email>>.value(<_i14.Email>[]))
|
||||||
as _i3.Future<List<_i13.Email>>);
|
as _i3.Future<List<_i14.Email>>);
|
||||||
@override
|
@override
|
||||||
_i3.Future<bool> emptyTrashFolder(
|
_i3.Future<bool> emptyTrashFolder(
|
||||||
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
||||||
|
|||||||
+13
-10
@@ -5,19 +5,22 @@
|
|||||||
import 'dart:async' as _i3;
|
import 'dart:async' as _i3;
|
||||||
|
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart' as _i5;
|
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/properties/properties.dart' as _i9;
|
||||||
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart' as _i7;
|
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/state.dart' as _i10;
|
||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart' as _i6;
|
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:jmap_dart_client/jmap/mail/mailbox/mailbox.dart' as _i11;
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
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'
|
import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'
|
||||||
as _i4;
|
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;
|
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'
|
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart'
|
||||||
as _i2;
|
as _i2;
|
||||||
|
|
||||||
@@ -64,7 +67,7 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
_i9.Properties? propertiesCreated,
|
_i9.Properties? propertiesCreated,
|
||||||
_i9.Properties? propertiesUpdated,
|
_i9.Properties? propertiesUpdated,
|
||||||
_i11.MailboxId? inMailboxId,
|
_i11.MailboxId? inMailboxId,
|
||||||
_i8.FilterMessageOption? filterOption}) =>
|
_i12.FilterMessageOption? filterOption}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(#refreshChanges, [
|
Invocation.method(#refreshChanges, [
|
||||||
accountId,
|
accountId,
|
||||||
@@ -80,15 +83,15 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
as _i3.Stream<_i4.EmailsResponse>);
|
as _i3.Stream<_i4.EmailsResponse>);
|
||||||
@override
|
@override
|
||||||
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
_i3.Stream<_i4.EmailsResponse> loadMoreEmails(
|
||||||
_i12.GetEmailRequest? emailRequest) =>
|
_i13.GetEmailRequest? emailRequest) =>
|
||||||
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
(super.noSuchMethod(Invocation.method(#loadMoreEmails, [emailRequest]),
|
||||||
returnValue: Stream<_i4.EmailsResponse>.empty())
|
returnValue: Stream<_i4.EmailsResponse>.empty())
|
||||||
as _i3.Stream<_i4.EmailsResponse>);
|
as _i3.Stream<_i4.EmailsResponse>);
|
||||||
@override
|
@override
|
||||||
_i3.Future<List<_i13.Email>> searchEmails(_i5.AccountId? accountId,
|
_i3.Future<List<_i14.Email>> searchEmails(_i5.AccountId? accountId,
|
||||||
{_i6.UnsignedInt? limit,
|
{_i6.UnsignedInt? limit,
|
||||||
Set<_i7.Comparator>? sort,
|
Set<_i7.Comparator>? sort,
|
||||||
_i14.Filter? filter,
|
_i15.Filter? filter,
|
||||||
_i9.Properties? properties}) =>
|
_i9.Properties? properties}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(#searchEmails, [
|
Invocation.method(#searchEmails, [
|
||||||
@@ -99,8 +102,8 @@ class MockThreadRepository extends _i1.Mock implements _i2.ThreadRepository {
|
|||||||
#filter: filter,
|
#filter: filter,
|
||||||
#properties: properties
|
#properties: properties
|
||||||
}),
|
}),
|
||||||
returnValue: Future<List<_i13.Email>>.value(<_i13.Email>[]))
|
returnValue: Future<List<_i14.Email>>.value(<_i14.Email>[]))
|
||||||
as _i3.Future<List<_i13.Email>>);
|
as _i3.Future<List<_i14.Email>>);
|
||||||
@override
|
@override
|
||||||
_i3.Future<bool> emptyTrashFolder(
|
_i3.Future<bool> emptyTrashFolder(
|
||||||
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
_i5.AccountId? accountId, _i11.MailboxId? trashMailboxId) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user