TF-381 Navigation route ThreadView to EmailView on browser

This commit is contained in:
dab246
2022-03-21 15:25:49 +07:00
committed by Dat H. Pham
parent 3914f3ad65
commit f942041701
17 changed files with 220 additions and 170 deletions
@@ -1,39 +1,47 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
class ResponsiveUtils { class ResponsiveUtils {
static const int minDesktopWidth = 1288; final int minDesktopWidth = 1200;
static const int minTabletWidth = 600; final int minTabletWidth = 600;
static const int minTabletLargeWidth = 900; final int minTabletLargeWidth = 900;
static const double _loginTextFieldWidthSmallScreen = 280.0; final double _loginTextFieldWidthSmallScreen = 280.0;
static const double _loginTextFieldWidthLargeScreen = 320.0; final double _loginTextFieldWidthLargeScreen = 320.0;
static const double _loginButtonWidth = 240.0; final double _loginButtonWidth = 240.0;
final double tabletHorizontalMargin = 120.0; final double tabletHorizontalMargin = 120.0;
final double tabletVerticalMargin = 200.0; final double tabletVerticalMargin = 200.0;
final double desktopVerticalMargin = 120.0; final double desktopVerticalMargin = 120.0;
final double desktopHorizontalMargin = 200.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; double getWidthLoginTextField(BuildContext context) => isMobile(context) ? _loginTextFieldWidthSmallScreen : _loginTextFieldWidthLargeScreen;
@@ -1,9 +1,9 @@
import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ResponsiveWidget extends StatelessWidget { class ResponsiveWidget extends StatelessWidget {
final Widget mobile; final Widget mobile;
final Widget tablet; final Widget? tablet;
final Widget? tabletLarge; final Widget? tabletLarge;
final Widget? desktop; final Widget? desktop;
@@ -11,27 +11,18 @@ class ResponsiveWidget extends StatelessWidget {
const ResponsiveWidget({ const ResponsiveWidget({
Key? key, Key? key,
required this.responsiveUtils,
required this.mobile, required this.mobile,
required this.tablet, this.tablet,
this.desktop, this.desktop,
this.tabletLarge, this.tabletLarge,
required this.responsiveUtils,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) { if (desktop != null && responsiveUtils.isDesktop(context)) return desktop!;
if (responsiveUtils.isMobileDevice(context)) { if (tabletLarge != null && responsiveUtils.isTabletLarge(context)) return tabletLarge!;
return mobile; if (tablet != null && responsiveUtils.isTablet(context)) return tablet!;
} else if (responsiveUtils.isDesktop(context)) { return mobile;
return desktop ?? tablet;
} else if (responsiveUtils.isTabletLarge(context)) {
return tabletLarge ?? tablet;
} else if (responsiveUtils.isTablet(context)) {
return tablet;
} else {
return mobile;
}
});
} }
} }
@@ -180,11 +180,11 @@ class ComposerController extends BaseController {
@override @override
void onError(error) { void onError(error) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
textColor: AppColor.toastErrorBackgroundColor, 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); icon: _imagePaths.icSendToast);
} }
popBack(); popBack();
@@ -204,9 +204,9 @@ class ComposerController extends BaseController {
} }
void _initSubjectEmail(ComposerArguments arguments) { void _initSubjectEmail(ComposerArguments arguments) {
if (Get.context != null) { if (currentContext != null) {
final subjectEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? ''; final subjectEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? '';
final newSubject = arguments.emailActionType.getSubjectComposer(Get.context!, subjectEmail); final newSubject = arguments.emailActionType.getSubjectComposer(currentContext!, subjectEmail);
setSubjectEmail(newSubject); setSubjectEmail(newSubject);
subjectEmailInputController.text = newSubject; subjectEmailInputController.text = newSubject;
} }
@@ -476,8 +476,8 @@ class ComposerController extends BaseController {
void _pickFileFailure(Failure failure) { void _pickFileFailure(Failure failure) {
if (failure is LocalFilePickerFailure) { if (failure is LocalFilePickerFailure) {
if (Get.context != null) { if (currentContext != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).can_not_upload_this_file_as_attachments); _appToast.showErrorToast(AppLocalizations.of(currentContext!).can_not_upload_this_file_as_attachments);
} }
} }
} }
@@ -498,8 +498,8 @@ class ComposerController extends BaseController {
} }
void _uploadAttachmentsFailure(Failure failure) { void _uploadAttachmentsFailure(Failure failure) {
if (Get.context != null) { if (currentContext != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).can_not_upload_this_file_as_attachments); _appToast.showErrorToast(AppLocalizations.of(currentContext!).can_not_upload_this_file_as_attachments);
} }
} }
@@ -523,8 +523,8 @@ class ComposerController extends BaseController {
attachments.addAll(listAttachment); attachments.addAll(listAttachment);
} }
if (Get.context != null) { if (currentContext != null) {
_appToast.showSuccessToast(AppLocalizations.of(Get.context!).attachments_uploaded_successfully); _appToast.showSuccessToast(AppLocalizations.of(currentContext!).attachments_uploaded_successfully);
} }
} }
@@ -546,7 +546,7 @@ class ComposerController extends BaseController {
final newEmailSubject = subjectEmail.value; final newEmailSubject = subjectEmail.value;
final titleEmail = arguments.presentationEmail?.getEmailTitle().trim() ?? ''; 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 isEmailSubjectChanged = !oldEmailSubject.isSame(newEmailSubject);
final recipients = arguments.presentationEmail final recipients = arguments.presentationEmail
@@ -73,8 +73,8 @@ class ComposerView extends GetWidget<ComposerController> {
elevation: 20, elevation: 20,
child: Container( child: Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(10))), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(10))),
width: responsiveUtils.getSizeWidthScreen(context) * 0.85, width: responsiveUtils.getSizeScreenWidth(context) * 0.85,
height: responsiveUtils.getSizeHeightScreen(context) * 0.85, height: responsiveUtils.getSizeScreenHeight(context) * 0.85,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)), borderRadius: BorderRadius.all(Radius.circular(10)),
child: SafeArea( child: SafeArea(
@@ -399,9 +399,9 @@ class ComposerView extends GetWidget<ComposerController> {
} }
int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) { int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth < ResponsiveUtils.minTabletWidth) { if (constraints.maxWidth < responsiveUtils.minTabletWidth) {
return 2; return 2;
} else if (constraints.maxWidth < ResponsiveUtils.minTabletLargeWidth) { } else if (constraints.maxWidth < responsiveUtils.minTabletLargeWidth) {
return 3; return 3;
} else { } else {
return 4; return 4;
@@ -55,8 +55,8 @@ class ComposerView extends GetWidget<ComposerController> {
color: Colors.transparent, color: Colors.transparent,
child: Container( child: Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))),
width: responsiveUtils.getSizeWidthScreen(context) * 0.55, width: responsiveUtils.getSizeScreenWidth(context) * 0.55,
height: responsiveUtils.getSizeHeightScreen(context) * 0.75, height: responsiveUtils.getSizeScreenHeight(context) * 0.75,
child: PointerInterceptor(child: Column( child: PointerInterceptor(child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@@ -119,8 +119,8 @@ class ComposerView extends GetWidget<ComposerController> {
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))), shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))),
child: Container( child: Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))),
width: responsiveUtils.getSizeWidthScreen(context) * 0.85, width: responsiveUtils.getSizeScreenWidth(context) * 0.85,
height: responsiveUtils.getSizeHeightScreen(context) * 0.9, height: responsiveUtils.getSizeScreenHeight(context) * 0.9,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)), borderRadius: BorderRadius.all(Radius.circular(20)),
child: PointerInterceptor(child: Column( child: PointerInterceptor(child: Column(
@@ -542,9 +542,9 @@ class ComposerView extends GetWidget<ComposerController> {
} }
int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) { int _getMaxItemRowListAttachment(BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth < ResponsiveUtils.minTabletWidth) { if (constraints.maxWidth < responsiveUtils.minTabletWidth) {
return 2; return 2;
} else if (constraints.maxWidth < ResponsiveUtils.minTabletLargeWidth) { } else if (constraints.maxWidth < responsiveUtils.minTabletLargeWidth) {
return 3; return 3;
} else { } else {
return 4; return 4;
@@ -37,7 +37,7 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
mobile: _responsiveUtils.isPortrait(context) mobile: _responsiveUtils.isPortrait(context)
? Container( ? Container(
child: _buildBodyMailboxLocation(context, actions), child: _buildBodyMailboxLocation(context, actions),
width: _responsiveUtils.getSizeWidthScreen(context)) width: _responsiveUtils.getSizeScreenWidth(context))
: _buildBodyMailboxDestination(context, actions), : _buildBodyMailboxDestination(context, actions),
tablet: Container( tablet: Container(
child: Row( child: Row(
@@ -289,7 +289,7 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
right: _responsiveUtils.tabletHorizontalMargin, right: _responsiveUtils.tabletHorizontalMargin,
top: 50.0); top: 50.0);
} else if (_responsiveUtils.isTablet(context)) { } else if (_responsiveUtils.isTablet(context)) {
return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.tabletVerticalMargin * 2 return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.tabletVerticalMargin * 2
? EdgeInsets.symmetric( ? EdgeInsets.symmetric(
horizontal: _responsiveUtils.tabletHorizontalMargin, horizontal: _responsiveUtils.tabletHorizontalMargin,
vertical: 0.0) vertical: 0.0)
@@ -297,7 +297,7 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
horizontal: _responsiveUtils.tabletHorizontalMargin, horizontal: _responsiveUtils.tabletHorizontalMargin,
vertical: _responsiveUtils.tabletVerticalMargin); vertical: _responsiveUtils.tabletVerticalMargin);
} else if (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context)) { } else if (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context)) {
return _responsiveUtils.getSizeHeightScreen(context) <= _responsiveUtils.desktopVerticalMargin * 2 return _responsiveUtils.getSizeScreenHeight(context) <= _responsiveUtils.desktopVerticalMargin * 2
? EdgeInsets.symmetric( ? EdgeInsets.symmetric(
horizontal: _responsiveUtils.desktopHorizontalMargin, horizontal: _responsiveUtils.desktopHorizontalMargin,
vertical: 0.0) vertical: 0.0)
@@ -313,11 +313,11 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
if (_responsiveUtils.isMobileDevice(context) && _responsiveUtils.isLandscape(context)) { if (_responsiveUtils.isMobileDevice(context) && _responsiveUtils.isLandscape(context)) {
return BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius)); return BorderRadius.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius));
} else if (_responsiveUtils.isTablet(context)) { } 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.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius))
: BorderRadius.circular(radius); : BorderRadius.circular(radius);
} else if (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context)) { } 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.only(topLeft: Radius.circular(radius), topRight: Radius.circular(radius))
: BorderRadius.circular(radius); : BorderRadius.circular(radius);
} else { } else {
@@ -192,20 +192,16 @@ class EmailController extends BaseController {
if (success is MarkAsEmailReadSuccess if (success is MarkAsEmailReadSuccess
&& success.readActions == ReadActions.markAsUnread && success.readActions == ReadActions.markAsUnread
&& Get.context != null && currentContext != null) {
&& !responsiveUtils.isDesktop(Get.context!) backToThreadView(currentContext!);
&& !responsiveUtils.isTabletLarge(Get.context!)) {
backToThreadView();
} }
} }
void _markAsEmailReadFailure(Failure failure) { void _markAsEmailReadFailure(Failure failure) {
if (failure is MarkAsEmailReadFailure if (failure is MarkAsEmailReadFailure
&& failure.readActions == ReadActions.markAsUnread && failure.readActions == ReadActions.markAsUnread
&& Get.context != null && currentContext != null) {
&& !responsiveUtils.isDesktop(Get.context!) backToThreadView(currentContext!);
&& !responsiveUtils.isTabletLarge(Get.context!)) {
backToThreadView();
} }
} }
@@ -254,8 +250,8 @@ class EmailController extends BaseController {
} }
void _downloadAttachmentsFailure(Failure failure) { void _downloadAttachmentsFailure(Failure failure) {
if (Get.context != null) { if (currentContext != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).attachment_download_failed); _appToast.showErrorToast(AppLocalizations.of(currentContext!).attachment_download_failed);
} }
} }
@@ -365,11 +361,11 @@ class EmailController extends BaseController {
if (success is MoveToMailboxSuccess if (success is MoveToMailboxSuccess
&& success.moveAction == MoveAction.moveTo && success.moveAction == MoveAction.moveTo
&& Get.context != null && Get.overlayContext != null) { && currentContext != null && currentOverlayContext != null) {
_appToast.showToastWithAction( _appToast.showToastWithAction(
Get.overlayContext!, currentOverlayContext!,
AppLocalizations.of(Get.context!).moved_to_mailbox(success.destinationPath ?? ''), AppLocalizations.of(currentContext!).moved_to_mailbox(success.destinationPath ?? ''),
AppLocalizations.of(Get.context!).undo_action, AppLocalizations.of(currentContext!).undo_action,
() { () {
final newMoveRequest = MoveRequest( final newMoveRequest = MoveRequest(
[success.emailId], [success.emailId],
@@ -499,11 +495,15 @@ class EmailController extends BaseController {
popBack(); popBack();
} }
void backToThreadView() { void backToThreadView(BuildContext context) {
attachmentsExpandMode.value = ExpandMode.COLLAPSE; attachmentsExpandMode.value = ExpandMode.COLLAPSE;
emailAddressExpandMode.value = ExpandMode.COLLAPSE; emailAddressExpandMode.value = ExpandMode.COLLAPSE;
isDisplayFullEmailAddress.value = false; isDisplayFullEmailAddress.value = false;
popBack(); if (responsiveUtils.isDesktop(context) || responsiveUtils.isTabletLarge(context)) {
mailboxDashBoardController.dispatchRoute(AppRoutes.THREAD);
} else {
popBack();
}
} }
void pressEmailAction(EmailActionType emailActionType) { void pressEmailAction(EmailActionType emailActionType) {
@@ -75,7 +75,7 @@ class EmailView extends GetView {
responsiveUtils, responsiveUtils,
emailController.currentEmail, emailController.currentEmail,
emailController.currentMailbox) emailController.currentMailbox)
..onBackActionClick(() => emailController.backToThreadView()) ..onBackActionClick(() => emailController.backToThreadView(context))
..addOnEmailActionClick((email, action) => emailController.handleEmailAction(context, email, action)) ..addOnEmailActionClick((email, action) => emailController.handleEmailAction(context, email, action))
..addOnMoreActionClick((email, position) => responsiveUtils.isMobileDevice(context) ..addOnMoreActionClick((email, position) => responsiveUtils.isMobileDevice(context)
? emailController.openMoreMenuEmailAction( ? emailController.openMoreMenuEmailAction(
@@ -2,9 +2,9 @@
import 'package:core/core.dart'; import 'package:core/core.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:model/model.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 OnBackActionClick = void Function();
typedef OnEmailActionClick = void Function(PresentationEmail, EmailActionType); typedef OnEmailActionClick = void Function(PresentationEmail, EmailActionType);
@@ -53,9 +53,9 @@ class AppBarMailWidgetBuilder {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
if (_conditionShowBackButton()) if (_conditionShow(_context))
_buildBackButton(), _buildBackButton(),
if (_conditionShowBackButton()) if (_conditionShow(_context))
Expanded(child: _buildMailboxName()), Expanded(child: _buildMailboxName()),
if (_presentationEmail != null) _buildListOptionButton(), if (_presentationEmail != null) _buildListOptionButton(),
] ]
@@ -64,13 +64,12 @@ class AppBarMailWidgetBuilder {
); );
} }
bool _conditionShowBackButton() { bool _conditionShow(BuildContext context) {
if (Get.currentRoute == AppRoutes.MAILBOX_DASHBOARD) { if (AppSetting.readingPane == ReadingPane.rightOfInbox
return !_responsiveUtils.isDesktop(_context) && !_responsiveUtils.isTabletLarge(_context); && (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context))) {
} else if (Get.currentRoute == AppRoutes.EMAIL) {
return _responsiveUtils.isMobileDevice(_context) || _responsiveUtils.isTablet(_context);
} else {
return false; return false;
} else {
return true;
} }
} }
@@ -308,11 +308,11 @@ class MailboxController extends BaseMailboxController {
} }
void _createNewMailboxSuccess(CreateNewMailboxSuccess success) { void _createNewMailboxSuccess(CreateNewMailboxSuccess success) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
textColor: AppColor.toastSuccessBackgroundColor, 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); icon: _imagePaths.icFolderMailbox);
} }
@@ -320,11 +320,11 @@ class MailboxController extends BaseMailboxController {
} }
void _createNewMailboxFailure(CreateNewMailboxFailure failure) { void _createNewMailboxFailure(CreateNewMailboxFailure failure) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
textColor: AppColor.toastErrorBackgroundColor, textColor: AppColor.toastErrorBackgroundColor,
message: AppLocalizations.of(Get.context!).create_new_mailbox_failure, message: AppLocalizations.of(currentContext!).create_new_mailbox_failure,
icon: _imagePaths.icFolderMailbox); icon: _imagePaths.icFolderMailbox);
} }
} }
@@ -503,20 +503,20 @@ class MailboxController extends BaseMailboxController {
} }
void _deleteMailboxSuccess(DeleteMultipleMailboxSuccess success) { void _deleteMailboxSuccess(DeleteMultipleMailboxSuccess success) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
message: AppLocalizations.of(Get.context!).delete_mailboxes_successfully, message: AppLocalizations.of(currentContext!).delete_mailboxes_successfully,
icon: _imagePaths.icSelected); icon: _imagePaths.icSelected);
} }
refreshMailboxChanges(); refreshMailboxChanges();
} }
void _deleteMailboxFailure(DeleteMultipleMailboxFailure failure) { void _deleteMailboxFailure(DeleteMultipleMailboxFailure failure) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
message: AppLocalizations.of(Get.context!).delete_mailboxes_failure, message: AppLocalizations.of(currentContext!).delete_mailboxes_failure,
icon: _imagePaths.icDeleteToast); icon: _imagePaths.icDeleteToast);
} }
} }
@@ -24,7 +24,7 @@ class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
responsiveUtils: _responsiveUtils, responsiveUtils: _responsiveUtils,
mobile: Container( mobile: Container(
child: _buildBody(context), child: _buildBody(context),
width: _responsiveUtils.getSizeWidthScreen(context)), width: _responsiveUtils.getSizeScreenWidth(context)),
tablet: Container( tablet: Container(
child: Row( child: Row(
children: [ children: [
@@ -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_state.dart';
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/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/router_arguments.dart'; import 'package:tmail_ui_user/main/routes/router_arguments.dart';
class MailboxDashBoardController extends ReloadableController { class MailboxDashBoardController extends ReloadableController {
@@ -42,6 +44,7 @@ class MailboxDashBoardController extends ReloadableController {
final searchState = SearchState.initial().obs; final searchState = SearchState.initial().obs;
final suggestionSearch = <String>[].obs; final suggestionSearch = <String>[].obs;
final dashBoardAction = DashBoardAction.none.obs; final dashBoardAction = DashBoardAction.none.obs;
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
SearchQuery? searchQuery; SearchQuery? searchQuery;
Session? sessionCurrent; Session? sessionCurrent;
@@ -66,10 +69,10 @@ class MailboxDashBoardController extends ReloadableController {
super.onData(newState); super.onData(newState);
viewState.value.map((success) { viewState.value.map((success) {
if (success is SendingEmailState) { if (success is SendingEmailState) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
message: AppLocalizations.of(Get.context!).your_email_being_sent, message: AppLocalizations.of(currentContext!).your_email_being_sent,
icon: _imagePaths.icSendToast); icon: _imagePaths.icSendToast);
} }
} }
@@ -81,11 +84,11 @@ class MailboxDashBoardController extends ReloadableController {
viewState.value.fold( viewState.value.fold(
(failure) { (failure) {
if (failure is SendEmailFailure) { if (failure is SendEmailFailure) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
textColor: AppColor.toastErrorBackgroundColor, 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); icon: _imagePaths.icSendToast);
} }
clearState(); clearState();
@@ -99,11 +102,11 @@ class MailboxDashBoardController extends ReloadableController {
if (success is GetUserProfileSuccess) { if (success is GetUserProfileSuccess) {
userProfile.value = success.userProfile; userProfile.value = success.userProfile;
} else if (success is SendEmailSuccess) { } else if (success is SendEmailSuccess) {
if (Get.overlayContext != null && Get.context != null) { if (currentOverlayContext != null && currentContext != null) {
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
textColor: AppColor.toastSuccessBackgroundColor, 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); icon: _imagePaths.icSendToast);
} }
clearState(); clearState();
@@ -152,11 +155,13 @@ class MailboxDashBoardController extends ReloadableController {
void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) { void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) {
selectedMailbox.value = newPresentationMailbox; selectedMailbox.value = newPresentationMailbox;
dispatchRoute(AppRoutes.THREAD);
} }
void setNewFirstSelectedMailbox(PresentationMailbox? newPresentationMailbox) { void setNewFirstSelectedMailbox(PresentationMailbox? newPresentationMailbox) {
selectedMailbox.firstRebuild = true; selectedMailbox.firstRebuild = true;
selectedMailbox.value = newPresentationMailbox; selectedMailbox.value = newPresentationMailbox;
dispatchRoute(AppRoutes.THREAD);
} }
void setSelectedEmail(PresentationEmail? newPresentationEmail) { void setSelectedEmail(PresentationEmail? newPresentationEmail) {
@@ -217,11 +222,11 @@ class MailboxDashBoardController extends ReloadableController {
} }
void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) { void _saveEmailAsDraftsSuccess(SaveEmailAsDraftsSuccess success) {
if (Get.context != null && Get.overlayContext != null) { if (currentContext != null && currentOverlayContext != null) {
_appToast.showToastWithAction( _appToast.showToastWithAction(
Get.overlayContext!, currentOverlayContext!,
AppLocalizations.of(Get.context!).drafts_saved, AppLocalizations.of(currentContext!).drafts_saved,
AppLocalizations.of(Get.context!).discard, AppLocalizations.of(currentContext!).discard,
() => _discardEmail(success.emailAsDrafts) () => _discardEmail(success.emailAsDrafts)
); );
} }
@@ -248,6 +253,11 @@ class MailboxDashBoardController extends ReloadableController {
dashBoardAction.value = action; dashBoardAction.value = action;
} }
void dispatchRoute(String route) {
routePath.value = route;
log('MailboxDashBoardController::dispatchRoute(): $route');
}
@override @override
void handleReloaded(Session session) { void handleReloaded(Session session) {
sessionCurrent = session; sessionCurrent = session;
@@ -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/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/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.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/features/thread/presentation/thread_view.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> { class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> {
final responsiveUtils = Get.find<ResponsiveUtils>(); final _responsiveUtils = Get.find<ResponsiveUtils>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
key: controller.scaffoldKey, key: controller.scaffoldKey,
drawer: ResponsiveWidget( drawer: ResponsiveWidget(
responsiveUtils: responsiveUtils, responsiveUtils: _responsiveUtils,
mobile: Container( mobile: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context)),
child: MailboxView(), tablet: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context) / 2),
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),
desktop: SizedBox.shrink() desktop: SizedBox.shrink()
), ),
drawerEnableOpenDragGesture: !responsiveUtils.isDesktop(context), drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context),
body: Stack(children: [ body: Stack(children: [
ResponsiveWidget( ResponsiveWidget(
responsiveUtils: responsiveUtils, responsiveUtils: _responsiveUtils,
desktop: Container( desktop: Container(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
children: [ Expanded(flex: 1, child: MailboxView()),
Expanded(flex: 1, child: MailboxView()), Expanded(flex: 3, child: _buildThreadAndEmailContainer(context)),
Expanded(flex: 1, child: ThreadView()), ],
Expanded(flex: 2, child: EmailView()),
],
),
), ),
tabletLarge: Container( ),
child: Row( tabletLarge: Container(
crossAxisAlignment: CrossAxisAlignment.start, child: Row(
mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( Expanded(flex: 2, child: MailboxView()),
width: responsiveUtils.getSizeWidthScreen(context) * 0.35, Expanded(flex: 4, child: _buildThreadAndEmailContainer(context)),
padding: EdgeInsets.symmetric(horizontal: 16), ],
child: ThreadView()
),
Expanded(child: EmailView()),
],
),
), ),
tablet: ThreadView(), ),
mobile: ThreadView()), tablet: ThreadView(),
mobile: ThreadView()
),
Obx(() => controller.dashBoardAction == DashBoardAction.compose Obx(() => controller.dashBoardAction == DashBoardAction.compose
? ComposerView() ? ComposerView()
: SizedBox.shrink()), : 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();
}
}
} }
@@ -0,0 +1,6 @@
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
class AppSetting {
static ReadingPane readingPane = ReadingPane.noSplit;
}
@@ -0,0 +1,5 @@
enum ReadingPane {
noSplit,
rightOfInbox,
}
@@ -360,7 +360,9 @@ class ThreadController extends BaseController {
void previewEmail(BuildContext context, PresentationEmail presentationEmailSelected) { void previewEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
mailboxDashBoardController.setSelectedEmail(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); goToEmail(context);
} }
} }
@@ -445,12 +447,12 @@ class ThreadController extends BaseController {
readActions = success.readActions; readActions = success.readActions;
} }
if (Get.context != null && readActions != null && Get.overlayContext != null) { if (currentContext != null && readActions != null && currentOverlayContext != null) {
final message = readActions == ReadActions.markAsUnread final message = readActions == ReadActions.markAsUnread
? AppLocalizations.of(Get.context!).marked_message_toast(AppLocalizations.of(Get.context!).unread) ? AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).unread)
: AppLocalizations.of(Get.context!).marked_message_toast(AppLocalizations.of(Get.context!).read); : AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).read);
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
message: message, message: message,
icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast); icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast);
} }
@@ -458,7 +460,7 @@ class ThreadController extends BaseController {
void _markAsSelectedEmailReadFailure(Failure failure) { void _markAsSelectedEmailReadFailure(Failure failure) {
cancelSelectEmail(); cancelSelectEmail();
_appToast.showErrorToast(AppLocalizations.of(Get.context!).an_error_occurred); _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred);
} }
void openFilterMessagesCupertinoActionSheet(BuildContext context, List<Widget> actionTiles, {Widget? cancelButton}) { void openFilterMessagesCupertinoActionSheet(BuildContext context, List<Widget> actionTiles, {Widget? cancelButton}) {
@@ -489,7 +491,7 @@ class ThreadController extends BaseController {
filterMessageOption.value = newFilterOption; filterMessageOption.value = newFilterOption;
_appToast.showToastWithIcon( _appToast.showToastWithIcon(
Get.overlayContext!, currentOverlayContext!,
message: newFilterOption.getMessageToast(context), message: newFilterOption.getMessageToast(context),
icon: newFilterOption.getIconToast(_imagePaths)); icon: newFilterOption.getIconToast(_imagePaths));
@@ -548,12 +550,12 @@ class ThreadController extends BaseController {
moveAction = success.moveAction; moveAction = success.moveAction;
} }
if (Get.context != null && Get.overlayContext != null if (currentContext != null && currentOverlayContext != null
&& destinationPath != null && moveAction == MoveAction.moveTo) { && destinationPath != null && moveAction == MoveAction.moveTo) {
_appToast.showToastWithAction( _appToast.showToastWithAction(
Get.overlayContext!, currentOverlayContext!,
AppLocalizations.of(Get.context!).moved_to_mailbox(destinationPath), AppLocalizations.of(currentContext!).moved_to_mailbox(destinationPath),
AppLocalizations.of(Get.context!).undo_action, AppLocalizations.of(currentContext!).undo_action,
() { () {
final newCurrentMailboxId = destinationMailboxId; final newCurrentMailboxId = destinationMailboxId;
final newDestinationMailboxId = currentMailboxId; final newDestinationMailboxId = currentMailboxId;
@@ -615,17 +617,17 @@ class ThreadController extends BaseController {
countMarkStarSuccess = success.countMarkStarSuccess; countMarkStarSuccess = success.countMarkStarSuccess;
} }
if (Get.context != null && markStarAction != null) { if (currentContext != null && markStarAction != null) {
_appToast.showSuccessToast(markStarAction == MarkStarAction.unMarkStar _appToast.showSuccessToast(markStarAction == MarkStarAction.unMarkStar
? AppLocalizations.of(Get.context!).marked_unstar_multiple_item(countMarkStarSuccess) ? AppLocalizations.of(currentContext!).marked_unstar_multiple_item(countMarkStarSuccess)
: AppLocalizations.of(Get.context!).marked_star_multiple_item(countMarkStarSuccess)); : AppLocalizations.of(currentContext!).marked_star_multiple_item(countMarkStarSuccess));
} }
} }
void _markAsStarMultipleEmailFailure(Failure failure) { void _markAsStarMultipleEmailFailure(Failure failure) {
cancelSelectEmail(); cancelSelectEmail();
if (Get.context != null) { if (currentContext != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).an_error_occurred); _appToast.showErrorToast(AppLocalizations.of(currentContext!).an_error_occurred);
} }
} }
+5
View File
@@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
Future<dynamic> push(String routeName, {dynamic arguments}) async { Future<dynamic> push(String routeName, {dynamic arguments}) async {
@@ -16,3 +17,7 @@ Future<dynamic> pushAndPopAll(String routeName, {dynamic arguments}) async {
void popBack({dynamic result}) { void popBack({dynamic result}) {
Get.back(result: result); Get.back(result: result);
} }
BuildContext? get currentContext => Get.context;
BuildContext? get currentOverlayContext => Get.overlayContext;