TF-1831 Handle system back button in search email

Signed-off-by: dab246 <tdvu@linagora.com>

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit f4ffd113f192415c8613bf12fe40db1af902edaf)
This commit is contained in:
dab246
2023-12-09 15:59:20 +07:00
committed by Dat H. Pham
parent 535ac67971
commit bb98f02918
20 changed files with 492 additions and 250 deletions
@@ -23,3 +23,5 @@ class RefreshChangeEmailAction extends EmailUIAction {
class CloseEmailDetailedViewToRedirectToTheInboxAction extends EmailUIAction {} class CloseEmailDetailedViewToRedirectToTheInboxAction extends EmailUIAction {}
class CloseEmailDetailedViewAction extends EmailUIAction {} class CloseEmailDetailedViewAction extends EmailUIAction {}
class CloseSearchEmailViewAction extends EmailUIAction {}
@@ -234,8 +234,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.clearSelectedEmail(); mailboxDashBoardController.clearSelectedEmail();
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
mailboxDashBoardController.clearEmailUIAction(); mailboxDashBoardController.clearEmailUIAction();
} else if (action is CloseEmailDetailedViewAction && currentContext != null) { } else if (action is CloseEmailDetailedViewAction) {
closeEmailView(currentContext!); closeEmailView(context: currentContext);
mailboxDashBoardController.clearEmailUIAction(); mailboxDashBoardController.clearEmailUIAction();
} }
}); });
@@ -575,17 +575,15 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.dispatchState(Right(success)); mailboxDashBoardController.dispatchState(Right(success));
if (success is MarkAsEmailReadSuccess if (success is MarkAsEmailReadSuccess
&& success.readActions == ReadActions.markAsUnread && success.readActions == ReadActions.markAsUnread) {
&& currentContext != null) { closeEmailView(context: currentContext);
closeEmailView(currentContext!);
} }
} }
void _markAsEmailReadFailure(Failure failure) { void _markAsEmailReadFailure(Failure failure) {
if (failure is MarkAsEmailReadFailure if (failure is MarkAsEmailReadFailure
&& failure.readActions == ReadActions.markAsUnread && failure.readActions == ReadActions.markAsUnread) {
&& currentContext != null) { closeEmailView(context: currentContext);
closeEmailView(currentContext!);
} }
} }
@@ -844,7 +842,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _moveToMailbox(BuildContext context, Session session, AccountId accountId, MoveToMailboxRequest moveRequest) { void _moveToMailbox(BuildContext context, Session session, AccountId accountId, MoveToMailboxRequest moveRequest) {
closeEmailView(context); closeEmailView(context: context);
consumeState(_moveToMailboxInteractor.execute(session, accountId, moveRequest)); consumeState(_moveToMailboxInteractor.execute(session, accountId, moveRequest));
} }
@@ -905,7 +903,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
AccountId accountId, AccountId accountId,
MoveToMailboxRequest moveRequest MoveToMailboxRequest moveRequest
) { ) {
closeEmailView(context); closeEmailView(context: context);
mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest); mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest);
} }
@@ -955,7 +953,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
AccountId accountId, AccountId accountId,
MoveToMailboxRequest moveRequest MoveToMailboxRequest moveRequest
) { ) {
closeEmailView(context); closeEmailView(context: context);
mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest); mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest);
} }
@@ -1082,7 +1080,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void _deleteEmailPermanentlyAction(BuildContext context, PresentationEmail email) { void _deleteEmailPermanentlyAction(BuildContext context, PresentationEmail email) {
popBack(); popBack();
closeEmailView(context); closeEmailView(context: context);
mailboxDashBoardController.deleteEmailPermanently(email); mailboxDashBoardController.deleteEmailPermanently(email);
} }
@@ -1167,7 +1165,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void closeEmailView(BuildContext context) { void closeEmailView({BuildContext? context}) {
if (emailSupervisorController.supportedPageView.isTrue) { if (emailSupervisorController.supportedPageView.isTrue) {
emailSupervisorController.popEmailQueue(_currentEmailId); emailSupervisorController.popEmailQueue(_currentEmailId);
emailSupervisorController.setCurrentEmailIndex(-1); emailSupervisorController.setCurrentEmailIndex(-1);
@@ -1176,9 +1174,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.clearSelectedEmail(); mailboxDashBoardController.clearSelectedEmail();
_updateCurrentEmailId(null); _updateCurrentEmailId(null);
_resetToOriginalValue(); _resetToOriginalValue();
_updateRouteOnBrowser(); _replaceBrowserHistory();
if (mailboxDashBoardController.searchController.isSearchEmailRunning) { if (mailboxDashBoardController.searchController.isSearchEmailRunning) {
if (responsiveUtils.isWebDesktop(context)) { if (context != null && responsiveUtils.isWebDesktop(context)) {
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
} else { } else {
mailboxDashBoardController.dispatchRoute(DashboardRoutes.searchEmail); mailboxDashBoardController.dispatchRoute(DashboardRoutes.searchEmail);
@@ -1194,20 +1192,29 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
bool get isOpenEmailNotMailboxFromRoute => emailSupervisorController.supportedPageView.isFalse bool get isOpenEmailNotMailboxFromRoute => emailSupervisorController.supportedPageView.isFalse
&& mailboxDashBoardController.selectedMailbox.value == null; && mailboxDashBoardController.selectedMailbox.value == null;
void _updateRouteOnBrowser() { void _replaceBrowserHistory() {
log('SingleEmailController::_updateRouteOnBrowser(): isSearchEmailRunning: ${mailboxDashBoardController.searchController.isSearchEmailRunning}');
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
final selectedMailboxId = mailboxDashBoardController.selectedMailbox.value?.id; final selectedMailboxId = mailboxDashBoardController.selectedMailbox.value?.id;
final route = RouteUtils.generateRouteBrowser( final isSearchRunning = mailboxDashBoardController.searchController.isSearchEmailRunning;
AppRoutes.dashboard, RouteUtils.replaceBrowserHistory(
NavigationRouter( title: isSearchRunning
mailboxId: selectedMailboxId, ? 'SearchEmail'
dashboardType: mailboxDashBoardController.searchController.isSearchEmailRunning : 'Mailbox-${selectedMailboxId?.id.value}',
? DashboardType.search url: RouteUtils.createUrlWebLocationBar(
: DashboardType.normal AppRoutes.dashboard,
router: NavigationRouter(
mailboxId: isSearchRunning
? null
: selectedMailboxId,
dashboardType: isSearchRunning
? DashboardType.search
: DashboardType.normal,
searchQuery: isSearchRunning
? mailboxDashBoardController.searchController.searchQuery
: null
)
) )
); );
RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route);
} }
} }
@@ -1311,13 +1318,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
Future<bool> backButtonPressedCallbackAction(BuildContext context) async {
if (PlatformInfo.isMobile) {
closeEmailView(context);
}
return false;
}
void _storeOpenedEmailAction(Session? session, AccountId? accountId, DetailedEmail detailedEmail) async { void _storeOpenedEmailAction(Session? session, AccountId? accountId, DetailedEmail detailedEmail) async {
if (session != null && accountId != null) { if (session != null && accountId != null) {
consumeState(_storeOpenedEmailInteractor.execute(session, accountId, detailedEmail)); consumeState(_storeOpenedEmailInteractor.execute(session, accountId, detailedEmail));
@@ -62,7 +62,7 @@ class EmailView extends GetWidget<SingleEmailController> {
presentationEmail: controller.currentEmail!, presentationEmail: controller.currentEmail!,
mailboxContain: _getMailboxContain(controller.currentEmail!), mailboxContain: _getMailboxContain(controller.currentEmail!),
isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackAction: () => controller.closeEmailView(context), onBackAction: () => controller.closeEmailView(context: context),
onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action),
onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position) onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position)
), ),
@@ -96,7 +96,7 @@ class EmailView extends GetWidget<SingleEmailController> {
presentationEmail: currentEmail, presentationEmail: currentEmail,
mailboxContain: _getMailboxContain(currentEmail), mailboxContain: _getMailboxContain(currentEmail),
isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackAction: () => controller.closeEmailView(context), onBackAction: () => controller.closeEmailView(context: context),
onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action),
onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position), onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position),
optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue
@@ -20,7 +20,6 @@ import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_lo
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_username_interactor.dart'; import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_login_username_interactor.dart';
import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_search_cache_interactor.dart'; import 'package:tmail_ui_user/features/cleanup/domain/usecases/cleanup_recent_search_cache_interactor.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
@@ -60,10 +59,7 @@ class HomeController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
popAndPush( popAndPush(
RouteUtils.generateNavigationRoute( RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
AppRoutes.dashboard,
NavigationRouter()
),
arguments: session arguments: session
); );
} }
@@ -49,7 +49,6 @@ import 'package:tmail_ui_user/features/login/domain/usecases/save_login_username
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart'; import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/model/login_arguments.dart'; import 'package:tmail_ui_user/features/login/presentation/model/login_arguments.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart';
@@ -195,7 +194,7 @@ class LoginController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
popAndPush( popAndPush(
RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
arguments: session arguments: session
); );
} }
@@ -1,7 +1,7 @@
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
class MailboxUIAction extends UIAction { class MailboxUIAction extends UIAction {
static final idle = MailboxUIAction(); static final idle = MailboxUIAction();
@@ -32,3 +32,5 @@ class OpenMailboxAction extends MailboxUIAction {
@override @override
List<Object?> get props => [presentationMailbox]; List<Object?> get props => [presentationMailbox];
} }
class SystemBackToInboxAction extends MailboxUIAction {}
@@ -84,5 +84,8 @@ extension PresentationMailboxExtension on PresentationMailbox {
} }
} }
Uri get mailboxRouteWeb => RouteUtils.generateRouteBrowser(AppRoutes.dashboard, NavigationRouter(mailboxId: id)); Uri get mailboxRouteWeb => RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(mailboxId: id)
);
} }
@@ -102,6 +102,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
final _activeScrollBottom = RxBool(true); final _activeScrollBottom = RxBool(true);
MailboxId? _newFolderId; MailboxId? _newFolderId;
NavigationRouter? _navigationRouter;
final _openMailboxEventController = StreamController<OpenMailboxViewEvent>(); final _openMailboxEventController = StreamController<OpenMailboxViewEvent>();
final mailboxListScrollController = ScrollController(); final mailboxListScrollController = ScrollController();
@@ -291,6 +292,10 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
} }
} }
mailboxDashBoardController.clearMailboxUIAction(); mailboxDashBoardController.clearMailboxUIAction();
} else if (action is SystemBackToInboxAction) {
_disableAllSearchEmail();
_switchBackToMailboxDefault();
mailboxDashBoardController.clearMailboxUIAction();
} }
}); });
} }
@@ -418,68 +423,122 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
} }
void _handleDataFromNavigationRouter() { void _handleDataFromNavigationRouter() {
log('MailboxController::_handleDataFromNavigationRouter():navigationRouter: $navigationRouter'); log('MailboxController::_handleDataFromNavigationRouter():navigationRouter: $_navigationRouter');
if (!PlatformInfo.isWeb || _navigationRouter == null) {
if (isHasDataFromRoute) {
if (isRedirectToMailtoURL) {
mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri(
emailAddress: navigationRouter?.emailAddress,
subject: navigationRouter?.subject,
body: navigationRouter?.body
)
);
}
if (mailboxIdFromNavigationRouter != null) {
_selectMailboxFromRouter();
} else if (emailIdFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction(SelectEmailByIdAction(navigationRouter!));
_clearNavigationRouter();
} else if (searchQueryFromNavigationRouter != null && searchQueryFromNavigationRouter?.value.isNotEmpty == true) {
mailboxDashBoardController.dispatchAction(SearchEmailByQueryAction(navigationRouter!));
_clearNavigationRouter();
} else {
_clearNavigationRouter();
_selectSelectedMailboxDefault();
_updateSelectedMailboxRouteOnBrowser();
}
} else {
_selectSelectedMailboxDefault(); _selectSelectedMailboxDefault();
_updateSelectedMailboxRouteOnBrowser(); _replaceBrowserHistory();
return;
}
if (_navigationRouter?.routeName == AppRoutes.mailtoURL) {
mailboxDashBoardController.goToComposer(
ComposerArguments.fromMailtoUri(
emailAddress: _navigationRouter?.emailAddress,
subject: _navigationRouter?.subject,
body: _navigationRouter?.body
)
);
}
switch(_navigationRouter!.dashboardType) {
case DashboardType.search:
if (_navigationRouter!.emailId != null) {
_openEmailSearchedFromLocationBar(
_navigationRouter!.emailId!,
searchQuery: _navigationRouter!.searchQuery,
);
} else if (_navigationRouter!.searchQuery?.value.isNotEmpty == true) {
_searchEmailFromLocationBar(_navigationRouter!.searchQuery!);
} else {
_clearNavigationRouter();
_selectSelectedMailboxDefault();
_replaceBrowserHistory();
}
break;
case DashboardType.normal:
if (_navigationRouter!.mailboxId != null) {
final matchedMailboxNode = findMailboxNodeById(_navigationRouter!.mailboxId!);
if (matchedMailboxNode != null) {
if (_navigationRouter!.emailId != null) {
_openEmailInsideMailboxFromLocationBar(
matchedMailboxNode.item,
_navigationRouter!.emailId!
);
} else {
_openMailboxFromLocationBar(matchedMailboxNode.item);
}
} else {
_clearNavigationRouter();
popAndPush(AppRoutes.unknownRoutePage);
}
} else if (_navigationRouter!.emailId != null) {
_openEmailWithoutMailboxFromLocationBar(_navigationRouter!.emailId!);
} else {
_clearNavigationRouter();
_selectSelectedMailboxDefault();
_replaceBrowserHistory();
}
break;
} }
} }
NavigationRouter? get navigationRouter => mailboxDashBoardController.navigationRouter; void _openEmailInsideMailboxFromLocationBar(
PresentationMailbox presentationMailbox,
EmailId emailId
) {
mailboxDashBoardController.setSelectedMailbox(presentationMailbox);
mailboxDashBoardController.dispatchAction(OpenEmailInsideMailboxFromLocationBar(emailId, presentationMailbox));
_clearNavigationRouter();
}
bool get isHasDataFromRoute => PlatformInfo.isWeb && navigationRouter != null; void _openMailboxFromLocationBar(PresentationMailbox presentationMailbox) {
mailboxDashBoardController.setSelectedMailbox(presentationMailbox);
if (PlatformInfo.isWeb) {
RouteUtils.replaceBrowserHistory(
title: 'Mailbox-${presentationMailbox.mailboxId?.id.value}',
url: RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
mailboxId: presentationMailbox.mailboxId,
dashboardType: DashboardType.normal
)
)
);
}
_clearNavigationRouter();
}
MailboxId? get mailboxIdFromNavigationRouter => navigationRouter?.mailboxId; void _openEmailWithoutMailboxFromLocationBar(EmailId emailId) {
mailboxDashBoardController.dispatchAction(
OpenEmailWithoutMailboxFromLocationBar(emailId)
);
_clearNavigationRouter();
}
EmailId? get emailIdFromNavigationRouter => navigationRouter?.emailId; void _openEmailSearchedFromLocationBar(
EmailId emailId,
{
SearchQuery? searchQuery,
}
) {
mailboxDashBoardController.dispatchAction(
OpenEmailSearchedFromLocationBar(
emailId,
searchQuery: searchQuery,
)
);
_clearNavigationRouter();
}
SearchQuery? get searchQueryFromNavigationRouter => navigationRouter?.searchQuery; void _searchEmailFromLocationBar(SearchQuery searchQuery) {
mailboxDashBoardController.dispatchAction(
bool get isRedirectToMailtoURL => navigationRouter?.routeName == AppRoutes.mailtoURL; SearchEmailFromLocationBar(searchQuery)
);
_clearNavigationRouter();
}
void _clearNavigationRouter() { void _clearNavigationRouter() {
mailboxDashBoardController.navigationRouter = null; _navigationRouter = null;
}
void _selectMailboxFromRouter() {
final matchedMailboxNode = findMailboxNodeById(mailboxIdFromNavigationRouter!);
if (matchedMailboxNode != null) {
mailboxDashBoardController.setSelectedMailbox(matchedMailboxNode.item);
if (emailIdFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction(SelectEmailByIdAction(navigationRouter!));
} else {
_updateSelectedMailboxRouteOnBrowser();
}
_clearNavigationRouter();
} else {
_clearNavigationRouter();
popAndPush(AppRoutes.unknownRoutePage);
}
} }
void _handleOpenMailbox( void _handleOpenMailbox(
@@ -494,7 +553,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
mailboxDashBoardController.clearFilterMessageOption(); mailboxDashBoardController.clearFilterMessageOption();
} }
_disableAllSearchEmail(); _disableAllSearchEmail();
_updateSelectedMailboxRouteOnBrowser(); _replaceBrowserHistory();
mailboxDashBoardController.closeMailboxMenuDrawer(); mailboxDashBoardController.closeMailboxMenuDrawer();
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
} }
@@ -779,7 +838,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
void _switchBackToMailboxDefault() { void _switchBackToMailboxDefault() {
final inboxMailbox = findMailboxNodeByRole(PresentationMailbox.roleInbox); final inboxMailbox = findMailboxNodeByRole(PresentationMailbox.roleInbox);
mailboxDashBoardController.setSelectedMailbox(inboxMailbox?.item); mailboxDashBoardController.setSelectedMailbox(inboxMailbox?.item);
_updateSelectedMailboxRouteOnBrowser(); _replaceBrowserHistory();
_autoScrollToTopMailboxList(); _autoScrollToTopMailboxList();
} }
@@ -911,7 +970,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
if (parameters != null) { if (parameters != null) {
final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters); final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters);
log('MailboxController::_handleNavigationRouteParameters():navigationRouter: $navigationRouter'); log('MailboxController::_handleNavigationRouteParameters():navigationRouter: $navigationRouter');
mailboxDashBoardController.navigationRouter = navigationRouter; _navigationRouter = navigationRouter;
} }
} }
@@ -1005,12 +1064,13 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
} }
} }
void _updateSelectedMailboxRouteOnBrowser() { void _replaceBrowserHistory() {
log('MailboxController::_updateSelectedMailboxRouteOnBrowser:selectedMailbox: ${selectedMailbox?.id}');
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
final selectedMailboxId = selectedMailbox?.id; final selectedMailboxId = selectedMailbox?.id;
final route = RouteUtils.generateRouteBrowser( final route = RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( router: NavigationRouter(
mailboxId: selectedMailboxId, mailboxId: selectedMailboxId,
searchQuery: mailboxDashBoardController.searchController.isSearchEmailRunning searchQuery: mailboxDashBoardController.searchController.isSearchEmailRunning
? mailboxDashBoardController.searchController.searchQuery ? mailboxDashBoardController.searchController.searchQuery
@@ -1020,7 +1080,10 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
: DashboardType.normal : DashboardType.normal
) )
); );
RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route); RouteUtils.replaceBrowserHistory(
title: 'Mailbox-${selectedMailboxId?.id.value}',
url: route
);
} }
} }
@@ -1060,7 +1123,6 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM
} }
_setMapMailbox(); _setMapMailbox();
_setOutboxMailbox(); _setOutboxMailbox();
_selectSelectedMailboxDefault();
} }
void _handleRefreshChangesAllMailboxSuccess(RefreshChangesAllMailboxSuccess success) async { void _handleRefreshChangesAllMailboxSuccess(RefreshChangesAllMailboxSuccess success) async {
@@ -1,13 +1,15 @@
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/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.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:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart'; import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
class DashBoardAction extends UIAction { class DashBoardAction extends UIAction {
static final idle = DashBoardAction(); static final idle = DashBoardAction();
@@ -81,24 +83,51 @@ class ClearSearchEmailAction extends DashBoardAction {}
class ClearAllFieldOfAdvancedSearchAction extends DashBoardAction {} class ClearAllFieldOfAdvancedSearchAction extends DashBoardAction {}
class SelectEmailByIdAction extends DashBoardAction { class OpenEmailInsideMailboxFromLocationBar extends DashBoardAction {
final NavigationRouter navigationRouter; final EmailId emailId;
final PresentationMailbox presentationMailbox;
SelectEmailByIdAction(this.navigationRouter); OpenEmailInsideMailboxFromLocationBar(this.emailId, this.presentationMailbox);
@override @override
List<Object?> get props => [navigationRouter]; List<Object?> get props => [emailId, presentationMailbox];
} }
class SearchEmailByQueryAction extends DashBoardAction { class OpenEmailWithoutMailboxFromLocationBar extends DashBoardAction {
final NavigationRouter navigationRouter; final EmailId emailId;
SearchEmailByQueryAction(this.navigationRouter); OpenEmailWithoutMailboxFromLocationBar(this.emailId);
@override @override
List<Object?> get props => [navigationRouter]; List<Object?> get props => [emailId];
}
class OpenEmailSearchedFromLocationBar extends DashBoardAction {
final EmailId emailId;
final SearchQuery? searchQuery;
OpenEmailSearchedFromLocationBar(
this.emailId,
{
this.searchQuery,
}
);
@override
List<Object?> get props => [emailId, searchQuery];
}
class SearchEmailFromLocationBar extends DashBoardAction {
final SearchQuery searchQuery;
SearchEmailFromLocationBar(this.searchQuery);
@override
List<Object?> get props => [searchQuery];
} }
class SelectDateRangeToAdvancedSearch extends DashBoardAction { class SelectDateRangeToAdvancedSearch extends DashBoardAction {
@@ -140,7 +140,6 @@ import 'package:tmail_ui_user/main/exceptions/remote_exception.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';
import 'package:tmail_ui_user/main/routes/dialog_router.dart'; import 'package:tmail_ui_user/main/routes/dialog_router.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart';
@@ -217,7 +216,6 @@ class MailboxDashBoardController extends ReloadableController {
final listResultSearch = RxList<PresentationEmail>(); final listResultSearch = RxList<PresentationEmail>();
PresentationMailbox? outboxMailbox; PresentationMailbox? outboxMailbox;
ComposerArguments? composerArguments; ComposerArguments? composerArguments;
NavigationRouter? navigationRouter;
late StreamSubscription _emailAddressStreamSubscription; late StreamSubscription _emailAddressStreamSubscription;
late StreamSubscription _emailContentStreamSubscription; late StreamSubscription _emailContentStreamSubscription;
@@ -585,9 +583,9 @@ class MailboxDashBoardController extends ReloadableController {
setSelectedEmail(presentationEmail); setSelectedEmail(presentationEmail);
dispatchRoute(DashboardRoutes.emailDetailed); dispatchRoute(DashboardRoutes.emailDetailed);
if (PlatformInfo.isWeb && presentationEmail.routeWeb != null) { if (PlatformInfo.isWeb && presentationEmail.routeWeb != null) {
RouteUtils.updateRouteOnBrowser( RouteUtils.replaceBrowserHistory(
'Email-${presentationEmail.id?.id.value ?? ''}', title: 'Email-${presentationEmail.id?.id.value ?? ''}',
presentationEmail.routeWeb! url: presentationEmail.routeWeb!
); );
} }
} }
@@ -2233,12 +2231,18 @@ class MailboxDashBoardController extends ReloadableController {
dispatchEmailUIAction(CloseEmailDetailedViewAction()); dispatchEmailUIAction(CloseEmailDetailedViewAction());
return true; return true;
case DashboardRoutes.thread: case DashboardRoutes.thread:
if (PlatformInfo.isMobile) {
return false;
}
if (searchController.isSearchEmailRunning) { if (searchController.isSearchEmailRunning) {
dispatchMailboxUIAction(SelectMailboxDefaultAction()); dispatchMailboxUIAction(SystemBackToInboxAction());
} else { } else {
pushAndPopAll(AppRoutes.home); pushAndPopAll(AppRoutes.home);
} }
return true; return true;
case DashboardRoutes.searchEmail:
dispatchAction(CloseSearchEmailViewAction());
return true;
default: default:
break; break;
} }
@@ -4,7 +4,6 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart'; import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
import 'package:tmail_ui_user/features/mailto/presentation/model/mailto_arguments.dart'; import 'package:tmail_ui_user/features/mailto/presentation/model/mailto_arguments.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
@@ -32,10 +31,7 @@ class MailtoUrlController extends ReloadableController {
mailtoUri: parameters['uri'] mailtoUri: parameters['uri']
); );
popAndPush( popAndPush(
RouteUtils.generateNavigationRoute( RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
AppRoutes.dashboard,
NavigationRouter.initial()
),
arguments: mailtoArgument arguments: mailtoArgument
); );
} else { } else {
@@ -31,7 +31,6 @@ import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vaca
import 'package:tmail_ui_user/main/error/capability_validator.dart'; import 'package:tmail_ui_user/main/error/capability_validator.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';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart'; import 'package:tmail_ui_user/main/routes/route_utils.dart';
@@ -205,7 +204,7 @@ class ManageAccountDashBoardController extends ReloadableController {
} else { } else {
log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE'); log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE');
pushAndPopAll( pushAndPopAll(
RouteUtils.generateNavigationRoute(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateNavigationRoute(AppRoutes.dashboard),
arguments: sessionCurrent); arguments: sessionCurrent);
} }
} }
@@ -36,8 +36,8 @@ import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_sta
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart';
@@ -71,7 +71,9 @@ import 'package:tmail_ui_user/features/thread/presentation/mixin/email_action_co
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/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/dialog_router.dart'; import 'package:tmail_ui_user/main/routes/dialog_router.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
class SearchEmailController extends BaseController class SearchEmailController extends BaseController
with EmailActionController, with EmailActionController,
@@ -99,6 +101,7 @@ class SearchEmailController extends BaseController
late Debouncer<String> _deBouncerTime; late Debouncer<String> _deBouncerTime;
late Worker dashBoardViewStateWorker; late Worker dashBoardViewStateWorker;
late Worker dashBoardActionWorker;
late SearchMoreState searchMoreState; late SearchMoreState searchMoreState;
late bool canSearchMore; late bool canSearchMore;
@@ -217,6 +220,16 @@ class SearchEmailController extends BaseController
} }
}); });
}); });
dashBoardActionWorker = ever(
mailboxDashBoardController.dashBoardAction,
(action) {
if (action is CloseSearchEmailViewAction) {
closeSearchView(context: currentContext);
mailboxDashBoardController.clearDashBoardAction();
}
}
);
} }
void _refreshEmailChanges() { void _refreshEmailChanges() {
@@ -293,7 +306,18 @@ class SearchEmailController extends BaseController
canSearchMore = true; canSearchMore = true;
searchIsRunning.value = true; searchIsRunning.value = true;
cancelSelectionMode(context); cancelSelectionMode(context);
if (PlatformInfo.isWeb) {
RouteUtils.replaceBrowserHistory(
title: 'SearchEmail',
url: RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
searchQuery: searchQuery,
dashboardType: DashboardType.search
)
)
);
}
consumeState(_searchEmailInteractor.execute( consumeState(_searchEmailInteractor.execute(
session!, session!,
accountId!, accountId!,
@@ -646,7 +670,6 @@ class SearchEmailController extends BaseController
textInputSearchController.clear(); textInputSearchController.clear();
currentSearchText.value = ''; currentSearchText.value = '';
listSuggestionSearch.clear(); listSuggestionSearch.clear();
textInputSearchFocus.requestFocus();
} }
void clearAllResultSearch() { void clearAllResultSearch() {
@@ -658,14 +681,26 @@ class SearchEmailController extends BaseController
simpleSearchFilter.value = SimpleSearchFilter(); simpleSearchFilter.value = SimpleSearchFilter();
} }
void closeSearchView(BuildContext context) { void closeSearchView({BuildContext? context}) {
log('SearchEmailController::closeSearchView(): ');
clearAllTextInputSearchForm(); clearAllTextInputSearchForm();
clearAllResultSearch(); clearAllResultSearch();
KeyboardUtils.hideKeyboard(context); if (context != null) {
KeyboardUtils.hideKeyboard(context);
}
mailboxDashBoardController.searchController.disableAllSearchEmail(); mailboxDashBoardController.searchController.disableAllSearchEmail();
mailboxDashBoardController.dispatchMailboxUIAction(SelectMailboxDefaultAction());
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
if (PlatformInfo.isWeb) {
RouteUtils.replaceBrowserHistory(
title: 'Mailbox-${mailboxDashBoardController.selectedMailbox.value?.id.id.value}',
url: RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
mailboxId: mailboxDashBoardController.selectedMailbox.value?.id,
dashboardType: DashboardType.normal
)
)
);
}
SearchEmailBindings().disposeBindings(); SearchEmailBindings().disposeBindings();
} }
@@ -811,6 +846,7 @@ class SearchEmailController extends BaseController
resultSearchScrollController.dispose(); resultSearchScrollController.dispose();
_deBouncerTime.cancel(); _deBouncerTime.cancel();
dashBoardViewStateWorker.dispose(); dashBoardViewStateWorker.dispose();
dashBoardActionWorker.dispose();
super.onClose(); super.onClose();
} }
} }
@@ -43,7 +43,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (controller.responsiveUtils.isWebDesktop(context)) { if (controller.responsiveUtils.isWebDesktop(context)) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
controller.closeSearchView(context); controller.closeSearchView(context: context);
}); });
} }
@@ -115,7 +115,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
fit: BoxFit.fill fit: BoxFit.fill
), ),
tooltip: AppLocalizations.of(context).back, tooltip: AppLocalizations.of(context).back,
onTap: () => controller.closeSearchView(context) onTap: () => controller.closeSearchView(context: context)
), ),
Expanded(child: TextFieldBuilder( Expanded(child: TextFieldBuilder(
onTextChange: controller.onTextSearchChange, onTextChange: controller.onTextSearchChange,
@@ -1,16 +1,26 @@
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:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
class GetEmailByIdLoading extends LoadingState {} class GetEmailByIdLoading extends LoadingState {}
class GetEmailByIdSuccess extends UIState { class GetEmailByIdSuccess extends UIState {
final PresentationEmail email; final PresentationEmail email;
final PresentationMailbox? mailboxContain;
final SearchQuery? searchQuery;
GetEmailByIdSuccess(this.email); GetEmailByIdSuccess(
this.email,
{
this.mailboxContain,
this.searchQuery,
}
);
@override @override
List<Object?> get props => [email]; List<Object?> get props => [email, mailboxContain, searchQuery];
} }
class GetEmailByIdFailure extends FeatureFailure { class GetEmailByIdFailure extends FeatureFailure {
@@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/extensions/email_extension.dart'; import 'package:model/extensions/email_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.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';
@@ -24,6 +25,7 @@ class GetEmailByIdInteractor {
EmailId emailId, EmailId emailId,
{ {
Properties? properties, Properties? properties,
PresentationMailbox? mailboxContain,
} }
) async* { ) async* {
try { try {
@@ -31,7 +33,13 @@ class GetEmailByIdInteractor {
if (PlatformInfo.isMobile) { if (PlatformInfo.isMobile) {
yield* _getStoredEmail(session, accountId, emailId, properties: properties); yield* _getStoredEmail(session, accountId, emailId, properties: properties);
} else { } else {
yield* _getEmailByIdFromServer(session, accountId, emailId, properties: properties); yield* _getEmailByIdFromServer(
session,
accountId,
emailId,
properties: properties,
mailboxContain: mailboxContain,
);
} }
} catch (e) { } catch (e) {
logError('GetEmailByIdInteractor::execute():EXCEPTION: $e'); logError('GetEmailByIdInteractor::execute():EXCEPTION: $e');
@@ -45,11 +53,14 @@ class GetEmailByIdInteractor {
EmailId emailId, EmailId emailId,
{ {
Properties? properties, Properties? properties,
PresentationMailbox? mailboxContain,
} }
) async* { ) async* {
try { try {
final email = await _threadRepository.getEmailById(session, accountId, emailId, properties: properties); final email = await _threadRepository.getEmailById(session, accountId, emailId, properties: properties);
yield Right<Failure, Success>(GetEmailByIdSuccess(email)); yield Right<Failure, Success>(
GetEmailByIdSuccess(email, mailboxContain: mailboxContain)
);
} catch (e) { } catch (e) {
logError('GetEmailByIdInteractor::_getEmailByIdFromServer():EXCEPTION: $e'); logError('GetEmailByIdInteractor::_getEmailByIdFromServer():EXCEPTION: $e');
yield Left<Failure, Success>(GetEmailByIdFailure(e)); yield Left<Failure, Success>(GetEmailByIdFailure(e));
@@ -42,11 +42,11 @@ extension ListPresentationEmailExtensions on List<PresentationEmail> {
SearchQuery? searchQuery, SearchQuery? searchQuery,
}) { }) {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
final route = RouteUtils.generateRouteBrowser( final route = RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( router: NavigationRouter(
emailId: currentEmail.id, emailId: currentEmail.id,
mailboxId: selectedMailbox?.id, mailboxId: isSearchEmailRunning ? null : selectedMailbox?.id,
searchQuery: isSearchEmailRunning ? searchQuery : null, searchQuery: isSearchEmailRunning ? searchQuery : null,
dashboardType: isSearchEmailRunning ? DashboardType.search : DashboardType.normal dashboardType: isSearchEmailRunning ? DashboardType.search : DashboardType.normal
) )
@@ -22,6 +22,7 @@ import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart';
@@ -104,7 +105,6 @@ class ThreadController extends BaseController with EmailActionController {
LoadingMoreStatus loadingMoreStatus = LoadingMoreStatus.idle; LoadingMoreStatus loadingMoreStatus = LoadingMoreStatus.idle;
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>();
@@ -123,9 +123,7 @@ class ThreadController extends BaseController with EmailActionController {
SearchEmailFilter get _searchEmailFilter => searchController.searchEmailFilter.value; SearchEmailFilter get _searchEmailFilter => searchController.searchEmailFilter.value;
String get currentTextSearch => searchController.searchInputController.text; SearchQuery? get searchQuery => _searchEmailFilter.text;
SearchQuery? get searchQuery => searchController.searchEmailFilter.value.text;
ThreadController( ThreadController(
this._getEmailsInMailboxInteractor, this._getEmailsInMailboxInteractor,
@@ -174,7 +172,18 @@ 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); if (searchController.isSearchEmailRunning) {
_openEmailSearchedFromLocationBar(
email: success.email,
searchQuery: searchQuery
);
} else {
if (success.mailboxContain != null) {
_openEmailInsideMailboxFromLocationBar(success.email, success.mailboxContain!);
} else {
_openEmailWithoutMailboxFromLocationBar(success.email);
}
}
} else if (success is CreateNewRuleFilterSuccess) { } else if (success is CreateNewRuleFilterSuccess) {
_createNewRuleFilterSuccess(success); _createNewRuleFilterSuccess(success);
} }
@@ -191,7 +200,6 @@ class ThreadController extends BaseController with EmailActionController {
loadingMoreStatus = LoadingMoreStatus.completed; loadingMoreStatus = LoadingMoreStatus.completed;
} else if (failure is GetEmailByIdFailure) { } else if (failure is GetEmailByIdFailure) {
openingEmail.value = false; openingEmail.value = false;
_navigationRouter = null;
popAndPush(AppRoutes.unknownRoutePage); popAndPush(AppRoutes.unknownRoutePage);
} else if (failure is GetAllEmailFailure) { } else if (failure is GetAllEmailFailure) {
mailboxDashBoardController.refreshingMailboxState.value = Left(failure); mailboxDashBoardController.refreshingMailboxState.value = Left(failure);
@@ -265,32 +273,37 @@ class ThreadController extends BaseController with EmailActionController {
} else if (action is OpenEmailDetailedFromSuggestionQuickSearchAction) { } else if (action is OpenEmailDetailedFromSuggestionQuickSearchAction) {
final mailboxContain = action.presentationEmail.findMailboxContain(mailboxDashBoardController.mapMailboxById); final mailboxContain = action.presentationEmail.findMailboxContain(mailboxDashBoardController.mapMailboxById);
final newEmail = generateEmailByPlatform(action.presentationEmail); final newEmail = generateEmailByPlatform(action.presentationEmail);
pressEmailAction( handleEmailActionType(
action.context,
EmailActionType.preview, EmailActionType.preview,
newEmail, newEmail,
mailboxContain: mailboxContain mailboxContain: mailboxContain,
context: action.context,
); );
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is StartSearchEmailAction) { } else if (action is StartSearchEmailAction) {
cancelSelectEmail(); cancelSelectEmail();
_updateSearchRouteOnBrowser(); _replaceBrowserHistory();
_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 OpenEmailInsideMailboxFromLocationBar) {
_navigationRouter = action.navigationRouter; _getEmailByIdFromLocationBar(
if (_navigationRouter!.searchQuery != null) { action.emailId,
_activateSearchFromRouter(); mailboxContain: action.presentationMailbox,
} );
_getEmailByIdAction(_navigationRouter!.emailId!);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is SearchEmailByQueryAction) { } else if (action is OpenEmailWithoutMailboxFromLocationBar) {
_navigationRouter = action.navigationRouter; _getEmailByIdFromLocationBar(action.emailId);
_activateSearchFromRouter();
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is OpenEmailSearchedFromLocationBar) {
_handleOpenEmailSearchedFromLocationBar(
emailId: action.emailId,
searchQuery: action.searchQuery
);
} else if (action is SearchEmailFromLocationBar) {
_handleSearchEmailFromLocationBar(action.searchQuery);
} else if (action is SelectDateRangeToAdvancedSearch || action is ClearDateRangeToAdvancedSearch) { } else if (action is SelectDateRangeToAdvancedSearch || action is ClearDateRangeToAdvancedSearch) {
if (listEmailController.hasClients) { if (listEmailController.hasClients) {
listEmailController.jumpTo(0); listEmailController.jumpTo(0);
@@ -356,17 +369,6 @@ class ThreadController extends BaseController with EmailActionController {
}); });
} }
void _activateSearchFromRouter() {
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(Object error, StackTrace stackTrace) async { void _handleErrorGetAllOrRefreshChangesEmail(Object error, StackTrace stackTrace) async {
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error'); logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
if (error is CannotCalculateChangesMethodResponseException) { if (error is CannotCalculateChangesMethodResponseException) {
@@ -735,18 +737,24 @@ class ThreadController extends BaseController with EmailActionController {
filter: _searchEmailFilter.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()), filter: _searchEmailFilter.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()),
properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!), properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!),
)); ));
} else {
dispatchState(Left(SearchEmailFailure(NotFoundEmailException())));
} }
} }
void _updateSearchRouteOnBrowser() { void _replaceBrowserHistory() {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
final route = RouteUtils.generateRouteBrowser( RouteUtils.replaceBrowserHistory(
AppRoutes.dashboard, title: 'SearchEmail',
NavigationRouter( url: RouteUtils.createUrlWebLocationBar(
searchQuery: searchQuery, AppRoutes.dashboard,
dashboardType: DashboardType.search) router: NavigationRouter(
mailboxId: _searchEmailFilter.mailbox?.mailboxId,
searchQuery: searchQuery,
dashboardType: DashboardType.search
)
)
); );
RouteUtils.updateRouteOnBrowser('SearchEmail', route);
} }
} }
@@ -780,7 +788,7 @@ class ThreadController extends BaseController with EmailActionController {
_accountId!, _accountId!,
limit: ThreadConstants.defaultLimit, limit: ThreadConstants.defaultLimit,
sort: _searchEmailFilter.sortOrder ?? _sortOrder, sort: _searchEmailFilter.sortOrder ?? _sortOrder,
filter: searchController.searchEmailFilter.value.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()), filter: _searchEmailFilter.mappingToEmailFilterCondition(moreFilterCondition: _getFilterCondition()),
properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!), properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!),
lastEmailId: oldestEmail?.id lastEmailId: oldestEmail?.id
)); ));
@@ -877,11 +885,13 @@ class ThreadController extends BaseController with EmailActionController {
} }
} }
void pressEmailAction( void handleEmailActionType(
BuildContext context, EmailActionType actionType,
EmailActionType actionType, PresentationEmail selectedEmail,
PresentationEmail selectedEmail, {
{PresentationMailbox? mailboxContain} PresentationMailbox? mailboxContain,
BuildContext? context,
}
) { ) {
switch(actionType) { switch(actionType) {
case EmailActionType.preview: case EmailActionType.preview:
@@ -892,7 +902,7 @@ class ThreadController extends BaseController with EmailActionController {
} }
break; break;
case EmailActionType.selection: case EmailActionType.selection:
selectEmail(context, selectedEmail); selectEmail(context!, selectedEmail);
break; break;
case EmailActionType.markAsRead: case EmailActionType.markAsRead:
markAsEmailRead(selectedEmail, ReadActions.markAsRead, MarkReadAction.tap); markAsEmailRead(selectedEmail, ReadActions.markAsRead, MarkReadAction.tap);
@@ -907,13 +917,13 @@ 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, mailboxContain: mailboxContain); moveToMailbox(context!, selectedEmail, mailboxContain: mailboxContain);
break; break;
case EmailActionType.moveToTrash: case EmailActionType.moveToTrash:
moveToTrash(selectedEmail, mailboxContain: mailboxContain); 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();
@@ -924,7 +934,7 @@ class ThreadController extends BaseController with EmailActionController {
unSpam(selectedEmail); unSpam(selectedEmail);
break; break;
case EmailActionType.openInNewTab: case EmailActionType.openInNewTab:
openEmailInNewTabAction(context, selectedEmail); openEmailInNewTabAction(context!, selectedEmail);
break; break;
default: default:
break; break;
@@ -939,6 +949,7 @@ class ThreadController extends BaseController with EmailActionController {
void goToSearchView() { void goToSearchView() {
SearchEmailBindings().dependencies(); SearchEmailBindings().dependencies();
_replaceBrowserHistory();
mailboxDashBoardController.dispatchRoute(DashboardRoutes.searchEmail); mailboxDashBoardController.dispatchRoute(DashboardRoutes.searchEmail);
} }
@@ -970,11 +981,13 @@ class ThreadController extends BaseController with EmailActionController {
PresentationEmail generateEmailByPlatform(PresentationEmail currentEmail) { PresentationEmail generateEmailByPlatform(PresentationEmail currentEmail) {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
final route = RouteUtils.generateRouteBrowser( final route = RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( router: NavigationRouter(
emailId: currentEmail.id, emailId: currentEmail.id,
mailboxId: currentMailbox?.id, mailboxId: searchController.isSearchEmailRunning
? currentEmail.mailboxContain?.mailboxId
: currentMailbox?.id,
searchQuery: searchController.isSearchEmailRunning searchQuery: searchController.isSearchEmailRunning
? searchQuery ? searchQuery
: null, : null,
@@ -990,37 +1003,98 @@ class ThreadController extends BaseController with EmailActionController {
} }
} }
void _getEmailByIdAction(EmailId emailId) { void _getEmailByIdFromLocationBar(
EmailId emailId,
{
PresentationMailbox? mailboxContain,
}
) {
if (_session != null && _accountId != null) { if (_session != null && _accountId != null) {
consumeState(_getEmailByIdInteractor.execute( consumeState(_getEmailByIdInteractor.execute(
_session!, _session!,
_accountId!, _accountId!,
emailId, emailId,
properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!) properties: EmailUtils.getPropertiesForEmailGetMethod(_session!, _accountId!),
mailboxContain: mailboxContain,
)); ));
} else {
logError('ThreadController::_getEmailByIdFromLocationBar: session & accountId is NULL');
popAndPush(AppRoutes.unknownRoutePage);
} }
} }
void _openEmailDetailView(PresentationEmail email) { void _openEmailInsideMailboxFromLocationBar(
if (currentContext != null) { PresentationEmail email,
final mailboxContain = email.findMailboxContain(mailboxDashBoardController.mapMailboxById); PresentationMailbox mailboxContain
final route = RouteUtils.generateRouteBrowser( ) {
final presentationEmailWithRouter = email.withRouteWeb(RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
emailId: email.id,
mailboxId: mailboxContain.mailboxId,
dashboardType: DashboardType.normal
)
));
handleEmailActionType(
EmailActionType.preview,
presentationEmailWithRouter,
mailboxContain: mailboxContain
);
}
void _openEmailWithoutMailboxFromLocationBar(PresentationEmail email) {
final mailboxContain = email.findMailboxContain(mailboxDashBoardController.mapMailboxById);
if (mailboxContain != null) {
mailboxDashBoardController.setSelectedMailbox(mailboxContain);
final presentationEmailWithRouter = email.withRouteWeb(RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard, AppRoutes.dashboard,
NavigationRouter( router: NavigationRouter(
emailId: email.id, emailId: email.id,
mailboxId: _navigationRouter?.mailboxId, mailboxId: mailboxContain.mailboxId,
searchQuery: _navigationRouter?.searchQuery, dashboardType: DashboardType.normal
dashboardType: _navigationRouter?.dashboardType ?? DashboardType.normal
) )
); ));
pressEmailAction( handleEmailActionType(
currentContext!,
EmailActionType.preview, EmailActionType.preview,
email.withRouteWeb(route), presentationEmailWithRouter,
mailboxContain: mailboxContain
);
} else {
searchController.enableSearch();
_searchEmail();
final presentationEmailWithRouter = email.withRouteWeb(RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
emailId: email.id,
dashboardType: DashboardType.search
)
));
handleEmailActionType(
EmailActionType.preview,
presentationEmailWithRouter,
mailboxContain: mailboxContain mailboxContain: mailboxContain
); );
} }
_navigationRouter = null; }
void _openEmailSearchedFromLocationBar({
required PresentationEmail email,
SearchQuery? searchQuery,
}) {
final presentationEmailWithRouter = email.withRouteWeb(RouteUtils.createUrlWebLocationBar(
AppRoutes.dashboard,
router: NavigationRouter(
emailId: email.id,
searchQuery: searchQuery,
dashboardType: DashboardType.search
)
));
handleEmailActionType(
EmailActionType.preview,
presentationEmailWithRouter,
mailboxContain: email.findMailboxContain(mailboxDashBoardController.mapMailboxById)
);
} }
void onDragMailBox(bool isDrag) { void onDragMailBox(bool isDrag) {
@@ -1086,7 +1160,7 @@ class ThreadController extends BaseController with EmailActionController {
return false; return false;
} }
DismissDirection getSwipeDirection (bool isWebDesktop, SelectMode selectMode) { DismissDirection getSwipeDirection(bool isWebDesktop, SelectMode selectMode) {
if (isWebDesktop) { if (isWebDesktop) {
return DismissDirection.none; return DismissDirection.none;
} }
@@ -1098,19 +1172,40 @@ class ThreadController extends BaseController with EmailActionController {
return DismissDirection.startToEnd; return DismissDirection.startToEnd;
} }
Future<bool> backButtonPressedCallbackAction(BuildContext context) async {
if (PlatformInfo.isMobile &&
mailboxDashBoardController.selectedMailbox.value?.isInbox == false) {
mailboxDashBoardController.openDefaultMailbox();
return false;
} else {
return true;
}
}
void scrollToTop() { void scrollToTop() {
if (listEmailController.hasClients) { if (listEmailController.hasClients) {
listEmailController.animateTo(0, duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn); listEmailController.animateTo(0, duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
} }
} }
void _handleOpenEmailSearchedFromLocationBar({
required EmailId emailId,
SearchQuery? searchQuery,
}) {
searchController.enableSearch();
if (searchQuery != null) {
searchController.updateTextSearch(searchQuery.value);
searchController.updateFilterEmail(text: searchQuery);
if (currentContext != null) {
FocusScope.of(currentContext!).unfocus();
}
searchController.searchFocus.unfocus();
}
_searchEmail();
_getEmailByIdFromLocationBar(emailId);
mailboxDashBoardController.clearDashBoardAction();
}
void _handleSearchEmailFromLocationBar(SearchQuery searchQuery) {
dispatchState(Right(SearchingState()));
searchController.enableSearch();
searchController.updateTextSearch(searchQuery.value);
searchController.updateFilterEmail(text: searchQuery);
if (currentContext != null) {
FocusScope.of(currentContext!).unfocus();
}
searchController.searchFocus.unfocus();
_searchEmail();
mailboxDashBoardController.clearDashBoardAction();
}
} }
@@ -482,11 +482,11 @@ class ThreadView extends GetWidget<ThreadController>
PresentationEmail presentationEmail, PresentationEmail presentationEmail,
EmailActionType actionType EmailActionType actionType
) { ) {
controller.pressEmailAction( controller.handleEmailActionType(
context,
actionType, actionType,
presentationEmail, presentationEmail,
mailboxContain: presentationEmail.mailboxContain mailboxContain: presentationEmail.mailboxContain,
context: context
); );
} }
@@ -629,11 +629,12 @@ class ThreadView extends GetWidget<ThreadController>
iconRightPadding: controller.responsiveUtils.isMobile(context) iconRightPadding: controller.responsiveUtils.isMobile(context)
? const EdgeInsets.only(right: 12) ? const EdgeInsets.only(right: 12)
: EdgeInsets.zero) : EdgeInsets.zero)
..onActionClick((email) => controller.pressEmailAction(context, ..onActionClick((email) => controller.handleEmailActionType(
mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam, mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam,
email, email,
mailboxContain: mailboxContain) mailboxContain: mailboxContain,
) context: context,
))
).build(); ).build();
} }
@@ -689,11 +690,11 @@ class ThreadView extends GetWidget<ThreadController>
fontSize: 16, fontSize: 16,
color: Colors.black color: Colors.black
), ),
onCallbackAction: () => controller.pressEmailAction( onCallbackAction: () => controller.handleEmailActionType(
context,
mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam, mailboxContain?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam,
email, email,
mailboxContain: mailboxContain mailboxContain: mailboxContain,
context: context
) )
) )
); );
+19 -22
View File
@@ -33,9 +33,17 @@ abstract class RouteUtils {
static String get baseUrl => Uri.base.path; static String get baseUrl => Uri.base.path;
static String generateNavigationRoute(String route, NavigationRouter router) { static String generateNavigationRoute(String route, {NavigationRouter? router}) {
ServicePath servicePath = ServicePath(route);
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
return _createServicePath(route, router: router).path;
} else {
return route;
}
}
static ServicePath _createServicePath(String route, {NavigationRouter? router}) {
ServicePath servicePath = ServicePath(route);
if (router != null) {
if (router.emailId != null) { if (router.emailId != null) {
servicePath = servicePath.withPathParameter(router.emailId!.id.value); servicePath = servicePath.withPathParameter(router.emailId!.id.value);
} }
@@ -46,26 +54,16 @@ abstract class RouteUtils {
if (router.searchQuery != null) if (router.searchQuery != null)
StringQueryParameter(paramQuery, router.searchQuery!.value), StringQueryParameter(paramQuery, router.searchQuery!.value),
]); ]);
return servicePath.path;
} else { } else {
return servicePath.path; servicePath = servicePath.withQueryParameters([
StringQueryParameter(paramType, DashboardType.normal.name)
]);
} }
return servicePath;
} }
static Uri generateRouteBrowser(String route, NavigationRouter router) { static Uri createUrlWebLocationBar(String route, {NavigationRouter? router}) {
final baseRoutePath = '$baseOriginUrl$route'; final servicePath = _createServicePath('$baseOriginUrl$route', router: router);
ServicePath servicePath = ServicePath(baseRoutePath);
if (router.emailId != null) {
servicePath = servicePath.withPathParameter(router.emailId!.id.value);
}
servicePath = servicePath.withQueryParameters([
StringQueryParameter(paramType, router.dashboardType.name),
if (router.mailboxId != null)
StringQueryParameter(paramContext, router.mailboxId!.id.value),
if (router.searchQuery != null)
StringQueryParameter(paramQuery, router.searchQuery!.value),
]);
return Uri.parse(servicePath.path); return Uri.parse(servicePath.path);
} }
@@ -101,10 +99,9 @@ abstract class RouteUtils {
); );
} }
static void updateRouteOnBrowser(String title, Uri newRoute) { static void replaceBrowserHistory({required String title, required Uri url}) {
log('RouteUtils::updateRouteOnBrowser(): title: $title'); log('RouteUtils::replaceBrowserHistory(): title: $title | url: $url');
log('RouteUtils::updateRouteOnBrowser(): newRoute: $newRoute'); html.window.history.replaceState(null, title, url.toString());
html.window.history.replaceState(null, title, newRoute.toString());
} }
static Map<String, String?> parseMapMailtoFromUri(String? mailtoUri) { static Map<String, String?> parseMapMailtoFromUri(String? mailtoUri) {