TF-934 Implement search by query when open new tab

This commit is contained in:
dab246
2022-11-11 00:11:48 +07:00
committed by Dat H. Pham
parent 6050ee5386
commit 71abe0cf37
22 changed files with 224 additions and 120 deletions
@@ -20,6 +20,7 @@ class EmailSupervisorController extends BaseController {
int currentIndexPageView = -1; int currentIndexPageView = -1;
final canGetNewerEmail = true.obs; final canGetNewerEmail = true.obs;
final canGetOlderEmail = true.obs; final canGetOlderEmail = true.obs;
final supportedPageView = RxBool(true);
Rxn<PresentationEmail> get selectedEmail => mailboxDashBoardController.selectedEmail; Rxn<PresentationEmail> get selectedEmail => mailboxDashBoardController.selectedEmail;
Session? get sessionCurrent => mailboxDashBoardController.sessionCurrent; Session? get sessionCurrent => mailboxDashBoardController.sessionCurrent;
@@ -33,8 +34,6 @@ class EmailSupervisorController extends BaseController {
} }
} }
bool get supportedPageView => listEmail.isNotEmpty;
@override @override
void onClose() { void onClose() {
pageController?.dispose(); pageController?.dispose();
@@ -181,10 +181,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
if (presentationEmail is PresentationEmail) { if (presentationEmail is PresentationEmail) {
if (_currentEmailId != presentationEmail.id) { if (_currentEmailId != presentationEmail.id) {
_currentEmailId = presentationEmail.id; _currentEmailId = presentationEmail.id;
if (emailSupervisorController.supportedPageView) { if (emailSupervisorController.listEmail.isNotEmpty) {
emailSupervisorController.supportedPageView.value = true;
emailSupervisorController.setCurrentPositionEmailInListEmail(_currentEmailId); emailSupervisorController.setCurrentPositionEmailInListEmail(_currentEmailId);
_getEmailDeBouncer.value = emailSupervisorController.currentIndexPageView; _getEmailDeBouncer.value = emailSupervisorController.currentIndexPageView;
} else { } else {
emailSupervisorController.supportedPageView.value = false;
_getEmailContentAction(presentationEmail.id); _getEmailContentAction(presentationEmail.id);
} }
_resetToOriginalValue(); _resetToOriginalValue();
@@ -364,9 +366,13 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
PresentationMailbox? getMailboxContain(PresentationEmail email) { PresentationMailbox? getMailboxContain(PresentationEmail email) {
return mailboxDashBoardController.searchController.isSearchEmailRunning if (mailboxDashBoardController.selectedMailbox.value == null) {
return email.findMailboxContain(mailboxDashBoardController.mapMailboxById);
} else {
return mailboxDashBoardController.searchController.isSearchEmailRunning
? email.findMailboxContain(mailboxDashBoardController.mapMailboxById) ? email.findMailboxContain(mailboxDashBoardController.mapMailboxById)
: mailboxDashBoardController.selectedMailbox.value; : mailboxDashBoardController.selectedMailbox.value;
}
} }
void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions) async { void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions) async {
@@ -378,6 +384,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _markAsEmailReadSuccess(Success success) { void _markAsEmailReadSuccess(Success success) {
log('SingleEmailController::_markAsEmailReadSuccess(): $success');
mailboxDashBoardController.dispatchState(Right(success)); mailboxDashBoardController.dispatchState(Right(success));
if (success is MarkAsEmailReadSuccess if (success is MarkAsEmailReadSuccess
@@ -744,7 +751,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void _markAsEmailStarSuccess(Success success) { void _markAsEmailStarSuccess(Success success) {
if (success is MarkAsStarEmailSuccess) { if (success is MarkAsStarEmailSuccess) {
mailboxDashBoardController.setSelectedEmail(success.updatedEmail.toPresentationEmail(selectMode: SelectMode.ACTIVE)); final selectedEmail = mailboxDashBoardController.selectedEmail.value;
mailboxDashBoardController.setSelectedEmail(selectedEmail?.updateKeywords(success.updatedEmail.keywords));
} }
mailboxDashBoardController.dispatchState(Right(success)); mailboxDashBoardController.dispatchState(Right(success));
} }
@@ -992,7 +1000,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void closeEmailView(BuildContext context) { void closeEmailView(BuildContext context) {
log('SingleEmailController::closeEmailView(): '); log('SingleEmailController::closeEmailView(): ');
if (emailSupervisorController.supportedPageView) { if (emailSupervisorController.supportedPageView.isTrue) {
emailSupervisorController.presentationEmailsLoaded.removeWhere((e) => e.emailCurrent?.id == currentEmail?.id); emailSupervisorController.presentationEmailsLoaded.removeWhere((e) => e.emailCurrent?.id == currentEmail?.id);
emailSupervisorController.currentIndexPageView = -1; emailSupervisorController.currentIndexPageView = -1;
_getEmailDeBouncer.value = null; _getEmailDeBouncer.value = null;
@@ -1015,10 +1023,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
bool get isOpenEmailNotMailboxFromRoute => !emailSupervisorController.supportedPageView bool get isOpenEmailNotMailboxFromRoute => emailSupervisorController.supportedPageView.isFalse
&& mailboxDashBoardController.selectedMailbox.value == null; && mailboxDashBoardController.selectedMailbox.value == null;
void _updateRouteOnBrowser() { void _updateRouteOnBrowser() {
log('SingleEmailController::_updateRouteOnBrowser(): isSearchEmailRunning: ${mailboxDashBoardController.searchController.isSearchEmailRunning}');
if (BuildUtils.isWeb) { if (BuildUtils.isWeb) {
final selectedMailboxId = mailboxDashBoardController.selectedMailbox.value?.id; final selectedMailboxId = mailboxDashBoardController.selectedMailbox.value?.id;
final route = RouteUtils.generateRouteBrowser( final route = RouteUtils.generateRouteBrowser(
@@ -88,9 +88,11 @@ class EmailView extends GetWidget<SingleEmailController> {
_buildAppBar(context, email), _buildAppBar(context, email),
_buildVacationNotificationMessage(context), _buildVacationNotificationMessage(context),
const Divider(color: AppColor.colorDividerHorizontal, height: 1), const Divider(color: AppColor.colorDividerHorizontal, height: 1),
Expanded(child: controller.emailSupervisorController.supportedPageView Expanded(child: Obx(() {
? _buildMultipleEmailView(controller.emailSupervisorController.listEmail) return controller.emailSupervisorController.supportedPageView.isTrue
: _buildSingleEmailView(context, email), ? _buildMultipleEmailView(controller.emailSupervisorController.listEmail)
: _buildSingleEmailView(context, email);
}),
), ),
const Divider(color: AppColor.colorDividerHorizontal, height: 1), const Divider(color: AppColor.colorDividerHorizontal, height: 1),
_buildBottomBar(context, email), _buildBottomBar(context, email),
@@ -98,6 +100,7 @@ class EmailView extends GetWidget<SingleEmailController> {
} }
Widget _buildMultipleEmailView(List<PresentationEmail> listEmails) { Widget _buildMultipleEmailView(List<PresentationEmail> listEmails) {
log('EmailView::_buildMultipleEmailView(): ');
return PageView.builder( return PageView.builder(
physics: BuildUtils.isWeb ? const NeverScrollableScrollPhysics() : null, physics: BuildUtils.isWeb ? const NeverScrollableScrollPhysics() : null,
itemCount: listEmails.length, itemCount: listEmails.length,
@@ -108,6 +111,7 @@ class EmailView extends GetWidget<SingleEmailController> {
} }
Widget _buildSingleEmailView(BuildContext context, PresentationEmail email) { Widget _buildSingleEmailView(BuildContext context, PresentationEmail email) {
log('EmailView::_buildSingleEmailView(): ');
return _buildEmailBody(context, email); return _buildEmailBody(context, email);
} }
@@ -144,7 +148,7 @@ class EmailView extends GetWidget<SingleEmailController> {
Widget _buildAppBar(BuildContext context, PresentationEmail presentationEmail) { Widget _buildAppBar(BuildContext context, PresentationEmail presentationEmail) {
return Obx(() => AppBarMailWidgetBuilder( return Obx(() => AppBarMailWidgetBuilder(
presentationEmail, presentationEmail,
currentMailbox: controller.mailboxDashBoardController.selectedMailbox.value, mailboxContain: _getMailboxContain(presentationEmail),
isSearchIsRunning: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchIsRunning: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackActionClick: () => controller.closeEmailView(context), onBackActionClick: () => controller.closeEmailView(context),
onEmailActionClick: (email, action) => onEmailActionClick: (email, action) =>
@@ -161,12 +165,16 @@ class EmailView extends GetWidget<SingleEmailController> {
_popupMenuEmailActionTile(context, email)); _popupMenuEmailActionTile(context, email));
} }
}, },
optionsWidget: BuildUtils.isWeb && controller.emailSupervisorController.supportedPageView optionsWidget: BuildUtils.isWeb && controller.emailSupervisorController.supportedPageView.isTrue
? _buildNavigatorPageViewWidgets(context) ? _buildNavigatorPageViewWidgets(context)
: null, : null,
)); ));
} }
PresentationMailbox? _getMailboxContain(PresentationEmail currentEmail) {
return currentEmail.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById);
}
List<Widget> _buildNavigatorPageViewWidgets(BuildContext context) { List<Widget> _buildNavigatorPageViewWidgets(BuildContext context) {
return [ return [
buildIconWeb( buildIconWeb(
@@ -16,7 +16,7 @@ class AppBarMailWidgetBuilder extends StatelessWidget {
final PresentationEmail _presentationEmail; final PresentationEmail _presentationEmail;
final List<Widget>? optionsWidget; final List<Widget>? optionsWidget;
final PresentationMailbox? currentMailbox; final PresentationMailbox? mailboxContain;
final bool isSearchIsRunning; final bool isSearchIsRunning;
final OnBackActionClick? onBackActionClick; final OnBackActionClick? onBackActionClick;
final OnEmailActionClick? onEmailActionClick; final OnEmailActionClick? onEmailActionClick;
@@ -26,7 +26,7 @@ class AppBarMailWidgetBuilder extends StatelessWidget {
this._presentationEmail, this._presentationEmail,
{ {
Key? key, Key? key,
this.currentMailbox, this.mailboxContain,
this.onBackActionClick, this.onBackActionClick,
this.onEmailActionClick, this.onEmailActionClick,
this.onMoreActionClick, this.onMoreActionClick,
@@ -70,7 +70,7 @@ class AppBarMailWidgetBuilder extends StatelessWidget {
constraints: BoxConstraints( constraints: BoxConstraints(
maxWidth: _responsiveUtils.getSizeScreenWidth(context) - 250), maxWidth: _responsiveUtils.getSizeScreenWidth(context) - 250),
child: Text( child: Text(
currentMailbox?.name?.name.capitalizeFirstEach ?? '', mailboxContain?.name?.name.capitalizeFirstEach ?? '',
maxLines: 1, maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow, overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap, softWrap: CommonTextStyle.defaultSoftWrap,
@@ -134,17 +134,17 @@ class AppBarMailWidgetBuilder extends StatelessWidget {
buildIconWeb( buildIconWeb(
icon: SvgPicture.asset( icon: SvgPicture.asset(
_imagePaths.icDeleteComposer, _imagePaths.icDeleteComposer,
color: currentMailbox?.role != PresentationMailbox.roleTrash color: mailboxContain?.isTrash == false
? AppColor.colorTextButton ? AppColor.colorTextButton
: AppColor.colorDeletePermanentlyButton, : AppColor.colorDeletePermanentlyButton,
width: BuildUtils.isWeb ? 18 : 20, width: BuildUtils.isWeb ? 18 : 20,
height: BuildUtils.isWeb ? 18 : 20, height: BuildUtils.isWeb ? 18 : 20,
fit: BoxFit.fill), fit: BoxFit.fill),
tooltip: currentMailbox?.role != PresentationMailbox.roleTrash tooltip: mailboxContain?.isTrash == false
? AppLocalizations.of(context).move_to_trash ? AppLocalizations.of(context).move_to_trash
: AppLocalizations.of(context).delete_permanently, : AppLocalizations.of(context).delete_permanently,
onTap: () { onTap: () {
if (currentMailbox?.role != PresentationMailbox.roleTrash) { if (mailboxContain?.isTrash == false) {
onEmailActionClick?.call( onEmailActionClick?.call(
_presentationEmail, _presentationEmail,
EmailActionType.moveToTrash); EmailActionType.moveToTrash);
@@ -194,7 +194,7 @@ class LoginController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
pushAndPop( pushAndPop(
RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()),
arguments: session); arguments: session);
} }
@@ -177,8 +177,10 @@ class MailboxController extends BaseMailboxController {
} }
}, },
(success) async { (success) async {
if (success is GetAllMailboxSuccess || success is RefreshChangesAllMailboxSuccess) { if (success is GetAllMailboxSuccess) {
_initialMailboxVariableStorage(); _initialMailboxVariableStorage();
} else if (success is RefreshChangesAllMailboxSuccess) {
_initialMailboxVariableStorage(isRefreshChange: true);
} else if (success is CreateNewMailboxSuccess) { } else if (success is CreateNewMailboxSuccess) {
_createNewMailboxSuccess(success); _createNewMailboxSuccess(success);
} else if (success is SearchMailboxSuccess) { } else if (success is SearchMailboxSuccess) {
@@ -315,10 +317,10 @@ class MailboxController extends BaseMailboxController {
} }
} }
void _initialMailboxVariableStorage() { void _initialMailboxVariableStorage({bool isRefreshChange = false}) {
_setMapMailbox(); _setMapMailbox();
_setOutboxMailbox(); _setOutboxMailbox();
_selectMailboxDefault(); _selectMailboxDefault(isRefreshChange: isRefreshChange);
} }
void _setMapMailbox() { void _setMapMailbox() {
@@ -352,7 +354,7 @@ class MailboxController extends BaseMailboxController {
} }
} }
void _selectMailboxDefault() { void _selectMailboxDefault({bool isRefreshChange = false}) {
final mapDefaultMailbox = { final mapDefaultMailbox = {
for (var mailboxNode in defaultMailboxTree.value.root.childrenItems ?? List<MailboxNode>.empty()) for (var mailboxNode in defaultMailboxTree.value.root.childrenItems ?? List<MailboxNode>.empty())
mailboxNode.item.role!: mailboxNode.item mailboxNode.item.role!: mailboxNode.item
@@ -385,24 +387,29 @@ class MailboxController extends BaseMailboxController {
} }
} }
if (isHasDataFromRoute) { if (isRefreshChange) {
if (mailboxIdFromNavigationRouter != null) { mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_selectMailboxFromRouter(); } else {
} else if (emailIdFromNavigationRouter != null) { if (isHasDataFromRoute) {
mailboxDashBoardController.dispatchAction( log('MailboxController::_selectMailboxDefault(): isHasDataFromRoute is true:navigationRouter: $navigationRouter');
SelectEmailByIdAction( if (mailboxIdFromNavigationRouter != null) {
emailIdFromNavigationRouter!, _selectMailboxFromRouter();
mailboxIdFromNavigationRouter, } else if (emailIdFromNavigationRouter != null) {
navigationRouter!.dashboardType mailboxDashBoardController.dispatchAction(SelectEmailByIdAction(navigationRouter!));
) _clearNavigationRouter();
); } else if (searchQueryFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction(SearchEmailByQueryAction(navigationRouter!));
_clearNavigationRouter();
} else {
_clearNavigationRouter();
mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_updateSelectedMailboxRouteOnBrowser();
}
} else { } else {
log('MailboxController::_selectMailboxDefault(): isHasDataFromRoute is false');
mailboxDashBoardController.setSelectedMailbox(mailboxSelected); mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_updateSelectedMailboxRouteOnBrowser(); _updateSelectedMailboxRouteOnBrowser();
} }
} else {
mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_updateSelectedMailboxRouteOnBrowser();
} }
} }
@@ -414,6 +421,8 @@ class MailboxController extends BaseMailboxController {
EmailId? get emailIdFromNavigationRouter => navigationRouter?.emailId; EmailId? get emailIdFromNavigationRouter => navigationRouter?.emailId;
SearchQuery? get searchQueryFromNavigationRouter => navigationRouter?.searchQuery;
void _clearNavigationRouter() { void _clearNavigationRouter() {
mailboxDashBoardController.navigationRouter = null; mailboxDashBoardController.navigationRouter = null;
} }
@@ -423,13 +432,7 @@ class MailboxController extends BaseMailboxController {
if (matchedMailboxNode != null) { if (matchedMailboxNode != null) {
mailboxDashBoardController.setSelectedMailbox(matchedMailboxNode.item); mailboxDashBoardController.setSelectedMailbox(matchedMailboxNode.item);
if (emailIdFromNavigationRouter != null) { if (emailIdFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction( mailboxDashBoardController.dispatchAction(SelectEmailByIdAction(navigationRouter!));
SelectEmailByIdAction(
emailIdFromNavigationRouter!,
mailboxIdFromNavigationRouter,
navigationRouter!.dashboardType
)
);
} else { } else {
_updateSelectedMailboxRouteOnBrowser(); _updateSelectedMailboxRouteOnBrowser();
} }
@@ -443,6 +446,7 @@ class MailboxController extends BaseMailboxController {
BuildContext context, BuildContext context,
PresentationMailbox presentationMailboxSelected PresentationMailbox presentationMailboxSelected
) { ) {
log('MailboxController::_handleOpenMailbox(): ');
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
mailboxDashBoardController.clearSelectedEmail(); mailboxDashBoardController.clearSelectedEmail();
@@ -584,6 +588,7 @@ class MailboxController extends BaseMailboxController {
} }
void _searchMailboxAction(List<PresentationMailbox> allMailboxes, SearchQuery searchQuery) { void _searchMailboxAction(List<PresentationMailbox> allMailboxes, SearchQuery searchQuery) {
log('MailboxController::_searchMailboxAction():');
if (searchQuery.value.isNotEmpty) { if (searchQuery.value.isNotEmpty) {
consumeState(_searchMailboxInteractor.execute(allMailboxes, searchQuery)); consumeState(_searchMailboxInteractor.execute(allMailboxes, searchQuery));
} else { } else {
@@ -1112,7 +1117,12 @@ class MailboxController extends BaseMailboxController {
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( NavigationRouter(
mailboxId: selectedMailboxId, mailboxId: selectedMailboxId,
dashboardType: DashboardType.normal searchQuery: mailboxDashBoardController.searchController.isSearchEmailRunning
? mailboxDashBoardController.searchController.searchQuery
: null,
dashboardType: mailboxDashBoardController.searchController.isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
) )
); );
RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route); RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route);
@@ -1,7 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/email_action_type.dart'; import 'package:model/email/email_action_type.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';
@@ -116,12 +114,20 @@ class SelectMailboxDefaultAction extends DashBoardAction {
class SelectEmailByIdAction extends DashBoardAction { class SelectEmailByIdAction extends DashBoardAction {
final EmailId emailId; final NavigationRouter navigationRouter;
final MailboxId? mailboxId;
final DashboardType dashboardType;
SelectEmailByIdAction(this.emailId, this.mailboxId, this.dashboardType); SelectEmailByIdAction(this.navigationRouter);
@override @override
List<Object?> get props => [emailId, mailboxId, dashboardType]; List<Object?> get props => [navigationRouter];
}
class SearchEmailByQueryAction extends DashBoardAction {
final NavigationRouter navigationRouter;
SearchEmailByQueryAction(this.navigationRouter);
@override
List<Object?> get props => [navigationRouter];
} }
@@ -391,6 +391,7 @@ class MailboxDashBoardController extends ReloadableController {
} }
void setSelectedEmail(PresentationEmail? newPresentationEmail) { void setSelectedEmail(PresentationEmail? newPresentationEmail) {
log('MailboxDashBoardController::setSelectedEmail(): $newPresentationEmail');
selectedEmail.value = newPresentationEmail; selectedEmail.value = newPresentationEmail;
} }
@@ -440,6 +441,7 @@ class MailboxDashBoardController extends ReloadableController {
} }
void _closeEmailDetailedView() { void _closeEmailDetailedView() {
log('MailboxDashBoardController::_closeEmailDetailedView(): ');
dispatchRoute(DashboardRoutes.thread); dispatchRoute(DashboardRoutes.thread);
clearSelectedEmail(); clearSelectedEmail();
} }
@@ -1012,6 +1014,7 @@ class MailboxDashBoardController extends ReloadableController {
} }
void dispatchRoute(DashboardRoutes route) { void dispatchRoute(DashboardRoutes route) {
log('MailboxDashBoardController::dispatchRoute(): $route');
dashboardRoute.value = route; dashboardRoute.value = route;
if (dashboardRoute.value == DashboardRoutes.searchEmail) { if (dashboardRoute.value == DashboardRoutes.searchEmail) {
@@ -40,6 +40,7 @@ class SearchController extends BaseController {
final emailReceiveTimeType = Rxn<EmailReceiveTimeType>(); final emailReceiveTimeType = Rxn<EmailReceiveTimeType>();
final simpleSearchIsActivated = RxBool(false); final simpleSearchIsActivated = RxBool(false);
final advancedSearchIsActivated = RxBool(false); final advancedSearchIsActivated = RxBool(false);
final autoFocus = RxBool(true);
SearchQuery? get searchQuery => searchEmailFilter.value.text; SearchQuery? get searchQuery => searchEmailFilter.value.text;
@@ -55,7 +55,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
suggestionsBoxVerticalOffset: 0.0, suggestionsBoxVerticalOffset: 0.0,
textFieldConfiguration: QuickSearchTextFieldConfiguration( textFieldConfiguration: QuickSearchTextFieldConfiguration(
controller: controller.searchInputController, controller: controller.searchInputController,
autofocus: true, autofocus: controller.autoFocus.value,
enabled: controller.isAdvancedSearchViewOpen.isFalse, enabled: controller.isAdvancedSearchViewOpen.isFalse,
focusNode: controller.searchFocus, focusNode: controller.searchFocus,
textInputAction: TextInputAction.done, textInputAction: TextInputAction.done,
@@ -227,7 +227,7 @@ class ManageAccountDashBoardController extends ReloadableController {
} else { } else {
log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE'); log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE');
pushAndPopAll( pushAndPopAll(
RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()),
arguments: sessionCurrent); arguments: sessionCurrent);
} }
} }
@@ -584,6 +584,7 @@ class SearchEmailController extends BaseController
} }
void closeSearchView(BuildContext context) { void closeSearchView(BuildContext context) {
log('SearchEmailController::closeSearchView(): ');
clearAllTextInputSearchForm(); clearAllTextInputSearchForm();
clearAllResultSearch(); clearAllResultSearch();
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
@@ -623,17 +624,17 @@ class SearchEmailController extends BaseController
markAsStarEmail(selectedEmail, MarkStarAction.unMarkStar); markAsStarEmail(selectedEmail, MarkStarAction.unMarkStar);
break; break;
case EmailActionType.moveToMailbox: case EmailActionType.moveToMailbox:
moveToMailbox(context, selectedEmail); moveToMailbox(context, selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.moveToTrash: case EmailActionType.moveToTrash:
moveToTrash(selectedEmail); moveToTrash(selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.deletePermanently: case EmailActionType.deletePermanently:
deleteEmailPermanently(context, selectedEmail); deleteEmailPermanently(context, selectedEmail);
break; break;
case EmailActionType.moveToSpam: case EmailActionType.moveToSpam:
popBack(); popBack();
moveToSpam(selectedEmail); moveToSpam(selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.unSpam: case EmailActionType.unSpam:
popBack(); popBack();
@@ -735,6 +736,7 @@ class SearchEmailController extends BaseController
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( NavigationRouter(
emailId: currentEmail.id, emailId: currentEmail.id,
searchQuery: searchQuery,
dashboardType: DashboardType.search dashboardType: DashboardType.search
) )
); );
@@ -58,7 +58,7 @@ class SessionController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
pushAndPop( pushAndPop(
RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()),
arguments: session); arguments: session);
} }
@@ -108,7 +108,7 @@ class SessionController extends ReloadableController {
if (apiUrl.isNotEmpty) { if (apiUrl.isNotEmpty) {
_dynamicUrlInterceptors.changeBaseUrl(apiUrl); _dynamicUrlInterceptors.changeBaseUrl(apiUrl);
pushAndPop( pushAndPop(
RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()),
arguments: success.session); arguments: success.session);
} else { } else {
_goToLogin(); _goToLogin();
@@ -1,20 +1,16 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
class GetEmailByIdLoading extends LoadingState {} class GetEmailByIdLoading extends LoadingState {}
class GetEmailByIdSuccess extends UIState { class GetEmailByIdSuccess extends UIState {
final PresentationEmail email; final PresentationEmail email;
final MailboxId? mailboxId;
final DashboardType dashboardType;
GetEmailByIdSuccess(this.email, this.mailboxId, this.dashboardType); GetEmailByIdSuccess(this.email);
@override @override
List<Object?> get props => [email, mailboxId, dashboardType]; List<Object?> get props => [email];
} }
class GetEmailByIdFailure extends FeatureFailure { class GetEmailByIdFailure extends FeatureFailure {
@@ -4,10 +4,8 @@ import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart'; import 'package:jmap_dart_client/jmap/core/properties/properties.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: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_email_by_id_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/get_email_by_id_state.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
class GetEmailByIdInteractor { class GetEmailByIdInteractor {
final ThreadRepository _threadRepository; final ThreadRepository _threadRepository;
@@ -18,15 +16,13 @@ class GetEmailByIdInteractor {
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
{ {
MailboxId? mailboxId,
DashboardType dashboardType = DashboardType.normal,
Properties? properties, Properties? properties,
} }
) async* { ) async* {
try { try {
yield Right<Failure, Success>(GetEmailByIdLoading()); yield Right<Failure, Success>(GetEmailByIdLoading());
final email = await _threadRepository.getEmailById(accountId, emailId, properties: properties); final email = await _threadRepository.getEmailById(accountId, emailId, properties: properties);
yield Right<Failure, Success>(GetEmailByIdSuccess(email, mailboxId, dashboardType)); yield Right<Failure, Success>(GetEmailByIdSuccess(email));
} catch (e) { } catch (e) {
yield Left<Failure, Success>(GetEmailByIdFailure(e)); yield Left<Failure, Success>(GetEmailByIdFailure(e));
} }
@@ -4,6 +4,7 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart'; import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart'; import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart'; import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@@ -46,6 +47,7 @@ mixin EmailActionController on ViewAsDialogActionMixin {
} }
void previewEmail(BuildContext context, PresentationEmail presentationEmail) { void previewEmail(BuildContext context, PresentationEmail presentationEmail) {
log('EmailActionController::previewEmail():presentationEmailId: ${presentationEmail.id}');
mailboxDashBoardController.setSelectedEmail(presentationEmail); mailboxDashBoardController.setSelectedEmail(presentationEmail);
mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed); mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed);
if (BuildUtils.isWeb && presentationEmail.routeWeb != null) { if (BuildUtils.isWeb && presentationEmail.routeWeb != null) {
@@ -55,14 +57,13 @@ mixin EmailActionController on ViewAsDialogActionMixin {
} }
} }
void moveToTrash(PresentationEmail email) async { void moveToTrash(PresentationEmail email, {PresentationMailbox? mailboxContain}) async {
final currentMailbox = mailboxDashBoardController.selectedMailbox.value;
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
final trashMailboxId = mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash]; final trashMailboxId = mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash];
if (currentMailbox != null && accountId != null && trashMailboxId != null) { if (mailboxContain != null && accountId != null && trashMailboxId != null) {
_moveToTrashAction(accountId, MoveToMailboxRequest( _moveToTrashAction(accountId, MoveToMailboxRequest(
{currentMailbox.id: [email.id]}, {mailboxContain.id: [email.id]},
trashMailboxId, trashMailboxId,
MoveAction.moving, MoveAction.moving,
mailboxDashBoardController.sessionCurrent!, mailboxDashBoardController.sessionCurrent!,
@@ -75,14 +76,13 @@ mixin EmailActionController on ViewAsDialogActionMixin {
mailboxDashBoardController.moveToMailbox(accountId, moveRequest); mailboxDashBoardController.moveToMailbox(accountId, moveRequest);
} }
void moveToSpam(PresentationEmail email) async { void moveToSpam(PresentationEmail email, {PresentationMailbox? mailboxContain}) async {
final currentMailbox = mailboxDashBoardController.selectedMailbox.value;
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam); final spamMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleSpam);
if (currentMailbox != null && accountId != null && spamMailboxId != null) { if (mailboxContain != null && accountId != null && spamMailboxId != null) {
moveToSpamAction(accountId, MoveToMailboxRequest( moveToSpamAction(accountId, MoveToMailboxRequest(
{currentMailbox.id: [email.id]}, {mailboxContain.id: [email.id]},
spamMailboxId, spamMailboxId,
MoveAction.moving, MoveAction.moving,
mailboxDashBoardController.sessionCurrent!, mailboxDashBoardController.sessionCurrent!,
@@ -111,11 +111,14 @@ mixin EmailActionController on ViewAsDialogActionMixin {
mailboxDashBoardController.moveToMailbox(accountId, moveRequest); mailboxDashBoardController.moveToMailbox(accountId, moveRequest);
} }
void moveToMailbox(BuildContext context, PresentationEmail email) async { void moveToMailbox(
final currentMailbox = mailboxDashBoardController.selectedMailbox.value; BuildContext context,
PresentationEmail email,
{PresentationMailbox? mailboxContain}
) async {
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
if (currentMailbox != null && accountId != null) { if (mailboxContain != null && accountId != null) {
final arguments = DestinationPickerArguments(accountId, MailboxActions.moveEmail); final arguments = DestinationPickerArguments(accountId, MailboxActions.moveEmail);
if (BuildUtils.isWeb) { if (BuildUtils.isWeb) {
@@ -129,7 +132,7 @@ mixin EmailActionController on ViewAsDialogActionMixin {
accountId, accountId,
mailboxDashBoardController.sessionCurrent!, mailboxDashBoardController.sessionCurrent!,
email, email,
currentMailbox, mailboxContain,
destinationMailbox); destinationMailbox);
} }
}); });
@@ -146,7 +149,7 @@ mixin EmailActionController on ViewAsDialogActionMixin {
accountId, accountId,
mailboxDashBoardController.sessionCurrent!, mailboxDashBoardController.sessionCurrent!,
email, email,
currentMailbox, mailboxContain,
destinationMailbox); destinationMailbox);
} }
} }
@@ -90,9 +90,9 @@ class ThreadController extends BaseController with EmailActionController {
bool canLoadMore = true; bool canLoadMore = true;
bool canSearchMore = true; bool canSearchMore = true;
bool _isLoadingMore = false; bool _isLoadingMore = false;
get isLoadingMore => _isLoadingMore;
MailboxId? _currentMailboxId; MailboxId? _currentMailboxId;
jmap.State? _currentEmailState; jmap.State? _currentEmailState;
NavigationRouter? _navigationRouter;
final ScrollController listEmailController = ScrollController(); final ScrollController listEmailController = ScrollController();
final FocusNode focusNodeKeyBoard = FocusNode(); final FocusNode focusNodeKeyBoard = FocusNode();
final latestEmailSelectedOrUnselected = Rxn<PresentationEmail>(); final latestEmailSelectedOrUnselected = Rxn<PresentationEmail>();
@@ -102,6 +102,8 @@ class ThreadController extends BaseController with EmailActionController {
..add(EmailComparator(EmailComparatorProperty.receivedAt) ..add(EmailComparator(EmailComparatorProperty.receivedAt)
..setIsAscending(false)); ..setIsAscending(false));
bool get isLoadingMore => _isLoadingMore;
AccountId? get _accountId => mailboxDashBoardController.accountId.value; AccountId? get _accountId => mailboxDashBoardController.accountId.value;
PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value; PresentationMailbox? get currentMailbox => mailboxDashBoardController.selectedMailbox.value;
@@ -157,6 +159,7 @@ class ThreadController extends BaseController with EmailActionController {
_isLoadingMore = false; _isLoadingMore = false;
} else if (failure is GetEmailByIdFailure) { } else if (failure is GetEmailByIdFailure) {
openingEmail.value = false; openingEmail.value = false;
_navigationRouter = null;
} }
}, },
(success) { (success) {
@@ -176,7 +179,7 @@ class ThreadController extends BaseController with EmailActionController {
openingEmail.value = true; openingEmail.value = true;
} else if (success is GetEmailByIdSuccess) { } else if (success is GetEmailByIdSuccess) {
openingEmail.value = false; openingEmail.value = false;
_openEmailDetailView(success.email, success.mailboxId, success.dashboardType); _openEmailDetailView(success.email);
} }
} }
); );
@@ -246,13 +249,22 @@ class ThreadController extends BaseController with EmailActionController {
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is StartSearchEmailAction) { } else if (action is StartSearchEmailAction) {
cancelSelectEmail(); cancelSelectEmail();
_updateSearchRouteOnBrowser();
_searchEmail(); _searchEmail();
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is EmptyTrashAction) { } else if (action is EmptyTrashAction) {
deleteSelectionEmailsPermanently(action.context, DeleteActionType.all); deleteSelectionEmailsPermanently(action.context, DeleteActionType.all);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is SelectEmailByIdAction) { } else if (action is SelectEmailByIdAction) {
_getEmailByIdAction(action.emailId, action.mailboxId, action.dashboardType); _navigationRouter = action.navigationRouter;
if (_navigationRouter!.searchQuery != null) {
_activateSearchFromRouter();
}
_getEmailByIdAction(_navigationRouter!.emailId!);
mailboxDashBoardController.clearDashBoardAction();
} else if (action is SearchEmailByQueryAction) {
_navigationRouter = action.navigationRouter;
_activateSearchFromRouter();
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} }
}); });
@@ -312,6 +324,18 @@ class ThreadController extends BaseController with EmailActionController {
viewStateWorker.dispose(); viewStateWorker.dispose();
} }
void _activateSearchFromRouter() {
searchController.autoFocus.value = false;
searchController.enableSearch();
searchController.updateTextSearch(_navigationRouter!.searchQuery!.value);
searchController.updateFilterEmail(text: _navigationRouter!.searchQuery!);
if (currentContext != null) {
FocusScope.of(currentContext!).unfocus();
}
searchController.searchFocus.unfocus();
_searchEmail();
}
void _handleErrorGetAllOrRefreshChangesEmail(dynamic error) async { void _handleErrorGetAllOrRefreshChangesEmail(dynamic error) async {
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error'); logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
if (error is CannotCalculateChangesMethodResponseException) { if (error is CannotCalculateChangesMethodResponseException) {
@@ -334,7 +358,6 @@ class ThreadController extends BaseController with EmailActionController {
canLoadMore = true; canLoadMore = true;
_isLoadingMore = false; _isLoadingMore = false;
cancelSelectEmail(); cancelSelectEmail();
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
} }
void _getAllEmailSuccess(GetAllEmailSuccess success) { void _getAllEmailSuccess(GetAllEmailSuccess success) {
@@ -613,6 +636,18 @@ class ThreadController extends BaseController with EmailActionController {
} }
} }
void _updateSearchRouteOnBrowser() {
if (BuildUtils.isWeb) {
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
searchQuery: searchQuery,
dashboardType: DashboardType.search)
);
RouteUtils.updateRouteOnBrowser('SearchEmail', route);
}
}
void _searchEmailsSuccess(SearchEmailSuccess success) { void _searchEmailsSuccess(SearchEmailSuccess success) {
final resultEmailSearchList = success.emailList final resultEmailSearchList = success.emailList
.map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById)) .map((email) => email.toSearchPresentationEmail(mailboxDashBoardController.mapMailboxById))
@@ -622,6 +657,7 @@ class ThreadController extends BaseController with EmailActionController {
final emailsSearchAfterChanges = resultEmailSearchList; final emailsSearchAfterChanges = resultEmailSearchList;
final newListEmailSearch = emailsSearchAfterChanges.combine(emailsSearchBeforeChanges); final newListEmailSearch = emailsSearchAfterChanges.combine(emailsSearchBeforeChanges);
emailList.value = newListEmailSearch; emailList.value = newListEmailSearch;
searchController.autoFocus.value = true;
} }
void searchMoreEmails() { void searchMoreEmails() {
@@ -750,17 +786,17 @@ class ThreadController extends BaseController with EmailActionController {
markAsStarEmail(selectedEmail, MarkStarAction.unMarkStar); markAsStarEmail(selectedEmail, MarkStarAction.unMarkStar);
break; break;
case EmailActionType.moveToMailbox: case EmailActionType.moveToMailbox:
moveToMailbox(context, selectedEmail); moveToMailbox(context, selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.moveToTrash: case EmailActionType.moveToTrash:
moveToTrash(selectedEmail); moveToTrash(selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.deletePermanently: case EmailActionType.deletePermanently:
deleteEmailPermanently(context, selectedEmail); deleteEmailPermanently(context, selectedEmail);
break; break;
case EmailActionType.moveToSpam: case EmailActionType.moveToSpam:
popBack(); popBack();
moveToSpam(selectedEmail); moveToSpam(selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.unSpam: case EmailActionType.unSpam:
popBack(); popBack();
@@ -815,6 +851,9 @@ class ThreadController extends BaseController with EmailActionController {
NavigationRouter( NavigationRouter(
emailId: currentEmail.id, emailId: currentEmail.id,
mailboxId: currentMailbox?.id, mailboxId: currentMailbox?.id,
searchQuery: searchController.isSearchEmailRunning
? searchQuery
: null,
dashboardType: searchController.isSearchEmailRunning dashboardType: searchController.isSearchEmailRunning
? DashboardType.search ? DashboardType.search
: DashboardType.normal : DashboardType.normal
@@ -827,30 +866,29 @@ class ThreadController extends BaseController with EmailActionController {
} }
} }
void _getEmailByIdAction(EmailId emailId, MailboxId? mailboxId, DashboardType dashboardType) { PresentationMailbox? getMailboxContain(PresentationEmail currentEmail) {
return currentEmail.findMailboxContain(mailboxDashBoardController.mapMailboxById);
}
void _getEmailByIdAction(EmailId emailId) {
if (_accountId != null) { if (_accountId != null) {
consumeState(_getEmailByIdInteractor.execute( consumeState(_getEmailByIdInteractor.execute(
_accountId!, _accountId!,
emailId, emailId,
mailboxId: mailboxId,
dashboardType: dashboardType,
properties: ThreadConstants.propertiesDefault)); properties: ThreadConstants.propertiesDefault));
} }
} }
void _openEmailDetailView( void _openEmailDetailView(PresentationEmail email) {
PresentationEmail email,
MailboxId? mailboxId,
DashboardType dashboardType
) {
if (currentContext != null) { if (currentContext != null) {
final mailboxContain = email.findMailboxContain(mailboxDashBoardController.mapMailboxById); final mailboxContain = email.findMailboxContain(mailboxDashBoardController.mapMailboxById);
final route = RouteUtils.generateRouteBrowser( final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( NavigationRouter(
emailId: email.id, emailId: email.id,
mailboxId: mailboxId, mailboxId: _navigationRouter?.mailboxId,
dashboardType: dashboardType searchQuery: _navigationRouter?.searchQuery,
dashboardType: _navigationRouter?.dashboardType ?? DashboardType.normal
) )
); );
pressEmailAction( pressEmailAction(
@@ -860,5 +898,6 @@ class ThreadController extends BaseController with EmailActionController {
mailboxContain: mailboxContain mailboxContain: mailboxContain
); );
} }
_navigationRouter = null;
} }
} }
@@ -335,7 +335,7 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
itemExtent: _getItemExtent(context), itemExtent: _getItemExtent(context),
itemCount: listPresentationEmail.length, itemCount: listPresentationEmail.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final mailboxContain = _getMailboxContain(listPresentationEmail[index]); final mailboxContain = controller.getMailboxContain(listPresentationEmail[index]);
final newPresentationEmail = controller.generateEmailByPlatform(listPresentationEmail[index]); final newPresentationEmail = controller.generateEmailByPlatform(listPresentationEmail[index]);
return Obx(() => Draggable<List<PresentationEmail>>( return Obx(() => Draggable<List<PresentationEmail>>(
maxSimultaneousDrags: kIsWeb ? null : 0, maxSimultaneousDrags: kIsWeb ? null : 0,
@@ -375,12 +375,6 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
); );
} }
PresentationMailbox? _getMailboxContain(PresentationEmail currentEmail) {
return controller.searchController.isSearchEmailRunning
? currentEmail.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById)
: controller.currentMailbox;
}
Widget _buildFeedBackWidget(BuildContext context) { Widget _buildFeedBackWidget(BuildContext context) {
return SizedBox( return SizedBox(
height: 60, height: 60,
@@ -508,7 +502,7 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
} }
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
final mailboxContain = _getMailboxContain(email); final mailboxContain = controller.getMailboxContain(email);
return (EmailActionCupertinoActionSheetActionBuilder( return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_spam_or_un_spam_action'), const Key('mark_as_spam_or_un_spam_action'),
SvgPicture.asset( SvgPicture.asset(
@@ -421,7 +421,7 @@ class EmailTileBuilder with BaseEmailItemTile {
: EmailActionType.markAsRead, : EmailActionType.markAsRead,
_presentationEmail)), _presentationEmail)),
const SizedBox(width: 5), const SizedBox(width: 5),
if (mailboxContain?.isDrafts == false) if (mailboxContain != null && mailboxContain?.isDrafts == false)
... [ ... [
buildIconWeb( buildIconWeb(
minSize: 18, minSize: 18,
+4 -1
View File
@@ -2,6 +2,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.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:tmail_ui_user/features/thread/domain/model/search_query.dart';
enum DashboardType { enum DashboardType {
normal, normal,
@@ -12,13 +13,15 @@ class NavigationRouter with EquatableMixin {
final EmailId? emailId; final EmailId? emailId;
final MailboxId? mailboxId; final MailboxId? mailboxId;
final DashboardType dashboardType; final DashboardType dashboardType;
final SearchQuery? searchQuery;
NavigationRouter({ NavigationRouter({
this.emailId, this.emailId,
this.mailboxId, this.mailboxId,
this.searchQuery,
this.dashboardType = DashboardType.normal this.dashboardType = DashboardType.normal
}); });
@override @override
List<Object?> get props => [emailId, mailboxId, dashboardType]; List<Object?> get props => [emailId, mailboxId, searchQuery, dashboardType];
} }
+22 -10
View File
@@ -1,4 +1,5 @@
import 'package:core/core.dart';
import 'package:core/data/model/query/query_parameter.dart'; import 'package:core/data/model/query/query_parameter.dart';
import 'package:core/data/network/config/service_path.dart'; import 'package:core/data/network/config/service_path.dart';
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
@@ -6,6 +7,7 @@ import 'package:jmap_dart_client/jmap/core/id.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:tmail_ui_user/features/login/data/extensions/service_path_extension.dart'; import 'package:tmail_ui_user/features/login/data/extensions/service_path_extension.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart'; import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:universal_html/html.dart' as html; import 'package:universal_html/html.dart' as html;
@@ -15,18 +17,23 @@ abstract class RouteUtils {
static String get baseUrl => Uri.base.path; static String get baseUrl => Uri.base.path;
static String generateRouteMobile(String route, NavigationRouter router) { static String generateNavigationRoute(String route, NavigationRouter router) {
ServicePath servicePath = ServicePath(route); ServicePath servicePath = ServicePath(route);
if (router.emailId != null) { if (BuildUtils.isWeb) {
servicePath = servicePath.withPathParameter(router.emailId!.id.value); if (router.emailId != null) {
servicePath = servicePath.withPathParameter(router.emailId!.id.value);
}
servicePath = servicePath.withQueryParameters([
StringQueryParameter('type', router.dashboardType.name),
if (router.mailboxId != null)
StringQueryParameter('context', router.mailboxId!.id.value),
if (router.searchQuery != null)
StringQueryParameter('q', router.searchQuery!.value),
]);
return servicePath.path;
} else {
return servicePath.path;
} }
servicePath = servicePath.withQueryParameters([
StringQueryParameter('type', router.dashboardType.name),
if (router.mailboxId != null)
StringQueryParameter('context', router.mailboxId!.id.value),
]);
return servicePath.path;
} }
static Uri generateRouteBrowser(String route, NavigationRouter router) { static Uri generateRouteBrowser(String route, NavigationRouter router) {
@@ -39,6 +46,8 @@ abstract class RouteUtils {
StringQueryParameter('type', router.dashboardType.name), StringQueryParameter('type', router.dashboardType.name),
if (router.mailboxId != null) if (router.mailboxId != null)
StringQueryParameter('context', router.mailboxId!.id.value), StringQueryParameter('context', router.mailboxId!.id.value),
if (router.searchQuery != null)
StringQueryParameter('q', router.searchQuery!.value),
]); ]);
return Uri.parse(servicePath.path); return Uri.parse(servicePath.path);
@@ -48,9 +57,11 @@ abstract class RouteUtils {
final idParam = parameters['id']; final idParam = parameters['id'];
final typeParam = parameters['type']; final typeParam = parameters['type'];
final contextPram = parameters['context']; final contextPram = parameters['context'];
final queryParam = parameters['q'];
final emailId = idParam != null ? EmailId(Id(idParam)) : null; final emailId = idParam != null ? EmailId(Id(idParam)) : null;
final mailboxId = contextPram != null ? MailboxId(Id(contextPram)) : null; final mailboxId = contextPram != null ? MailboxId(Id(contextPram)) : null;
final searchQuery = queryParam != null ? SearchQuery(queryParam) : null;
final dashboardType = typeParam == DashboardType.search.name final dashboardType = typeParam == DashboardType.search.name
? DashboardType.search ? DashboardType.search
: DashboardType.normal; : DashboardType.normal;
@@ -58,6 +69,7 @@ abstract class RouteUtils {
return NavigationRouter( return NavigationRouter(
emailId: emailId, emailId: emailId,
mailboxId: mailboxId, mailboxId: mailboxId,
searchQuery: searchQuery,
dashboardType: dashboardType, dashboardType: dashboardType,
); );
} }
@@ -5,6 +5,7 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.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/email_action_type.dart'; import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
@@ -192,4 +193,26 @@ extension PresentationEmailExtension on PresentationEmail {
routeWeb: routeWeb routeWeb: routeWeb
); );
} }
PresentationEmail updateKeywords(Map<KeyWordIdentifier, bool>? newKeywords) {
return PresentationEmail(
this.id,
keywords: newKeywords,
size: size,
receivedAt: receivedAt,
hasAttachment: hasAttachment,
preview: preview,
subject: subject,
sentAt: sentAt,
from: from,
to: to,
cc: cc,
bcc: bcc,
replyTo: replyTo,
mailboxIds: mailboxIds,
mailboxNames: mailboxNames,
selectMode: selectMode,
routeWeb: routeWeb
);
}
} }