From f9420417016427b7167341f4b8550983baf67796 Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 21 Mar 2022 15:25:49 +0700 Subject: [PATCH] TF-381 Navigation route ThreadView to EmailView on browser --- .../presentation/utils/responsive_utils.dart | 40 ++++--- .../views/responsive/responsive_widget.dart | 25 ++--- .../presentation/composer_controller.dart | 24 ++-- .../composer/presentation/composer_view.dart | 8 +- .../presentation/composer_view_web.dart | 12 +- .../presentation/destination_picker_view.dart | 10 +- .../email/presentation/email_controller.dart | 32 +++--- .../email/presentation/email_view.dart | 2 +- .../widgets/app_bar_mail_widget_builder.dart | 19 ++-- .../presentation/mailbox_controller.dart | 24 ++-- .../presentation/mailbox_creator_view.dart | 2 +- .../mailbox_dashboard_controller.dart | 36 +++--- .../presentation/mailbox_dashboard_view.dart | 104 +++++++++++------- .../presentation/model/app_setting.dart | 6 + .../presentation/model/reading_pane.dart | 5 + .../presentation/thread_controller.dart | 34 +++--- lib/main/routes/route_navigation.dart | 7 +- 17 files changed, 220 insertions(+), 170 deletions(-) create mode 100644 lib/features/setting/presentation/model/app_setting.dart create mode 100644 lib/features/setting/presentation/model/reading_pane.dart diff --git a/core/lib/presentation/utils/responsive_utils.dart b/core/lib/presentation/utils/responsive_utils.dart index 85ecf2770..7bd3158c4 100644 --- a/core/lib/presentation/utils/responsive_utils.dart +++ b/core/lib/presentation/utils/responsive_utils.dart @@ -1,39 +1,47 @@ import 'package:flutter/widgets.dart'; +import 'package:get/get.dart'; class ResponsiveUtils { - static const int minDesktopWidth = 1288; - static const int minTabletWidth = 600; - static const int minTabletLargeWidth = 900; + final int minDesktopWidth = 1200; + final int minTabletWidth = 600; + final int minTabletLargeWidth = 900; - static const double _loginTextFieldWidthSmallScreen = 280.0; - static const double _loginTextFieldWidthLargeScreen = 320.0; - static const double _loginButtonWidth = 240.0; + final double _loginTextFieldWidthSmallScreen = 280.0; + final double _loginTextFieldWidthLargeScreen = 320.0; + final double _loginButtonWidth = 240.0; final double tabletHorizontalMargin = 120.0; final double tabletVerticalMargin = 200.0; final double desktopVerticalMargin = 120.0; final double desktopHorizontalMargin = 200.0; - bool isMobileDevice(BuildContext context) => MediaQuery.of(context).size.shortestSide < minTabletWidth; + bool isMobileDevice(BuildContext context) => context.mediaQueryShortestSide < minTabletWidth; - double getSizeWidthScreen(BuildContext context) => MediaQuery.of(context).size.width; + double getSizeScreenWidth(BuildContext context) => context.width; - double getSizeHeightScreen(BuildContext context) => MediaQuery.of(context).size.height; + double getSizeScreenHeight(BuildContext context) => context.height; - double getMinSizeScreen(BuildContext context) => MediaQuery.of(context).size.shortestSide; + double getSizeScreenShortestSide(BuildContext context) => context.mediaQueryShortestSide; - bool isMobile(BuildContext context) => getSizeWidthScreen(context) < minTabletWidth; + double getDeviceWidth(BuildContext context) { + if (GetPlatform.isDesktop) { + return context.width; + } + return context.mediaQueryShortestSide; + } - bool isTablet(BuildContext context) => getSizeWidthScreen(context) >= minTabletWidth && getSizeWidthScreen(context) < minTabletLargeWidth; + bool isMobile(BuildContext context) => getDeviceWidth(context) < minTabletWidth; - bool isDesktop(BuildContext context) => getSizeWidthScreen(context) > minDesktopWidth; + bool isTablet(BuildContext context) => getDeviceWidth(context) >= minTabletWidth && getDeviceWidth(context) < minDesktopWidth; - bool isTabletLarge(BuildContext context) => getSizeWidthScreen(context) >= minTabletLargeWidth && getSizeWidthScreen(context) <= minDesktopWidth; + bool isDesktop(BuildContext context) => getDeviceWidth(context) >= minDesktopWidth; - bool isPortrait(BuildContext context) => MediaQuery.of(context).orientation == Orientation.portrait; + bool isTabletLarge(BuildContext context) => getDeviceWidth(context) >= minTabletLargeWidth && getDeviceWidth(context) < minDesktopWidth; - bool isLandscape(BuildContext context) => MediaQuery.of(context).orientation == Orientation.landscape; + bool isPortrait(BuildContext context) => context.orientation == Orientation.portrait; + + bool isLandscape(BuildContext context) => context.orientation == Orientation.landscape; double getWidthLoginTextField(BuildContext context) => isMobile(context) ? _loginTextFieldWidthSmallScreen : _loginTextFieldWidthLargeScreen; diff --git a/core/lib/presentation/views/responsive/responsive_widget.dart b/core/lib/presentation/views/responsive/responsive_widget.dart index 058cc462a..65b14cd82 100644 --- a/core/lib/presentation/views/responsive/responsive_widget.dart +++ b/core/lib/presentation/views/responsive/responsive_widget.dart @@ -1,9 +1,9 @@ -import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:core/core.dart'; import 'package:flutter/material.dart'; class ResponsiveWidget extends StatelessWidget { final Widget mobile; - final Widget tablet; + final Widget? tablet; final Widget? tabletLarge; final Widget? desktop; @@ -11,27 +11,18 @@ class ResponsiveWidget extends StatelessWidget { const ResponsiveWidget({ Key? key, + required this.responsiveUtils, required this.mobile, - required this.tablet, + this.tablet, this.desktop, this.tabletLarge, - required this.responsiveUtils, }) : super(key: key); @override Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, constraints) { - if (responsiveUtils.isMobileDevice(context)) { - return mobile; - } else if (responsiveUtils.isDesktop(context)) { - return desktop ?? tablet; - } else if (responsiveUtils.isTabletLarge(context)) { - return tabletLarge ?? tablet; - } else if (responsiveUtils.isTablet(context)) { - return tablet; - } else { - return mobile; - } - }); + if (desktop != null && responsiveUtils.isDesktop(context)) return desktop!; + if (tabletLarge != null && responsiveUtils.isTabletLarge(context)) return tabletLarge!; + if (tablet != null && responsiveUtils.isTablet(context)) return tablet!; + return mobile; } } \ No newline at end of file diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 1361c0ba9..9bcd73e59 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -180,11 +180,11 @@ class ComposerController extends BaseController { @override void onError(error) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, textColor: AppColor.toastErrorBackgroundColor, - message: AppLocalizations.of(Get.context!).message_has_been_sent_failure, + message: AppLocalizations.of(currentContext!).message_has_been_sent_failure, icon: _imagePaths.icSendToast); } popBack(); @@ -204,9 +204,9 @@ class ComposerController extends BaseController { } void _initSubjectEmail(ComposerArguments arguments) { - if (Get.context != null) { + if (currentContext != null) { final subjectEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? ''; - final newSubject = arguments.emailActionType.getSubjectComposer(Get.context!, subjectEmail); + final newSubject = arguments.emailActionType.getSubjectComposer(currentContext!, subjectEmail); setSubjectEmail(newSubject); subjectEmailInputController.text = newSubject; } @@ -476,8 +476,8 @@ class ComposerController extends BaseController { void _pickFileFailure(Failure failure) { if (failure is LocalFilePickerFailure) { - if (Get.context != null) { - _appToast.showErrorToast(AppLocalizations.of(Get.context!).can_not_upload_this_file_as_attachments); + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).can_not_upload_this_file_as_attachments); } } } @@ -498,8 +498,8 @@ class ComposerController extends BaseController { } void _uploadAttachmentsFailure(Failure failure) { - if (Get.context != null) { - _appToast.showErrorToast(AppLocalizations.of(Get.context!).can_not_upload_this_file_as_attachments); + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).can_not_upload_this_file_as_attachments); } } @@ -523,8 +523,8 @@ class ComposerController extends BaseController { attachments.addAll(listAttachment); } - if (Get.context != null) { - _appToast.showSuccessToast(AppLocalizations.of(Get.context!).attachments_uploaded_successfully); + if (currentContext != null) { + _appToast.showSuccessToast(AppLocalizations.of(currentContext!).attachments_uploaded_successfully); } } @@ -546,7 +546,7 @@ class ComposerController extends BaseController { final newEmailSubject = subjectEmail.value; final titleEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? ''; - final oldEmailSubject = arguments.emailActionType.getSubjectComposer(Get.context!, titleEmail); + final oldEmailSubject = arguments.emailActionType.getSubjectComposer(currentContext!, titleEmail); final isEmailSubjectChanged = !oldEmailSubject.isSame(newEmailSubject); final recipients = arguments.presentationEmail diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart index 4d5ae376e..43f5ee53b 100644 --- a/lib/features/composer/presentation/composer_view.dart +++ b/lib/features/composer/presentation/composer_view.dart @@ -73,8 +73,8 @@ class ComposerView extends GetWidget { elevation: 20, child: Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(10))), - width: responsiveUtils.getSizeWidthScreen(context) * 0.85, - height: responsiveUtils.getSizeHeightScreen(context) * 0.85, + width: responsiveUtils.getSizeScreenWidth(context) * 0.85, + height: responsiveUtils.getSizeScreenHeight(context) * 0.85, child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(10)), child: SafeArea( @@ -399,9 +399,9 @@ class ComposerView extends GetWidget { } int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) { - if (constraints.maxWidth < ResponsiveUtils.minTabletWidth) { + if (constraints.maxWidth < responsiveUtils.minTabletWidth) { return 2; - } else if (constraints.maxWidth < ResponsiveUtils.minTabletLargeWidth) { + } else if (constraints.maxWidth < responsiveUtils.minTabletLargeWidth) { return 3; } else { return 4; diff --git a/lib/features/composer/presentation/composer_view_web.dart b/lib/features/composer/presentation/composer_view_web.dart index 5603ff575..68d385d3e 100644 --- a/lib/features/composer/presentation/composer_view_web.dart +++ b/lib/features/composer/presentation/composer_view_web.dart @@ -55,8 +55,8 @@ class ComposerView extends GetWidget { color: Colors.transparent, child: Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), - width: responsiveUtils.getSizeWidthScreen(context) * 0.55, - height: responsiveUtils.getSizeHeightScreen(context) * 0.75, + width: responsiveUtils.getSizeScreenWidth(context) * 0.55, + height: responsiveUtils.getSizeScreenHeight(context) * 0.75, child: PointerInterceptor(child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -119,8 +119,8 @@ class ComposerView extends GetWidget { shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))), child: Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), - width: responsiveUtils.getSizeWidthScreen(context) * 0.85, - height: responsiveUtils.getSizeHeightScreen(context) * 0.9, + width: responsiveUtils.getSizeScreenWidth(context) * 0.85, + height: responsiveUtils.getSizeScreenHeight(context) * 0.9, child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(20)), child: PointerInterceptor(child: Column( @@ -542,9 +542,9 @@ class ComposerView extends GetWidget { } int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) { - if (constraints.maxWidth < ResponsiveUtils.minTabletWidth) { + if (constraints.maxWidth < responsiveUtils.minTabletWidth) { return 2; - } else if (constraints.maxWidth < ResponsiveUtils.minTabletLargeWidth) { + } else if (constraints.maxWidth < responsiveUtils.minTabletLargeWidth) { return 3; } else { return 4; diff --git a/lib/features/destination_picker/presentation/destination_picker_view.dart b/lib/features/destination_picker/presentation/destination_picker_view.dart index 4112e95a0..b832114b4 100644 --- a/lib/features/destination_picker/presentation/destination_picker_view.dart +++ b/lib/features/destination_picker/presentation/destination_picker_view.dart @@ -37,7 +37,7 @@ class DestinationPickerView extends GetWidget { mobile: _responsiveUtils.isPortrait(context) ? Container( child: _buildBodyMailboxLocation(context, actions), - width: _responsiveUtils.getSizeWidthScreen(context)) + width: _responsiveUtils.getSizeScreenWidth(context)) : _buildBodyMailboxDestination(context, actions), tablet: Container( child: Row( @@ -289,7 +289,7 @@ class DestinationPickerView extends GetWidget { right: _responsiveUtils.tabletHorizontalMargin, top: 50.0); } else if (_responsiveUtils.isTablet(context)) { - return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.tabletVerticalMargin * 2 + return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.tabletVerticalMargin * 2 ? EdgeInsets.symmetric( horizontal: _responsiveUtils.tabletHorizontalMargin, vertical: 0.0) @@ -297,7 +297,7 @@ class DestinationPickerView extends GetWidget { horizontal: _responsiveUtils.tabletHorizontalMargin, vertical: _responsiveUtils.tabletVerticalMargin); } else if (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context)) { - return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.desktopVerticalMargin * 2 + return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.desktopVerticalMargin * 2 ? EdgeInsets.symmetric( horizontal: _responsiveUtils.desktopHorizontalMargin, vertical: 0.0) @@ -313,11 +313,11 @@ class DestinationPickerView extends GetWidget { if (_responsiveUtils.isMobileDevice(context) && _responsiveUtils.isLandscape(context)) { return BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)); } else if (_responsiveUtils.isTablet(context)) { - return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.tabletVerticalMargin * 2 + return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.tabletVerticalMargin * 2 ? BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)) : BorderRadius.circular(radius); } else if (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context)) { - return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.desktopVerticalMargin * 2 + return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.desktopVerticalMargin * 2 ? BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)) : BorderRadius.circular(radius); } else { diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index 8fbeaf19e..4858c7f56 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -192,20 +192,16 @@ class EmailController extends BaseController { if (success is MarkAsEmailReadSuccess && success.readActions == ReadActions.markAsUnread - && Get.context != null - && !responsiveUtils.isDesktop(Get.context!) - && !responsiveUtils.isTabletLarge(Get.context!)) { - backToThreadView(); + && currentContext != null) { + backToThreadView(currentContext!); } } void _markAsEmailReadFailure(Failure failure) { if (failure is MarkAsEmailReadFailure && failure.readActions == ReadActions.markAsUnread - && Get.context != null - && !responsiveUtils.isDesktop(Get.context!) - && !responsiveUtils.isTabletLarge(Get.context!)) { - backToThreadView(); + && currentContext != null) { + backToThreadView(currentContext!); } } @@ -254,8 +250,8 @@ class EmailController extends BaseController { } void _downloadAttachmentsFailure(Failure failure) { - if (Get.context != null) { - _appToast.showErrorToast(AppLocalizations.of(Get.context!).attachment_download_failed); + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).attachment_download_failed); } } @@ -365,11 +361,11 @@ class EmailController extends BaseController { if (success is MoveToMailboxSuccess && success.moveAction == MoveAction.moveTo - && Get.context != null && Get.overlayContext != null) { + && currentContext != null && currentOverlayContext != null) { _appToast.showToastWithAction( - Get.overlayContext!, - AppLocalizations.of(Get.context!).moved_to_mailbox(success.destinationPath ?? ''), - AppLocalizations.of(Get.context!).undo_action, + currentOverlayContext!, + AppLocalizations.of(currentContext!).moved_to_mailbox(success.destinationPath ?? ''), + AppLocalizations.of(currentContext!).undo_action, () { final newMoveRequest = MoveRequest( [success.emailId], @@ -499,11 +495,15 @@ class EmailController extends BaseController { popBack(); } - void backToThreadView() { + void backToThreadView(BuildContext context) { attachmentsExpandMode.value = ExpandMode.COLLAPSE; emailAddressExpandMode.value = ExpandMode.COLLAPSE; isDisplayFullEmailAddress.value = false; - popBack(); + if (responsiveUtils.isDesktop(context) || responsiveUtils.isTabletLarge(context)) { + mailboxDashBoardController.dispatchRoute(AppRoutes.THREAD); + } else { + popBack(); + } } void pressEmailAction(EmailActionType emailActionType) { diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index a81490d99..fd24f49c5 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -75,7 +75,7 @@ class EmailView extends GetView { responsiveUtils, emailController.currentEmail, emailController.currentMailbox) - ..onBackActionClick(() => emailController.backToThreadView()) + ..onBackActionClick(() => emailController.backToThreadView(context)) ..addOnEmailActionClick((email, action) => emailController.handleEmailAction(context, email, action)) ..addOnMoreActionClick((email, position) => responsiveUtils.isMobileDevice(context) ? emailController.openMoreMenuEmailAction( diff --git a/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart b/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart index 3177bb14e..e2351fe57 100644 --- a/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart +++ b/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart @@ -2,9 +2,9 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.dart'; import 'package:model/model.dart'; -import 'package:tmail_ui_user/main/routes/app_routes.dart'; +import 'package:tmail_ui_user/features/setting/presentation/model/app_setting.dart'; +import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart'; typedef OnBackActionClick = void Function(); typedef OnEmailActionClick = void Function(PresentationEmail, EmailActionType); @@ -53,9 +53,9 @@ class AppBarMailWidgetBuilder { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [ - if (_conditionShowBackButton()) + if (_conditionShow(_context)) _buildBackButton(), - if (_conditionShowBackButton()) + if (_conditionShow(_context)) Expanded(child: _buildMailboxName()), if (_presentationEmail != null) _buildListOptionButton(), ] @@ -64,13 +64,12 @@ class AppBarMailWidgetBuilder { ); } - bool _conditionShowBackButton() { - if (Get.currentRoute == AppRoutes.MAILBOX_DASHBOARD) { - return !_responsiveUtils.isDesktop(_context) && !_responsiveUtils.isTabletLarge(_context); - } else if (Get.currentRoute == AppRoutes.EMAIL) { - return _responsiveUtils.isMobileDevice(_context) || _responsiveUtils.isTablet(_context); - } else { + bool _conditionShow(BuildContext context) { + if (AppSetting.readingPane == ReadingPane.rightOfInbox + && (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context))) { return false; + } else { + return true; } } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 7326c3e29..f1ad303ab 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -308,11 +308,11 @@ class MailboxController extends BaseMailboxController { } void _createNewMailboxSuccess(CreateNewMailboxSuccess success) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, textColor: AppColor.toastSuccessBackgroundColor, - message: AppLocalizations.of(Get.context!).new_mailbox_is_created(success.newMailbox.name?.name ?? ''), + message: AppLocalizations.of(currentContext!).new_mailbox_is_created(success.newMailbox.name?.name ?? ''), icon: _imagePaths.icFolderMailbox); } @@ -320,11 +320,11 @@ class MailboxController extends BaseMailboxController { } void _createNewMailboxFailure(CreateNewMailboxFailure failure) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, textColor: AppColor.toastErrorBackgroundColor, - message: AppLocalizations.of(Get.context!).create_new_mailbox_failure, + message: AppLocalizations.of(currentContext!).create_new_mailbox_failure, icon: _imagePaths.icFolderMailbox); } } @@ -503,20 +503,20 @@ class MailboxController extends BaseMailboxController { } void _deleteMailboxSuccess(DeleteMultipleMailboxSuccess success) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, - message: AppLocalizations.of(Get.context!).delete_mailboxes_successfully, + currentOverlayContext!, + message: AppLocalizations.of(currentContext!).delete_mailboxes_successfully, icon: _imagePaths.icSelected); } refreshMailboxChanges(); } void _deleteMailboxFailure(DeleteMultipleMailboxFailure failure) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, - message: AppLocalizations.of(Get.context!).delete_mailboxes_failure, + currentOverlayContext!, + message: AppLocalizations.of(currentContext!).delete_mailboxes_failure, icon: _imagePaths.icDeleteToast); } } diff --git a/lib/features/mailbox_creator/presentation/mailbox_creator_view.dart b/lib/features/mailbox_creator/presentation/mailbox_creator_view.dart index 8548fcc5e..66e3fba0a 100644 --- a/lib/features/mailbox_creator/presentation/mailbox_creator_view.dart +++ b/lib/features/mailbox_creator/presentation/mailbox_creator_view.dart @@ -24,7 +24,7 @@ class MailboxCreatorView extends GetWidget { responsiveUtils: _responsiveUtils, mobile: Container( child: _buildBody(context), - width: _responsiveUtils.getSizeWidthScreen(context)), + width: _responsiveUtils.getSizeScreenWidth(context)), tablet: Container( child: Row( children: [ diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart index 9ea732d39..2e0004842 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart @@ -25,6 +25,8 @@ import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.da import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.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/router_arguments.dart'; class MailboxDashBoardController extends ReloadableController { @@ -42,6 +44,7 @@ class MailboxDashBoardController extends ReloadableController { final searchState = SearchState.initial().obs; final suggestionSearch = [].obs; final dashBoardAction = DashBoardAction.none.obs; + final routePath = AppRoutes.MAILBOX_DASHBOARD.obs; SearchQuery? searchQuery; Session? sessionCurrent; @@ -66,10 +69,10 @@ class MailboxDashBoardController extends ReloadableController { super.onData(newState); viewState.value.map((success) { if (success is SendingEmailState) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, - message: AppLocalizations.of(Get.context!).your_email_being_sent, + currentOverlayContext!, + message: AppLocalizations.of(currentContext!).your_email_being_sent, icon: _imagePaths.icSendToast); } } @@ -81,11 +84,11 @@ class MailboxDashBoardController extends ReloadableController { viewState.value.fold( (failure) { if (failure is SendEmailFailure) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, textColor: AppColor.toastErrorBackgroundColor, - message: AppLocalizations.of(Get.context!).message_has_been_sent_failure, + message: AppLocalizations.of(currentContext!).message_has_been_sent_failure, icon: _imagePaths.icSendToast); } clearState(); @@ -99,11 +102,11 @@ class MailboxDashBoardController extends ReloadableController { if (success is GetUserProfileSuccess) { userProfile.value = success.userProfile; } else if (success is SendEmailSuccess) { - if (Get.overlayContext != null && Get.context != null) { + if (currentOverlayContext != null && currentContext != null) { _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, textColor: AppColor.toastSuccessBackgroundColor, - message: AppLocalizations.of(Get.context!).message_has_been_sent_successfully, + message: AppLocalizations.of(currentContext!).message_has_been_sent_successfully, icon: _imagePaths.icSendToast); } clearState(); @@ -152,11 +155,13 @@ class MailboxDashBoardController extends ReloadableController { void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) { selectedMailbox.value = newPresentationMailbox; + dispatchRoute(AppRoutes.THREAD); } void setNewFirstSelectedMailbox(PresentationMailbox? newPresentationMailbox) { selectedMailbox.firstRebuild = true; selectedMailbox.value = newPresentationMailbox; + dispatchRoute(AppRoutes.THREAD); } void setSelectedEmail(PresentationEmail? newPresentationEmail) { @@ -217,11 +222,11 @@ class MailboxDashBoardController extends ReloadableController { } void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) { - if (Get.context != null && Get.overlayContext != null) { + if (currentContext != null && currentOverlayContext != null) { _appToast.showToastWithAction( - Get.overlayContext!, - AppLocalizations.of(Get.context!).drafts_saved, - AppLocalizations.of(Get.context!).discard, + currentOverlayContext!, + AppLocalizations.of(currentContext!).drafts_saved, + AppLocalizations.of(currentContext!).discard, () => _discardEmail(success.emailAsDrafts) ); } @@ -248,6 +253,11 @@ class MailboxDashBoardController extends ReloadableController { dashBoardAction.value = action; } + void dispatchRoute(String route) { + routePath.value = route; + log('MailboxDashBoardController::dispatchRoute(): $route'); + } + @override void handleReloaded(Session session) { sessionCurrent = session; diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart index 9e83e3c28..c48622328 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart @@ -7,66 +7,90 @@ import 'package:tmail_ui_user/features/email/presentation/email_view.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart'; +import 'package:tmail_ui_user/features/setting/presentation/model/app_setting.dart'; +import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; class MailboxDashBoardView extends GetWidget { - final responsiveUtils = Get.find(); + final _responsiveUtils = Get.find(); @override Widget build(BuildContext context) { return Scaffold( key: controller.scaffoldKey, drawer: ResponsiveWidget( - responsiveUtils: responsiveUtils, - mobile: Container( - child: MailboxView(), - width: responsiveUtils.isPortrait(context) - ? responsiveUtils.getSizeWidthScreen(context) - : responsiveUtils.getSizeWidthScreen(context) / 2), - tablet: Container( - child: MailboxView(), - width: responsiveUtils.getSizeWidthScreen(context) / 2), - tabletLarge: Container( - child: MailboxView(), - width: responsiveUtils.getSizeWidthScreen(context) * 0.35), + responsiveUtils: _responsiveUtils, + mobile: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context)), + tablet: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context) / 2), desktop: SizedBox.shrink() ), - drawerEnableOpenDragGesture: !responsiveUtils.isDesktop(context), + drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context), body: Stack(children: [ ResponsiveWidget( - responsiveUtils: responsiveUtils, - desktop: Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded(flex: 1, child: MailboxView()), - Expanded(flex: 1, child: ThreadView()), - Expanded(flex: 2, child: EmailView()), - ], - ), + responsiveUtils: _responsiveUtils, + desktop: Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 1, child: MailboxView()), + Expanded(flex: 3, child: _buildThreadAndEmailContainer(context)), + ], ), - tabletLarge: Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: responsiveUtils.getSizeWidthScreen(context) * 0.35, - padding: EdgeInsets.symmetric(horizontal: 16), - child: ThreadView() - ), - Expanded(child: EmailView()), - ], - ), + ), + tabletLarge: Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 2, child: MailboxView()), + Expanded(flex: 4, child: _buildThreadAndEmailContainer(context)), + ], ), - tablet: ThreadView(), - mobile: ThreadView()), + ), + tablet: ThreadView(), + mobile: ThreadView() + ), Obx(() => controller.dashBoardAction == DashBoardAction.compose ? ComposerView() : SizedBox.shrink()), ]), ); } + + Widget _buildThreadAndEmailContainer(BuildContext context) { + switch(AppSetting.readingPane) { + case ReadingPane.noSplit: + return Obx(() { + switch(controller.routePath.value) { + case AppRoutes.THREAD: + return ThreadView(); + case AppRoutes.EMAIL: + return EmailView(); + default: + return SizedBox.shrink(); + } + }); + case ReadingPane.rightOfInbox: + if (_responsiveUtils.isDesktop(context)) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 1, child: ThreadView()), + Expanded(flex: 2, child: EmailView()), + ], + ); + } else { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 1, child: ThreadView()), + Expanded(flex: 1, child: EmailView()), + ], + ); + } + default: + return SizedBox.shrink(); + } + } } \ No newline at end of file diff --git a/lib/features/setting/presentation/model/app_setting.dart b/lib/features/setting/presentation/model/app_setting.dart new file mode 100644 index 000000000..b2a67ec8f --- /dev/null +++ b/lib/features/setting/presentation/model/app_setting.dart @@ -0,0 +1,6 @@ + +import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart'; + +class AppSetting { + static ReadingPane readingPane = ReadingPane.noSplit; +} \ No newline at end of file diff --git a/lib/features/setting/presentation/model/reading_pane.dart b/lib/features/setting/presentation/model/reading_pane.dart new file mode 100644 index 000000000..dfbca5f9c --- /dev/null +++ b/lib/features/setting/presentation/model/reading_pane.dart @@ -0,0 +1,5 @@ + +enum ReadingPane { + noSplit, + rightOfInbox, +} \ No newline at end of file diff --git a/lib/features/thread/presentation/thread_controller.dart b/lib/features/thread/presentation/thread_controller.dart index 01122becb..f7120c549 100644 --- a/lib/features/thread/presentation/thread_controller.dart +++ b/lib/features/thread/presentation/thread_controller.dart @@ -360,7 +360,9 @@ class ThreadController extends BaseController { void previewEmail(BuildContext context, PresentationEmail presentationEmailSelected) { mailboxDashBoardController.setSelectedEmail(presentationEmailSelected); - if (!responsiveUtils.isDesktop(context) && !responsiveUtils.isTabletLarge(context)) { + if (responsiveUtils.isDesktop(context) || responsiveUtils.isTabletLarge(context)) { + mailboxDashBoardController.dispatchRoute(AppRoutes.EMAIL); + } else { goToEmail(context); } } @@ -445,12 +447,12 @@ class ThreadController extends BaseController { readActions = success.readActions; } - if (Get.context != null && readActions != null && Get.overlayContext != null) { + if (currentContext != null && readActions != null && currentOverlayContext != null) { final message = readActions == ReadActions.markAsUnread - ? AppLocalizations.of(Get.context!).marked_message_toast(AppLocalizations.of(Get.context!).unread) - : AppLocalizations.of(Get.context!).marked_message_toast(AppLocalizations.of(Get.context!).read); + ? AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).unread) + : AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).read); _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, message: message, icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast); } @@ -458,7 +460,7 @@ class ThreadController extends BaseController { void _markAsSelectedEmailReadFailure(Failure failure) { cancelSelectEmail(); - _appToast.showErrorToast(AppLocalizations.of(Get.context!).an_error_occurred); + _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred); } void openFilterMessagesCupertinoActionSheet(BuildContext context, List actionTiles, {Widget? cancelButton}) { @@ -489,7 +491,7 @@ class ThreadController extends BaseController { filterMessageOption.value = newFilterOption; _appToast.showToastWithIcon( - Get.overlayContext!, + currentOverlayContext!, message: newFilterOption.getMessageToast(context), icon: newFilterOption.getIconToast(_imagePaths)); @@ -548,12 +550,12 @@ class ThreadController extends BaseController { moveAction = success.moveAction; } - if (Get.context != null && Get.overlayContext != null + if (currentContext != null && currentOverlayContext != null && destinationPath != null && moveAction == MoveAction.moveTo) { _appToast.showToastWithAction( - Get.overlayContext!, - AppLocalizations.of(Get.context!).moved_to_mailbox(destinationPath), - AppLocalizations.of(Get.context!).undo_action, + currentOverlayContext!, + AppLocalizations.of(currentContext!).moved_to_mailbox(destinationPath), + AppLocalizations.of(currentContext!).undo_action, () { final newCurrentMailboxId = destinationMailboxId; final newDestinationMailboxId = currentMailboxId; @@ -615,17 +617,17 @@ class ThreadController extends BaseController { countMarkStarSuccess = success.countMarkStarSuccess; } - if (Get.context != null && markStarAction != null) { + if (currentContext != null && markStarAction != null) { _appToast.showSuccessToast(markStarAction == MarkStarAction.unMarkStar - ? AppLocalizations.of(Get.context!).marked_unstar_multiple_item(countMarkStarSuccess) - : AppLocalizations.of(Get.context!).marked_star_multiple_item(countMarkStarSuccess)); + ? AppLocalizations.of(currentContext!).marked_unstar_multiple_item(countMarkStarSuccess) + : AppLocalizations.of(currentContext!).marked_star_multiple_item(countMarkStarSuccess)); } } void _markAsStarMultipleEmailFailure(Failure failure) { cancelSelectEmail(); - if (Get.context != null) { - _appToast.showErrorToast(AppLocalizations.of(Get.context!).an_error_occurred); + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred); } } diff --git a/lib/main/routes/route_navigation.dart b/lib/main/routes/route_navigation.dart index d563c2729..b2a2c742a 100644 --- a/lib/main/routes/route_navigation.dart +++ b/lib/main/routes/route_navigation.dart @@ -1,4 +1,5 @@ +import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; Future push(String routeName, {dynamic arguments}) async { @@ -15,4 +16,8 @@ Future pushAndPopAll(String routeName, {dynamic arguments}) async { void popBack({dynamic result}) { Get.back(result: result); -} \ No newline at end of file +} + +BuildContext? get currentContext => Get.context; + +BuildContext? get currentOverlayContext => Get.overlayContext; \ No newline at end of file