TF-934 Select mailbox, email when change route on browser

This commit is contained in:
dab246
2022-11-10 20:14:47 +07:00
committed by Dat H. Pham
parent aa8b80975e
commit 6050ee5386
21 changed files with 491 additions and 287 deletions
@@ -1,6 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
@@ -25,8 +25,15 @@ class EmailSupervisorController extends BaseController {
Session? get sessionCurrent => mailboxDashBoardController.sessionCurrent; Session? get sessionCurrent => mailboxDashBoardController.sessionCurrent;
AccountId? get accountId => mailboxDashBoardController.accountId.value; AccountId? get accountId => mailboxDashBoardController.accountId.value;
RxList<PresentationEmail> get listEmail => mailboxDashBoardController.searchController.isSearchEmailRunning && !kIsWeb ? RxList<PresentationEmail> get listEmail {
mailboxDashBoardController.listResultSearch : mailboxDashBoardController.emailsInCurrentMailbox; if (mailboxDashBoardController.searchController.isSearchEmailRunning && !BuildUtils.isWeb) {
return mailboxDashBoardController.listResultSearch;
} else {
return mailboxDashBoardController.emailsInCurrentMailbox;
}
}
bool get supportedPageView => listEmail.isNotEmpty;
@override @override
void onClose() { void onClose() {
@@ -52,6 +52,7 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen
import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_dialog_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_dialog_builder.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/presentation/action/dashboard_action.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
@@ -66,7 +67,9 @@ import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.
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/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:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
class SingleEmailController extends BaseController with AppLoaderMixin { class SingleEmailController extends BaseController with AppLoaderMixin {
@@ -129,7 +132,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
@override @override
void onInit() { void onInit() {
_initializeDebounceTimeIndexPageViewChange(); _initializeDebounceTimeIndexPageViewChange();
_initWorker(); _registerListenerWorker();
_listenDownloadAttachmentProgressState(); _listenDownloadAttachmentProgressState();
injectRuleFilterBindings( injectRuleFilterBindings(
emailSupervisorController.sessionCurrent, emailSupervisorController.sessionCurrent,
@@ -160,7 +163,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void onClose() { void onClose() {
_downloadProgressStateController.close(); _downloadProgressStateController.close();
_getEmailDeBouncer.cancel(); _getEmailDeBouncer.cancel();
_clearWorker(); _unregisterListenerWorker();
super.onClose(); super.onClose();
} }
@@ -172,14 +175,18 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}); });
} }
void _initWorker() { void _registerListenerWorker() {
emailWorker = ever(emailSupervisorController.selectedEmail, (presentationEmail) { emailWorker = ever(emailSupervisorController.selectedEmail, (presentationEmail) {
log('SingleEmailController::_initWorker(): $presentationEmail'); log('SingleEmailController::_initWorker(): $presentationEmail');
if (presentationEmail is PresentationEmail) { if (presentationEmail is PresentationEmail) {
if (_currentEmailId != presentationEmail.id) { if (_currentEmailId != presentationEmail.id) {
_currentEmailId = presentationEmail.id; _currentEmailId = presentationEmail.id;
emailSupervisorController.setCurrentPositionEmailInListEmail(_currentEmailId); if (emailSupervisorController.supportedPageView) {
_getEmailDeBouncer.value = emailSupervisorController.currentIndexPageView; emailSupervisorController.setCurrentPositionEmailInListEmail(_currentEmailId);
_getEmailDeBouncer.value = emailSupervisorController.currentIndexPageView;
} else {
_getEmailContentAction(presentationEmail.id);
}
_resetToOriginalValue(); _resetToOriginalValue();
if (!presentationEmail.hasRead) { if (!presentationEmail.hasRead) {
markAsEmailRead(presentationEmail, ReadActions.markAsRead); markAsEmailRead(presentationEmail, ReadActions.markAsRead);
@@ -192,8 +199,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
}); });
} }
void _clearWorker() { void _unregisterListenerWorker() {
emailWorker.call(); emailWorker.dispose();
} }
void _listenDownloadAttachmentProgressState() { void _listenDownloadAttachmentProgressState() {
@@ -984,12 +991,16 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void closeEmailView(BuildContext context) { void closeEmailView(BuildContext context) {
emailSupervisorController.presentationEmailsLoaded.removeWhere((e) => e.emailCurrent?.id == currentEmail?.id); log('SingleEmailController::closeEmailView(): ');
emailSupervisorController.currentIndexPageView = -1; if (emailSupervisorController.supportedPageView) {
_getEmailDeBouncer.value = null; emailSupervisorController.presentationEmailsLoaded.removeWhere((e) => e.emailCurrent?.id == currentEmail?.id);
emailSupervisorController.currentIndexPageView = -1;
_getEmailDeBouncer.value = null;
}
mailboxDashBoardController.clearSelectedEmail(); mailboxDashBoardController.clearSelectedEmail();
_currentEmailId = null; _currentEmailId = null;
_resetToOriginalValue(); _resetToOriginalValue();
_updateRouteOnBrowser();
if (mailboxDashBoardController.searchController.isSearchEmailRunning) { if (mailboxDashBoardController.searchController.isSearchEmailRunning) {
if (responsiveUtils.isWebDesktop(context)) { if (responsiveUtils.isWebDesktop(context)) {
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
@@ -998,6 +1009,28 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} else { } else {
mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread);
if (isOpenEmailNotMailboxFromRoute) {
mailboxDashBoardController.dispatchAction(SelectMailboxDefaultAction());
}
}
}
bool get isOpenEmailNotMailboxFromRoute => !emailSupervisorController.supportedPageView
&& mailboxDashBoardController.selectedMailbox.value == null;
void _updateRouteOnBrowser() {
if (BuildUtils.isWeb) {
final selectedMailboxId = mailboxDashBoardController.selectedMailbox.value?.id;
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
mailboxId: selectedMailboxId,
dashboardType: mailboxDashBoardController.searchController.isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
)
);
RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route);
} }
} }
+19 -13
View File
@@ -1,7 +1,6 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:filesize/filesize.dart'; import 'package:filesize/filesize.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -55,7 +54,6 @@ class EmailView extends GetWidget<SingleEmailController> {
: const BoxDecoration(color: Colors.white), : const BoxDecoration(color: Colors.white),
margin: _getMarginEmailView(context), margin: _getMarginEmailView(context),
child: Obx(() { child: Obx(() {
log('EmailView::_buildLoadingView(): ${controller.currentEmail}');
if (controller.currentEmail != null) { if (controller.currentEmail != null) {
return _buildEmailView(context, controller.currentEmail!); return _buildEmailView(context, controller.currentEmail!);
} else { } else {
@@ -90,21 +88,28 @@ 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( Expanded(child: controller.emailSupervisorController.supportedPageView
child: PageView.builder( ? _buildMultipleEmailView(controller.emailSupervisorController.listEmail)
physics: kIsWeb ? const NeverScrollableScrollPhysics() : null, : _buildSingleEmailView(context, email),
itemCount: controller.emailSupervisorController.listEmail.length,
controller: controller.emailSupervisorController.pageController,
onPageChanged: controller.emailSupervisorController.onPageChanged,
itemBuilder: (context, index) {
return _buildEmailBody(context, controller.emailSupervisorController.listEmail[index]);
}),
), ),
const Divider(color: AppColor.colorDividerHorizontal, height: 1), const Divider(color: AppColor.colorDividerHorizontal, height: 1),
_buildBottomBar(context, email), _buildBottomBar(context, email),
]); ]);
} }
Widget _buildMultipleEmailView(List<PresentationEmail> listEmails) {
return PageView.builder(
physics: BuildUtils.isWeb ? const NeverScrollableScrollPhysics() : null,
itemCount: listEmails.length,
controller: controller.emailSupervisorController.pageController,
onPageChanged: controller.emailSupervisorController.onPageChanged,
itemBuilder: (context, index) => _buildSingleEmailView(context, listEmails[index])
);
}
Widget _buildSingleEmailView(BuildContext context, PresentationEmail email) {
return _buildEmailBody(context, email);
}
bool _supportVerticalDivider(BuildContext context) { bool _supportVerticalDivider(BuildContext context) {
if (BuildUtils.isWeb) { if (BuildUtils.isWeb) {
@@ -156,7 +161,9 @@ class EmailView extends GetWidget<SingleEmailController> {
_popupMenuEmailActionTile(context, email)); _popupMenuEmailActionTile(context, email));
} }
}, },
optionsWidget: kIsWeb ? _buildNavigatorPageViewWidgets(context) : null, optionsWidget: BuildUtils.isWeb && controller.emailSupervisorController.supportedPageView
? _buildNavigatorPageViewWidgets(context)
: null,
)); ));
} }
@@ -323,7 +330,6 @@ class EmailView extends GetWidget<SingleEmailController> {
return controller.viewState.value.fold( return controller.viewState.value.fold(
(failure) => const SizedBox.shrink(), (failure) => const SizedBox.shrink(),
(success) { (success) {
log('EmailView::_buildLoadingView(): $success');
if (success is LoadingState) { if (success is LoadingState) {
return const Align(alignment: Alignment.topCenter, child: Padding( return const Align(alignment: Alignment.topCenter, child: Padding(
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
@@ -194,7 +194,7 @@ class LoginController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
pushAndPop( pushAndPop(
RouteUtils.generateRoutePathMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()),
arguments: session); arguments: session);
} }
@@ -10,6 +10,7 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/error/method/error_method_response.dart'; import 'package:jmap_dart_client/jmap/core/error/method/error_method_response.dart';
import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
@@ -46,7 +47,6 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_action
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories_expand_mode.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories_expand_mode.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart';
@@ -68,6 +68,7 @@ import 'package:tmail_ui_user/features/thread/presentation/model/search_state.da
import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.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';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@@ -108,6 +109,8 @@ class MailboxController extends BaseMailboxController {
dashboardActionWorker, dashboardActionWorker,
routerParametersWorker; routerParametersWorker;
PresentationMailbox? get selectedMailbox => mailboxDashBoardController.selectedMailbox.value;
MailboxController( MailboxController(
this._getAllMailboxInteractor, this._getAllMailboxInteractor,
this._refreshAllMailboxInteractor, this._refreshAllMailboxInteractor,
@@ -154,12 +157,9 @@ class MailboxController extends BaseMailboxController {
if (success is GetAllMailboxSuccess) { if (success is GetAllMailboxSuccess) {
_currentMailboxState = success.currentMailboxState; _currentMailboxState = success.currentMailboxState;
await buildTree(success.mailboxList); await buildTree(success.mailboxList);
_setUpMapMailbox(success.mailboxList, defaultMailboxTree.value, folderMailboxTree.value);
_selectMailboxById();
} else if (success is RefreshChangesAllMailboxSuccess) { } else if (success is RefreshChangesAllMailboxSuccess) {
_currentMailboxState = success.currentMailboxState; _currentMailboxState = success.currentMailboxState;
await refreshTree(success.mailboxList); await refreshTree(success.mailboxList);
_setUpMapMailbox(success.mailboxList, defaultMailboxTree.value, folderMailboxTree.value);
} }
}); });
} }
@@ -167,32 +167,34 @@ class MailboxController extends BaseMailboxController {
@override @override
void onDone() { void onDone() {
viewState.value.fold( viewState.value.fold(
(failure) { (failure) {
if (failure is CreateNewMailboxFailure) { if (failure is CreateNewMailboxFailure) {
_createNewMailboxFailure(failure); _createNewMailboxFailure(failure);
} else if (failure is SearchMailboxFailure) { } else if (failure is SearchMailboxFailure) {
_searchMailboxFailure(failure); _searchMailboxFailure(failure);
} else if (failure is DeleteMultipleMailboxFailure) { } else if (failure is DeleteMultipleMailboxFailure) {
_deleteMailboxFailure(failure); _deleteMailboxFailure(failure);
}
},
(success) {
if (success is CreateNewMailboxSuccess) {
_createNewMailboxSuccess(success);
} else if (success is SearchMailboxSuccess) {
_searchMailboxSuccess(success);
} else if (success is DeleteMultipleMailboxAllSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if (success is DeleteMultipleMailboxHasSomeSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if ((success is GetAllMailboxSuccess || success is RefreshChangesAllMailboxSuccess) && isSearchActive()) {
_searchMailboxAction(allMailboxes, searchQuery.value);
} else if (success is RenameMailboxSuccess) {
refreshMailboxChanges(currentMailboxState: success.currentMailboxState);
} else if (success is MoveMailboxSuccess) {
_moveMailboxSuccess(success);
}
} }
},
(success) async {
if (success is GetAllMailboxSuccess || success is RefreshChangesAllMailboxSuccess) {
_initialMailboxVariableStorage();
} else if (success is CreateNewMailboxSuccess) {
_createNewMailboxSuccess(success);
} else if (success is SearchMailboxSuccess) {
_searchMailboxSuccess(success);
} else if (success is DeleteMultipleMailboxAllSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if (success is DeleteMultipleMailboxHasSomeSuccess) {
_deleteMultipleMailboxSuccess(success.listMailboxIdDeleted, success.currentMailboxState);
} else if ((success is GetAllMailboxSuccess || success is RefreshChangesAllMailboxSuccess) && isSearchActive()) {
_searchMailboxAction(allMailboxes, searchQuery.value);
} else if (success is RenameMailboxSuccess) {
refreshMailboxChanges(currentMailboxState: success.currentMailboxState);
} else if (success is MoveMailboxSuccess) {
_moveMailboxSuccess(success);
}
}
); );
} }
@@ -313,64 +315,128 @@ class MailboxController extends BaseMailboxController {
} }
} }
void _setUpMapMailbox(List<PresentationMailbox> allMailbox, MailboxTree defaultTree, MailboxTree folderTree) { void _initialMailboxVariableStorage() {
_setMapMailbox();
_setOutboxMailbox();
_selectMailboxDefault();
}
void _setMapMailbox() {
final mapDefaultMailboxIdByRole = { final mapDefaultMailboxIdByRole = {
for (var mailboxNode for (var mailboxNode in defaultMailboxTree.value.root.childrenItems ?? List<MailboxNode>.empty())
in defaultTree.root.childrenItems ?? List<MailboxNode>.empty())
mailboxNode.item.role!: mailboxNode.item.id mailboxNode.item.role!: mailboxNode.item.id
}; };
final mapDefaultMailbox = {
for (var mailboxNode
in defaultTree.root.childrenItems ?? List<MailboxNode>.empty())
mailboxNode.item.role!: mailboxNode.item
};
final mapMailboxById = { final mapMailboxById = {
for (var presentationMailbox in allMailbox) for (var presentationMailbox in allMailboxes)
presentationMailbox.id: presentationMailbox presentationMailbox.id: presentationMailbox
}; };
mailboxDashBoardController.setMapDefaultMailboxIdByRole(mapDefaultMailboxIdByRole); mailboxDashBoardController.setMapDefaultMailboxIdByRole(mapDefaultMailboxIdByRole);
mailboxDashBoardController.setMapMailboxById(mapMailboxById); mailboxDashBoardController.setMapMailboxById(mapMailboxById);
}
void _setOutboxMailbox() {
try { try {
final outboxMailboxIdByRole = mapDefaultMailboxIdByRole[PresentationMailbox.roleOutbox]; final outboxMailboxIdByRole = mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleOutbox];
if (outboxMailboxIdByRole == null) { if (outboxMailboxIdByRole == null) {
final outboxMailboxByName = allMailbox final outboxMailboxByName = allMailboxes
.firstWhere((mailbox) => mailbox.name?.toLowerCase() == PresentationMailbox.lowerCaseOutboxMailboxName); .firstWhere((mailbox) => mailbox.name?.toLowerCase() == PresentationMailbox.lowerCaseOutboxMailboxName);
mailboxDashBoardController.setOutboxMailbox(outboxMailboxByName); mailboxDashBoardController.setOutboxMailbox(outboxMailboxByName);
} else { } else {
mailboxDashBoardController.setOutboxMailbox(mapMailboxById[outboxMailboxIdByRole]!); mailboxDashBoardController.setOutboxMailbox(mailboxDashBoardController.mapMailboxById[outboxMailboxIdByRole]!);
} }
} catch (e) { } catch (e) {
logError('MailboxController::_setUpMapMailboxIdDefault: Not found outbox mailbox'); logError('MailboxController::_setOutboxMailbox: Not found outbox mailbox');
mailboxDashBoardController.setOutboxMailbox(null); mailboxDashBoardController.setOutboxMailbox(null);
} }
}
var mailboxCurrent = mailboxDashBoardController.selectedMailbox.value; void _selectMailboxDefault() {
final mapDefaultMailbox = {
for (var mailboxNode in defaultMailboxTree.value.root.childrenItems ?? List<MailboxNode>.empty())
mailboxNode.item.role!: mailboxNode.item
};
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
final mapMailboxById = mailboxDashBoardController.mapMailboxById;
final isSearchEmailRunning = mailboxDashBoardController.searchController.isSearchEmailRunning;
PresentationMailbox? mailboxSelected;
if (mailboxCurrent != null) { if (mailboxCurrent != null) {
if (mailboxCurrent.hasRole()) { if (mailboxCurrent.hasRole()) {
mailboxDashBoardController.setNewFirstSelectedMailbox(mapDefaultMailbox.containsKey(mailboxCurrent.role) mailboxSelected = mapDefaultMailbox.containsKey(mailboxCurrent.role)
? mapDefaultMailbox[mailboxCurrent.role] ? mapDefaultMailbox[mailboxCurrent.role]
: mailboxCurrent); : mailboxCurrent;
} else { } else {
mailboxDashBoardController.setNewFirstSelectedMailbox(mapMailboxById.containsKey(mailboxCurrent.id) mailboxSelected = mapMailboxById.containsKey(mailboxCurrent.id)
? mapMailboxById[mailboxCurrent.id] ? mapMailboxById[mailboxCurrent.id]
: mailboxCurrent); : mailboxCurrent;
} }
} else { } else {
if (!mailboxDashBoardController.searchController.isSearchEmailRunning) { if (!isSearchEmailRunning) {
if (mapDefaultMailbox.containsKey(PresentationMailbox.roleInbox)) { if (mapDefaultMailbox.containsKey(PresentationMailbox.roleInbox)) {
mailboxDashBoardController.setNewFirstSelectedMailbox(mapDefaultMailbox[PresentationMailbox.roleInbox]); mailboxSelected = mapDefaultMailbox[PresentationMailbox.roleInbox];
} else { } else {
if (allMailbox.isNotEmpty) { if (allMailboxes.isNotEmpty) {
mailboxDashBoardController.setNewFirstSelectedMailbox(allMailbox.first); mailboxSelected = allMailboxes.first;
} }
} }
} }
} }
if (isHasDataFromRoute) {
if (mailboxIdFromNavigationRouter != null) {
_selectMailboxFromRouter();
} else if (emailIdFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction(
SelectEmailByIdAction(
emailIdFromNavigationRouter!,
mailboxIdFromNavigationRouter,
navigationRouter!.dashboardType
)
);
} else {
mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_updateSelectedMailboxRouteOnBrowser();
}
} else {
mailboxDashBoardController.setSelectedMailbox(mailboxSelected);
_updateSelectedMailboxRouteOnBrowser();
}
}
NavigationRouter? get navigationRouter => mailboxDashBoardController.navigationRouter;
bool get isHasDataFromRoute => BuildUtils.isWeb && navigationRouter != null;
MailboxId? get mailboxIdFromNavigationRouter => navigationRouter?.mailboxId;
EmailId? get emailIdFromNavigationRouter => navigationRouter?.emailId;
void _clearNavigationRouter() {
mailboxDashBoardController.navigationRouter = null;
}
void _selectMailboxFromRouter() {
final matchedMailboxNode = findMailboxNodeById(mailboxIdFromNavigationRouter!);
if (matchedMailboxNode != null) {
mailboxDashBoardController.setSelectedMailbox(matchedMailboxNode.item);
if (emailIdFromNavigationRouter != null) {
mailboxDashBoardController.dispatchAction(
SelectEmailByIdAction(
emailIdFromNavigationRouter!,
mailboxIdFromNavigationRouter,
navigationRouter!.dashboardType
)
);
} else {
_updateSelectedMailboxRouteOnBrowser();
}
_clearNavigationRouter();
} else {
_clearNavigationRouter();
}
} }
void _handleOpenMailbox( void _handleOpenMailbox(
@@ -386,6 +452,7 @@ class MailboxController extends BaseMailboxController {
_disableAllSearchEmail(); _disableAllSearchEmail();
mailboxDashBoardController.setSelectedMailbox(presentationMailboxSelected); mailboxDashBoardController.setSelectedMailbox(presentationMailboxSelected);
_updateSelectedMailboxRouteOnBrowser();
if (mailboxDashBoardController.isDrawerOpen) { if (mailboxDashBoardController.isDrawerOpen) {
mailboxDashBoardController.closeMailboxMenuDrawer(); mailboxDashBoardController.closeMailboxMenuDrawer();
@@ -748,7 +815,11 @@ class MailboxController extends BaseMailboxController {
void _switchBackToMailboxDefault() { void _switchBackToMailboxDefault() {
final inboxMailbox = findMailboxNodeByRole(PresentationMailbox.roleInbox); final inboxMailbox = findMailboxNodeByRole(PresentationMailbox.roleInbox);
mailboxDashBoardController.setSelectedMailbox(inboxMailbox?.item); mailboxDashBoardController.setSelectedMailbox(inboxMailbox?.item);
mailboxListScrollController.animateTo(0, duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn); _updateSelectedMailboxRouteOnBrowser();
mailboxListScrollController.animateTo(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn);
} }
void _deleteMailboxFailure(DeleteMultipleMailboxFailure failure) { void _deleteMailboxFailure(DeleteMultipleMailboxFailure failure) {
@@ -996,30 +1067,11 @@ class MailboxController extends BaseMailboxController {
} }
} }
void _selectMailboxById() {
if (mailboxDashBoardController.navigationRouter != null) {
final mailboxId = mailboxDashBoardController.navigationRouter?.mailboxId;
if (mailboxId != null) {
final matchedMailboxNode = findMailboxNodeById(mailboxId);
if (matchedMailboxNode != null && currentContext != null) {
mailboxDashBoardController.setSelectedMailbox(matchedMailboxNode.item);
}
}
final emailId = mailboxDashBoardController.navigationRouter?.emailId;
if (emailId != null) {
mailboxDashBoardController.dispatchAction(SelectEmailByIdAction(emailId));
}
mailboxDashBoardController.navigationRouter = null;
}
}
void _handleNavigationRouteParameters(Map<String, String?>? parameters) { void _handleNavigationRouteParameters(Map<String, String?>? parameters) {
log('MailboxDashBoardController::_handleNavigationRouteParameters(): parameters: $parameters'); log('MailboxController::_handleNavigationRouteParameters(): parameters: $parameters');
if (parameters != null) { if (parameters != null) {
final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters); final navigationRouter = RouteUtils.parsingRouteParametersToNavigationRouter(parameters);
log('ThreadController::_handleNavigationRouteParameters():navigationRouter: $navigationRouter'); log('MailboxController::_handleNavigationRouteParameters():navigationRouter: $navigationRouter');
mailboxDashBoardController.navigationRouter = navigationRouter; mailboxDashBoardController.navigationRouter = navigationRouter;
} }
} }
@@ -1053,6 +1105,20 @@ class MailboxController extends BaseMailboxController {
} }
} }
void _updateSelectedMailboxRouteOnBrowser() {
if (BuildUtils.isWeb) {
final selectedMailboxId = selectedMailbox?.id;
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
mailboxId: selectedMailboxId,
dashboardType: DashboardType.normal
)
);
RouteUtils.updateRouteOnBrowser('Mailbox-${selectedMailboxId?.id.value}', route);
}
}
void closeMailboxScreen(BuildContext context) { void closeMailboxScreen(BuildContext context) {
_cancelSelectMailbox(); _cancelSelectMailbox();
mailboxDashBoardController.closeMailboxMenuDrawer(); mailboxDashBoardController.closeMailboxMenuDrawer();
@@ -1,10 +1,12 @@
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.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';
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';
class DashBoardAction extends UIAction { class DashBoardAction extends UIAction {
static final idle = DashBoardAction(); static final idle = DashBoardAction();
@@ -115,9 +117,11 @@ class SelectMailboxDefaultAction extends DashBoardAction {
class SelectEmailByIdAction extends DashBoardAction { class SelectEmailByIdAction extends DashBoardAction {
final EmailId emailId; final EmailId emailId;
final MailboxId? mailboxId;
final DashboardType dashboardType;
SelectEmailByIdAction(this.emailId); SelectEmailByIdAction(this.emailId, this.mailboxId, this.dashboardType);
@override @override
List<Object?> get props => [emailId]; List<Object?> get props => [emailId, mailboxId, dashboardType];
} }
@@ -326,7 +326,7 @@ class MailboxDashBoardController extends ReloadableController {
void _getSessionCurrent() { void _getSessionCurrent() {
final arguments = Get.arguments; final arguments = Get.arguments;
log('MailboxDashBoardController::_setSessionCurrent(): arguments = $arguments'); log('MailboxDashBoardController::_getSessionCurrent(): arguments = $arguments');
if (arguments is Session) { if (arguments is Session) {
sessionCurrent = arguments; sessionCurrent = arguments;
accountId.value = sessionCurrent?.accounts.keys.first; accountId.value = sessionCurrent?.accounts.keys.first;
@@ -381,12 +381,13 @@ class MailboxDashBoardController extends ReloadableController {
} }
void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) { void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) {
selectedMailbox.value = newPresentationMailbox; final previousMailbox = selectedMailbox.value;
} if (previousMailbox == newPresentationMailbox) {
selectedMailbox.value = newPresentationMailbox;
void setNewFirstSelectedMailbox(PresentationMailbox? newPresentationMailbox) { selectedMailbox.refresh();
selectedMailbox.firstRebuild = true; } else {
selectedMailbox.value = newPresentationMailbox; selectedMailbox.value = newPresentationMailbox;
}
} }
void setSelectedEmail(PresentationEmail? newPresentationEmail) { void setSelectedEmail(PresentationEmail? newPresentationEmail) {
@@ -885,7 +886,7 @@ class MailboxDashBoardController extends ReloadableController {
Function? onCancelSelectionEmail, Function? onCancelSelectionEmail,
} }
) { ) {
if (_responsiveUtils.isMobile(context)) { if (_responsiveUtils.isScreenWithShortestSide(context)) {
(ConfirmationDialogActionSheetBuilder(context) (ConfirmationDialogActionSheetBuilder(context)
..messageText(actionType.getContentDialog( ..messageText(actionType.getContentDialog(
context, context,
@@ -1020,6 +1021,8 @@ class MailboxDashBoardController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
log('MailboxDashBoardController::handleReloaded():');
_getRouteParameters();
sessionCurrent = session; sessionCurrent = session;
accountId.value = sessionCurrent?.accounts.keys.first; accountId.value = sessionCurrent?.accounts.keys.first;
_getUserProfile(); _getUserProfile();
@@ -1028,7 +1031,6 @@ class MailboxDashBoardController extends ReloadableController {
injectRuleFilterBindings(sessionCurrent, accountId.value); injectRuleFilterBindings(sessionCurrent, accountId.value);
injectVacationBindings(sessionCurrent, accountId.value); injectVacationBindings(sessionCurrent, accountId.value);
_getVacationResponse(); _getVacationResponse();
_getRouteParameters();
} }
void _getRouteParameters() { void _getRouteParameters() {
@@ -227,7 +227,7 @@ class ManageAccountDashBoardController extends ReloadableController {
} else { } else {
log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE'); log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE');
pushAndPopAll( pushAndPopAll(
RouteUtils.generateRoutePathMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()),
arguments: sessionCurrent); arguments: sessionCurrent);
} }
} }
@@ -53,7 +53,9 @@ import 'package:tmail_ui_user/features/thread/domain/usecases/search_more_email_
import 'package:tmail_ui_user/features/thread/presentation/mixin/email_action_controller.dart'; import 'package:tmail_ui_user/features/thread/presentation/mixin/email_action_controller.dart';
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
import 'package:tmail_ui_user/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';
class SearchEmailController extends BaseController class SearchEmailController extends BaseController
with EmailActionController { with EmailActionController {
@@ -727,6 +729,22 @@ class SearchEmailController extends BaseController
} }
} }
PresentationEmail generateEmailByPlatform(PresentationEmail currentEmail) {
if (BuildUtils.isWeb) {
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: currentEmail.id,
dashboardType: DashboardType.search
)
);
final emailOnWeb = currentEmail.withRouteWeb(route);
return emailOnWeb;
} else {
return currentEmail;
}
}
@override @override
void onClose() { void onClose() {
textInputSearchController.dispose(); textInputSearchController.dispose();
@@ -420,31 +420,33 @@ class SearchEmailView extends GetWidget<SearchEmailController>
key: const PageStorageKey('list_presentation_email_in_search_view'), key: const PageStorageKey('list_presentation_email_in_search_view'),
itemExtent: _getItemExtent(context), itemExtent: _getItemExtent(context),
itemCount: listPresentationEmail.length, itemCount: listPresentationEmail.length,
itemBuilder: (context, index) => Obx(() => (EmailTileBuilder( itemBuilder: (context, index) {
context, final mailboxContain = _getMailboxContain(listPresentationEmail[index]);
listPresentationEmail[index], final newPresentationEmail = controller.generateEmailByPlatform(listPresentationEmail[index]);
controller.selectionMode.value, return Obx(() => (EmailTileBuilder(
controller.searchQuery, context,
controller.mailboxDashBoardController.selectedEmail.value?.id == listPresentationEmail[index].id, newPresentationEmail,
isSearchEmailRunning: true, controller.selectionMode.value,
padding: SearchEmailUtils.getPaddingSearchResultList(context, _responsiveUtils), controller.searchQuery,
paddingDivider: SearchEmailUtils.getPaddingDividerSearchResultList(context, _responsiveUtils), controller.mailboxDashBoardController.selectedEmail.value?.id == newPresentationEmail.id,
mailboxCurrent: listPresentationEmail[index].findMailboxContain( isSearchEmailRunning: true,
controller.mailboxDashBoardController.mapMailboxById)) padding: SearchEmailUtils.getPaddingSearchResultList(context, _responsiveUtils),
..addOnPressEmailActionClick((action, email) => paddingDivider: SearchEmailUtils.getPaddingDividerSearchResultList(context, _responsiveUtils),
controller.pressEmailAction( mailboxContain: mailboxContain)
context, ..addOnPressEmailActionClick((action, email) =>
action, controller.pressEmailAction(context, action, email, mailboxContain: mailboxContain))
email, ..addOnMoreActionClick((email, position) => _responsiveUtils.isScreenWithShortestSide(context)
mailboxContain: email.findMailboxContain( ? controller.openContextMenuAction(context, _contextMenuActionTile(context, email))
controller.mailboxDashBoardController.mapMailboxById))) : controller.openPopupMenuAction(context, position, _popupMenuActionTile(context, email)))
..addOnMoreActionClick((email, position) => _responsiveUtils.isMobile(context) ).build());
? controller.openContextMenuAction(context, _contextMenuActionTile(context, email)) })
: controller.openPopupMenuAction(context, position, _popupMenuActionTile(context, email))))
.build()))
); );
} }
PresentationMailbox? _getMailboxContain(PresentationEmail currentEmail) {
return currentEmail.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById);
}
double? _getItemExtent(BuildContext context) { double? _getItemExtent(BuildContext context) {
if (BuildUtils.isWeb) { if (BuildUtils.isWeb) {
return _responsiveUtils.isDesktop(context) ? 52 : 95; return _responsiveUtils.isDesktop(context) ? 52 : 95;
@@ -470,7 +472,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
} }
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
final mailboxContain = email.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById); final mailboxContain = _getMailboxContain(email);
return (EmailActionCupertinoActionSheetActionBuilder( return (EmailActionCupertinoActionSheetActionBuilder(
const Key('mark_as_spam_or_un_spam_action'), const Key('mark_as_spam_or_un_spam_action'),
@@ -58,7 +58,7 @@ class SessionController extends ReloadableController {
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
pushAndPop( pushAndPop(
RouteUtils.generateRoutePathMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateRouteMobile(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.generateRoutePathMobile(AppRoutes.dashboard, NavigationRouter()), RouteUtils.generateRouteMobile(AppRoutes.dashboard, NavigationRouter()),
arguments: success.session); arguments: success.session);
} else { } else {
_goToLogin(); _goToLogin();
@@ -1,16 +1,20 @@
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/model.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.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); GetEmailByIdSuccess(this.email, this.mailboxId, this.dashboardType);
@override @override
List<Object?> get props => [email]; List<Object?> get props => [email, mailboxId, dashboardType];
} }
class GetEmailByIdFailure extends FeatureFailure { class GetEmailByIdFailure extends FeatureFailure {
@@ -4,8 +4,10 @@ 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;
@@ -16,13 +18,15 @@ 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)); yield Right<Failure, Success>(GetEmailByIdSuccess(email, mailboxId, dashboardType));
} catch (e) { } catch (e) {
yield Left<Failure, Success>(GetEmailByIdFailure(e)); yield Left<Failure, Success>(GetEmailByIdFailure(e));
} }
@@ -28,6 +28,7 @@ import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_t
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/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
mixin EmailActionController on ViewAsDialogActionMixin { mixin EmailActionController on ViewAsDialogActionMixin {
@@ -47,6 +48,11 @@ mixin EmailActionController on ViewAsDialogActionMixin {
void previewEmail(BuildContext context, PresentationEmail presentationEmail) { void previewEmail(BuildContext context, PresentationEmail presentationEmail) {
mailboxDashBoardController.setSelectedEmail(presentationEmail); mailboxDashBoardController.setSelectedEmail(presentationEmail);
mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed); mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed);
if (BuildUtils.isWeb && presentationEmail.routeWeb != null) {
RouteUtils.updateRouteOnBrowser(
'Email-${presentationEmail.id.id.value}',
presentationEmail.routeWeb!);
}
} }
void moveToTrash(PresentationEmail email) async { void moveToTrash(PresentationEmail email) async {
@@ -3,10 +3,10 @@ import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart'; import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.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/sort/comparator.dart'; import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
@@ -85,6 +85,8 @@ class ThreadController extends BaseController with EmailActionController {
final listEmailDrag = <PresentationEmail>[].obs; final listEmailDrag = <PresentationEmail>[].obs;
bool _rangeSelectionMode = false; bool _rangeSelectionMode = false;
final openingEmail = RxBool(false);
bool canLoadMore = true; bool canLoadMore = true;
bool canSearchMore = true; bool canSearchMore = true;
bool _isLoadingMore = false; bool _isLoadingMore = false;
@@ -153,6 +155,8 @@ class ThreadController extends BaseController with EmailActionController {
emailList.clear(); emailList.clear();
} else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) { } else if (failure is SearchMoreEmailFailure || failure is LoadMoreEmailsFailure) {
_isLoadingMore = false; _isLoadingMore = false;
} else if (failure is GetEmailByIdFailure) {
openingEmail.value = false;
} }
}, },
(success) { (success) {
@@ -168,26 +172,11 @@ class ThreadController extends BaseController with EmailActionController {
_searchMoreEmailsSuccess(success); _searchMoreEmailsSuccess(success);
} else if (success is SearchingMoreState || success is LoadingMoreState) { } else if (success is SearchingMoreState || success is LoadingMoreState) {
_isLoadingMore = true; _isLoadingMore = true;
} else if (success is GetEmailByIdLoading) {
openingEmail.value = true;
} else if (success is GetEmailByIdSuccess) { } else if (success is GetEmailByIdSuccess) {
if (currentContext != null) { openingEmail.value = false;
final mailboxContain = success.email _openEmailDetailView(success.email, success.mailboxId, success.dashboardType);
.findMailboxContain(mailboxDashBoardController.mapMailboxById);
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: success.email.id,
mailboxId: mailboxContain?.id,
dashboardType: searchController.isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
)
);
pressEmailAction(
currentContext!,
EmailActionType.preview,
success.email.withRouteWeb(route),
mailboxContain: mailboxContain);
}
} }
} }
); );
@@ -246,23 +235,14 @@ class ThreadController extends BaseController with EmailActionController {
pressEmailSelectionAction(action.context, action.emailAction, action.listEmailSelected); pressEmailSelectionAction(action.context, action.emailAction, action.listEmailSelected);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is OpenEmailDetailedFromSuggestionQuickSearchAction) { } else if (action is OpenEmailDetailedFromSuggestionQuickSearchAction) {
final mailboxContain = action.presentationEmail final mailboxContain = action.presentationEmail.findMailboxContain(mailboxDashBoardController.mapMailboxById);
.findMailboxContain(mailboxDashBoardController.mapMailboxById); final newEmail = generateEmailByPlatform(action.presentationEmail);
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: action.presentationEmail.id,
mailboxId: mailboxContain?.id,
dashboardType: searchController.isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
)
);
pressEmailAction( pressEmailAction(
action.context, action.context,
EmailActionType.preview, EmailActionType.preview,
action.presentationEmail.withRouteWeb(route), newEmail,
mailboxContain: mailboxContain); mailboxContain: mailboxContain
);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is StartSearchEmailAction) { } else if (action is StartSearchEmailAction) {
cancelSelectEmail(); cancelSelectEmail();
@@ -272,7 +252,7 @@ class ThreadController extends BaseController with EmailActionController {
deleteSelectionEmailsPermanently(action.context, DeleteActionType.all); deleteSelectionEmailsPermanently(action.context, DeleteActionType.all);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} else if (action is SelectEmailByIdAction) { } else if (action is SelectEmailByIdAction) {
_openEmailDetailedView(action.emailId); _getEmailByIdAction(action.emailId, action.mailboxId, action.dashboardType);
mailboxDashBoardController.clearDashBoardAction(); mailboxDashBoardController.clearDashBoardAction();
} }
}); });
@@ -503,11 +483,6 @@ class ThreadController extends BaseController with EmailActionController {
: SelectMode.INACTIVE; : SelectMode.INACTIVE;
} }
void previewEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
mailboxDashBoardController.setSelectedEmail(presentationEmailSelected);
mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed);
}
Tuple2<StartRangeSelection,EndRangeSelection> _getSelectionEmailsRange(PresentationEmail presentationEmailSelected) { Tuple2<StartRangeSelection,EndRangeSelection> _getSelectionEmailsRange(PresentationEmail presentationEmailSelected) {
final emailSelectedIndex = emailList.indexWhere((e) => e.id == presentationEmailSelected.id); final emailSelectedIndex = emailList.indexWhere((e) => e.id == presentationEmailSelected.id);
final latestEmailSelectedOrUnselectedIndex = emailList.indexWhere((e) => e.id == latestEmailSelectedOrUnselected.value?.id); final latestEmailSelectedOrUnselectedIndex = emailList.indexWhere((e) => e.id == latestEmailSelectedOrUnselected.value?.id);
@@ -833,12 +808,57 @@ class ThreadController extends BaseController with EmailActionController {
: KeyEventResult.ignored; : KeyEventResult.ignored;
} }
void _openEmailDetailedView(EmailId emailId) { PresentationEmail generateEmailByPlatform(PresentationEmail currentEmail) {
if (BuildUtils.isWeb) {
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: currentEmail.id,
mailboxId: currentMailbox?.id,
dashboardType: searchController.isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
)
);
final emailOnWeb = currentEmail.withRouteWeb(route);
return emailOnWeb;
} else {
return currentEmail;
}
}
void _getEmailByIdAction(EmailId emailId, MailboxId? mailboxId, DashboardType dashboardType) {
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(
PresentationEmail email,
MailboxId? mailboxId,
DashboardType dashboardType
) {
if (currentContext != null) {
final mailboxContain = email.findMailboxContain(mailboxDashBoardController.mapMailboxById);
final route = RouteUtils.generateRouteBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: email.id,
mailboxId: mailboxId,
dashboardType: dashboardType
)
);
pressEmailAction(
currentContext!,
EmailActionType.preview,
email.withRouteWeb(route),
mailboxContain: mailboxContain
);
}
}
} }
@@ -251,7 +251,7 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget) ? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget)
: const SizedBox.shrink(); : const SizedBox.shrink();
} else { } else {
return success is LoadingState return success is LoadingState || controller.openingEmail.isTrue
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget) ? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget)
: const SizedBox.shrink(); : const SizedBox.shrink();
} }
@@ -283,7 +283,9 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
color: Colors.white, color: Colors.white,
child: Obx(() { child: Obx(() {
return _buildResultListEmail(context, controller.emailList); return Visibility(
visible: controller.openingEmail.isFalse,
child: _buildResultListEmail(context, controller.emailList));
}) })
); );
} }
@@ -333,48 +335,39 @@ 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 newPresentationEmail = controller.generateEmailByPlatform(listPresentationEmail[index]);
return Obx(() => Draggable<List<PresentationEmail>>( return Obx(() => Draggable<List<PresentationEmail>>(
maxSimultaneousDrags: kIsWeb ? null : 0, maxSimultaneousDrags: kIsWeb ? null : 0,
data: controller.listEmailDrag, data: controller.listEmailDrag,
child: (EmailTileBuilder( child: (EmailTileBuilder(
context,
listPresentationEmail[index],
controller.mailboxDashBoardController.currentSelectMode.value,
controller.searchQuery,
controller.mailboxDashBoardController.selectedEmail.value?.id == listPresentationEmail[index].id,
mailboxCurrent: controller.searchController.isSearchEmailRunning
? listPresentationEmail[index].findMailboxContain(controller.mailboxDashBoardController.mapMailboxById)
: controller.currentMailbox,
isSearchEmailRunning: controller.searchController.isSearchEmailRunning)
..addOnPressEmailActionClick((action, email) =>
controller.pressEmailAction(
context, context,
action, newPresentationEmail,
email, controller.mailboxDashBoardController.currentSelectMode.value,
mailboxContain: controller.searchController.isSearchEmailRunning controller.searchQuery,
? email.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById) controller.mailboxDashBoardController.selectedEmail.value?.id == newPresentationEmail.id,
: controller.currentMailbox)) mailboxContain: mailboxContain,
..addOnMoreActionClick((email, position) => _responsiveUtils.isMobile(context) isSearchEmailRunning: controller.searchController.isSearchEmailRunning)
? controller.openContextMenuAction(context, _contextMenuActionTile(context, email)) ..addOnPressEmailActionClick((action, email) =>
: controller.openPopupMenuAction(context, position, _popupMenuActionTile(context, email))) controller.pressEmailAction(context, action, email, mailboxContain: mailboxContain))
..addOnMoreActionClick((email, position) => _responsiveUtils.isScreenWithShortestSide(context)
? controller.openContextMenuAction(context, _contextMenuActionTile(context, email))
: controller.openPopupMenuAction(context, position, _popupMenuActionTile(context, email)))
).build(), ).build(),
feedback: _buildFeedBackWidget(context), feedback: _buildFeedBackWidget(context),
childWhenDragging: (EmailTileBuilder( childWhenDragging: (EmailTileBuilder(
context, context,
listPresentationEmail[index], newPresentationEmail,
controller.mailboxDashBoardController.currentSelectMode.value, controller.mailboxDashBoardController.currentSelectMode.value,
controller.searchQuery, controller.searchQuery,
controller.mailboxDashBoardController.selectedEmail.value?.id == listPresentationEmail[index].id, controller.mailboxDashBoardController.selectedEmail.value?.id == newPresentationEmail.id,
mailboxCurrent: controller.searchController.isSearchEmailRunning mailboxContain: mailboxContain,
? listPresentationEmail[index].findMailboxContain(
controller.mailboxDashBoardController.mapMailboxById)
: controller.currentMailbox,
isSearchEmailRunning: controller.searchController.isSearchEmailRunning, isSearchEmailRunning: controller.searchController.isSearchEmailRunning,
isDrag: true) isDrag: true)
).build(), ).build(),
dragAnchorStrategy: pointerDragAnchorStrategy, dragAnchorStrategy: pointerDragAnchorStrategy,
onDragStarted: () { onDragStarted: () {
controller.calculateDragValue(listPresentationEmail[index]); controller.calculateDragValue(newPresentationEmail);
}, },
)); ));
}), }),
@@ -382,6 +375,12 @@ 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,
@@ -509,9 +508,7 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
} }
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) { Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
final mailboxContain = controller.searchController.isSearchEmailRunning final mailboxContain = _getMailboxContain(email);
? email.findMailboxContain(controller.mailboxDashBoardController.mapMailboxById)
: controller.currentMailbox;
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(
@@ -13,7 +13,7 @@ class EmailTileBuilder with BaseEmailItemTile {
final PresentationEmail _presentationEmail; final PresentationEmail _presentationEmail;
final BuildContext _context; final BuildContext _context;
final SelectMode _selectModeAll; final SelectMode _selectModeAll;
final PresentationMailbox? mailboxCurrent; final PresentationMailbox? mailboxContain;
final SearchQuery? _searchQuery; final SearchQuery? _searchQuery;
final bool isSearchEmailRunning; final bool isSearchEmailRunning;
final EdgeInsets? padding; final EdgeInsets? padding;
@@ -31,7 +31,7 @@ class EmailTileBuilder with BaseEmailItemTile {
this._isShowingEmailContent, this._isShowingEmailContent,
{ {
this.isSearchEmailRunning = false, this.isSearchEmailRunning = false,
this.mailboxCurrent, this.mailboxContain,
this.padding, this.padding,
this.paddingDivider, this.paddingDivider,
this.isDrag = false, this.isDrag = false,
@@ -83,7 +83,7 @@ class EmailTileBuilder with BaseEmailItemTile {
fit: BoxFit.fill)), fit: BoxFit.fill)),
Expanded(child: buildInformationSender( Expanded(child: buildInformationSender(
_presentationEmail, _presentationEmail,
mailboxCurrent, mailboxContain,
isSearchEmailRunning, isSearchEmailRunning,
_searchQuery)), _searchQuery)),
if (_presentationEmail.hasAttachment == true) if (_presentationEmail.hasAttachment == true)
@@ -11,9 +11,6 @@ import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.dart'; import 'package:tmail_ui_user/features/thread/presentation/mixin/base_email_item_tile.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/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:url_launcher/link.dart'; import 'package:url_launcher/link.dart';
class EmailTileBuilder with BaseEmailItemTile { class EmailTileBuilder with BaseEmailItemTile {
@@ -21,7 +18,7 @@ class EmailTileBuilder with BaseEmailItemTile {
final PresentationEmail _presentationEmail; final PresentationEmail _presentationEmail;
final BuildContext _context; final BuildContext _context;
final SelectMode _selectModeAll; final SelectMode _selectModeAll;
final PresentationMailbox? mailboxCurrent; final PresentationMailbox? mailboxContain;
final SearchQuery? _searchQuery; final SearchQuery? _searchQuery;
final bool isSearchEmailRunning; final bool isSearchEmailRunning;
final EdgeInsets? padding; final EdgeInsets? padding;
@@ -43,7 +40,7 @@ class EmailTileBuilder with BaseEmailItemTile {
this._isShowingEmailContent, this._isShowingEmailContent,
{ {
this.isSearchEmailRunning = false, this.isSearchEmailRunning = false,
this.mailboxCurrent, this.mailboxContain,
this.padding, this.padding,
this.paddingDivider, this.paddingDivider,
this.isDrag = false, this.isDrag = false,
@@ -80,56 +77,43 @@ class EmailTileBuilder with BaseEmailItemTile {
} }
Widget _wrapContainerForTile(Widget tile) { Widget _wrapContainerForTile(Widget tile) {
return Container(
margin: _getMarginItem(),
padding: _getPaddingItem(),
decoration: _getDecorationItem(),
alignment: Alignment.center,
child: Link(
uri: _presentationEmail.routeWeb,
builder: (_, __) => tile
)
);
}
EdgeInsets _getMarginItem() {
if (responsiveUtils.isDesktop(_context)) { if (responsiveUtils.isDesktop(_context)) {
return Container( return const EdgeInsets.only(top: 3);
margin: const EdgeInsets.only(top: 3),
padding: const EdgeInsets.symmetric(vertical: 8),
decoration: (_selectModeAll == SelectMode.ACTIVE &&
_presentationEmail.selectMode == SelectMode.ACTIVE) || isDrag || _isShowingEmailContent
? BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: AppColor.colorItemEmailSelectedDesktop)
: null,
child: Link(
uri: RouteUtils.generateRoutePathBrowser(
AppRoutes.dashboard,
NavigationRouter(
emailId: _presentationEmail.id,
mailboxId: mailboxCurrent?.id,
dashboardType: isSearchEmailRunning
? DashboardType.search
: DashboardType.normal
)
),
builder: (_, __) => tile
)
);
} else { } else {
return Container( return const EdgeInsets.only(top: 3, left: 16, right: 16);
margin: const EdgeInsets.only(top: 3, left: 16, right: 16), }
padding: const EdgeInsets.only(bottom: 8, right: 8, top: 8), }
decoration: (_selectModeAll == SelectMode.ACTIVE &&
_presentationEmail.selectMode == SelectMode.ACTIVE) || isDrag || _isShowingEmailContent EdgeInsets _getPaddingItem() {
? BoxDecoration( if (responsiveUtils.isDesktop(_context)) {
borderRadius: BorderRadius.circular(14), return const EdgeInsets.symmetric(vertical: 8);
color: AppColor.colorItemEmailSelectedDesktop) } else {
: BoxDecoration( return const EdgeInsets.only(bottom: 8, right: 8, top: 8);
borderRadius: BorderRadius.circular(0), }
color: Colors.white), }
alignment: Alignment.center,
child: Link( BoxDecoration _getDecorationItem() {
uri: RouteUtils.generateRoutePathBrowser( if ((_selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE) || isDrag || _isShowingEmailContent) {
AppRoutes.dashboard, return BoxDecoration(
NavigationRouter( borderRadius: BorderRadius.circular(14),
emailId: _presentationEmail.id, color: AppColor.colorItemEmailSelectedDesktop);
mailboxId: mailboxCurrent?.id, } else {
dashboardType: isSearchEmailRunning return BoxDecoration(
? DashboardType.search borderRadius: BorderRadius.circular(0),
: DashboardType.normal color: Colors.white);
)
),
builder: (_, __) => tile
));
} }
} }
@@ -168,7 +152,7 @@ class EmailTileBuilder with BaseEmailItemTile {
fit: BoxFit.fill)), fit: BoxFit.fill)),
Expanded(child: buildInformationSender( Expanded(child: buildInformationSender(
_presentationEmail, _presentationEmail,
mailboxCurrent, mailboxContain,
isSearchEmailRunning, isSearchEmailRunning,
_searchQuery _searchQuery
)), )),
@@ -264,7 +248,7 @@ class EmailTileBuilder with BaseEmailItemTile {
fit: BoxFit.fill)), fit: BoxFit.fill)),
Expanded(child: buildInformationSender( Expanded(child: buildInformationSender(
_presentationEmail, _presentationEmail,
mailboxCurrent, mailboxContain,
isSearchEmailRunning, isSearchEmailRunning,
_searchQuery _searchQuery
)), )),
@@ -385,7 +369,7 @@ class EmailTileBuilder with BaseEmailItemTile {
width: 160, width: 160,
child: buildInformationSender( child: buildInformationSender(
_presentationEmail, _presentationEmail,
mailboxCurrent, mailboxContain,
isSearchEmailRunning, isSearchEmailRunning,
_searchQuery _searchQuery
)), )),
@@ -437,7 +421,7 @@ class EmailTileBuilder with BaseEmailItemTile {
: EmailActionType.markAsRead, : EmailActionType.markAsRead,
_presentationEmail)), _presentationEmail)),
const SizedBox(width: 5), const SizedBox(width: 5),
if (mailboxCurrent?.isDrafts == false) if (mailboxContain?.isDrafts == false)
... [ ... [
buildIconWeb( buildIconWeb(
minSize: 18, minSize: 18,
@@ -476,7 +460,7 @@ class EmailTileBuilder with BaseEmailItemTile {
: EmailActionType.moveToTrash, : EmailActionType.moveToTrash,
_presentationEmail)), _presentationEmail)),
const SizedBox(width: 5), const SizedBox(width: 5),
if (mailboxCurrent?.isDrafts == false) if (mailboxContain?.isDrafts == false)
buildIconWebHasPosition( buildIconWebHasPosition(
_context, _context,
icon: SvgPicture.asset( icon: SvgPicture.asset(
@@ -501,7 +485,7 @@ class EmailTileBuilder with BaseEmailItemTile {
} }
bool get canDeletePermanently { bool get canDeletePermanently {
return mailboxCurrent?.isTrash == true || mailboxCurrent?.isDrafts == true; return mailboxContain?.isTrash == true || mailboxContain?.isDrafts == true;
} }
Widget _buildDateTimeForDesktopScreen() { Widget _buildDateTimeForDesktopScreen() {
+13 -3
View File
@@ -1,17 +1,21 @@
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:jmap_dart_client/jmap/core/id.dart'; 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/main/routes/navigation_router.dart'; import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:universal_html/html.dart' as html;
class RouteUtils { abstract class RouteUtils {
static String get baseOriginUrl => Uri.base.origin; static String get baseOriginUrl => Uri.base.origin;
static String generateRoutePathMobile(String route, NavigationRouter router) { static String get baseUrl => Uri.base.path;
static String generateRouteMobile(String route, NavigationRouter router) {
ServicePath servicePath = ServicePath(route); ServicePath servicePath = ServicePath(route);
if (router.emailId != null) { if (router.emailId != null) {
servicePath = servicePath.withPathParameter(router.emailId!.id.value); servicePath = servicePath.withPathParameter(router.emailId!.id.value);
@@ -25,7 +29,7 @@ class RouteUtils {
return servicePath.path; return servicePath.path;
} }
static Uri generateRoutePathBrowser(String route, NavigationRouter router) { static Uri generateRouteBrowser(String route, NavigationRouter router) {
final baseRoutePath = '$baseOriginUrl/#$route'; final baseRoutePath = '$baseOriginUrl/#$route';
ServicePath servicePath = ServicePath(baseRoutePath); ServicePath servicePath = ServicePath(baseRoutePath);
if (router.emailId != null) { if (router.emailId != null) {
@@ -57,4 +61,10 @@ class RouteUtils {
dashboardType: dashboardType, dashboardType: dashboardType,
); );
} }
static void updateRouteOnBrowser(String title, Uri newRoute) {
log('RouteUtils::updateRouteOnBrowser(): title: $title');
log('RouteUtils::updateRouteOnBrowser(): newRoute: $newRoute');
html.window.history.replaceState(null, title, newRoute.toString());
}
} }
+12 -3
View File
@@ -1,5 +1,5 @@
import 'package:core/core.dart'; import 'package:core/presentation/extensions/string_extension.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart';
@@ -7,7 +7,8 @@ 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:jmap_dart_client/jmap/mail/email/keyword_identifier.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/model.dart'; import 'package:model/extensions/email_address_extension.dart';
import 'package:model/mailbox/select_mode.dart';
class PresentationEmail with EquatableMixin { class PresentationEmail with EquatableMixin {
@@ -27,6 +28,7 @@ class PresentationEmail with EquatableMixin {
final Map<MailboxId, bool>? mailboxIds; final Map<MailboxId, bool>? mailboxIds;
final List<MailboxName?>? mailboxNames; final List<MailboxName?>? mailboxNames;
final SelectMode selectMode; final SelectMode selectMode;
final Uri? routeWeb;
PresentationEmail( PresentationEmail(
this.id, this.id,
@@ -46,6 +48,7 @@ class PresentationEmail with EquatableMixin {
this.mailboxIds, this.mailboxIds,
this.mailboxNames, this.mailboxNames,
this.selectMode = SelectMode.INACTIVE, this.selectMode = SelectMode.INACTIVE,
this.routeWeb
} }
); );
@@ -72,6 +75,8 @@ class PresentationEmail with EquatableMixin {
String get mailboxName => mailboxNames?.first?.name ?? ''; String get mailboxName => mailboxNames?.first?.name ?? '';
String get routeWebAsString => routeWeb.toString();
@override @override
List<Object?> get props => [ List<Object?> get props => [
id, id,
@@ -86,6 +91,10 @@ class PresentationEmail with EquatableMixin {
sentAt, sentAt,
replyTo, replyTo,
preview, preview,
hasAttachment hasAttachment,
mailboxIds,
mailboxNames,
selectMode,
routeWeb
]; ];
} }
@@ -1,11 +1,18 @@
import 'dart:ui'; import 'dart:ui';
import 'package:core/core.dart'; import 'package:core/domain/extensions/datetime_extension.dart';
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/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/list_email_address_extension.dart';
import 'package:model/extensions/utc_date_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
extension PresentationEmailExtension on PresentationEmail { extension PresentationEmailExtension on PresentationEmail {
@@ -43,6 +50,7 @@ extension PresentationEmailExtension on PresentationEmail {
mailboxIds: mailboxIds, mailboxIds: mailboxIds,
mailboxNames: mailboxNames, mailboxNames: mailboxNames,
selectMode: selectMode == SelectMode.INACTIVE ? SelectMode.ACTIVE : SelectMode.INACTIVE, selectMode: selectMode == SelectMode.INACTIVE ? SelectMode.ACTIVE : SelectMode.INACTIVE,
routeWeb: routeWeb
); );
} }
@@ -64,6 +72,7 @@ extension PresentationEmailExtension on PresentationEmail {
mailboxIds: mailboxIds, mailboxIds: mailboxIds,
mailboxNames: mailboxNames, mailboxNames: mailboxNames,
selectMode: selectMode, selectMode: selectMode,
routeWeb: routeWeb
); );
} }
@@ -111,7 +120,7 @@ extension PresentationEmailExtension on PresentationEmail {
case EmailActionType.edit: case EmailActionType.edit:
return Tuple3(to.asList(), cc.asList(), bcc.asList()); return Tuple3(to.asList(), cc.asList(), bcc.asList());
default: default:
return Tuple3([], [], []); return const Tuple3([], [], []);
} }
} }
@@ -145,6 +154,7 @@ extension PresentationEmailExtension on PresentationEmail {
mailboxIds: mailboxIds, mailboxIds: mailboxIds,
mailboxNames: listMailboxName, mailboxNames: listMailboxName,
selectMode: selectMode, selectMode: selectMode,
routeWeb: routeWeb
); );
} }
@@ -160,4 +170,26 @@ extension PresentationEmailExtension on PresentationEmail {
} }
return null; return null;
} }
PresentationEmail withRouteWeb(Uri routeWeb) {
return PresentationEmail(
this.id,
keywords: keywords,
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
);
}
} }