TF-3953 Close several modals when click outside

This commit is contained in:
DatDang
2025-08-07 14:14:50 +07:00
committed by Dat H. Pham
parent 44c17bc762
commit 9e7298bc76
34 changed files with 575 additions and 580 deletions
+1 -4
View File
@@ -17,7 +17,6 @@ import 'package:model/model.dart';
import 'package:rule_filter/rule_filter/capability_rule_filter.dart';
import 'package:tmail_ui_user/features/base/before_reconnect_manager.dart';
import 'package:tmail_ui_user/features/base/mixin/logout_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/popup_context_menu_action_mixin.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/email/presentation/bindings/mdn_interactor_bindings.dart';
@@ -64,9 +63,7 @@ import 'package:tmail_ui_user/main/utils/twake_app_manager.dart';
import 'package:uuid/uuid.dart';
abstract class BaseController extends GetxController
with MessageDialogActionMixin,
PopupContextMenuActionMixin,
LogoutMixin {
with PopupContextMenuActionMixin, LogoutMixin {
final CachingManager cachingManager = Get.find<CachingManager>();
final LanguageCacheManager languageCacheManager = Get.find<LanguageCacheManager>();
+13 -19
View File
@@ -1,8 +1,6 @@
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/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
@@ -17,11 +15,11 @@ import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_name_action.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_total_emails_count_action.dart';
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_unread_count_action.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart';
@@ -378,9 +376,10 @@ abstract class BaseMailboxController extends BaseController {
)))
).show(context);
} else {
showInputDialogAction(
MessageDialogActionManager().showInputDialogAction(
key: const Key('rename_mailbox_dialog'),
context: context,
outsideDismissible: true,
title: AppLocalizations.of(context).renameFolder,
value: presentationMailbox.name?.name ?? '',
negativeText: AppLocalizations.of(context).cancel,
@@ -449,21 +448,16 @@ abstract class BaseMailboxController extends BaseController {
..onConfirmAction(AppLocalizations.of(context).delete, () => onDeleteMailboxAction(presentationMailbox))
).show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_mailbox'),
imagePath: imagePaths,
title: AppLocalizations.of(context).deleteFolders,
textContent: AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)),
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => onDeleteMailboxAction(presentationMailbox),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).message_confirmation_dialog_delete_folder(presentationMailbox.getDisplayName(context)),
AppLocalizations.of(context).delete,
key: const Key('confirm_dialog_delete_mailbox'),
title: AppLocalizations.of(context).deleteFolders,
cancelTitle: AppLocalizations.of(context).cancel,
onConfirmAction: () => onDeleteMailboxAction(presentationMailbox),
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -1,12 +1,9 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/empty_folder_name_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/invalid_mail_format_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subaddressing_action.dart';
@@ -67,34 +64,29 @@ extension HandleMailboxActionTypeExtension on BaseMailboxController {
))
).show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_subAddressing'),
imagePath: imagePaths,
title: AppLocalizations.of(context).allowSubaddressing,
textContent: AppLocalizations.of(context)
.message_confirmation_dialog_allow_subaddressing(mailboxName),
confirmText: AppLocalizations.of(context).allow,
cancelText: AppLocalizations.of(context).cancel,
additionalWidgetContent: CopySubaddressWidget(
imagePath: imagePaths,
subaddress: subAddress,
onCopyButtonAction: () => copySubAddressAction(
context,
subAddress,
),
),
onConfirmButtonAction: () => onAllowSubAddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context)
.message_confirmation_dialog_allow_subaddressing(mailboxName),
AppLocalizations.of(context).allow,
key: const Key('confirm_dialog_subAddressing'),
title: AppLocalizations.of(context).allowSubaddressing,
cancelTitle: AppLocalizations.of(context).cancel,
additionalWidgetContent: CopySubaddressWidget(
imagePath: imagePaths,
subaddress: subAddress,
onCopyButtonAction: () => copySubAddressAction(
context,
subAddress,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
onConfirmAction: () => onAllowSubAddressingAction(
mailboxId,
currentRights,
MailboxActions.allowSubaddressing,
),
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -26,6 +26,9 @@ mixin DateRangePickerMixin {
initStartDate: initStartDate,
initEndDate: initEndDate,
autoClose: false,
barrierDismissible: true,
barrierLabel: 'Multiple view date range picker',
usePointerInterceptor: false,
selectDateRangeActionCallback: (startDate, endDate) {
_handleSelectDateRangeResult(
context,
+3 -3
View File
@@ -1,9 +1,9 @@
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
mixin LogoutMixin implements MessageDialogActionMixin {
mixin LogoutMixin {
void showLogoutConfirmDialog({
required BuildContext context,
required String userAddress,
@@ -11,7 +11,7 @@ mixin LogoutMixin implements MessageDialogActionMixin {
}) {
final appLocalizations = AppLocalizations.of(context);
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
'',
appLocalizations.yesLogout,
@@ -1,15 +1,12 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -53,7 +50,6 @@ mixin MailboxActionHandlerMixin {
MailboxDashBoardController dashboardController
) {
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
final appToast = Get.find<AppToast>();
if (responsiveUtils.isScreenWithShortestSide(context)) {
@@ -76,34 +72,29 @@ mixin MailboxActionHandlerMixin {
}))
.show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_trash'),
imagePath: imagePaths,
title: AppLocalizations.of(context).emptyTrash,
textContent: AppLocalizations.of(context).empty_trash_dialog_message,
cancelText: AppLocalizations.of(context).cancel,
confirmText: AppLocalizations.of(context).delete,
onCloseButtonAction: popBack,
onConfirmButtonAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptyTrashFolderAction(
trashFolderId: mailbox.id,
totalEmails: mailbox.countTotalEmails
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_empty_trash'),
context,
title: AppLocalizations.of(context).emptyTrash,
AppLocalizations.of(context).empty_trash_dialog_message,
cancelTitle: AppLocalizations.of(context).cancel,
AppLocalizations.of(context).delete,
onCloseButtonAction: popBack,
onConfirmAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptyTrashFolderAction(
trashFolderId: mailbox.id,
totalEmails: mailbox.countTotalEmails
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelAction: popBack,
);
}
}
@@ -118,7 +109,6 @@ mixin MailboxActionHandlerMixin {
}
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
final appToast = Get.find<AppToast>();
if (responsiveUtils.isScreenWithShortestSide(context)) {
@@ -138,31 +128,26 @@ mixin MailboxActionHandlerMixin {
}))
.show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_spam'),
imagePath: imagePaths,
title: AppLocalizations.of(context).emptySpamFolder,
textContent: AppLocalizations.of(context).emptySpamMessageDialog,
cancelText: AppLocalizations.of(context).cancel,
confirmText: AppLocalizations.of(context).delete_all,
onCloseButtonAction: popBack,
onConfirmButtonAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptySpamFolderAction(spamFolderId: mailbox.id, totalEmails: mailbox.countTotalEmails);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_empty_spam'),
context,
title: AppLocalizations.of(context).emptySpamFolder,
AppLocalizations.of(context).emptySpamMessageDialog,
cancelTitle: AppLocalizations.of(context).cancel,
AppLocalizations.of(context).delete_all,
onCloseButtonAction: popBack,
onConfirmAction: () {
popBack();
if (mailbox.countTotalEmails > 0) {
dashboardController.emptySpamFolderAction(spamFolderId: mailbox.id, totalEmails: mailbox.countTotalEmails);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelAction: popBack
);
}
}
@@ -8,13 +8,21 @@ import 'package:core/presentation/views/dialog/edit_text_dialog_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
mixin MessageDialogActionMixin {
class MessageDialogActionManager {
static final _instance = MessageDialogActionManager._();
Future<dynamic> showConfirmDialogAction(
factory MessageDialogActionManager() => _instance;
MessageDialogActionManager._();
final _isConfirmDialogOpened = RxBool(false);
final _isInputDialogOpened = RxBool(false);
bool get isDialogOpened => _isConfirmDialogOpened.value || _isInputDialogOpened.value;
Future<void> showConfirmDialogAction(
BuildContext context,
String message,
String actionName,
@@ -33,6 +41,7 @@ mixin MessageDialogActionMixin {
bool usePopScope = false,
List<TextSpan>? listTextSpan,
Widget? icon,
Widget? additionalWidgetContent,
Color? actionButtonColor,
Color? cancelButtonColor,
Color? cancelLabelButtonColor,
@@ -45,31 +54,82 @@ mixin MessageDialogActionMixin {
EdgeInsets? outsideDialogPadding,
}
) async {
if (PlatformInfo.isWeb) {
_isConfirmDialogOpened.value = true;
}
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
if (alignCenter) {
final childWidget = PointerInterceptor(
child: ConfirmationDialogBuilder(
final childWidget = ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
listTextSpan: listTextSpan,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
title: title ?? '',
textContent: message,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
iconWidget: icon,
outsideDialogPadding: outsideDialogPadding ??
(responsiveUtils.isScreenWithShortestSide(context)
? const EdgeInsets.all(16)
: null),
additionalWidgetContent: additionalWidgetContent,
cancelBackgroundButtonColor: cancelButtonColor,
confirmBackgroundButtonColor: actionButtonColor,
cancelLabelButtonColor: cancelLabelButtonColor,
confirmLabelButtonColor: confirmLabelButtonColor,
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction,
);
await Get.dialog(
usePopScope && PlatformInfo.isMobile
? PopScope(onPopInvokedWithResult: onPopInvoked, canPop: false, child: childWidget)
: childWidget,
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
barrierDismissible: outsideDismissible
);
} else {
if (responsiveUtils.isMobile(context)) {
final childWidget = ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
showAsBottomSheet: true,
listTextSpan: listTextSpan,
maxWidth: responsiveUtils.getSizeScreenShortestSide(context) - 16,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
title: title ?? '',
textContent: message,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
title: title ?? '',
iconWidget: icon,
outsideDialogPadding: outsideDialogPadding ??
(responsiveUtils.isScreenWithShortestSide(context)
? const EdgeInsets.all(16)
: null),
cancelBackgroundButtonColor: cancelButtonColor,
additionalWidgetContent: additionalWidgetContent,
margin: dialogMargin,
confirmBackgroundButtonColor: actionButtonColor,
cancelBackgroundButtonColor: cancelButtonColor,
cancelLabelButtonColor: cancelLabelButtonColor,
confirmLabelButtonColor: confirmLabelButtonColor,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
@@ -82,55 +142,10 @@ mixin MessageDialogActionMixin {
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction,
),
);
return await Get.dialog(
usePopScope && PlatformInfo.isMobile
? PopScope(onPopInvokedWithResult: onPopInvoked, canPop: false, child: childWidget)
: childWidget,
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
barrierDismissible: outsideDismissible
);
} else {
if (responsiveUtils.isMobile(context)) {
final childWidget = PointerInterceptor(
child: ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
showAsBottomSheet: true,
listTextSpan: listTextSpan,
maxWidth: responsiveUtils.getSizeScreenShortestSide(context) - 16,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
textContent: message,
title: title ?? '',
iconWidget: icon,
margin: dialogMargin,
confirmBackgroundButtonColor: actionButtonColor,
cancelBackgroundButtonColor: cancelButtonColor,
cancelLabelButtonColor: cancelLabelButtonColor,
confirmLabelButtonColor: confirmLabelButtonColor,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction ?? popBack
),
onCloseButtonAction: onCloseButtonAction ?? popBack,
);
if (showAsBottomSheet) {
return await Get.bottomSheet(
await Get.bottomSheet(
usePopScope && PlatformInfo.isMobile
? PopScope(onPopInvokedWithResult: onPopInvoked, canPop: false, child: childWidget)
: childWidget,
@@ -143,7 +158,7 @@ mixin MessageDialogActionMixin {
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(18))),
);
} else {
return (ConfirmationDialogActionSheetBuilder(context, listTextSpan: listTextSpan)
await (ConfirmationDialogActionSheetBuilder(context, listTextSpan: listTextSpan)
..messageText(message)
..onCancelAction(
cancelTitle ?? AppLocalizations.of(context).cancel,
@@ -162,39 +177,39 @@ mixin MessageDialogActionMixin {
})).show();
}
} else {
final childWidget = PointerInterceptor(
child: ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
listTextSpan: listTextSpan,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
title: title ?? '',
textContent: message,
iconWidget: icon,
confirmBackgroundButtonColor: actionButtonColor,
cancelBackgroundButtonColor: cancelButtonColor,
cancelLabelButtonColor: cancelLabelButtonColor,
confirmLabelButtonColor: confirmLabelButtonColor,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction ?? popBack,
),
final childWidget = ConfirmationDialogBuilder(
key: key,
imagePath: imagePaths,
listTextSpan: listTextSpan,
isArrangeActionButtonsVertical: isArrangeActionButtonsVertical,
useIconAsBasicLogo: useIconAsBasicLogo,
isScrollContentEnabled: isScrollContentEnabled,
title: title ?? '',
textContent: message,
iconWidget: icon,
additionalWidgetContent: additionalWidgetContent,
confirmBackgroundButtonColor: actionButtonColor,
cancelBackgroundButtonColor: cancelButtonColor,
cancelLabelButtonColor: cancelLabelButtonColor,
confirmLabelButtonColor: confirmLabelButtonColor,
confirmText: actionName,
cancelText: hasCancelButton ? cancelTitle ?? AppLocalizations.of(context).cancel : '',
onConfirmButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onConfirmAction?.call();
},
onCancelButtonAction: () {
if (autoPerformPopBack) {
popBack();
}
onCancelAction?.call();
},
onCloseButtonAction: onCloseButtonAction ?? popBack,
outsideDialogPadding: outsideDialogPadding,
);
return await Get.dialog(
await Get.dialog(
usePopScope && PlatformInfo.isMobile
? PopScope(onPopInvokedWithResult: onPopInvoked, canPop: false, child: childWidget)
: childWidget,
@@ -203,9 +218,10 @@ mixin MessageDialogActionMixin {
);
}
}
_isConfirmDialogOpened.value = false;
}
Future<dynamic> showInputDialogAction({
Future<void> showInputDialogAction({
required BuildContext context,
required String title,
required String value,
@@ -216,23 +232,27 @@ mixin MessageDialogActionMixin {
String? closeIcon,
OnInputDialogNegativeButtonAction? onNegativeButtonAction,
OnInputDialogInputErrorChangedAction? onInputErrorChanged,
bool outsideDismissible = false,
}) async {
return await Get.dialog(
PointerInterceptor(
child: EditTextDialogBuilder(
key: key,
title: AppLocalizations.of(context).renameFolder,
value: value,
positiveText: positiveText,
negativeText: negativeText,
closeIcon: closeIcon,
onInputErrorChanged: onInputErrorChanged,
onPositiveButtonAction: onPositiveButtonAction,
onNegativeButtonAction: onNegativeButtonAction,
onCloseButtonAction: closeIcon != null ? popBack : null,
),
_isInputDialogOpened.value = true;
await Get.dialog(
EditTextDialogBuilder(
key: key,
title: AppLocalizations.of(context).renameFolder,
value: value,
positiveText: positiveText,
negativeText: negativeText,
closeIcon: closeIcon,
onInputErrorChanged: onInputErrorChanged,
onPositiveButtonAction: onPositiveButtonAction,
onNegativeButtonAction: onNegativeButtonAction,
onCloseButtonAction: closeIcon != null ? popBack : null,
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
barrierDismissible: outsideDismissible,
);
_isInputDialogOpened.value = false;
}
}
@@ -0,0 +1,17 @@
import 'package:flutter/widgets.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class PopBackBarrierWidget extends StatelessWidget {
const PopBackBarrierWidget({super.key, required this.child});
final Widget child;
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: popBack,
child: child,
);
}
}
@@ -31,6 +31,7 @@ import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/before_reconnect_handler.dart';
import 'package:tmail_ui_user/features/base/before_reconnect_manager.dart';
import 'package:tmail_ui_user/features/base/mixin/auto_complete_result_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/state/base_ui_state.dart';
import 'package:tmail_ui_user/features/base/state/button_state.dart';
import 'package:tmail_ui_user/features/composer/domain/exceptions/compose_email_exception.dart';
@@ -781,7 +782,7 @@ class ComposerController extends BaseController
}
if (!isEnableEmailSendButton.value) {
showConfirmDialogAction(context,
MessageDialogActionManager().showConfirmDialogAction(context,
AppLocalizations.of(context).message_dialog_send_email_without_recipient,
AppLocalizations.of(context).add_recipients,
title: AppLocalizations.of(context).sending_failed,
@@ -797,7 +798,7 @@ class ComposerController extends BaseController
.where((emailAddress) => !EmailUtils.isEmailAddressValid(emailAddress.emailAddress))
.toList();
if (listEmailAddressInvalid.isNotEmpty) {
showConfirmDialogAction(context,
MessageDialogActionManager().showConfirmDialogAction(context,
AppLocalizations.of(context).message_dialog_send_email_with_email_address_invalid,
AppLocalizations.of(context).fix_email_addresses,
onConfirmAction: () {
@@ -815,7 +816,7 @@ class ComposerController extends BaseController
}
if (subjectEmail.value == null || subjectEmail.isEmpty == true) {
showConfirmDialogAction(context,
MessageDialogActionManager().showConfirmDialogAction(context,
AppLocalizations.of(context).message_dialog_send_email_without_a_subject,
AppLocalizations.of(context).cancel,
cancelTitle: AppLocalizations.of(context).send_anyway,
@@ -830,7 +831,7 @@ class ComposerController extends BaseController
}
if (!uploadController.allUploadAttachmentsCompleted) {
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).messageDialogSendEmailUploadingAttachment,
AppLocalizations.of(context).got_it,
@@ -843,7 +844,7 @@ class ComposerController extends BaseController
}
if (uploadController.isExceededMaxSizeAttachmentsPerEmail()) {
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).message_dialog_send_email_exceeds_maximum_size(
filesize(mailboxDashBoardController.maxSizeAttachmentsPerEmail?.value ?? 0, 0)),
@@ -985,7 +986,7 @@ class ComposerController extends BaseController
appLocalizations: AppLocalizations.of(context),
exception: failure.exception,
);
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
context,
title: '',
errorMessage,
@@ -1956,14 +1957,13 @@ class ComposerController extends BaseController
}
Future<void> _showConfirmDialogSaveMessage(BuildContext context) async {
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
context,
title: AppLocalizations.of(context).saveMessage.capitalizeFirstEach,
AppLocalizations.of(context).warningMessageWhenClickCloseComposer,
AppLocalizations.of(context).save,
cancelTitle: AppLocalizations.of(context).discardChanges,
alignCenter: true,
outsideDismissible: false,
autoPerformPopBack: false,
isArrangeActionButtonsVertical: true,
isScrollContentEnabled: responsiveUtils.isLandscapeMobile(context),
@@ -1987,6 +1987,7 @@ class ComposerController extends BaseController
}
},
);
_closeComposerButtonState = ButtonState.enabled;
}
void handleOnDragEnterHtmlEditorWeb(List<dynamic>? types) {
@@ -2212,7 +2213,7 @@ class ComposerController extends BaseController
exception: failure.exception,
isDraft: true,
);
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
context,
title: '',
errorMessage,
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:model/email/prefix_email_address.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/composer_print_draft_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_edit_recipient_extension.dart';
@@ -27,6 +28,7 @@ import 'package:tmail_ui_user/features/composer/presentation/widgets/web/from_co
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/local_file_drop_zone_widget.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/mobile_responsive_app_bar_composer_widget.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/toolbar_rich_text_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/verify_display_overlay_view_on_iframe_extension.dart';
class ComposerView extends GetWidget<ComposerController> {
@@ -39,6 +41,20 @@ class ComposerView extends GetWidget<ComposerController> {
@override
Widget build(BuildContext context) {
final iframeOverlay = Obx(() {
if (controller.mailboxDashBoardController.isDisplayedOverlayViewOnIFrame ||
MessageDialogActionManager().isDialogOpened) {
return Positioned.fill(
key: const ValueKey('tap-to-close'),
child: PointerInterceptor(
child: const SizedBox.expand(),
),
);
} else {
return const SizedBox.shrink();
}
});
return ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
mobile: MobileResponsiveContainerView(
@@ -329,6 +345,7 @@ class ComposerView extends GetWidget<ComposerController> {
return const SizedBox.shrink();
}
}),
iframeOverlay,
],
);
}
@@ -647,6 +664,7 @@ class ComposerView extends GetWidget<ComposerController> {
return const SizedBox.shrink();
}
}),
iframeOverlay,
],
);
}
@@ -967,6 +985,7 @@ class ComposerView extends GetWidget<ComposerController> {
return const SizedBox.shrink();
}
}),
iframeOverlay,
],
);
},
@@ -10,7 +10,6 @@ import 'package:core/utils/html/html_utils.dart';
import 'package:core/presentation/utils/html_transformer/dom/sanitize_hyper_link_tag_in_html_transformers.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
@@ -40,6 +39,7 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:share_plus/share_plus.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/state/button_state.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/list_attachments_extension.dart';
@@ -772,7 +772,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void _handleReadReceipt() {
if (currentContext != null) {
showConfirmDialogAction(currentContext!,
MessageDialogActionManager().showConfirmDialogAction(currentContext!,
AppLocalizations.of(currentContext!).subTitleReadReceiptRequestNotificationMessage,
AppLocalizations.of(currentContext!).yes,
onConfirmAction: () => _handleSendReceiptToSenderAction(currentContext!),
@@ -13,11 +13,13 @@ import 'package:model/extensions/list_email_address_extension.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/widget/optional_expanded.dart';
import 'package:tmail_ui_user/features/base/widget/optional_scroll.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_action_reactor/email_action_reactor.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart';
@@ -529,7 +531,9 @@ class EmailView extends GetWidget<SingleEmailController> {
),
),
Obx(() {
if (controller.mailboxDashBoardController.isDisplayedOverlayViewOnIFrame) {
if (controller.mailboxDashBoardController.isDisplayedOverlayViewOnIFrame ||
MessageDialogActionManager().isDialogOpened ||
EmailActionReactor.isDialogOpened) {
return Positioned.fill(
child: PointerInterceptor(
child: const SizedBox.expand(),
@@ -11,7 +11,6 @@ import 'package:core/presentation/utils/html_transformer/transform_configuration
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:dartz/dartz.dart';
@@ -36,8 +35,7 @@ import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_item_action_widget.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
@@ -88,8 +86,8 @@ typedef OpenPopUpContextMenuAction = Future<void> Function(
List<PopupMenuEntry> popupMenuItems,
);
class EmailActionReactor with MessageDialogActionMixin {
const EmailActionReactor(
class EmailActionReactor {
EmailActionReactor(
this._markAsEmailReadInteractor,
this._markAsStarEmailInteractor,
this._createNewEmailRuleFilterInteractor,
@@ -105,6 +103,9 @@ class EmailActionReactor with MessageDialogActionMixin {
final GetEmailContentInteractor _getEmailContentInteractor;
final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor;
static final _isEmailAddressDialogOpened = false.obs;
static bool get isDialogOpened => _isEmailAddressDialogOpened.value;
Stream<Either<Failure, Success>> markAsEmailRead(
Session session,
AccountId accountId,
@@ -210,19 +211,16 @@ class EmailActionReactor with MessageDialogActionMixin {
)
).show();
} else {
await Get.dialog(
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_email_permanently'),
imagePath: imagePaths,
title: DeleteActionType.single.getTitleDialog(currentContext!),
textContent: DeleteActionType.single.getContentDialog(currentContext!),
cancelText: DeleteActionType.single.getConfirmActionName(currentContext!),
confirmText: AppLocalizations.of(currentContext!).cancel,
onCancelButtonAction: () => onDeleteEmailRequest.call(presentationEmail),
onConfirmButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
await MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_delete_email_permanently'),
currentContext!,
title: DeleteActionType.single.getTitleDialog(currentContext!),
DeleteActionType.single.getContentDialog(currentContext!),
cancelTitle: DeleteActionType.single.getConfirmActionName(currentContext!),
AppLocalizations.of(currentContext!).cancel,
onCancelAction: () => onDeleteEmailRequest.call(presentationEmail),
onConfirmAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -331,7 +329,7 @@ class EmailActionReactor with MessageDialogActionMixin {
}) async {
if (currentContext == null || !currentContext!.mounted) return;
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
currentContext!,
'',
AppLocalizations.of(currentContext!).unsubscribe,
@@ -656,7 +654,7 @@ class EmailActionReactor with MessageDialogActionMixin {
}).toList();
}
void openEmailAddressDialog(
Future<void> openEmailAddressDialog(
Session session,
AccountId accountId, {
required EmailAddress emailAddress,
@@ -665,24 +663,25 @@ class EmailActionReactor with MessageDialogActionMixin {
required AppToast appToast,
required void Function(EmailAddress emailAddress) onComposeEmailFromEmailAddressRequest,
required void Function(Stream<Either<Failure, Success>> quickCreateRuleStream) onQuickCreateRuleRequest,
}) {
}) async {
if (currentContext?.mounted != true) return;
if (PlatformInfo.isWeb) {
_isEmailAddressDialogOpened.value = true;
}
if (responsiveUtils.isScreenWithShortestSide(currentContext!)) {
Get.bottomSheet(
PointerInterceptor(
child: EmailAddressBottomSheetBuilder(
imagePaths: imagePaths,
emailAddress: emailAddress,
onCloseDialogAction: popBack,
onCopyEmailAddressAction: (emailAddress) =>
_copyEmailAddress(currentContext!, emailAddress, appToast),
onComposeEmailAction: (emailAddress) =>
onComposeEmailFromEmailAddressRequest(emailAddress),
onQuickCreatingRuleEmailDialogAction: (emailAddress) =>
onQuickCreateRuleRequest(
quickCreateRule(session, accountId, emailAddress: emailAddress),
),
await Get.bottomSheet(
EmailAddressBottomSheetBuilder(
imagePaths: imagePaths,
emailAddress: emailAddress,
onCloseDialogAction: popBack,
onCopyEmailAddressAction: (emailAddress) =>
_copyEmailAddress(currentContext!, emailAddress, appToast),
onComposeEmailAction: (emailAddress) =>
onComposeEmailFromEmailAddressRequest(emailAddress),
onQuickCreatingRuleEmailDialogAction: (emailAddress) =>
onQuickCreateRuleRequest(
quickCreateRule(session, accountId, emailAddress: emailAddress),
),
),
useRootNavigator: true,
@@ -697,25 +696,25 @@ class EmailActionReactor with MessageDialogActionMixin {
backgroundColor: Colors.transparent,
);
} else {
Get.dialog(
PointerInterceptor(
child: EmailAddressDialogBuilder(
imagePaths: imagePaths,
emailAddress: emailAddress,
onCloseDialogAction: popBack,
onCopyEmailAddressAction: (emailAddress) =>
_copyEmailAddress(currentContext!, emailAddress, appToast),
onComposeEmailAction: (emailAddress) =>
onComposeEmailFromEmailAddressRequest(emailAddress),
onQuickCreatingRuleEmailDialogAction: (emailAddress) =>
onQuickCreateRuleRequest(
quickCreateRule(session, accountId, emailAddress: emailAddress),
),
await Get.dialog(
EmailAddressDialogBuilder(
imagePaths: imagePaths,
emailAddress: emailAddress,
onCloseDialogAction: popBack,
onCopyEmailAddressAction: (emailAddress) =>
_copyEmailAddress(currentContext!, emailAddress, appToast),
onComposeEmailAction: (emailAddress) =>
onComposeEmailFromEmailAddressRequest(emailAddress),
onQuickCreatingRuleEmailDialogAction: (emailAddress) =>
onQuickCreateRuleRequest(
quickCreateRule(session, accountId, emailAddress: emailAddress),
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
_isEmailAddressDialogOpened.value = false;
}
void _copyEmailAddress(
@@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/base/widget/default_field/default_close_b
import 'package:tmail_ui_user/features/base/widget/default_field/default_date_drop_down_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_input_field_with_tab_key_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/pop_back_barrier_widget.dart';
import 'package:tmail_ui_user/features/email_recovery/presentation/email_recovery_controller.dart';
import 'package:tmail_ui_user/features/email_recovery/presentation/extension/handle_drag_email_tag_between_field_extension.dart';
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/limits_banner.dart';
@@ -26,11 +27,10 @@ class EmailRecoveryFormDesktopBuilder extends StatelessWidget {
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
return Scaffold(
backgroundColor: Colors.black.withValues(alpha: 0.20),
body: GestureDetector(
onTap: FocusScope.of(context).unfocus,
child: Center(
final child = PopBackBarrierWidget(
child: Center(
child: GestureDetector(
onTap: FocusScope.of(context).unfocus,
child: Card(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
@@ -264,5 +264,10 @@ class EmailRecoveryFormDesktopBuilder extends StatelessWidget {
),
),
);
return Scaffold(
backgroundColor: Colors.black.withValues(alpha: 0.20),
body: child,
);
}
}
@@ -8,11 +8,9 @@ import 'package:core/presentation/views/text/type_ahead_form_field_builder.dart'
import 'package:core/utils/direction_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_email_address_drop_down_button.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_horizontal_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
@@ -313,20 +311,16 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
);
}
return PointerInterceptor(
child: ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
mobile: IdentityCreatorFormMobileBuilder(
controller: controller,
formView: bodyCreatorView,
enableRichTextKeyboard: PlatformInfo.isMobile,
),
tablet: Portal(
child: IdentityCreatorFormDesktopBuilder(
controller: controller,
formView: bodyCreatorView,
),
),
return ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
mobile: IdentityCreatorFormMobileBuilder(
controller: controller,
formView: bodyCreatorView,
enableRichTextKeyboard: PlatformInfo.isMobile,
),
tablet: IdentityCreatorFormDesktopBuilder(
controller: controller,
formView: bodyCreatorView,
),
);
}
@@ -7,6 +7,7 @@ import 'package:get/get.dart';
import 'package:rich_text_composer/views/keyboard_rich_text.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/pop_back_barrier_widget.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_title_widget.dart';
@@ -34,12 +35,12 @@ class IdentityCreatorFormDesktopBuilder extends StatelessWidget {
borderRadius: const BorderRadius.all(Radius.circular(16)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 24,
offset: const Offset(0, 2),
),
BoxShadow(
color: Colors.black.withOpacity(0.08),
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 2,
),
],
@@ -101,10 +102,14 @@ class IdentityCreatorFormDesktopBuilder extends StatelessWidget {
}
return Scaffold(
backgroundColor: Colors.black.withOpacity(0.2),
body: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: Center(child: bodyWidget),
backgroundColor: Colors.black.withValues(alpha: 0.2),
body: PopBackBarrierWidget(
child: Center(
child: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: bodyWidget,
),
),
),
);
}
@@ -15,13 +15,13 @@ import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:rxdart/transformers.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/base/extensions/handle_mailbox_action_type_extension.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/launcher_application_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/mailbox_action_handler_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
@@ -1056,19 +1056,16 @@ class MailboxController extends BaseMailboxController
_deleteMultipleMailboxAction(selectedMailboxList)))
.show();
} else {
Get.dialog(
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_multiple_mailbox'),
imagePath: imagePaths,
title: AppLocalizations.of(context).deleteFolders,
textContent: AppLocalizations.of(context).messageConfirmationDialogDeleteMultipleFolder(selectedMailboxList.length),
cancelText: AppLocalizations.of(context).cancel,
confirmText: AppLocalizations.of(context).delete,
onConfirmButtonAction: () => _deleteMultipleMailboxAction(selectedMailboxList),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_delete_multiple_mailbox'),
context,
title: AppLocalizations.of(context).deleteFolders,
AppLocalizations.of(context).messageConfirmationDialogDeleteMultipleFolder(selectedMailboxList.length),
cancelTitle: AppLocalizations.of(context).cancel,
AppLocalizations.of(context).delete,
onCancelAction: popBack,
onConfirmAction: () => _deleteMultipleMailboxAction(selectedMailboxList),
onCloseButtonAction: popBack,
);
}
}
@@ -26,11 +26,11 @@ import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:model/model.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:rxdart/transformers.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart';
import 'package:tmail_ui_user/features/composer/domain/extensions/email_request_extension.dart';
@@ -1669,30 +1669,27 @@ class MailboxDashBoardController extends ReloadableController
}))
.show();
} else {
Get.dialog(
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_emails_permanently'),
imagePath: imagePaths,
title: actionType.getTitleDialog(context),
textContent: actionType.getContentDialog(
context,
count: listEmails?.length,
mailboxName: mailboxCurrent?.getDisplayName(context),
),
confirmText: actionType.getConfirmActionName(context),
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () {
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_delete_emails_permanently'),
context,
title: actionType.getTitleDialog(context),
actionType.getContentDialog(
context,
count: listEmails?.length,
mailboxName: mailboxCurrent?.getDisplayName(context),
),
actionType.getConfirmActionName(context),
cancelTitle: AppLocalizations.of(context).cancel,
onConfirmAction: () {
onConfirm?.call();
_deleteSelectionEmailsPermanentlyAction(
actionType,
listEmails: listEmails,
onCancelSelectionEmail: onCancelSelectionEmail,
);
actionType,
listEmails: listEmails,
onCancelSelectionEmail: onCancelSelectionEmail,
);
},
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -2730,32 +2727,26 @@ class MailboxDashBoardController extends ReloadableController
}))
.show();
} else {
Get.dialog(
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_empty_spam'),
imagePath: imagePaths,
title: AppLocalizations.of(context).emptySpamFolder,
textContent: AppLocalizations.of(context).emptySpamMessageDialog,
confirmText: AppLocalizations.of(context).delete_all,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () {
popBack();
if (spamMailbox.countTotalEmails > 0) {
emptySpamFolderAction(
spamFolderId: spamMailbox.id,
totalEmails: spamMailbox.countTotalEmails,
);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder,
);
}
},
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_empty_spam'),
context,
title: AppLocalizations.of(context).emptySpamFolder,
AppLocalizations.of(context).emptySpamMessageDialog,
AppLocalizations.of(context).delete_all,
cancelTitle: AppLocalizations.of(context).cancel,
onConfirmAction: () {
popBack();
if (spamMailbox.countTotalEmails > 0) {
emptySpamFolderAction(spamFolderId: spamMailbox.id, totalEmails: spamMailbox.countTotalEmails);
} else {
appToast.showToastWarningMessage(
context,
AppLocalizations.of(context).noEmailInYourCurrentFolder
);
}
},
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -1,15 +1,13 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:rule_filter/rule_filter/tmail_rule.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/create_new_email_rule_filter_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/delete_email_rule_request.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/edit_email_rule_filter_request.dart';
@@ -166,20 +164,15 @@ class EmailRulesController extends BaseController {
}))
.show();
} else {
Get.dialog(
PointerInterceptor(
child: ConfirmationDialogBuilder(
imagePath: imagePaths,
title: AppLocalizations.of(context).deleteEmailRule,
textContent: AppLocalizations.of(context).messageConfirmationDialogDeleteEmailRule(emailRule.name),
confirmText: AppLocalizations.of(context).delete,
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _handleDeleteEmailRuleAction(emailRule),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
context,
title: AppLocalizations.of(context).deleteEmailRule,
AppLocalizations.of(context).messageConfirmationDialogDeleteEmailRule(emailRule.name),
AppLocalizations.of(context).delete,
cancelTitle: AppLocalizations.of(context).cancel,
onConfirmAction: () => _handleDeleteEmailRuleAction(emailRule),
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/export_trace_log_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/export_trace_log_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
@@ -18,7 +19,7 @@ extension ExportTraceLogExtension on ManageAccountDashBoardController {
}
Future<void> showExportTraceLogConfirmDialog(BuildContext context) async {
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).messageExportTraceLogDialog,
AppLocalizations.of(context).yes,
@@ -10,6 +10,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/state/banner_state.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
@@ -121,7 +122,7 @@ class ForwardController extends BaseController {
void deleteRecipients(BuildContext context, String emailAddress) {
clearInputFocus();
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
title: AppLocalizations.of(context).deleteRecipient,
AppLocalizations.of(context).messageConfirmationDialogDeleteRecipientForward(emailAddress),
@@ -210,7 +211,7 @@ class ForwardController extends BaseController {
void deleteMultipleRecipients(BuildContext context, Set<String> listEmailAddress) {
clearInputFocus();
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
title: AppLocalizations.of(context).deleteRecipient,
AppLocalizations.of(context).messageConfirmationDialogDeleteAllRecipientForward,
@@ -15,7 +15,7 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';
import 'package:super_tag_editor/tag_editor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/suggestion_email_address.dart';
import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart';
import 'package:tmail_ui_user/features/contact/presentation/widgets/contact_input_tag_item.dart';
@@ -58,7 +58,7 @@ class AutocompleteContactTextFieldWithTags extends StatefulWidget {
State<AutocompleteContactTextFieldWithTags> createState() => _AutocompleteContactTextFieldWithTagsState();
}
class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteContactTextFieldWithTags> with MessageDialogActionMixin {
class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteContactTextFieldWithTags> {
final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>();
@@ -461,7 +461,7 @@ class _AutocompleteContactTextFieldWithTagsState extends State<AutocompleteConta
final message = forwardWarningMessage
?? appLocalizations.dialogWarningMessageForForwardsToOtherDomains;
await showConfirmDialogAction(
await MessageDialogActionManager().showConfirmDialogAction(
context,
message,
AppLocalizations.of(context).yes,
@@ -1,8 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:dartz/dartz.dart';
@@ -16,6 +14,7 @@ import 'package:model/extensions/identity_request_dto_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/base/before_reconnect_handler.dart';
import 'package:tmail_ui_user/features/base/before_reconnect_manager.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/domain/model/identity_cache.dart';
import 'package:tmail_ui_user/features/identity_creator/domain/state/get_identity_cache_on_web_state.dart';
@@ -43,7 +42,6 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/transform_
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/identity_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/update_own_email_address_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/list_identity_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/identities/widgets/delete_identity_dialog_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/identity_action_type.dart';
import 'package:tmail_ui_user/features/public_asset/domain/extensions/string_to_public_asset_extension.dart';
@@ -291,13 +289,19 @@ class IdentitiesController extends ReloadableController implements BeforeReconne
}
void openConfirmationDialogDeleteIdentityAction(BuildContext context, Identity identity) {
Get.dialog(
DeleteIdentityDialogBuilder(
responsiveUtils: responsiveUtils,
imagePaths: imagePaths,
onDeleteIdentityAction: () => _dereferencePublicAssets(identity),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
final appLocalizations = AppLocalizations.of(context);
MessageDialogActionManager().showConfirmDialogAction(
context,
appLocalizations.message_confirmation_dialog_delete_identity,
appLocalizations.delete,
key: const Key('confirm_dialog_delete_identity'),
showAsBottomSheet: responsiveUtils.isMobile(context),
outsideDialogPadding: EdgeInsets.only(bottom: PlatformInfo.isWeb ? 42 : 16),
title: appLocalizations.delete_identity,
cancelTitle: appLocalizations.cancel,
onCancelAction: popBack,
onCloseButtonAction: popBack,
onConfirmAction: () => _dereferencePublicAssets(identity),
);
}
@@ -358,16 +362,14 @@ class IdentitiesController extends ReloadableController implements BeforeReconne
void _deleteIdentityFailure(DeleteIdentityFailure failure) {
if (currentContext != null) {
Get.dialog(
ConfirmationDialogBuilder(
key: const Key('dialog_message_delete_identity_failed'),
imagePath: imagePaths,
title: AppLocalizations.of(currentContext!).delete_failed,
confirmText: '${AppLocalizations.of(currentContext!).got_it}!',
onConfirmButtonAction: popBack,
onCloseButtonAction: popBack,
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('dialog_message_delete_identity_failed'),
currentContext!,
title: AppLocalizations.of(currentContext!).delete_failed,
'',
'${AppLocalizations.of(currentContext!).got_it}!',
onConfirmAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -1,67 +0,0 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
typedef OnDeleteIdentityAction = void Function();
class DeleteIdentityDialogBuilder extends StatelessWidget {
final ResponsiveUtils responsiveUtils;
final ImagePaths imagePaths;
final OnDeleteIdentityAction onDeleteIdentityAction;
const DeleteIdentityDialogBuilder({
Key? key,
required this.responsiveUtils,
required this.imagePaths,
required this.onDeleteIdentityAction
}) : super(key: key);
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final deleteDialogBuilder = ResponsiveWidget(
responsiveUtils: responsiveUtils,
mobile: _buildDeleteDialog(
appLocalizations: appLocalizations,
alignment: Alignment.bottomCenter,
outsideDialogPadding: EdgeInsets.only(bottom: PlatformInfo.isWeb ? 42 : 16),
),
landscapeMobile: _buildDeleteDialog(appLocalizations: appLocalizations),
tablet: _buildDeleteDialog(appLocalizations: appLocalizations),
tabletLarge: _buildDeleteDialog(appLocalizations: appLocalizations),
landscapeTablet: _buildDeleteDialog(appLocalizations: appLocalizations),
desktop: _buildDeleteDialog(appLocalizations: appLocalizations),
);
return PlatformInfo.isWeb
? PointerInterceptor(child: deleteDialogBuilder)
: deleteDialogBuilder;
}
ConfirmationDialogBuilder _buildDeleteDialog({
required AppLocalizations appLocalizations,
Alignment? alignment,
EdgeInsets? outsideDialogPadding,
}) {
return ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_identity'),
imagePath: imagePaths,
title: appLocalizations.delete_identity,
textContent: appLocalizations.message_confirmation_dialog_delete_identity,
confirmText: appLocalizations.delete,
cancelText: appLocalizations.cancel,
alignment: alignment,
outsideDialogPadding: outsideDialogPadding,
onConfirmButtonAction: onDeleteIdentityAction,
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -2,6 +2,10 @@ import 'package:core/presentation/views/html_viewer/html_content_viewer_on_web_w
import 'package:core/presentation/views/html_viewer/html_content_viewer_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/state_manager.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/main/routes/dialog_router.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
class SignatureBuilder extends StatelessWidget {
@@ -22,7 +26,20 @@ class SignatureBuilder extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (PlatformInfo.isWeb) {
return HtmlContentViewerOnWeb(
final iframeOverlay = Obx(() {
if (MessageDialogActionManager().isDialogOpened ||
DialogRouter.isDialogOpened) {
return Positioned.fill(
child: PointerInterceptor(
child: const SizedBox.expand(),
),
);
} else {
return const SizedBox.shrink();
}
});
final htmlView = HtmlContentViewerOnWeb(
contentHtml: value,
widthContent: width,
heightContent: height,
@@ -38,6 +55,13 @@ class SignatureBuilder extends StatelessWidget {
disableScrolling: true,
autoAdjustHeight: true,
);
return Stack(
children: [
htmlView,
iframeOverlay,
],
);
} else {
return HtmlContentViewer(
contentHtml: value,
@@ -4,6 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:rule_filter/rule_filter/rule_condition_group.dart';
import 'package:tmail_ui_user/features/base/widget/pop_back_barrier_widget.dart';
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/select_rule_action_field_extension.dart';
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/rule_filter_condition_type.dart';
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart';
@@ -23,80 +24,81 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
@override
Widget build(BuildContext context) {
final responsiveUtil = controller.responsiveUtils;
final focusScope = FocusScope.of(context);
return PointerInterceptor(
child: ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
mobile: Scaffold(
backgroundColor: PlatformInfo.isWeb
? Colors.black.withAlpha(24)
: Colors.black38,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SafeArea(
bottom: false,
left: false,
right: false,
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
color: Colors.white),
margin: EdgeInsets.only(top: PlatformInfo.isWeb ? 70 : 0),
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: SafeArea(child: _buildRulesFilterFormOnMobile(context))
)
responsiveUtils: responsiveUtil,
mobile: Scaffold(
backgroundColor:
PlatformInfo.isWeb ? Colors.black.withAlpha(24) : Colors.black38,
body: PopBackBarrierWidget(
child: SafeArea(
bottom: false,
left: false,
right: false,
child: GestureDetector(
onTap: focusScope.unfocus,
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.vertical(
top: Radius.circular(16),
),
color: Colors.white,
),
margin: EdgeInsets.only(top: PlatformInfo.isWeb ? 70 : 0),
child: SafeArea(
child: _buildRulesFilterFormOnMobile(context),
),
),
)
),
),
),
tablet: Scaffold(
backgroundColor: Colors.black.withAlpha(24),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(alignment: Alignment.bottomCenter, child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
)),
width: double.infinity,
height: controller.responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: _buildRulesFilterFormOnTablet(context)
)
)),
)
),
tablet: Scaffold(
backgroundColor: Colors.black.withAlpha(24),
body: PopBackBarrierWidget(
child: Align(
alignment: Alignment.bottomCenter,
child: GestureDetector(
onTap: focusScope.unfocus,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(
top: Radius.circular(16),
),
),
height: responsiveUtil.getSizeScreenHeight(context) * 0.7,
child: _buildRulesFilterFormOnTablet(context),
),
),
),
),
desktop: Scaffold(
backgroundColor: Colors.black.withAlpha(24),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Center(child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))),
width: controller.responsiveUtils.getSizeScreenWidth(context) * 0.6,
height: controller.responsiveUtils.getSizeScreenHeight(context) * 0.7,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: _buildRulesFilterFormOnDesktop(context)
)
)
)),
)
)
),
desktop: Scaffold(
backgroundColor: Colors.black.withAlpha(24),
body: PopBackBarrierWidget(
child: Center(
child: GestureDetector(
onTap: focusScope.unfocus,
child: Card(
color: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
),
clipBehavior: Clip.hardEdge,
child: SizedBox(
width: responsiveUtil.getSizeScreenWidth(context) * 0.6,
height: responsiveUtil.getSizeScreenHeight(context) * 0.7,
child: _buildRulesFilterFormOnDesktop(context),
),
),
),
),
),
),
),
);
}
@@ -9,7 +9,7 @@ import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_sending_email_state.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
@@ -35,7 +35,7 @@ import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class SendingQueueController extends BaseController with MessageDialogActionMixin {
class SendingQueueController extends BaseController {
final DeleteMultipleSendingEmailInteractor _deleteMultipleSendingEmailInteractor;
final UpdateSendingEmailInteractor _updateSendingEmailInteractor;
@@ -191,7 +191,7 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
}
void _deleteListSendingEmailAction(BuildContext context, List<SendingEmail> listSendingEmails) {
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).messageDialogDeleteSendingEmail,
AppLocalizations.of(context).cancel,
@@ -1,9 +1,7 @@
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/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart';
import 'package:core/presentation/views/dialog/confirmation_dialog_builder.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
@@ -17,7 +15,7 @@ import 'package:model/email/presentation_email.dart';
import 'package:model/email/read_actions.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
@@ -244,19 +242,16 @@ mixin EmailActionController {
() => _deleteEmailPermanentlyAction(context, email)))
.show();
} else {
Get.dialog(
PointerInterceptor(child: ConfirmationDialogBuilder(
key: const Key('confirm_dialog_delete_email_permanently'),
imagePath: imagePaths,
title: DeleteActionType.single.getTitleDialog(context),
textContent: DeleteActionType.single.getContentDialog(context),
confirmText: DeleteActionType.single.getConfirmActionName(context),
cancelText: AppLocalizations.of(context).cancel,
onConfirmButtonAction: () => _deleteEmailPermanentlyAction(context, email),
onCancelButtonAction: popBack,
onCloseButtonAction: popBack,
)),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
MessageDialogActionManager().showConfirmDialogAction(
key: const Key('confirm_dialog_delete_email_permanently'),
context,
title: DeleteActionType.single.getTitleDialog(context),
DeleteActionType.single.getContentDialog(context),
DeleteActionType.single.getConfirmActionName(context),
cancelTitle: AppLocalizations.of(context).cancel,
onConfirmAction: () => _deleteEmailPermanentlyAction(context, email),
onCancelAction: popBack,
onCloseButtonAction: popBack,
);
}
}
@@ -15,6 +15,7 @@ import 'package:model/email/attachment.dart';
import 'package:model/extensions/attachment_extension.dart';
import 'package:model/upload/file_info.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/state/base_ui_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_state.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart';
@@ -369,7 +370,7 @@ class UploadController extends BaseController {
void _showConfirmDialogWhenExceededMaxSizeAttachmentsPerEmail({required BuildContext context}) {
final maxSizeAttachmentsPerEmail = filesize(_mailboxDashBoardController.maxSizeAttachmentsPerEmail?.value ?? 0, 0);
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
AppLocalizations.of(context).message_dialog_upload_attachments_exceeds_maximum_size(maxSizeAttachmentsPerEmail),
AppLocalizations.of(context).got_it,
@@ -381,7 +382,7 @@ class UploadController extends BaseController {
required BuildContext context,
VoidCallback? confirmAction,
}) {
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
title: '',
AppLocalizations.of(context).warningMessageWhenExceedGenerallySizeInComposer,
+1 -2
View File
@@ -3,13 +3,12 @@ import 'dart:async';
import 'package:app_links/app_links.dart';
import 'package:core/utils/app_logger.dart';
import 'package:rxdart/subjects.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/main/deep_links/deep_link_action_type.dart';
import 'package:tmail_ui_user/main/deep_links/deep_link_callback_action_define.dart';
import 'package:tmail_ui_user/main/deep_links/deep_link_data.dart';
import 'package:tmail_ui_user/main/deep_links/open_app_deep_link_handler_mixin.dart';
class DeepLinksManager with MessageDialogActionMixin, OpenAppDeepLinkHandlerMixin {
class DeepLinksManager with OpenAppDeepLinkHandlerMixin {
BehaviorSubject<DeepLinkData?> _pendingDeepLinkData = BehaviorSubject.seeded(null);
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:rich_text_composer/views/commons/logger.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/home/domain/state/auto_sign_in_via_deep_link_state.dart';
import 'package:tmail_ui_user/features/home/domain/usecases/auto_sign_in_via_deep_link_interactor.dart';
import 'package:tmail_ui_user/main/deep_links/deep_link_callback_action_define.dart';
@@ -13,7 +13,7 @@ import 'package:tmail_ui_user/main/deep_links/open_app_deep_link_data.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
mixin OpenAppDeepLinkHandlerMixin on MessageDialogActionMixin {
mixin OpenAppDeepLinkHandlerMixin {
OpenAppDeepLinkData? parseOpenAppDeepLink(Uri uri) {
try {
final accessToken = uri.queryParameters['access_token'] ?? '';
@@ -120,7 +120,7 @@ mixin OpenAppDeepLinkHandlerMixin on MessageDialogActionMixin {
}) {
final appLocalizations = AppLocalizations.of(context);
showConfirmDialogAction(
MessageDialogActionManager().showConfirmDialogAction(
context,
'',
appLocalizations.yes,
+11 -2
View File
@@ -21,15 +21,24 @@ class DialogRouter {
static Future<dynamic> pushGeneralDialog({
required String routeName,
required Object? arguments
}) {
}) async {
_isDialogOpened.value = true;
_bindingDI(routeName);
return Get.generalDialog(
final returnedValue = await Get.generalDialog(
barrierDismissible: true,
barrierLabel: routeName,
routeSettings: RouteSettings(arguments: arguments),
pageBuilder: (_, __, ___) => _generateView(routeName: routeName, arguments: arguments)
);
_isDialogOpened.value = false;
return returnedValue;
}
static final RxBool _isDialogOpened = false.obs;
static bool get isDialogOpened => _isDialogOpened.value;
static void _bindingDI(String routeName) {
log('DialogRouter::_bindingDI():routeName: $routeName');
switch(routeName) {
+2 -2
View File
@@ -771,10 +771,10 @@ packages:
description:
path: "."
ref: main
resolved-ref: "66e3713f0e7a22da911b360cef4d219fc30cee77"
resolved-ref: "6c929093a154a2d16fa414f7d9a907e13f15b0ea"
url: "https://github.com/linagora/flutter-date-range-picker.git"
source: git
version: "2.0.0"
version: "2.0.1"
flutter_dotenv:
dependency: "direct main"
description:
@@ -127,6 +127,18 @@ class MockMailboxDashBoardController extends Mock implements MailboxDashBoardCon
@override
Map<MailboxId, PresentationMailbox> get mapMailboxById => {};
@override
RxBool get isAppGridDialogDisplayed => false.obs;
@override
RxBool get isDrawerOpened => false.obs;
@override
RxBool get isContextMenuOpened => false.obs;
@override
RxBool get isPopupMenuOpened => false.obs;
}
@GenerateNiceMocks([