TF-3766 Change context menu style for other widgets on mobile
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -234,24 +234,15 @@ class ThemeUtils {
|
||||
color: Colors.black,
|
||||
);
|
||||
|
||||
static TextStyle textStyleInter400() => const TextStyle(
|
||||
static const TextStyle textStyleInter400 = TextStyle(
|
||||
fontFamily: ConstantsUI.fontApp,
|
||||
fontWeight: FontWeight.normal,
|
||||
letterSpacing: 0.01,
|
||||
letterSpacing: -0.13,
|
||||
fontSize: 13,
|
||||
height: 16 / 13,
|
||||
color: Colors.black,
|
||||
);
|
||||
|
||||
static final TextStyle textStyleInter400 = TextStyle(
|
||||
fontFamily: ConstantsUI.fontApp,
|
||||
fontWeight: FontWeight.w400,
|
||||
letterSpacing: -0.15,
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
color: AppColor.gray424244.withOpacity(0.9),
|
||||
);
|
||||
|
||||
static TextStyle textStyleM3LabelLarge({Color? color}) => TextStyle(
|
||||
fontFamily: ConstantsUI.fontApp,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
@@ -11,51 +11,49 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
mixin PopupContextMenuActionMixin {
|
||||
|
||||
void openContextMenuAction(
|
||||
Future<void> openContextMenuAction(
|
||||
BuildContext context,
|
||||
List<Widget> actionTiles,
|
||||
{
|
||||
Widget? cancelButton,
|
||||
Key? key,
|
||||
List<ContextMenuItemAction>? itemActions,
|
||||
OnContextMenuActionClick? onContextMenuActionClick,
|
||||
}
|
||||
) async {
|
||||
if (actionTiles.isNotEmpty) {
|
||||
await (CupertinoActionSheetBuilder(context, key: key)
|
||||
..addTiles(actionTiles)
|
||||
..addCancelButton(cancelButton ?? buildCancelButton(context)))
|
||||
.show();
|
||||
} else {
|
||||
await showModalBottomSheet(
|
||||
context: context,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
isScrollControlled: true,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16.0),
|
||||
topRight: Radius.circular(16.0),
|
||||
),
|
||||
await (CupertinoActionSheetBuilder(context)
|
||||
..addTiles(actionTiles)
|
||||
..addCancelButton(buildCancelButton(context)))
|
||||
.show();
|
||||
}
|
||||
|
||||
Future<void> openBottomSheetContextMenuAction({
|
||||
required BuildContext context,
|
||||
required List<ContextMenuItemAction> itemActions,
|
||||
required OnContextMenuActionClick onContextMenuActionClick,
|
||||
Key? key,
|
||||
}) async {
|
||||
await showModalBottomSheet(
|
||||
context: context,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
isScrollControlled: true,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16.0),
|
||||
topRight: Radius.circular(16.0),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
barrierColor: Colors.black.withOpacity(0.2),
|
||||
builder: (_) {
|
||||
return PointerInterceptor(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsetsDirectional.only(bottom: 24),
|
||||
child: ContextMenuDialogView(
|
||||
actions: itemActions ?? [],
|
||||
onContextMenuActionClick: (menuAction) =>
|
||||
onContextMenuActionClick?.call(menuAction),
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
barrierColor: Colors.black.withOpacity(0.2),
|
||||
builder: (_) {
|
||||
return PointerInterceptor(
|
||||
child: Container(
|
||||
key: key,
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsetsDirectional.only(bottom: 24),
|
||||
child: ContextMenuDialogView(
|
||||
actions: itemActions,
|
||||
onContextMenuActionClick: onContextMenuActionClick,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void openPopupMenuAction(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -17,6 +16,76 @@ class ContextMenuDialogItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SvgPicture? icon;
|
||||
SvgPicture? selectedIcon;
|
||||
bool isSelected = false;
|
||||
|
||||
if (menuAction is ContextMenuItemActionRequiredIcon) {
|
||||
final specificMenuAction =
|
||||
menuAction as ContextMenuItemActionRequiredIcon;
|
||||
icon = SvgPicture.asset(
|
||||
specificMenuAction.actionIcon,
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: specificMenuAction.actionIconColor.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
} else if (menuAction is ContextMenuItemActionRequiredSelectedIcon) {
|
||||
final specificMenuAction =
|
||||
menuAction as ContextMenuItemActionRequiredSelectedIcon;
|
||||
selectedIcon = SvgPicture.asset(
|
||||
specificMenuAction.selectedIcon,
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: specificMenuAction.selectedIconColor.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
isSelected = specificMenuAction.selectedAction == menuAction.action;
|
||||
} else if (menuAction is ContextMenuItemActionRequiredFull) {
|
||||
final specificMenuAction =
|
||||
menuAction as ContextMenuItemActionRequiredFull;
|
||||
|
||||
icon = SvgPicture.asset(
|
||||
specificMenuAction.actionIcon,
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: specificMenuAction.actionIconColor.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
selectedIcon = SvgPicture.asset(
|
||||
specificMenuAction.selectedIcon,
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: specificMenuAction.selectedIconColor.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
);
|
||||
isSelected = specificMenuAction.selectedAction == menuAction.action;
|
||||
}
|
||||
|
||||
Widget? iconWidget = icon != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Container(
|
||||
height: 32,
|
||||
width: 32,
|
||||
alignment: Alignment.center,
|
||||
child: icon,
|
||||
),
|
||||
)
|
||||
: null;
|
||||
|
||||
Widget? selectedIconWidget = selectedIcon != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Container(
|
||||
height: 32,
|
||||
width: 32,
|
||||
alignment: Alignment.center,
|
||||
child: selectedIcon,
|
||||
),
|
||||
)
|
||||
: null;
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: InkWell(
|
||||
@@ -25,31 +94,24 @@ class ContextMenuDialogItem extends StatelessWidget {
|
||||
height: 48,
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Container(
|
||||
height: 32,
|
||||
width: 32,
|
||||
alignment: Alignment.center,
|
||||
child: SvgPicture.asset(
|
||||
menuAction.actionIcon,
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: menuAction.actionIconColor.asFilter(),
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (iconWidget != null) iconWidget else const SizedBox(width: 24),
|
||||
Expanded(
|
||||
child: Text(
|
||||
menuAction.actionName,
|
||||
style: ThemeUtils.textStyleInter400.copyWith(
|
||||
color: menuAction.actionNameColor,
|
||||
letterSpacing: -0.15,
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
if (isSelected && selectedIconWidget != null)
|
||||
selectedIconWidget
|
||||
else
|
||||
const SizedBox(width: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -12,13 +12,41 @@ abstract class ContextMenuItemAction<T> with EquatableMixin {
|
||||
@override
|
||||
List<Object?> get props => [action];
|
||||
|
||||
String get actionIcon;
|
||||
|
||||
Color get actionIconColor => AppColor.gray424244.withOpacity(0.72);
|
||||
|
||||
String get actionName;
|
||||
|
||||
Color get actionNameColor => AppColor.gray424244.withOpacity(0.9);
|
||||
|
||||
void onClick(OnContextMenuActionClick callback) => callback(this);
|
||||
}
|
||||
|
||||
mixin OptionalIcon {
|
||||
String get actionIcon;
|
||||
|
||||
Color get actionIconColor => AppColor.gray424244.withOpacity(0.72);
|
||||
}
|
||||
|
||||
mixin OptionalSelectedIcon<T> {
|
||||
String get selectedIcon;
|
||||
|
||||
Color get selectedIconColor => AppColor.primaryMain;
|
||||
}
|
||||
|
||||
abstract class ContextMenuItemActionRequiredIcon<T>
|
||||
extends ContextMenuItemAction<T> with OptionalIcon {
|
||||
ContextMenuItemActionRequiredIcon(super.action);
|
||||
}
|
||||
|
||||
abstract class ContextMenuItemActionRequiredSelectedIcon<T>
|
||||
extends ContextMenuItemAction<T> with OptionalSelectedIcon<T> {
|
||||
|
||||
final T? selectedAction;
|
||||
|
||||
ContextMenuItemActionRequiredSelectedIcon(super.action, this.selectedAction);
|
||||
}
|
||||
|
||||
abstract class ContextMenuItemActionRequiredFull<T>
|
||||
extends ContextMenuItemAction<T> with OptionalIcon, OptionalSelectedIcon<T> {
|
||||
final T selectedAction;
|
||||
|
||||
ContextMenuItemActionRequiredFull(super.action, this.selectedAction);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import 'package:rule_filter/rule_filter/rule_condition_group.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/font_name_type.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class DropDownButtonWidget<T> extends StatelessWidget {
|
||||
|
||||
@@ -173,6 +174,8 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
||||
}
|
||||
|
||||
String _getTextItemDropdown(BuildContext context, {required T? item}) {
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
if (item is Identity) {
|
||||
return item.name ?? '';
|
||||
}
|
||||
@@ -183,16 +186,16 @@ class DropDownButtonWidget<T> extends StatelessWidget {
|
||||
return item.name;
|
||||
}
|
||||
if (item is rule_condition.Field) {
|
||||
return item.getTitle(context);
|
||||
return item.getTitle(appLocalizations);
|
||||
}
|
||||
if (item is rule_condition.Comparator) {
|
||||
return item.getTitle(context);
|
||||
return item.getTitle(appLocalizations);
|
||||
}
|
||||
if (item is EmailRuleFilterAction) {
|
||||
return item.getTitle(context);
|
||||
return item.getTitle(appLocalizations);
|
||||
}
|
||||
if (item is ConditionCombiner) {
|
||||
return item.getTitle(context);
|
||||
return item.getTitle(appLocalizations);
|
||||
}
|
||||
return hintText ?? '';
|
||||
}
|
||||
|
||||
@@ -556,9 +556,8 @@ class EmailView extends GetWidget<SingleEmailController> {
|
||||
.toList();
|
||||
|
||||
if (position == null) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
controller.openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
popBack();
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/email_ac
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemEmailAction
|
||||
extends ContextMenuItemAction<EmailActionType> {
|
||||
extends ContextMenuItemActionRequiredIcon<EmailActionType> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension HandleMailboxActionExtension on MailboxController {
|
||||
|
||||
@@ -25,20 +26,21 @@ extension HandleMailboxActionExtension on MailboxController {
|
||||
mailboxDashBoardController.enableSpamReport,
|
||||
deletedMessageVaultSupported,
|
||||
isSubAddressingSupported,
|
||||
imagePaths,
|
||||
AppLocalizations.of(context),
|
||||
);
|
||||
|
||||
if (contextMenuActions.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
openContextMenuAction(
|
||||
context,
|
||||
contextMenuMailboxActionTiles(
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) => handleMailboxAction(
|
||||
context,
|
||||
imagePaths,
|
||||
menuAction.action,
|
||||
mailbox,
|
||||
contextMenuActions,
|
||||
handleMailboxAction: handleMailboxAction,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -76,6 +78,8 @@ extension HandleMailboxActionExtension on MailboxController {
|
||||
mailboxDashBoardController.enableSpamReport,
|
||||
deletedMessageVaultSupported,
|
||||
isSubAddressingSupported,
|
||||
imagePaths,
|
||||
AppLocalizations.of(context),
|
||||
);
|
||||
|
||||
if (contextMenuActions.isEmpty) {
|
||||
@@ -83,15 +87,14 @@ extension HandleMailboxActionExtension on MailboxController {
|
||||
}
|
||||
|
||||
if (responsiveUtils.isScreenWithShortestSide(context)) {
|
||||
openContextMenuAction(
|
||||
context,
|
||||
contextMenuMailboxActionTiles(
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) => handleMailboxAction(
|
||||
context,
|
||||
imagePaths,
|
||||
menuAction.action,
|
||||
mailbox,
|
||||
contextMenuActions,
|
||||
handleMailboxAction: handleMailboxAction,
|
||||
)
|
||||
),
|
||||
);
|
||||
} else {
|
||||
openPopupMenuAction(
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:model/mailbox/mailbox_constants.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:model/extensions/presentation_mailbox_extension.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_mailbox_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
|
||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
mixin MailboxWidgetMixin {
|
||||
@@ -97,65 +90,35 @@ mixin MailboxWidgetMixin {
|
||||
PresentationMailbox mailbox,
|
||||
bool spamReportEnabled,
|
||||
bool deletedMessageVaultSupported,
|
||||
bool subaddressingSupported,
|
||||
bool isSubAddressingSupported,
|
||||
) {
|
||||
if (mailbox.isDefault) {
|
||||
return _listActionForDefaultMailbox(mailbox, spamReportEnabled, deletedMessageVaultSupported);
|
||||
return _listActionForDefaultMailbox(
|
||||
mailbox,
|
||||
spamReportEnabled,
|
||||
deletedMessageVaultSupported,
|
||||
);
|
||||
} else if (mailbox.isPersonal) {
|
||||
return _listActionForPersonalMailbox(mailbox, subaddressingSupported);
|
||||
return _listActionForPersonalMailbox(mailbox, isSubAddressingSupported);
|
||||
} else {
|
||||
return _listActionForTeamMailbox(mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
void openMailboxMenuActionOnMobile(
|
||||
BuildContext context,
|
||||
ImagePaths imagePaths,
|
||||
PresentationMailbox mailbox,
|
||||
MailboxController controller
|
||||
) {
|
||||
final bool deletedMessageVaultSupported = MailboxUtils.isDeletedMessageVaultSupported(
|
||||
controller.mailboxDashBoardController.sessionCurrent,
|
||||
controller.mailboxDashBoardController.accountId.value);
|
||||
|
||||
final bool subaddressingSupported = isSubaddressingSupported(
|
||||
controller.mailboxDashBoardController.sessionCurrent,
|
||||
controller.mailboxDashBoardController.accountId.value);
|
||||
|
||||
final contextMenuActions = listContextMenuItemAction(
|
||||
mailbox,
|
||||
controller.mailboxDashBoardController.enableSpamReport,
|
||||
deletedMessageVaultSupported,
|
||||
subaddressingSupported,
|
||||
imagePaths,
|
||||
AppLocalizations.of(context),
|
||||
);
|
||||
|
||||
if (contextMenuActions.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) => controller.handleMailboxAction(
|
||||
context,
|
||||
menuAction.action,
|
||||
mailbox,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<ContextMenuItemMailboxAction> listContextMenuItemAction(
|
||||
PresentationMailbox mailbox,
|
||||
bool spamReportEnabled,
|
||||
bool deletedMessageVaultSupported,
|
||||
bool subaddressingSupported,
|
||||
bool isSubAddressingSupported,
|
||||
ImagePaths imagePaths,
|
||||
AppLocalizations appLocalizations,
|
||||
) {
|
||||
final mailboxActionsSupported = _listActionForAllMailboxType(mailbox, spamReportEnabled, deletedMessageVaultSupported, subaddressingSupported);
|
||||
final mailboxActionsSupported = _listActionForAllMailboxType(
|
||||
mailbox,
|
||||
spamReportEnabled,
|
||||
deletedMessageVaultSupported,
|
||||
isSubAddressingSupported,
|
||||
);
|
||||
|
||||
final listContextMenuItemAction = mailboxActionsSupported
|
||||
.map((action) => ContextMenuItemMailboxAction(
|
||||
@@ -168,61 +131,6 @@ mixin MailboxWidgetMixin {
|
||||
return listContextMenuItemAction;
|
||||
}
|
||||
|
||||
void openMailboxMenuActionOnWeb(
|
||||
BuildContext context,
|
||||
ImagePaths imagePaths,
|
||||
ResponsiveUtils responsiveUtils,
|
||||
RelativeRect position,
|
||||
PresentationMailbox mailbox,
|
||||
MailboxController controller
|
||||
) {
|
||||
final bool deletedMessageVaultSupported = MailboxUtils.isDeletedMessageVaultSupported(
|
||||
controller.mailboxDashBoardController.sessionCurrent,
|
||||
controller.mailboxDashBoardController.accountId.value);
|
||||
|
||||
final bool subaddressingSupported = isSubaddressingSupported(
|
||||
controller.mailboxDashBoardController.sessionCurrent,
|
||||
controller.mailboxDashBoardController.accountId.value);
|
||||
|
||||
final contextMenuActions = listContextMenuItemAction(
|
||||
mailbox,
|
||||
controller.mailboxDashBoardController.enableSpamReport,
|
||||
deletedMessageVaultSupported,
|
||||
subaddressingSupported,
|
||||
imagePaths,
|
||||
AppLocalizations.of(context),
|
||||
);
|
||||
|
||||
if (contextMenuActions.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (responsiveUtils.isScreenWithShortestSide(context)) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) => controller.handleMailboxAction(
|
||||
context,
|
||||
menuAction.action,
|
||||
mailbox,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
controller.openPopupMenuAction(
|
||||
context,
|
||||
position,
|
||||
popupMenuMailboxActionTiles(
|
||||
context,
|
||||
imagePaths,
|
||||
mailbox,
|
||||
contextMenuActions,
|
||||
handleMailboxAction: controller.handleMailboxAction
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<PopupMenuEntry> popupMenuMailboxActionTiles(
|
||||
BuildContext context,
|
||||
ImagePaths imagePaths,
|
||||
@@ -243,20 +151,6 @@ mixin MailboxWidgetMixin {
|
||||
.toList();
|
||||
}
|
||||
|
||||
static bool isSubaddressingSupported(Session? session, AccountId? accountId) {
|
||||
if (session == null || accountId == null) {
|
||||
return false;
|
||||
}
|
||||
if (!CapabilityIdentifier.jmapTeamMailboxes.isSupported(session, accountId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (session.getCapabilityProperties(accountId, CapabilityIdentifier.jmapTeamMailboxes)
|
||||
?.props[0] as Map<String, dynamic>?)
|
||||
?[subaddressingSupported]
|
||||
?? false;
|
||||
}
|
||||
|
||||
PopupMenuItem _buildPopupMenuItem(
|
||||
BuildContext context,
|
||||
ImagePaths imagePaths,
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_action
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextMenuItemMailboxAction
|
||||
extends ContextMenuItemAction<MailboxActions> {
|
||||
extends ContextMenuItemActionRequiredIcon<MailboxActions> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class CountOfEmailsWidget extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: PlatformInfo.isMobile
|
||||
? ThemeUtils.textStyleInter400()
|
||||
? ThemeUtils.textStyleInter400
|
||||
: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Colors.black,
|
||||
),
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
mixin FilterEmailPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -68,7 +69,7 @@ mixin FilterEmailPopupMenuMixin {
|
||||
: null),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: Text(
|
||||
option.getName(context),
|
||||
option.getName(AppLocalizations.of(context)),
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.black,
|
||||
|
||||
@@ -5,7 +5,6 @@ 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:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
@@ -22,8 +21,9 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/create_new
|
||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/delete_email_rule_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/edit_email_rule_filter_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_rules_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/email_rule_bottom_sheet_action_tile_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/context_item_email_rule_type_action.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/email_rule_action_type.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/creator_action_type.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/rules_filter_creator_arguments.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
@@ -241,45 +241,41 @@ class EmailRulesController extends BaseController {
|
||||
}
|
||||
|
||||
void openEditRuleMenuAction(BuildContext context, TMailRule rule) {
|
||||
openContextMenuAction(
|
||||
context,
|
||||
[
|
||||
_editEmailRuleActionTile(context, rule),
|
||||
_deleteEmailRuleActionTile(context, rule),
|
||||
],
|
||||
final contextMenuActions = [
|
||||
EmailRuleActionType.edit,
|
||||
EmailRuleActionType.delete,
|
||||
].map((filter) {
|
||||
return ContextItemEmailRuleTypeAction(
|
||||
filter,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (action) {
|
||||
popBack();
|
||||
_handleRuleFilterActionType(context, rule, action.action);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _deleteEmailRuleActionTile(BuildContext context, TMailRule rule) {
|
||||
return (EmailRuleBottomSheetActionTileBuilder(
|
||||
const Key('delete_emailRule_action'),
|
||||
SvgPicture.asset(
|
||||
imagePaths.icDeleteComposer,
|
||||
colorFilter: AppColor.colorActionDeleteConfirmDialog.asFilter()),
|
||||
AppLocalizations.of(context).deleteRule,
|
||||
rule,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12),
|
||||
textStyleAction: const TextStyle(
|
||||
fontSize: 17, color: AppColor.colorActionDeleteConfirmDialog),
|
||||
)..onActionClick((rule) {
|
||||
popBack();
|
||||
deleteEmailRule(context, rule);
|
||||
})).build();
|
||||
}
|
||||
|
||||
Widget _editEmailRuleActionTile(BuildContext context, TMailRule rule) {
|
||||
return (EmailRuleBottomSheetActionTileBuilder(
|
||||
const Key('edit_emailRule_action'),
|
||||
SvgPicture.asset(imagePaths.icEdit),
|
||||
AppLocalizations.of(context).editRule,
|
||||
rule,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12))
|
||||
..onActionClick((rule) {
|
||||
popBack();
|
||||
void _handleRuleFilterActionType(
|
||||
BuildContext context,
|
||||
TMailRule rule,
|
||||
EmailRuleActionType actionType,
|
||||
) {
|
||||
switch (actionType) {
|
||||
case EmailRuleActionType.edit:
|
||||
editEmailRule(context, rule);
|
||||
}))
|
||||
.build();
|
||||
break;
|
||||
case EmailRuleActionType.delete:
|
||||
deleteEmailRule(context, rule);
|
||||
break;
|
||||
case EmailRuleActionType.add:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/email_rule_action_type.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemEmailRuleTypeAction
|
||||
extends ContextMenuItemActionRequiredIcon<EmailRuleActionType> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemEmailRuleTypeAction(
|
||||
super.action,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionIcon => action.getIcon(imagePaths);
|
||||
|
||||
@override
|
||||
String get actionName => action.getName(appLocalizations);
|
||||
|
||||
@override
|
||||
Color get actionIconColor => action.getIconColor();
|
||||
|
||||
@override
|
||||
Color get actionNameColor => action.getNameColor();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
enum EmailRuleActionType {
|
||||
add,
|
||||
edit,
|
||||
delete;
|
||||
|
||||
String getName(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case EmailRuleActionType.add:
|
||||
return appLocalizations.addNewRule;
|
||||
case EmailRuleActionType.edit:
|
||||
return appLocalizations.editRule;
|
||||
case EmailRuleActionType.delete:
|
||||
return appLocalizations.deleteRule;
|
||||
}
|
||||
}
|
||||
|
||||
String getIcon(ImagePaths imagePaths) {
|
||||
switch(this) {
|
||||
case EmailRuleActionType.add:
|
||||
return imagePaths.icAddNewFolder;
|
||||
case EmailRuleActionType.edit:
|
||||
return imagePaths.icEdit;
|
||||
case EmailRuleActionType.delete:
|
||||
return imagePaths.icDeleteComposer;
|
||||
}
|
||||
}
|
||||
|
||||
Color getIconColor() {
|
||||
if (this == EmailRuleActionType.delete) {
|
||||
return AppColor.redFF3347;
|
||||
} else {
|
||||
return AppColor.gray424244.withOpacity(0.72);
|
||||
}
|
||||
}
|
||||
|
||||
Color getNameColor() {
|
||||
if (this == EmailRuleActionType.delete) {
|
||||
return AppColor.redFF3347;
|
||||
} else {
|
||||
return AppColor.gray424244.withOpacity(0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-15
@@ -1,51 +1,50 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition;
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition_group.dart' as rule_combiner;
|
||||
|
||||
extension RuleConditionFieldExtension on rule_condition.Field {
|
||||
|
||||
String getTitle(BuildContext context) {
|
||||
String getTitle(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case rule_condition.Field.from:
|
||||
return AppLocalizations.of(context).ruleFilterAddressFromField;
|
||||
return appLocalizations.ruleFilterAddressFromField;
|
||||
case rule_condition.Field.to:
|
||||
return AppLocalizations.of(context).ruleFilterAddressToField;
|
||||
return appLocalizations.ruleFilterAddressToField;
|
||||
case rule_condition.Field.cc:
|
||||
return AppLocalizations.of(context).ruleFilterAddressCcField;
|
||||
return appLocalizations.ruleFilterAddressCcField;
|
||||
case rule_condition.Field.recipient:
|
||||
return AppLocalizations.of(context).recipient;
|
||||
return appLocalizations.recipient;
|
||||
case rule_condition.Field.subject:
|
||||
return AppLocalizations.of(context).subject;
|
||||
return appLocalizations.subject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RuleConditionComparatorExtension on rule_condition.Comparator {
|
||||
|
||||
String getTitle(BuildContext context) {
|
||||
String getTitle(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case rule_condition.Comparator.contains:
|
||||
return AppLocalizations.of(context).contains;
|
||||
return appLocalizations.contains;
|
||||
case rule_condition.Comparator.notContains:
|
||||
return AppLocalizations.of(context).notContains;
|
||||
return appLocalizations.notContains;
|
||||
case rule_condition.Comparator.exactlyEquals:
|
||||
return AppLocalizations.of(context).exactlyEquals;
|
||||
return appLocalizations.exactlyEquals;
|
||||
case rule_condition.Comparator.notExactlyEquals:
|
||||
return AppLocalizations.of(context).notExactlyEquals;
|
||||
return appLocalizations.notExactlyEquals;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RuleConditionCombinerExtension on rule_combiner.ConditionCombiner {
|
||||
|
||||
String getTitle(BuildContext context) {
|
||||
String getTitle(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case rule_combiner.ConditionCombiner.AND:
|
||||
return AppLocalizations.of(context).all;
|
||||
return appLocalizations.all;
|
||||
case rule_combiner.ConditionCombiner.OR:
|
||||
return AppLocalizations.of(context).any;
|
||||
return appLocalizations.any;
|
||||
}
|
||||
}
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition_group.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/context_menu/context_item_condition_combiner_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/context_menu/context_item_rule_condition_comparator_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/context_menu/context_item_rule_condition_field_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/context_menu/context_item_rule_filter_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.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';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
extension SelectRuleActionFieldExtension on RulesFilterCreatorController {
|
||||
void unFocusAllInputField() {
|
||||
inputRuleNameFocusNode.unfocus();
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
void selectRuleConditionCombinerAction(
|
||||
BuildContext context,
|
||||
ConditionCombiner conditionCombiner,
|
||||
) {
|
||||
unFocusAllInputField();
|
||||
|
||||
final contextMenuActions = ConditionCombiner.values.map((filter) {
|
||||
return ContextItemConditionCombinerAction(
|
||||
filter,
|
||||
conditionCombiner,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
popBack();
|
||||
selectConditionCombiner(menuAction.action);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void selectRuleConditionFieldAction(
|
||||
BuildContext context,
|
||||
Field? currentField,
|
||||
Field selectedField,
|
||||
RuleFilterConditionScreenType screenType,
|
||||
int index,
|
||||
) {
|
||||
if (screenType == RuleFilterConditionScreenType.mobile) {
|
||||
unFocusAllInputField();
|
||||
|
||||
final contextMenuActions = Field.values.map((field) {
|
||||
return ContextItemRuleConditionFieldAction(
|
||||
field,
|
||||
selectedField,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
popBack();
|
||||
updateRuleConditionField(menuAction.action, index);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
updateRuleConditionField(currentField, index);
|
||||
}
|
||||
}
|
||||
|
||||
void selectRuleConditionComparatorAction(
|
||||
BuildContext context,
|
||||
Comparator? currentComparator,
|
||||
Comparator selectedComparator,
|
||||
RuleFilterConditionScreenType screenType,
|
||||
int index,
|
||||
) {
|
||||
if (screenType == RuleFilterConditionScreenType.mobile) {
|
||||
unFocusAllInputField();
|
||||
|
||||
final contextMenuActions = Comparator.values.map((comparator) {
|
||||
return ContextItemRuleConditionComparatorAction(
|
||||
comparator,
|
||||
selectedComparator,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
popBack();
|
||||
updateRuleConditionComparator(menuAction.action, index);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
updateRuleConditionComparator(currentComparator, index);
|
||||
}
|
||||
}
|
||||
|
||||
void selectRuleFilterAction(
|
||||
BuildContext context,
|
||||
EmailRuleFilterAction? selectedFilterAction,
|
||||
int index,
|
||||
) {
|
||||
final contextMenuActions = EmailRuleFilterAction.values.map((filterAction) {
|
||||
if (filterAction.isSupported) {
|
||||
return ContextItemRuleFilterAction(
|
||||
filterAction,
|
||||
selectedFilterAction,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).whereNotNull().toList();
|
||||
|
||||
if (contextMenuActions.isEmpty) return;
|
||||
|
||||
unFocusAllInputField();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
popBack();
|
||||
if (menuAction.action !=
|
||||
listEmailRuleFilterActionSelected[index].action) {
|
||||
updateEmailRuleFilterAction(context, menuAction.action, index);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition_group.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemConditionCombinerAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<ConditionCombiner> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemConditionCombinerAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitle(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemRuleConditionComparatorAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<Comparator> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemRuleConditionComparatorAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitle(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:rule_filter/rule_filter/rule_condition.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemRuleConditionFieldAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<Field> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemRuleConditionFieldAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitle(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemRuleFilterAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<EmailRuleFilterAction> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemRuleFilterAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitle(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
enum EmailRuleFilterAction {
|
||||
@@ -9,24 +8,22 @@ enum EmailRuleFilterAction {
|
||||
markAsSpam,
|
||||
forwardTo;
|
||||
|
||||
String getTitle(BuildContext context) {
|
||||
String getTitle(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case EmailRuleFilterAction.moveMessage:
|
||||
return AppLocalizations.of(context).moveMessage;
|
||||
return appLocalizations.moveMessage;
|
||||
case EmailRuleFilterAction.maskAsSeen:
|
||||
return AppLocalizations.of(context).maskAsSeen;
|
||||
return appLocalizations.maskAsSeen;
|
||||
case EmailRuleFilterAction.starIt:
|
||||
return AppLocalizations.of(context).starIt;
|
||||
return appLocalizations.starIt;
|
||||
case EmailRuleFilterAction.rejectIt:
|
||||
return AppLocalizations.of(context).rejectIt;
|
||||
return appLocalizations.rejectIt;
|
||||
case EmailRuleFilterAction.markAsSpam:
|
||||
return AppLocalizations.of(context).markAsSpam;
|
||||
return appLocalizations.markAsSpam;
|
||||
case EmailRuleFilterAction.forwardTo:
|
||||
return AppLocalizations.of(context).forwardTo;
|
||||
return appLocalizations.forwardTo;
|
||||
}
|
||||
}
|
||||
|
||||
bool getSupported() {
|
||||
return this != EmailRuleFilterAction.forwardTo;
|
||||
}
|
||||
bool get isSupported => this != EmailRuleFilterAction.forwardTo;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
|
||||
final TextEditingController forwardEmailController = TextEditingController();
|
||||
final FocusNode forwardEmailFocusNode = FocusNode();
|
||||
final listEmailRuleFilterActionSelected = RxList<RuleFilterActionArguments>();
|
||||
int maxCountAction = EmailRuleFilterAction.values.where((action) => action.getSupported() == true).length - 1;
|
||||
int maxCountAction = EmailRuleFilterAction.values.where((action) => action.isSupported).length - 1;
|
||||
final isShowAddAction = Rxn<bool>();
|
||||
|
||||
String? _newRuleName;
|
||||
@@ -330,7 +330,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
|
||||
);
|
||||
}
|
||||
|
||||
void selectRuleConditionField(rule_condition.Field? newField, int? ruleConditionIndex) {
|
||||
void updateRuleConditionField(rule_condition.Field? newField, int? ruleConditionIndex) {
|
||||
if (newField != null && ruleConditionIndex != null) {
|
||||
RuleCondition newRuleCondition = RuleCondition(
|
||||
field: newField,
|
||||
@@ -342,7 +342,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
|
||||
}
|
||||
}
|
||||
|
||||
void selectRuleConditionComparator(rule_condition.Comparator? newComparator, int? ruleConditionIndex) {
|
||||
void updateRuleConditionComparator(rule_condition.Comparator? newComparator, int? ruleConditionIndex) {
|
||||
if (newComparator != null && ruleConditionIndex != null) {
|
||||
RuleCondition newRuleCondition = RuleCondition(
|
||||
field: listRuleCondition[ruleConditionIndex].field,
|
||||
@@ -354,7 +354,7 @@ class RulesFilterCreatorController extends BaseMailboxController {
|
||||
}
|
||||
}
|
||||
|
||||
void selectEmailRuleFilterAction(
|
||||
void updateEmailRuleFilterAction(
|
||||
BuildContext context,
|
||||
EmailRuleFilterAction? newAction,
|
||||
int ruleFilterActionIndex
|
||||
|
||||
@@ -3,24 +3,16 @@ import 'package:flutter/material.dart';
|
||||
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.dart' as rule_condition;
|
||||
import 'package:rule_filter/rule_filter/rule_condition_group.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.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';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/styles/rule_filter_action_styles.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_action_bottom_sheet_action_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_combiner_bottomsheet_action_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_comparator_bottom_sheet_action_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_field_bottom_sheet_action_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_action_list.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_title_builder.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rules_filter_input_field_builder.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
import 'model/rule_filter_condition_type.dart';
|
||||
|
||||
class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
|
||||
@@ -183,7 +175,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
actionList: controller.listEmailRuleFilterActionSelected,
|
||||
onActionChanged: (newAction, index) {
|
||||
controller.selectEmailRuleFilterAction(context, newAction, index);
|
||||
controller.updateEmailRuleFilterAction(context, newAction, index);
|
||||
},
|
||||
forwardEmailEditingController: controller.forwardEmailController,
|
||||
forwardEmailFocusNode: controller.forwardEmailFocusNode,
|
||||
@@ -344,7 +336,7 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
actionList: controller.listEmailRuleFilterActionSelected,
|
||||
onActionChanged: (newAction, index) {
|
||||
controller.selectEmailRuleFilterAction(context, newAction, index);
|
||||
controller.updateEmailRuleFilterAction(context, newAction, index);
|
||||
},
|
||||
forwardEmailEditingController: controller.forwardEmailController,
|
||||
forwardEmailFocusNode: controller.forwardEmailFocusNode,
|
||||
@@ -463,14 +455,12 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
Obx(() => RuleFilterTitle(
|
||||
conditionCombinerType: controller.conditionCombinerType.value,
|
||||
ruleFilterConditionScreenType: RuleFilterConditionScreenType.mobile,
|
||||
tapActionCallback: (value) => {
|
||||
controller.openContextMenuAction(
|
||||
tapActionCallback: (_) {
|
||||
controller.selectRuleConditionCombinerAction(
|
||||
context,
|
||||
_bottomSheetRuleConditionCombinerActionTiles(
|
||||
context,
|
||||
controller.conditionCombinerType.value,
|
||||
)
|
||||
),
|
||||
controller.conditionCombinerType.value
|
||||
?? ConditionCombiner.AND,
|
||||
);
|
||||
},
|
||||
)),
|
||||
const SizedBox(height: 24),
|
||||
@@ -519,14 +509,10 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
actionList: controller.listEmailRuleFilterActionSelected,
|
||||
onActionChangeMobile: (currentAction, index) {
|
||||
KeyboardUtils.hideKeyboard(context);
|
||||
controller.openContextMenuAction(
|
||||
controller.selectRuleFilterAction(
|
||||
context,
|
||||
_bottomSheetActionRuleFilterActionTiles(
|
||||
context,
|
||||
currentAction,
|
||||
index
|
||||
)
|
||||
currentAction,
|
||||
index
|
||||
);
|
||||
},
|
||||
forwardEmailEditingController: controller.forwardEmailController,
|
||||
@@ -631,34 +617,22 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
conditionValueErrorText: controller.listRuleConditionValueArguments[index].errorText,
|
||||
conditionValueFocusNode: controller.listRuleConditionValueArguments[index].focusNode,
|
||||
conditionValueEditingController: controller.listRuleConditionValueArguments[index].controller,
|
||||
tapRuleConditionFieldCallback: (value) => {
|
||||
if (ruleFilterConditionScreenType == RuleFilterConditionScreenType.mobile) {
|
||||
controller.openContextMenuAction(
|
||||
tapRuleConditionFieldCallback: (value) =>
|
||||
controller.selectRuleConditionFieldAction(
|
||||
context,
|
||||
_bottomSheetRuleConditionFieldActionTiles(
|
||||
context,
|
||||
controller.listRuleCondition[index].field,
|
||||
index,
|
||||
)
|
||||
value,
|
||||
controller.listRuleCondition[index].field,
|
||||
ruleFilterConditionScreenType,
|
||||
index,
|
||||
),
|
||||
} else {
|
||||
controller.selectRuleConditionField(value, index)
|
||||
}
|
||||
},
|
||||
tapRuleConditionComparatorCallback: (value) => {
|
||||
if (ruleFilterConditionScreenType == RuleFilterConditionScreenType.mobile) {
|
||||
controller.openContextMenuAction(
|
||||
tapRuleConditionComparatorCallback: (value) =>
|
||||
controller.selectRuleConditionComparatorAction(
|
||||
context,
|
||||
_bottomSheetRuleConditionComparatorActionTiles(
|
||||
context,
|
||||
controller.listRuleCondition[index].comparator,
|
||||
index,
|
||||
)
|
||||
value,
|
||||
controller.listRuleCondition[index].comparator,
|
||||
ruleFilterConditionScreenType,
|
||||
index,
|
||||
),
|
||||
} else {
|
||||
controller.selectRuleConditionComparator(value, index),
|
||||
}
|
||||
},
|
||||
conditionValueOnChangeAction: (value) =>
|
||||
controller.updateConditionValue(context, value, index),
|
||||
tapRemoveRuleFilterConditionCallback: () => controller.tapRemoveCondition(index),
|
||||
@@ -670,147 +644,4 @@ class RuleFilterCreatorView extends GetWidget<RulesFilterCreatorController> {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
List<Widget> _bottomSheetRuleConditionFieldActionTiles(
|
||||
BuildContext context,
|
||||
rule_condition.Field? fieldSelected,
|
||||
int? ruleConditionIndex,
|
||||
) {
|
||||
return rule_condition.Field.values
|
||||
.map((field) =>
|
||||
_buildRuleConditionFieldWidget(context, field, fieldSelected, ruleConditionIndex))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Widget _buildRuleConditionFieldWidget(
|
||||
BuildContext context,
|
||||
rule_condition.Field field,
|
||||
rule_condition.Field? fieldSelected,
|
||||
int? ruleConditionIndex,
|
||||
) {
|
||||
return (RuleConditionFieldSheetActionTileBuilder(
|
||||
field.getTitle(context),
|
||||
fieldSelected,
|
||||
field,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12),
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((field) {
|
||||
controller.selectRuleConditionField(field, ruleConditionIndex);
|
||||
popBack();
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
List<Widget> _bottomSheetRuleConditionComparatorActionTiles(
|
||||
BuildContext context,
|
||||
rule_condition.Comparator? comparatorSelected,
|
||||
int? ruleConditionIndex,
|
||||
) {
|
||||
return rule_condition.Comparator.values
|
||||
.map((comparator) =>
|
||||
_buildRuleConditionComparatorWidget(context, comparator, comparatorSelected, ruleConditionIndex))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Widget _buildRuleConditionComparatorWidget(
|
||||
BuildContext context,
|
||||
rule_condition.Comparator comparator,
|
||||
rule_condition.Comparator? comparatorSelected,
|
||||
int? ruleConditionIndex,
|
||||
) {
|
||||
return (RuleConditionComparatorSheetActionTileBuilder(
|
||||
comparator.getTitle(context),
|
||||
comparatorSelected,
|
||||
comparator,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12),
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((comparator) {
|
||||
controller.selectRuleConditionComparator(comparator, ruleConditionIndex);
|
||||
popBack();
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
List<Widget> _bottomSheetRuleConditionCombinerActionTiles(
|
||||
BuildContext context,
|
||||
ConditionCombiner? combinerSelected,
|
||||
) {
|
||||
return ConditionCombiner.values
|
||||
.map((combiner) =>
|
||||
_buildRuleConditionCombinerWidget(context, combiner, combinerSelected))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Widget _buildRuleConditionCombinerWidget(
|
||||
BuildContext context,
|
||||
ConditionCombiner combiner,
|
||||
ConditionCombiner? combinerSelected,
|
||||
) {
|
||||
return (RuleConditionCombinerSheetActionTileBuilder(
|
||||
combiner.getTitle(context),
|
||||
combiner,
|
||||
combinerSelected,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12),
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((combiner) {
|
||||
controller.selectConditionCombiner(combiner);
|
||||
popBack();
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
List<Widget> _bottomSheetActionRuleFilterActionTiles(
|
||||
BuildContext context,
|
||||
EmailRuleFilterAction? ruleActionSelected,
|
||||
int ruleActionIndex,
|
||||
) {
|
||||
final supportedAction = EmailRuleFilterAction.values
|
||||
.where((ruleAction) => ruleAction.getSupported() == true)
|
||||
.toList();
|
||||
return supportedAction
|
||||
.map((ruleAction) =>
|
||||
_buildRuleActionWidget(context, ruleAction, ruleActionSelected, ruleActionIndex))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Widget _buildRuleActionWidget(
|
||||
BuildContext context,
|
||||
EmailRuleFilterAction ruleAction,
|
||||
EmailRuleFilterAction? ruleActionSelected,
|
||||
int ruleActionIndex,
|
||||
) {
|
||||
return (RuleActionSheetActionTileBuilder(
|
||||
ruleAction.getTitle(context),
|
||||
ruleActionSelected,
|
||||
ruleAction,
|
||||
iconLeftPadding: const EdgeInsets.only(left: 12, right: 16),
|
||||
iconRightPadding: const EdgeInsets.only(right: 12),
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((ruleAction) {
|
||||
if (ruleAction != controller.listEmailRuleFilterActionSelected[ruleActionIndex].action) {
|
||||
controller.selectEmailRuleFilterAction(context, ruleAction, ruleActionIndex);
|
||||
}
|
||||
popBack();
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -40,7 +40,7 @@ class RuleFilterActionRow extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final supportedAction = actionList.where((action) => action.getSupported() == true).toList();
|
||||
final supportedAction = actionList.where((action) => action.isSupported).toList();
|
||||
return Row(
|
||||
crossAxisAlignment: actionSelected == EmailRuleFilterAction.moveMessage ? CrossAxisAlignment.center : CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
+7
-4
@@ -11,6 +11,7 @@ import 'package:rule_filter/rule_filter/rule_condition_group.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnTapActionCallback<T> = Function(T? value);
|
||||
|
||||
@@ -63,20 +64,22 @@ class RuleFilterButtonField<T> extends StatelessWidget {
|
||||
}
|
||||
|
||||
String _getName(BuildContext context, T? value) {
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
if (value is PresentationMailbox) {
|
||||
return value.getDisplayName(context);
|
||||
}
|
||||
if (value is rule_condition.Field) {
|
||||
return value.getTitle(context);
|
||||
return value.getTitle(appLocalizations);
|
||||
}
|
||||
if (value is rule_condition.Comparator) {
|
||||
return value.getTitle(context);
|
||||
return value.getTitle(appLocalizations);
|
||||
}
|
||||
if (value is EmailRuleFilterAction) {
|
||||
return value.getTitle(context);
|
||||
return value.getTitle(appLocalizations);
|
||||
}
|
||||
if (value is ConditionCombiner) {
|
||||
return value.getTitle(context);
|
||||
return value.getTitle(appLocalizations);
|
||||
}
|
||||
return hintText ?? '';
|
||||
}
|
||||
|
||||
+2
-3
@@ -36,9 +36,8 @@ extension HandleEmailMoreActionExtension on SearchEmailController {
|
||||
))
|
||||
.toList();
|
||||
|
||||
openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
pressEmailAction(
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemReceiveTimeTypeAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<EmailReceiveTimeType> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemReceiveTimeTypeAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitleByAppLocalizations(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemSortOrderTypeAction
|
||||
extends ContextMenuItemActionRequiredSelectedIcon<EmailSortOrderType> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemSortOrderTypeAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionName => action.getTitleByAppLocalizations(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
@@ -22,15 +22,15 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/qu
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/recent_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/search_filters/search_filter_button.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/extension/handle_email_more_action_extension.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/model/context_item_receive_time_type_action.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/model/context_item_sort_order_type_action.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/model/search_more_state.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/styles/search_email_view_style.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/utils/search_email_utils.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/app_bar_selection_mode.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_receive_time_action_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_sort_by_action_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_sort_by_cupertino_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/empty_search_email_widget.dart';
|
||||
import 'package:tmail_ui_user/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
@@ -352,17 +352,25 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
}
|
||||
|
||||
void _openContextMenuDateFilter(BuildContext context) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
_emailReceiveTimeCupertinoActionTile(
|
||||
context,
|
||||
final contextMenuActions = EmailReceiveTimeType.values.map((timeType) {
|
||||
return ContextItemReceiveTimeTypeAction(
|
||||
timeType,
|
||||
controller.emailReceiveTimeType.value,
|
||||
(receiveTime) => controller.selectReceiveTimeQuickSearchFilter(
|
||||
context,
|
||||
receiveTime
|
||||
)
|
||||
),
|
||||
AppLocalizations.of(context),
|
||||
controller.imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
controller.openBottomSheetContextMenuAction(
|
||||
key: const Key('date_time_filter_context_menu'),
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
controller.selectReceiveTimeQuickSearchFilter(
|
||||
context,
|
||||
menuAction.action,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -379,14 +387,25 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
}
|
||||
|
||||
void _openContextMenuSortFilter(BuildContext context) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
_emailSortOrderCupertinoActionTitle(
|
||||
context,
|
||||
final contextMenuActions = EmailSortOrderType.values.map((orderType) {
|
||||
return ContextItemSortOrderTypeAction(
|
||||
orderType,
|
||||
controller.emailSortOrderType.value,
|
||||
controller.selectSortOrderQuickSearchFilter
|
||||
),
|
||||
key: const Key('sort_filter_context_menu')
|
||||
AppLocalizations.of(context),
|
||||
controller.imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
controller.openBottomSheetContextMenuAction(
|
||||
key: const Key('sort_filter_context_menu'),
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
controller.selectSortOrderQuickSearchFilter(
|
||||
context,
|
||||
menuAction.action,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -406,32 +425,6 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<Widget> _emailReceiveTimeCupertinoActionTile(
|
||||
BuildContext context,
|
||||
EmailReceiveTimeType? receiveTimeSelected,
|
||||
Function(EmailReceiveTimeType)? onCallBack
|
||||
) {
|
||||
return EmailReceiveTimeType.values
|
||||
.map((timeType) => (EmailReceiveTimeCupertinoActionSheetActionBuilder(
|
||||
timeType.getTitle(context),
|
||||
timeType,
|
||||
timeTypeCurrent: receiveTimeSelected,
|
||||
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||
: const EdgeInsetsDirectional.only(end: 12),
|
||||
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsetsDirectional.only(end: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick((timeType) => onCallBack?.call(timeType)))
|
||||
.build())
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<PopupMenuEntry> _popupMenuEmailSortOrderType(
|
||||
BuildContext context,
|
||||
EmailSortOrderType? sortTypeSelected,
|
||||
@@ -449,36 +442,6 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
||||
)).toList();
|
||||
}
|
||||
|
||||
List<Widget> _emailSortOrderCupertinoActionTitle(
|
||||
BuildContext context,
|
||||
EmailSortOrderType? sortOrderSelected,
|
||||
Function(BuildContext context, EmailSortOrderType)? onCallBack,
|
||||
) {
|
||||
return EmailSortOrderType.values
|
||||
.map(
|
||||
(sortType) => (
|
||||
EmailSortByCupertinoActionSheetActionBuilder(
|
||||
sortType.getTitle(context),
|
||||
sortType,
|
||||
sortTypeCurrent: sortOrderSelected,
|
||||
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||
: const EdgeInsetsDirectional.only(start: 12),
|
||||
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsetsDirectional.only(end: 12)
|
||||
: EdgeInsetsDirectional.zero,
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill
|
||||
)
|
||||
)
|
||||
..onActionClick((sortType) => onCallBack?.call(context, sortType))
|
||||
).build()
|
||||
).toList();
|
||||
}
|
||||
|
||||
Widget _buildShowAllResultSearchButton(BuildContext context, String textSearch) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
|
||||
@@ -283,9 +283,8 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
|
||||
}
|
||||
|
||||
if (controller.responsiveUtils.isScreenWithShortestSide(context) || position == null) {
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
controller.openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) => controller.handleMailboxAction(
|
||||
context,
|
||||
|
||||
@@ -79,16 +79,16 @@ extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
}
|
||||
}
|
||||
|
||||
String getName(BuildContext context) {
|
||||
String getName(AppLocalizations appLocalizations) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return AppLocalizations.of(context).unread;
|
||||
return appLocalizations.unread;
|
||||
case FilterMessageOption.attachments:
|
||||
return AppLocalizations.of(context).with_attachments;
|
||||
return appLocalizations.with_attachments;
|
||||
case FilterMessageOption.starred:
|
||||
return AppLocalizations.of(context).starred;
|
||||
return appLocalizations.starred;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/context_item_filter_message_option_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension HandleSelectMessageFilterExtension on ThreadController {
|
||||
void handleSelectMessageFilter(
|
||||
BuildContext context,
|
||||
FilterMessageOption selectedOption,
|
||||
) {
|
||||
final contextMenuActions = [
|
||||
FilterMessageOption.attachments,
|
||||
FilterMessageOption.unread,
|
||||
FilterMessageOption.starred,
|
||||
].map((filter) {
|
||||
return ContextItemFilterMessageOptionAction(
|
||||
filter,
|
||||
selectedOption,
|
||||
AppLocalizations.of(context),
|
||||
imagePaths,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (action) => filterMessagesAction(action.action),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ContextItemFilterMessageOptionAction
|
||||
extends ContextMenuItemActionRequiredFull<FilterMessageOption> {
|
||||
final AppLocalizations appLocalizations;
|
||||
final ImagePaths imagePaths;
|
||||
|
||||
ContextItemFilterMessageOptionAction(
|
||||
super.action,
|
||||
super.selectedAction,
|
||||
this.appLocalizations,
|
||||
this.imagePaths,
|
||||
);
|
||||
|
||||
@override
|
||||
String get actionIcon => action.getContextMenuIcon(imagePaths);
|
||||
|
||||
@override
|
||||
String get actionName => action.getName(appLocalizations);
|
||||
|
||||
@override
|
||||
String get selectedIcon => imagePaths.icFilterSelected;
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import 'package:tmail_ui_user/features/thread/domain/state/empty_trash_folder_st
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/handle_pull_to_refresh_list_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/handle_select_message_filter_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/loading_more_status.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart';
|
||||
@@ -39,7 +40,6 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_th
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
|
||||
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/empty_emails_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/scroll_to_top_button_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/spam_banner/spam_report_banner_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/thread_view_loading_bar_widget.dart';
|
||||
@@ -84,10 +84,7 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
cancelEditThreadAction: controller.cancelSelectEmail,
|
||||
emailSelectionAction: controller.pressEmailSelectionAction,
|
||||
onContextMenuFilterEmailAction: controller.responsiveUtils.isScreenWithShortestSide(context)
|
||||
? (filterOption) => controller.openContextMenuAction(
|
||||
context,
|
||||
_filterMessagesCupertinoActionTile(context, filterOption)
|
||||
)
|
||||
? (filterOption) => controller.handleSelectMessageFilter(context, filterOption)
|
||||
: null,
|
||||
onPopupMenuFilterEmailAction: !controller.responsiveUtils.isScreenWithShortestSide(context)
|
||||
? (filterOption, position) => controller.openPopupMenuAction(
|
||||
@@ -342,41 +339,6 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
});
|
||||
}
|
||||
|
||||
List<Widget> _filterMessagesCupertinoActionTile(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
final listFilter = [
|
||||
FilterMessageOption.attachments,
|
||||
FilterMessageOption.unread,
|
||||
FilterMessageOption.starred,
|
||||
];
|
||||
|
||||
return listFilter.map((filter) => (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
Key('filter_email_${filter.name}'),
|
||||
SvgPicture.asset(
|
||||
filter.getContextMenuIcon(controller.imagePaths),
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill,
|
||||
colorFilter: filter == FilterMessageOption.attachments
|
||||
? AppColor.colorTextButton.asFilter()
|
||||
: null),
|
||||
filter.getName(context),
|
||||
filter,
|
||||
optionCurrent: optionCurrent,
|
||||
iconLeftPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: controller.responsiveUtils.isMobile(context)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero,
|
||||
actionSelected: SvgPicture.asset(
|
||||
controller.imagePaths.icFilterSelected,
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill))
|
||||
..onActionClick(controller.filterMessagesAction))
|
||||
.build()).toList();
|
||||
}
|
||||
|
||||
Widget _buildResultListEmail(BuildContext context, List<PresentationEmail> listPresentationEmail) {
|
||||
return listPresentationEmail.isNotEmpty
|
||||
? _buildListEmailBody(context, listPresentationEmail)
|
||||
@@ -685,9 +647,8 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
))
|
||||
.toList();
|
||||
|
||||
controller.openContextMenuAction(
|
||||
context,
|
||||
[],
|
||||
controller.openBottomSheetContextMenuAction(
|
||||
context: context,
|
||||
itemActions: contextMenuActions,
|
||||
onContextMenuActionClick: (menuAction) {
|
||||
controller.handleEmailActionType(
|
||||
|
||||
@@ -52,7 +52,7 @@ class EmptyEmailsWidget extends StatelessWidget {
|
||||
Text(
|
||||
key: const Key('empty_email_sub_message'),
|
||||
AppLocalizations.of(context).startToComposeEmails,
|
||||
style: ThemeUtils.textStyleInter400().copyWith(
|
||||
style: ThemeUtils.textStyleInter400.copyWith(
|
||||
letterSpacing: -0.15,
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
|
||||
Reference in New Issue
Block a user