TF-3766 Change context menu style for search email view on mobile
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import 'package:core/presentation/extensions/color_extension.dart';
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/views/bottom_popup/cupertino_action_sheet_builder.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -20,30 +21,37 @@ mixin PopupContextMenuActionMixin {
|
|||||||
OnContextMenuActionClick? onContextMenuActionClick,
|
OnContextMenuActionClick? onContextMenuActionClick,
|
||||||
}
|
}
|
||||||
) async {
|
) async {
|
||||||
await showModalBottomSheet(
|
if (actionTiles.isNotEmpty) {
|
||||||
context: context,
|
await (CupertinoActionSheetBuilder(context, key: key)
|
||||||
showDragHandle: true,
|
..addTiles(actionTiles)
|
||||||
useSafeArea: true,
|
..addCancelButton(cancelButton ?? buildCancelButton(context)))
|
||||||
isScrollControlled: true,
|
.show();
|
||||||
shape: const RoundedRectangleBorder(
|
} else {
|
||||||
borderRadius: BorderRadius.only(
|
await showModalBottomSheet(
|
||||||
topLeft: Radius.circular(16.0),
|
context: context,
|
||||||
topRight: Radius.circular(16.0),
|
showDragHandle: true,
|
||||||
),
|
useSafeArea: true,
|
||||||
),
|
isScrollControlled: true,
|
||||||
backgroundColor: Colors.white,
|
shape: const RoundedRectangleBorder(
|
||||||
barrierColor: Colors.black.withOpacity(0.2),
|
borderRadius: BorderRadius.only(
|
||||||
builder: (_) {
|
topLeft: Radius.circular(16.0),
|
||||||
return ColoredBox(
|
topRight: Radius.circular(16.0),
|
||||||
color: Colors.white,
|
|
||||||
child: ContextMenuDialogView(
|
|
||||||
actions: itemActions ?? [],
|
|
||||||
onContextMenuActionClick: (menuAction) =>
|
|
||||||
onContextMenuActionClick?.call(menuAction),
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
backgroundColor: Colors.white,
|
||||||
);
|
barrierColor: Colors.black.withOpacity(0.2),
|
||||||
|
builder: (_) {
|
||||||
|
return ColoredBox(
|
||||||
|
color: Colors.white,
|
||||||
|
child: ContextMenuDialogView(
|
||||||
|
actions: itemActions ?? [],
|
||||||
|
onContextMenuActionClick: (menuAction) =>
|
||||||
|
onContextMenuActionClick?.call(menuAction),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void openPopupMenuAction(
|
void openPopupMenuAction(
|
||||||
|
|||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:model/email/email_action_type.dart';
|
||||||
|
import 'package:model/email/presentation_email.dart';
|
||||||
|
import 'package:model/extensions/presentation_mailbox_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/presentation/model/context_item_email_action.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart';
|
||||||
|
import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
|
extension HandleEmailMoreActionExtension on SearchEmailController {
|
||||||
|
void handleEmailMoreAction(
|
||||||
|
BuildContext context,
|
||||||
|
PresentationEmail presentationEmail,
|
||||||
|
RelativeRect? position,
|
||||||
|
) {
|
||||||
|
final mailboxContain = presentationEmail.mailboxContain;
|
||||||
|
|
||||||
|
final listEmailActions = [
|
||||||
|
mailboxContain?.isSpam == true
|
||||||
|
? EmailActionType.unSpam
|
||||||
|
: EmailActionType.moveToSpam,
|
||||||
|
if (mailboxContain?.isDrafts == false) EmailActionType.editAsNewEmail,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (listEmailActions.isEmpty) return;
|
||||||
|
|
||||||
|
if (responsiveUtils.isScreenWithShortestSide(context)) {
|
||||||
|
final contextMenuActions = listEmailActions
|
||||||
|
.map((action) => ContextItemEmailAction(
|
||||||
|
action,
|
||||||
|
AppLocalizations.of(context),
|
||||||
|
imagePaths,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
openContextMenuAction(
|
||||||
|
context,
|
||||||
|
[],
|
||||||
|
itemActions: contextMenuActions,
|
||||||
|
onContextMenuActionClick: (menuAction) {
|
||||||
|
pressEmailAction(
|
||||||
|
context,
|
||||||
|
menuAction.action,
|
||||||
|
presentationEmail,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final popupMenuEntries = listEmailActions
|
||||||
|
.map((actionType) => PopupMenuItem(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: _buildPopupMenuAction(
|
||||||
|
context,
|
||||||
|
presentationEmail,
|
||||||
|
actionType,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
openPopupMenuAction(
|
||||||
|
context,
|
||||||
|
position,
|
||||||
|
popupMenuEntries,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPopupMenuAction(
|
||||||
|
BuildContext context,
|
||||||
|
PresentationEmail presentationEmail,
|
||||||
|
EmailActionType emailActionType,
|
||||||
|
) {
|
||||||
|
return (EmailActionCupertinoActionSheetActionBuilder(
|
||||||
|
Key(emailActionType.name),
|
||||||
|
SvgPicture.asset(emailActionType.getIcon(imagePaths),
|
||||||
|
width: 28,
|
||||||
|
height: 28,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
colorFilter: AppColor.colorTextButton.asFilter()),
|
||||||
|
emailActionType.getTitle(AppLocalizations.of(context)),
|
||||||
|
presentationEmail,
|
||||||
|
iconLeftPadding: responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(start: 12, end: 16)
|
||||||
|
: const EdgeInsetsDirectional.only(end: 12),
|
||||||
|
iconRightPadding: responsiveUtils.isMobile(context)
|
||||||
|
? const EdgeInsetsDirectional.only(end: 12)
|
||||||
|
: EdgeInsets.zero,
|
||||||
|
)..onActionClick((email) => pressEmailAction(
|
||||||
|
context,
|
||||||
|
emailActionType,
|
||||||
|
email,
|
||||||
|
)))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -888,6 +888,10 @@ class SearchEmailController extends BaseController
|
|||||||
popBack();
|
popBack();
|
||||||
unSpam(selectedEmail);
|
unSpam(selectedEmail);
|
||||||
break;
|
break;
|
||||||
|
case EmailActionType.editAsNewEmail:
|
||||||
|
popBack();
|
||||||
|
editAsNewEmail(selectedEmail);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||||
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
|
import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
|
||||||
@@ -22,6 +21,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/qu
|
|||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/email_quick_search_item_tile_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/quick_search/email_quick_search_item_tile_widget.dart';
|
||||||
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/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/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/search_more_state.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/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/styles/search_email_view_style.dart';
|
||||||
@@ -39,7 +39,6 @@ import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_til
|
|||||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
|
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';
|
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
|
||||||
|
|
||||||
class SearchEmailView extends GetWidget<SearchEmailController>
|
class SearchEmailView extends GetWidget<SearchEmailController>
|
||||||
with AppLoaderMixin {
|
with AppLoaderMixin {
|
||||||
@@ -667,20 +666,12 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
|||||||
mailboxContain: currentPresentationEmail.mailboxContain
|
mailboxContain: currentPresentationEmail.mailboxContain
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onMoreActionClick: (email, position) {
|
onMoreActionClick: (email, position) =>
|
||||||
if (controller.responsiveUtils.isScreenWithShortestSide(context)) {
|
controller.handleEmailMoreAction(
|
||||||
controller.openContextMenuAction(
|
|
||||||
context,
|
|
||||||
_contextMenuActionTile(context, email)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
controller.openPopupMenuAction(
|
|
||||||
context,
|
context,
|
||||||
|
email,
|
||||||
position,
|
position,
|
||||||
_popupMenuActionTile(context, email)
|
),
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
@@ -720,21 +711,12 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
|||||||
mailboxContain: currentPresentationEmail.mailboxContain
|
mailboxContain: currentPresentationEmail.mailboxContain
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onMoreActionClick: (email, position) {
|
onMoreActionClick: (email, position) =>
|
||||||
if (controller.responsiveUtils.isScreenWithShortestSide(context)) {
|
controller.handleEmailMoreAction(
|
||||||
controller.openContextMenuAction(
|
|
||||||
context,
|
|
||||||
_contextMenuActionTile(context, email)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
controller.openPopupMenuAction(
|
|
||||||
context,
|
context,
|
||||||
|
email,
|
||||||
position,
|
position,
|
||||||
_popupMenuActionTile(context, email)
|
),
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) {
|
separatorBuilder: (context, index) {
|
||||||
@@ -752,84 +734,6 @@ class SearchEmailView extends GetWidget<SearchEmailController>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _contextMenuActionTile(BuildContext context, PresentationEmail email) {
|
|
||||||
return <Widget>[
|
|
||||||
_markAsEmailSpamOrUnSpamAction(context, email),
|
|
||||||
if (email.mailboxContain?.isDrafts == false)
|
|
||||||
_editAsNewEmailContextMenuItemAction(context, email),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
|
|
||||||
final mailboxContain = email.mailboxContain;
|
|
||||||
|
|
||||||
return (EmailActionCupertinoActionSheetActionBuilder(
|
|
||||||
const Key('mark_as_spam_or_un_spam_action'),
|
|
||||||
SvgPicture.asset(
|
|
||||||
mailboxContain?.isSpam == true ? controller.imagePaths.icNotSpam : controller.imagePaths.icSpam,
|
|
||||||
width: 28,
|
|
||||||
height: 28,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
colorFilter: AppColor.colorTextButton.asFilter()),
|
|
||||||
mailboxContain?.isSpam == true
|
|
||||||
? AppLocalizations.of(context).remove_from_spam
|
|
||||||
: AppLocalizations.of(context).mark_as_spam,
|
|
||||||
email,
|
|
||||||
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)
|
|
||||||
..onActionClick((email) => controller.pressEmailAction(context,
|
|
||||||
mailboxContain?.isSpam == true
|
|
||||||
? EmailActionType.unSpam
|
|
||||||
: EmailActionType.moveToSpam,
|
|
||||||
email)))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _editAsNewEmailContextMenuItemAction(
|
|
||||||
BuildContext context,
|
|
||||||
PresentationEmail email,
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
EmailActionCupertinoActionSheetActionBuilder(
|
|
||||||
const Key('edit_as_new_email_action'),
|
|
||||||
SvgPicture.asset(
|
|
||||||
controller.imagePaths.icEdit,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
colorFilter: AppColor.colorTextButton.asFilter()
|
|
||||||
),
|
|
||||||
AppLocalizations.of(context).editAsNewEmail,
|
|
||||||
email,
|
|
||||||
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(start: 12)
|
|
||||||
: EdgeInsets.zero)
|
|
||||||
..onActionClick((email) {
|
|
||||||
popBack();
|
|
||||||
controller.editAsNewEmail(email);
|
|
||||||
})
|
|
||||||
).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PopupMenuEntry> _popupMenuActionTile(BuildContext context, PresentationEmail email) {
|
|
||||||
return [
|
|
||||||
PopupMenuItem(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: _markAsEmailSpamOrUnSpamAction(context, email)),
|
|
||||||
if (email.mailboxContain?.isDrafts == false)
|
|
||||||
PopupMenuItem(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: _editAsNewEmailContextMenuItemAction(context, email)),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildLoadingViewLoadMore() {
|
Widget _buildLoadingViewLoadMore() {
|
||||||
return Obx(() => controller.viewState.value.fold(
|
return Obx(() => controller.viewState.value.fold(
|
||||||
(failure) => const SizedBox.shrink(),
|
(failure) => const SizedBox.shrink(),
|
||||||
|
|||||||
Reference in New Issue
Block a user