diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 9dff02731..82b5ed79b 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -48,6 +48,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/email_ac import 'package:tmail_ui_user/features/composer/presentation/model/image_source.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/inline_image.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/sending_email_arguments.dart'; import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; @@ -390,7 +391,9 @@ class ComposerController extends BaseController { } void _initEmail() { - final arguments = kIsWeb ? mailboxDashBoardController.routerArguments : Get.arguments; + final arguments = PlatformInfo.isWeb + ? mailboxDashBoardController.composerArguments + : Get.arguments; if (arguments is ComposerArguments) { composerArguments.value = arguments; injectAutoCompleteBindings( @@ -809,14 +812,25 @@ class ComposerController extends BaseController { ? CreateNewMailboxRequest(Id(_uuid.v1()), PresentationMailbox.outboxMailboxName) : null; - mailboxDashBoardController.handleSendEmailAction(session, accountId, emailRequest, mailboxRequest); + final sendingEmailArguments = SendingEmailArguments( + session, + accountId, + emailRequest, + mailboxRequest + ); uploadController.clearInlineFileUploaded(); - } - if (BuildUtils.isWeb) { - closeComposerWeb(); + if (PlatformInfo.isWeb) { + closeComposerWeb(result: sendingEmailArguments); + } else { + popBack(result: sendingEmailArguments); + } } else { - popBack(); + if (PlatformInfo.isWeb) { + closeComposerWeb(); + } else { + popBack(); + } } } @@ -1170,9 +1184,9 @@ class ComposerController extends BaseController { FocusManager.instance.primaryFocus?.unfocus(); } - void closeComposerWeb() { + void closeComposerWeb({dynamic result}) { FocusManager.instance.primaryFocus?.unfocus(); - mailboxDashBoardController.closeComposerOverlay(); + mailboxDashBoardController.closeComposerOverlay(result: result); } void displayScreenTypeComposerAction(ScreenDisplayMode displayMode) { diff --git a/lib/features/composer/presentation/model/sending_email_arguments.dart b/lib/features/composer/presentation/model/sending_email_arguments.dart new file mode 100644 index 000000000..71c7aa659 --- /dev/null +++ b/lib/features/composer/presentation/model/sending_email_arguments.dart @@ -0,0 +1,17 @@ +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/session/session.dart'; +import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; +import 'package:tmail_ui_user/main/routes/router_arguments.dart'; + +class SendingEmailArguments extends RouterArguments { + final Session session; + final AccountId accountId; + final EmailRequest emailRequest; + final CreateNewMailboxRequest? mailboxRequest; + + SendingEmailArguments(this.session, this.accountId, this.emailRequest, this.mailboxRequest); + + @override + List get props => [session, accountId, emailRequest, mailboxRequest]; +} diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index 7f405c78d..3118abc0e 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -137,7 +137,9 @@ class EmailView extends GetWidget { if (BuildUtils.isWeb) { return responsiveUtils.isTabletLarge(context); } else { - return responsiveUtils.isLandscapeTablet(context) || responsiveUtils.isDesktop(context); + return responsiveUtils.isLandscapeTablet(context) || + responsiveUtils.isDesktop(context) || + responsiveUtils.isTabletLarge(context); } } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index af6d53592..c6d246cde 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -200,7 +200,7 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM void _registerObxStreamListener() { ever(mailboxDashBoardController.accountId, (accountId) { - if (accountId is AccountId) { + if (accountId != null && mailboxDashBoardController.sessionCurrent != null) { getAllMailbox(mailboxDashBoardController.sessionCurrent!, accountId); } }); @@ -441,23 +441,17 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM BuildContext context, PresentationMailbox presentationMailboxSelected ) { - log('MailboxController::_handleOpenMailbox(): '); + log('MailboxController::_handleOpenMailbox():MailboxName: ${presentationMailboxSelected.name}'); KeyboardUtils.hideKeyboard(context); - + mailboxDashBoardController.setSelectedMailbox(presentationMailboxSelected); mailboxDashBoardController.clearSelectedEmail(); if (presentationMailboxSelected.id != mailboxDashBoardController.selectedMailbox.value?.id) { mailboxDashBoardController.clearFilterMessageOption(); } _disableAllSearchEmail(); - - mailboxDashBoardController.setSelectedMailbox(presentationMailboxSelected); _updateSelectedMailboxRouteOnBrowser(); - - if (mailboxDashBoardController.isDrawerOpen) { - mailboxDashBoardController.closeMailboxMenuDrawer(); - } else { - mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); - } + mailboxDashBoardController.closeMailboxMenuDrawer(); + mailboxDashBoardController.dispatchRoute(DashboardRoutes.thread); } void _disableAllSearchEmail() { @@ -1176,4 +1170,14 @@ class MailboxController extends BaseMailboxController with MailboxActionHandlerM bool get activeScrollTop => _activeScrollTop.value; bool get activeScrollBottom => _activeScrollBottom.value; + + void openSendingQueueViewAction(BuildContext context) { + KeyboardUtils.hideKeyboard(context); + _disableAllSearchEmail(); + mailboxDashBoardController.clearSelectedEmail(); + mailboxDashBoardController.clearFilterMessageOption(); + mailboxDashBoardController.setSelectedMailbox(null); + closeMailboxScreen(context); + mailboxDashBoardController.dispatchRoute(DashboardRoutes.sendingQueue); + } } \ No newline at end of file diff --git a/lib/features/mailbox/presentation/mailbox_view.dart b/lib/features/mailbox/presentation/mailbox_view.dart index 53777a059..da7258279 100644 --- a/lib/features/mailbox/presentation/mailbox_view.dart +++ b/lib/features/mailbox/presentation/mailbox_view.dart @@ -11,7 +11,9 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_catego import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/bottom_bar_selection_mailbox_widget.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/sending_queue_mailbox_widget.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget_builder.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/quotas/presentation/widget/quotas_footer_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; @@ -208,6 +210,19 @@ class MailboxView extends GetWidget return const SizedBox.shrink(); } }), + Obx(() { + if (controller.mailboxDashBoardController.listSendingEmails.isNotEmpty && + PlatformInfo.isMobile && + !controller.isSelectionEnabled()) { + return SendingQueueMailboxWidget( + listSendingEmails: controller.mailboxDashBoardController.listSendingEmails, + onOpenSendingQueueAction: () => controller.openSendingQueueViewAction(context), + isSelected: controller.mailboxDashBoardController.dashboardRoute.value == DashboardRoutes.sendingQueue, + ); + } else { + return const SizedBox.shrink(); + } + }), const SizedBox(height: 8), const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2), const SizedBox(height: 12), diff --git a/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart b/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart index 9b207beb7..eb3ef7f88 100644 --- a/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart +++ b/lib/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart @@ -339,7 +339,6 @@ mixin MailboxWidgetMixin { MailboxCategories.appGrid, controller), AnimatedContainer( - padding: const EdgeInsets.only(top: 8), duration: const Duration(milliseconds: 400), child: Obx(() { return controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.EXPAND @@ -358,27 +357,20 @@ mixin MailboxWidgetMixin { MailboxController controller ) { return Padding( - padding: EdgeInsets.only( - top: 8, - left: responsiveUtils.isDesktop(context) ? 0 : 36, - right: responsiveUtils.isDesktop(context) ? 0 : 28 - ), + padding: const EdgeInsets.only(left: 32, top: 8, bottom: 8, right: 4), child: Row(children: [ - buildIconWeb( - splashRadius: 5, - iconPadding: EdgeInsets.zero, - minSize: 12, - iconSize: 28, - icon: SvgPicture.asset( - imagePaths.icAppDashboard, - colorFilter: AppColor.primaryColor.asFilter(), - fit: BoxFit.fill), - tooltip: AppLocalizations.of(context).appGridTittle), + SvgPicture.asset( + imagePaths.icAppDashboard, + colorFilter: AppColor.primaryColor.asFilter(), + width: 20, + height: 20, + fit: BoxFit.fill), Expanded(child: Padding( - padding: const EdgeInsets.only(left: 12), + padding: const EdgeInsets.symmetric(horizontal: 8), child: Text(categories.getTitle(context), maxLines: 1, - overflow: TextOverflow.ellipsis, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, style: const TextStyle( fontSize: 16, color: AppColor.colorTextButton, @@ -391,7 +383,9 @@ mixin MailboxWidgetMixin { controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.COLLAPSE ? imagePaths.icCollapseFolder : imagePaths.icExpandFolder, - colorFilter: AppColor.primaryColor.asFilter(), + colorFilter: controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.COLLAPSE + ? AppColor.colorIconUnSubscribedMailbox.asFilter() + : AppColor.primaryColor.asFilter(), fit: BoxFit.fill )), tooltip: AppLocalizations.of(context).appGridTittle, @@ -408,7 +402,7 @@ mixin MailboxWidgetMixin { return ListView.builder( shrinkWrap: true, primary: false, - padding: const EdgeInsets.symmetric(horizontal: 16), + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 8), itemCount: linagoraApps.apps.length, itemBuilder: (context, index) { return AppListDashboardItem(linagoraApps.apps[index]); diff --git a/lib/features/mailbox/presentation/widgets/sending_queue_mailbox_widget.dart b/lib/features/mailbox/presentation/widgets/sending_queue_mailbox_widget.dart new file mode 100644 index 000000000..37e1dbca3 --- /dev/null +++ b/lib/features/mailbox/presentation/widgets/sending_queue_mailbox_widget.dart @@ -0,0 +1,107 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/presentation/utils/style_utils.dart'; +import 'package:core/utils/platform_info.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/utils/app_utils.dart'; + +class SendingQueueMailboxWidget extends StatelessWidget { + + final List listSendingEmails; + final bool isSelected; + final VoidCallback? onOpenSendingQueueAction; + + const SendingQueueMailboxWidget({ + super.key, + required this.listSendingEmails, + this.isSelected = false, + this.onOpenSendingQueueAction + }); + + @override + Widget build(BuildContext context) { + final imagePath = Get.find(); + final responsiveUtils = Get.find(); + + return Padding( + padding: const EdgeInsets.only(left: 20, right: 16), + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: onOpenSendingQueueAction, + borderRadius: const BorderRadius.all(Radius.circular(8)), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: isSelected ? AppColor.colorBgMailboxSelected : Colors.transparent), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(width: responsiveUtils.isLandscapeMobile(context) ? 20 : 28), + SvgPicture.asset( + imagePath.icMailboxSendingQueue, + width: PlatformInfo.isWeb ? 20 : 24, + height: PlatformInfo.isWeb ? 20 : 24, + colorFilter: AppColor.primaryColor.asFilter(), + fit: BoxFit.fill), + const SizedBox(width: 12), + Expanded(child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: Text( + AppLocalizations.of(context).sendingQueue, + maxLines: 1, + softWrap: CommonTextStyle.defaultSoftWrap, + overflow: CommonTextStyle.defaultTextOverFlow, + style: const TextStyle( + fontSize: 15, + color: AppColor.colorNameEmail, + fontWeight: FontWeight.normal), + ), + ), + Padding( + padding: EdgeInsets.only( + right: AppUtils.isDirectionRTL(context) ? 0 : 12, + left: AppUtils.isDirectionRTL(context) ? 12 : 0, + ), + child: Text( + _getCountSendingEmails(), + maxLines: 1, + overflow: CommonTextStyle.defaultTextOverFlow, + style: const TextStyle( + fontSize: 13, + color: Colors.black, + fontWeight: FontWeight.normal + ) + ), + ) + ], + )) + ] + ), + ] + ), + ), + ), + ), + ); + } + + String _getCountSendingEmails() { + if (listSendingEmails.isEmpty) { + return ''; + } + return listSendingEmails.length <= 999 ? '${listSendingEmails.length}' : '999+'; + } +} \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart index e946795af..e03e9242f 100644 --- a/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart +++ b/lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart @@ -1,3 +1,4 @@ +import 'package:core/core.dart'; import 'package:core/data/model/source_type/data_source_type.dart'; import 'package:core/data/network/dio_client.dart'; import 'package:core/utils/config/app_config_loader.dart'; @@ -103,6 +104,10 @@ import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_ import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller_bindings.dart'; import 'package:tmail_ui_user/features/search/email/domain/usecases/refresh_changes_search_email_interactor.dart'; import 'package:tmail_ui_user/features/search/email/presentation/search_email_bindings.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/bindings/sending_queue_bindings.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/datasource_impl/local_thread_datasource_impl.dart'; import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart'; @@ -128,6 +133,7 @@ class MailboxDashBoardBindings extends BaseBindings { @override void dependencies() { super.dependencies(); + SendingQueueBindings().dependencies(); MailboxBindings().dependencies(); ThreadBindings().dependencies(); EmailBindings().dependencies(); @@ -170,7 +176,8 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find(), Get.find(), Get.find(), - Get.find() + Get.find(), + Get.find() )); Get.put(AdvancedFilterController()); } @@ -324,6 +331,7 @@ class MailboxDashBoardBindings extends BaseBindings { Get.find() )); Get.lazyPut(() => StoreSendingEmailInteractor(Get.find())); + SendingQueueInteractorBindings().dependencies(); } @override @@ -382,5 +390,6 @@ class MailboxDashBoardBindings extends BaseBindings { Get.delete(); Get.delete(); Get.delete(); + Get.delete(); } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index 065981227..39dde3f7f 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -32,6 +32,7 @@ import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_draft 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/usecases/send_email_interactor.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/sending_email_arguments.dart'; import 'package:tmail_ui_user/features/email/domain/state/store_sending_email_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/store_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart'; @@ -98,6 +99,8 @@ import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_ema import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_mailbox_state_to_refresh_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_manager.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/state/get_all_sending_email_state.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart'; import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart'; import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; @@ -117,7 +120,6 @@ 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_utils.dart'; -import 'package:tmail_ui_user/main/routes/router_arguments.dart'; import 'package:tmail_ui_user/main/utils/email_receive_manager.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:uuid/uuid.dart'; @@ -152,6 +154,7 @@ class MailboxDashBoardController extends ReloadableController { final GetEmailByIdInteractor _getEmailByIdInteractor; final SendEmailInteractor _sendEmailInteractor; final StoreSendingEmailInteractor _storeSendingEmailInteractor; + final GetAllSendingEmailInteractor _getAllSendingEmailInteractor; GetAllVacationInteractor? _getAllVacationInteractor; UpdateVacationInteractor? _updateVacationInteractor; @@ -179,13 +182,15 @@ class MailboxDashBoardController extends ReloadableController { final routerParameters = Rxn>(); final _isDraggingMailbox = RxBool(false); final searchMailboxActivated = RxBool(false); + final listSendingEmails = RxList(); + Session? sessionCurrent; Map mapDefaultMailboxIdByRole = {}; Map mapMailboxById = {}; final emailsInCurrentMailbox = [].obs; final listResultSearch = RxList(); PresentationMailbox? outboxMailbox; - RouterArguments? routerArguments; + ComposerArguments? composerArguments; NavigationRouter? navigationRouter; late StreamSubscription _emailReceiveManagerStreamSubscription; @@ -220,6 +225,7 @@ class MailboxDashBoardController extends ReloadableController { this._getEmailByIdInteractor, this._sendEmailInteractor, this._storeSendingEmailInteractor, + this._getAllSendingEmailInteractor, ) : super( getAuthenticatedAccountInteractor, updateAuthenticationAccountInteractor @@ -324,6 +330,8 @@ class MailboxDashBoardController extends ReloadableController { _moveToEmailDetailedView(success); } else if (success is StoreSendingEmailSuccess) { _handleStoreSendingEmailSuccess(success); + } else if (success is GetAllSendingEmailSuccess) { + _handleGetAllSendingEmailsSuccess(success); } } @@ -434,7 +442,9 @@ class MailboxDashBoardController extends ReloadableController { injectFCMBindings(sessionCurrent, accountId.value); _getVacationResponse(); spamReportController.getSpamReportStateAction(); - + if (PlatformInfo.isMobile) { + _getAllSendingEmails(); + } if (!BuildUtils.isWeb && !_notificationManager.isNotificationClickedOnTerminate) { _handleClickLocalNotificationOnTerminated(); } else { @@ -532,7 +542,9 @@ class MailboxDashBoardController extends ReloadableController { } void closeMailboxMenuDrawer() { - scaffoldKey.currentState?.openEndDrawer(); + if (isDrawerOpen) { + scaffoldKey.currentState?.openEndDrawer(); + } } void hideMailboxMenuWhenScreenSizeChange(BuildContext context) { @@ -1168,16 +1180,25 @@ class MailboxDashBoardController extends ReloadableController { emailUIAction.value = newAction; } - void openComposerOverlay(RouterArguments? arguments) { - routerArguments = arguments; + void openComposerOverlay(ComposerArguments? arguments) { + composerArguments = arguments; ComposerBindings().dependencies(); composerOverlayState.value = ComposerOverlayState.active; } - void closeComposerOverlay() { - routerArguments = null; + void closeComposerOverlay({dynamic result}) { + composerArguments = null; ComposerBindings().dispose(); composerOverlayState.value = ComposerOverlayState.inActive; + + if (result is SendingEmailArguments) { + handleSendEmailAction( + result.session, + result.accountId, + result.emailRequest, + result.mailboxRequest + ); + } } void dispatchRoute(DashboardRoutes route) { @@ -1203,6 +1224,9 @@ class MailboxDashBoardController extends ReloadableController { injectVacationBindings(sessionCurrent, accountId.value); _getVacationResponse(); spamReportController.getSpamReportStateAction(); + if (PlatformInfo.isMobile) { + _getAllSendingEmails(); + } } void _getRouteParameters() { @@ -1281,13 +1305,21 @@ class MailboxDashBoardController extends ReloadableController { viewStateMarkAsReadMailbox.value = Right(UIState.idle); } - void goToComposer(ComposerArguments arguments) { - if (BuildUtils.isWeb) { + void goToComposer(ComposerArguments arguments) async { + if (PlatformInfo.isWeb) { if (composerOverlayState.value == ComposerOverlayState.inActive) { openComposerOverlay(arguments); } } else { - push(AppRoutes.composer, arguments: arguments); + final result = await push(AppRoutes.composer, arguments: arguments); + if (result is SendingEmailArguments) { + handleSendEmailAction( + result.session, + result.accountId, + result.emailRequest, + result.mailboxRequest + ); + } } } @@ -1304,9 +1336,7 @@ class MailboxDashBoardController extends ReloadableController { } void goToSettings() async { - if (isDrawerOpen) { - closeMailboxMenuDrawer(); - } + closeMailboxMenuDrawer(); final result = await push( AppRoutes.settings, arguments: ManageAccountArguments(sessionCurrent) @@ -1722,14 +1752,7 @@ class MailboxDashBoardController extends ReloadableController { EmailRequest emailRequest, CreateNewMailboxRequest? mailboxRequest ) { - if (PlatformInfo.isWeb) { - consumeState(_sendEmailInteractor.execute( - session, - accountId, - emailRequest, - mailboxRequest: mailboxRequest - )); - } else { + if (PlatformInfo.isMobile) { if (networkConnectionController.isNetworkConnectionAvailable()) { consumeState(_sendEmailInteractor.execute( session, @@ -1738,9 +1761,57 @@ class MailboxDashBoardController extends ReloadableController { mailboxRequest: mailboxRequest )); } else { - final sendingEmail = emailRequest.toSendingEmail(_uuid.v1(), mailboxRequest: mailboxRequest); - _storeSendingEmail(accountId, session.username, sendingEmail); + if (currentContext != null) { + showConfirmDialogAction( + currentContext!, + '', + AppLocalizations.of(currentContext!).proceed, + onConfirmAction: () { + final sendingEmail = emailRequest.toSendingEmail( + _uuid.v1(), + mailboxRequest: mailboxRequest + ); + _storeSendingEmail(accountId, session.username, sendingEmail); + }, + title: AppLocalizations.of(currentContext!).youAreInOfflineMode, + icon: SvgPicture.asset(_imagePaths.icDialogOfflineMode), + alignCenter: true, + messageStyle: const TextStyle( + color: AppColor.colorTitleSendingItem, + fontSize: 15, + fontWeight: FontWeight.normal + ), + listTextSpan: [ + TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailFirst), + TextSpan( + text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailSecond, + style: const TextStyle( + color: AppColor.colorTitleSendingItem, + fontSize: 15, + fontWeight: FontWeight.w600 + ), + ), + TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailThird), + TextSpan( + text: AppLocalizations.of(currentContext!).sendingQueue, + style: const TextStyle( + color: AppColor.colorTitleSendingItem, + fontSize: 15, + fontWeight: FontWeight.w600 + ), + ), + TextSpan(text: AppLocalizations.of(currentContext!).messageDialogWhenStoreSendingEmailTail) + ] + ); + } } + } else { + consumeState(_sendEmailInteractor.execute( + session, + accountId, + emailRequest, + mailboxRequest: mailboxRequest + )); } } @@ -1759,6 +1830,7 @@ class MailboxDashBoardController extends ReloadableController { } _addSendingEmailToSendingQueue(success.sendingEmail); + _getAllSendingEmails(); } void _addSendingEmailToSendingQueue(SendingEmail sendingEmail) async { @@ -1773,7 +1845,27 @@ class MailboxDashBoardController extends ReloadableController { initialDelay: const Duration(milliseconds: WorkManagerConstants.initialDelayTime), constraints: work_manager.Constraints(networkType: work_manager.NetworkType.connected) ); - await WorkSchedulerController().enqueue(workRequest); + + try { + await WorkSchedulerController().enqueue(workRequest); + } catch (e) { + logError('MailboxDashBoardController::_addSendingEmailToSendingQueue(): EXCEPTION: $e'); + } + } + + void _getAllSendingEmails() { + if (accountId.value != null && sessionCurrent != null) { + log('MailboxDashBoardController::_getAllSendingEmails():accountId: ${accountId.value} | userName: ${sessionCurrent?.username}'); + consumeState(_getAllSendingEmailInteractor.execute( + accountId.value!, + sessionCurrent!.username + )); + } + } + + void _handleGetAllSendingEmailsSuccess(GetAllSendingEmailSuccess success) { + log('MailboxDashBoardController::_handleGetAllSendingEmailsSuccess():COUNT: ${success.sendingEmails.length}'); + listSendingEmails.value = success.sendingEmails; } @override diff --git a/lib/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart b/lib/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart index ae839f936..a4428349e 100644 --- a/lib/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart +++ b/lib/features/manage_account/presentation/profiles/identities/widgets/delete_identity_dialog_builder.dart @@ -25,7 +25,7 @@ class DeleteIdentityDialogBuilder extends StatelessWidget { final deleteDialogBuilder = ResponsiveWidget( responsiveUtils: responsiveUtils, mobile: (_buildDeleteDialog(context) - ..aligment(Alignment.bottomCenter) + ..alignment(Alignment.bottomCenter) ..outsideDialogPadding(const EdgeInsets.only(left: 0, right: 0, bottom: BuildUtils.isWeb ? 42 : 16)) ..widthDialog(MediaQuery.of(context).size.width - 16) ..heightDialog(280)) diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index 8e37ff4e2..9052d28ea 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -6,6 +6,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; +import 'package:tmail_ui_user/features/base/mixin/compose_floating_button_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/popup_menu_widget_mixin.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; @@ -32,7 +33,8 @@ import 'package:tmail_ui_user/main/utils/app_utils.dart'; class ThreadView extends GetWidget with AppLoaderMixin, FilterEmailPopupMenuMixin, - PopupMenuWidgetMixin { + PopupMenuWidgetMixin, + ComposeFloatingButtonMixin { final _responsiveUtils = Get.find(); final _imagePaths = Get.find(); @@ -88,7 +90,9 @@ class ThreadView extends GetWidget if (BuildUtils.isWeb) { return _responsiveUtils.isTabletLarge(context); } else { - return _responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context); + return _responsiveUtils.isDesktop(context) || + _responsiveUtils.isTabletLarge(context) || + _responsiveUtils.isLandscapeTablet(context); } } @@ -181,33 +185,12 @@ class ThreadView extends GetWidget if (controller.isAllSearchInActive) { return Container( padding: BuildUtils.isWeb - ? EdgeInsets.zero - : controller.listEmailSelected.isNotEmpty ? const EdgeInsets.only(bottom: 70) : EdgeInsets.zero, - child: Align( - alignment: AppUtils.isDirectionRTL(context) - ? Alignment.bottomLeft - : Alignment.bottomRight, - child: ScrollingFloatingButtonAnimated( - icon: SvgPicture.asset(_imagePaths.icCompose, width: 20, height: 20, fit: BoxFit.fill), - text: Padding( - padding: EdgeInsets.only( - right: AppUtils.isDirectionRTL(context) ? 0 : 16, - left: AppUtils.isDirectionRTL(context) ? 16 : 0, - ), - child: Text(AppLocalizations.of(context).compose, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - style: const TextStyle( - color: AppColor.colorTextButton, - fontSize: 15.0, - fontWeight: FontWeight.w500))), - onPress: () => controller.mailboxDashBoardController.goToComposer(ComposerArguments()), - scrollController: controller.listEmailController, - color: Colors.white, - elevation: 4.0, - width: 140, - animateIcon: false - ) + ? EdgeInsets.zero + : controller.listEmailSelected.isNotEmpty ? const EdgeInsets.only(bottom: 70) : EdgeInsets.zero, + child: buildComposeFloatingButton( + context, + controller.listEmailController, + onTap: () => controller.mailboxDashBoardController.goToComposer(ComposerArguments()) ), ); } else { diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 76c14a3c2..91ef2f6a2 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2023-05-24T15:03:16.377036", + "@@last_modified": "2023-06-01T13:42:51.121212", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -2799,5 +2799,69 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "sendingQueue": "Sending queue", + "@sendingQueue": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "bannerMessageSendingQueueView": "Messages in Sending queue mailbox will be sent or scheduled when online.", + "@bannerMessageSendingQueueView": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "proceed": "Proceed", + "@proceed": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "youAreInOfflineMode": "You're in offline mode", + "@youAreInOfflineMode": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogWhenStoreSendingEmailFirst": "Fortunately, you can still", + "@messageDialogWhenStoreSendingEmailFirst": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogWhenStoreSendingEmailSecond": " send, reply, or forward ", + "@messageDialogWhenStoreSendingEmailSecond": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogWhenStoreSendingEmailThird": "emails. They will be delivered when you connect to the internet. To edit these emails before sending, go to the ", + "@messageDialogWhenStoreSendingEmailThird": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "messageDialogWhenStoreSendingEmailTail": " mailbox.", + "@messageDialogWhenStoreSendingEmailTail": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "titleRecipientSendingEmail": "To: {recipients}", + "@titleRecipientSendingEmail": { + "type": "text", + "placeholders_order": [ + "recipients" + ], + "placeholders": { + "recipients": {} + } + }, + "openMailboxMenu": "Open mailbox menu", + "@openMailboxMenu": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index be64bcc30..08108ac9b 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2876,4 +2876,74 @@ class AppLocalizations { name: 'messageHasBeenSavedToTheSendingQueue', ); } + + String get sendingQueue { + return Intl.message( + 'Sending queue', + name: 'sendingQueue' + ); + } + + String get bannerMessageSendingQueueView { + return Intl.message( + 'Messages in Sending queue mailbox will be sent or scheduled when online.', + name: 'bannerMessageSendingQueueView' + ); + } + + String get proceed { + return Intl.message( + 'Proceed', + name: 'proceed' + ); + } + + String get youAreInOfflineMode { + return Intl.message( + 'You\'re in offline mode', + name: 'youAreInOfflineMode' + ); + } + + String get messageDialogWhenStoreSendingEmailFirst { + return Intl.message( + 'Fortunately, you can still', + name: 'messageDialogWhenStoreSendingEmailFirst' + ); + } + + String get messageDialogWhenStoreSendingEmailSecond { + return Intl.message( + ' send, reply, or forward ', + name: 'messageDialogWhenStoreSendingEmailSecond' + ); + } + + String get messageDialogWhenStoreSendingEmailThird { + return Intl.message( + 'emails. They will be delivered when you connect to the internet. To edit these emails before sending, go to the ', + name: 'messageDialogWhenStoreSendingEmailThird' + ); + } + + String get messageDialogWhenStoreSendingEmailTail { + return Intl.message( + ' mailbox.', + name: 'messageDialogWhenStoreSendingEmailTail' + ); + } + + String titleRecipientSendingEmail(String recipients) { + return Intl.message( + 'To: $recipients', + name: 'titleRecipientSendingEmail', + args: [recipients]); + } + + String get openMailboxMenu { + return Intl.message( + 'Open mailbox menu', + name: 'openMailboxMenu' + ); + } } \ No newline at end of file