TF-79 Create popmenu for tablet

This commit is contained in:
dab246
2021-09-20 16:11:49 +07:00
committed by Dat H. Pham
parent c7a3e90a68
commit 8413615e29
21 changed files with 177 additions and 223 deletions
@@ -6,9 +6,11 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
typedef OnPressActionClick = void Function();
typedef OnTapDownActionClick = void Function(TapDownDetails details);
class ButtonBuilder {
OnPressActionClick? _onPressActionClick;
OnTapDownActionClick? _onTapActionClick;
String? _icon;
String? _text;
@@ -51,6 +53,11 @@ class ButtonBuilder {
return this;
}
ButtonBuilder onTapActionClick(OnTapDownActionClick onTapActionClick) {
_onTapActionClick = onTapActionClick;
return this;
}
Widget build() {
return Container(
key: _key,
@@ -65,6 +72,11 @@ class ButtonBuilder {
_onPressActionClick!();
}
},
onTapDown: (detail) {
if (_onTapActionClick != null) {
_onTapActionClick!(detail);
}
},
)
)
);
@@ -41,7 +41,10 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
child: Column(
children: [
_buildAppBar(context),
Expanded(child: _buildBodyDestinationPicker(context))
Expanded(child:
Container(
color: AppColor.bgMailboxListMail,
child: _buildBodyDestinationPicker(context)))
],
)
)
@@ -54,12 +57,9 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
}
Widget _buildAppBar(BuildContext context) {
return Padding(
padding: EdgeInsets.only(left: 24, right: 12),
child: (AppBarDestinationPickerBuilder(context, _imagePaths, _responsiveUtils)
..addCloseActionClick(() => controller.closeDestinationPicker()))
.build()
);
return (AppBarDestinationPickerBuilder(context, _imagePaths, _responsiveUtils)
..addCloseActionClick(() => controller.closeDestinationPicker()))
.build();
}
Widget _buildBodyDestinationPicker(BuildContext context) {
@@ -89,7 +89,8 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
return Obx(() => controller.viewState.value.fold(
(failure) => SizedBox.shrink(),
(success) => success is LoadingState
? Center(child: Padding(
? Center(
child: Padding(
padding: EdgeInsets.only(top: 16),
child: SizedBox(
width: 24,
@@ -117,15 +118,13 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
if (success is GetAllMailboxSuccess) {
final defaultMailboxList = success.defaultMailboxList;
return ListView.builder(
padding: EdgeInsets.only(top: 16, right: 10),
padding: EdgeInsets.only(top: 16, left: 8, right: 10),
key: Key('default_mailbox_list'),
itemCount: defaultMailboxList.length,
shrinkWrap: true,
primary: false,
itemBuilder: (context, index) => (MailboxTileBuilder(
context,
_imagePaths,
_responsiveUtils,
defaultMailboxList[index],
mailboxDisplayed: MailboxDisplayed.destinationPicker)
..onOpenMailboxAction((mailbox) =>
@@ -23,7 +23,7 @@ class AppBarDestinationPickerBuilder {
return Container(
key: Key('app_bar_destination_picker'),
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 8),
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
color: Colors.white,
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
@@ -30,7 +30,6 @@ abstract class EmailDataSource {
Future<List<EmailId>> moveToMailbox(AccountId accountId, MoveRequest moveRequest);
Future<bool> markAsImportant(AccountId accountId, EmailId emailId, ImportantAction importantAction);
Future<List<Email>> markAsStar(
AccountId accountId,
List<Email> emails,
@@ -220,7 +220,6 @@ class EmailAPI {
});
}
Future<bool> markAsImportant(AccountId accountId, EmailId emailId, ImportantAction importantAction) async {
Future<List<Email>> markAsStar(AccountId accountId, List<Email> emails, MarkStarAction markStarAction) async {
final emailIds = emails.map((email) => email.id).toList();
@@ -29,7 +29,6 @@ abstract class EmailRepository {
Future<List<EmailId>> moveToMailbox(AccountId accountId, MoveRequest moveRequest);
Future<bool> markAsImportant(AccountId accountId, EmailId emailId, ImportantAction importantAction);
Future<List<Email>> markAsStar(
AccountId accountId,
List<Email> emails,
@@ -36,7 +36,6 @@ class EmailBindings extends Bindings {
Get.find<EmailRepository>(),
Get.find<CredentialRepository>()));
Get.lazyPut(() => MoveToMailboxInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MarkAsEmailImportantInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MarkAsStarEmailInteractor(Get.find<EmailRepository>()));
Get.put(EmailController(
Get.find<GetEmailContentInteractor>(),
@@ -45,8 +44,7 @@ class EmailBindings extends Bindings {
Get.find<DeviceManager>(),
Get.find<AppToast>(),
Get.find<ExportAttachmentInteractor>(),
Get.find<MoveToMailboxInteractor>()));
Get.find<ExportAttachmentInteractor>(),
Get.find<MoveToMailboxInteractor>(),
Get.find<MarkAsStarEmailInteractor>()));
}
}
@@ -17,7 +17,6 @@ import 'package:tmail_ui_user/features/email/domain/state/download_attachments_s
import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_important_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
@@ -45,7 +44,6 @@ class EmailController extends BaseController {
final AppToast _appToast;
final ExportAttachmentInteractor _exportAttachmentInteractor;
final MoveToMailboxInteractor _moveToMailboxInteractor;
final MarkAsEmailImportantInteractor _markAsEmailImportantInteractor;
final MarkAsStarEmailInteractor _markAsStarEmailInteractor;
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
@@ -61,7 +59,6 @@ class EmailController extends BaseController {
this._appToast,
this._exportAttachmentInteractor,
this._moveToMailboxInteractor,
this._markAsEmailImportantInteractor,
this._markAsStarEmailInteractor,
);
@@ -119,8 +116,6 @@ class EmailController extends BaseController {
_exportAttachmentSuccessAction(success);
} else if (success is MoveToMailboxSuccess) {
_moveToMailboxSuccess(success);
} else if (success is MarkAsEmailImportantSuccess) {
_markAsEmailImportantSuccess(success);
} else if (success is MarkAsStarEmailSuccess) {
_markAsEmailStarSuccess(success);
}
@@ -313,7 +308,6 @@ class EmailController extends BaseController {
}
}
void markAsEmailImportant(PresentationEmail presentationEmail) async {
void markAsStarEmail(PresentationEmail presentationEmail) async {
final accountId = mailboxDashBoardController.accountId.value;
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
@@ -58,10 +58,7 @@ class EmailView extends GetView {
..onUnreadEmailActionClick((presentationEmail) =>
emailController.markAsEmailRead(presentationEmail, ReadActions.markAsUnread))
..addOnMoveToMailboxActionClick((presentationEmail) =>
emailController.openDestinationPickerView(presentationEmail)))
emailController.markAsEmailRead(presentationEmail, ReadActions.markAsUnread))
..addOnMarkAsImportantActionClick((presentationEmail) =>
emailController.markAsEmailImportant(presentationEmail)))
emailController.openDestinationPickerView(presentationEmail))
..addOnMarkAsStarActionClick((presentationEmail) =>
emailController.markAsStarEmail(presentationEmail)))
.build()));
@@ -9,14 +9,12 @@ import 'package:tmail_ui_user/main/routes/app_routes.dart';
typedef OnBackActionClick = void Function();
typedef OnUnreadEmailActionClick = void Function(PresentationEmail presentationEmail);
typedef OnMoveToMailboxActionClick = void Function(PresentationEmail presentationEmail);
typedef OnMarkAsImportantActionClick = void Function(PresentationEmail presentationEmail);
typedef OnMarkAsStarActionClick = void Function(PresentationEmail presentationEmail);
class AppBarMailWidgetBuilder {
OnBackActionClick? _onBackActionClick;
OnUnreadEmailActionClick? _onUnreadEmailActionClick;
OnMoveToMailboxActionClick? _onMoveToMailboxActionClick;
OnMarkAsImportantActionClick? _onMarkAsImportantActionClick;
OnMarkAsStarActionClick? _markAsStarActionClick;
final BuildContext _context;
@@ -43,8 +41,6 @@ class AppBarMailWidgetBuilder {
_onMoveToMailboxActionClick = onMoveToMailboxActionClick;
}
void addOnMarkAsImportantActionClick(OnMarkAsImportantActionClick onMarkAsImportantActionClick) {
_onMarkAsImportantActionClick = onMarkAsImportantActionClick;
void addOnMarkAsStarActionClick(OnMarkAsStarActionClick onMarkAsStarActionClick) {
_markAsStarActionClick = onMarkAsStarActionClick;
}
@@ -101,7 +97,7 @@ class AppBarMailWidgetBuilder {
ButtonBuilder((_presentationEmail != null && _presentationEmail!.isFlaggedEmail())
? _imagePaths.icFlagged
: _imagePaths.icFlag)
.key(Key('button_mark_as_email_important'))
.key(Key('button_mark_as_star_email'))
.onPressActionClick(() {
if (_markAsStarActionClick != null && _presentationEmail != null) {
_markAsStarActionClick!(_presentationEmail!);
@@ -98,7 +98,7 @@ class MailboxView extends GetWidget<MailboxController> {
Widget _buildSearchFormWidget(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 16, bottom: 12, left: 16, right: 16),
padding: EdgeInsets.only(top: 16, left: 16, right: 16),
child: SearchFormWidgetBuilder(context, imagePaths)
.onNewSearchQuery((searchQuery) => {})
.build());
@@ -111,8 +111,8 @@ class MailboxView extends GetWidget<MailboxController> {
? Center(child: Padding(
padding: EdgeInsets.only(top: 16),
child: SizedBox(
width: 30,
height: 30,
width: 24,
height: 24,
child: CircularProgressIndicator(color: AppColor.primaryColor))))
: SizedBox.shrink()));
}
@@ -128,7 +128,7 @@ class MailboxView extends GetWidget<MailboxController> {
: SizedBox.shrink()),
Padding(
padding: EdgeInsets.only(
left: responsiveUtils.isMobile(context) ? 40 : 32,
left: 25,
top: 20),
child: Text(
AppLocalizations.of(context).my_folders,
@@ -137,12 +137,12 @@ class MailboxView extends GetWidget<MailboxController> {
),
Padding(
padding: EdgeInsets.only(
left: responsiveUtils.isMobile(context) ? 16 : 2,
left: 8,
right: 16,
top: 10),
child: MailboxNewFolderTileBuilder(context, responsiveUtils)
.addIcon(imagePaths.icMailboxNewFolder)
.addName(AppLocalizations.of(context).new_folder)
child: (MailboxNewFolderTileBuilder()
..addIcon(imagePaths.icMailboxNewFolder)
..addName(AppLocalizations.of(context).new_folder))
.build()
),
_buildFolderMailbox(context),
@@ -159,9 +159,7 @@ class MailboxView extends GetWidget<MailboxController> {
primary: false,
itemBuilder: (context, index) =>
Obx(() => (MailboxTileBuilder(
context,
imagePaths,
responsiveUtils,
defaultMailbox[index],
selectMode: controller.getSelectMode(
defaultMailbox[index],
@@ -173,9 +171,9 @@ class MailboxView extends GetWidget<MailboxController> {
Widget _buildFolderMailbox(BuildContext context) {
return Obx(() => controller.folderMailboxNodeList.isNotEmpty
? Transform(
transform: Matrix4.translationValues(responsiveUtils.isMobile(context) ? 0.0 : -15.0, 0.0, 0.0),
transform: Matrix4.translationValues(-4.0, 0.0, 0.0),
child: Padding(
padding: EdgeInsets.only(left: 4, right: 16),
padding: EdgeInsets.only(right: 12),
child: TreeView(
startExpanded: false,
key: Key('folder_mailbox_list'),
@@ -9,29 +9,23 @@ typedef OnOpenMailboxNewFolderActionClick = void Function();
class MailboxNewFolderTileBuilder {
final BuildContext _context;
final ResponsiveUtils _responsiveUtils;
String? _icon;
String? _name;
OnOpenMailboxNewFolderActionClick? _onOpenMailboxFolderActionClick;
MailboxNewFolderTileBuilder(this._context, this._responsiveUtils);
MailboxNewFolderTileBuilder();
MailboxNewFolderTileBuilder addIcon(String icon) {
void addIcon(String icon) {
_icon = icon;
return this;
}
MailboxNewFolderTileBuilder addName(String name) {
void addName(String name) {
_name = name;
return this;
}
MailboxNewFolderTileBuilder onOpenMailboxFolderAction(OnOpenMailboxNewFolderActionClick onOpenMailboxFolderActionClick) {
void onOpenMailboxFolderAction(OnOpenMailboxNewFolderActionClick onOpenMailboxFolderActionClick) {
_onOpenMailboxFolderActionClick = onOpenMailboxFolderActionClick;
return this;
}
Widget build() {
@@ -55,7 +49,7 @@ class MailboxNewFolderTileBuilder {
}
},
leading: Padding(
padding: EdgeInsets.only(left: _responsiveUtils.isMobile(_context) ? 42 : 34),
padding: EdgeInsets.only(left: 34),
child: _icon != null
? SvgPicture.asset(_icon!, width: 24, height: 24, color: AppColor.mailboxIconColor, fit: BoxFit.fill)
: SizedBox.shrink()),
@@ -42,72 +42,74 @@ class MailBoxFolderTileBuilder {
}
Widget build() {
return Container(
key: Key('mailbox_folder_tile'),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular( mailboxDisplayed == MailboxDisplayed.mailbox ? 16 : 0),
color: mailboxDisplayed == MailboxDisplayed.mailbox
? selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedBackgroundColor : AppColor.mailboxBackgroundColor
: AppColor.bgMailboxListMail
),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: ListTile(
onTap: () {
if (_onSelectMailboxFolderClick != null) {
_onSelectMailboxFolderClick!(_mailboxNode);
}
},
contentPadding: EdgeInsets.zero,
leading: Padding(
padding: EdgeInsets.only(left: mailboxDisplayed == MailboxDisplayed.mailbox
? _responsiveUtils.isMobile(_context) ? 40 : 34
: 34),
child: SvgPicture.asset(
_imagePaths.icMailboxFolder,
width: 24,
height: 24,
color: selectMode == SelectMode.ACTIVE
? AppColor.mailboxSelectedIconColor
: AppColor.mailboxIconColor,
fit: BoxFit.fill)),
title: Padding(
padding: EdgeInsets.only(left: 8),
child: Text(
_mailboxNode.item.name!.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15,
return Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent),
child: Container(
key: Key('mailbox_folder_tile'),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular( mailboxDisplayed == MailboxDisplayed.mailbox ? 16 : 0),
color: mailboxDisplayed == MailboxDisplayed.mailbox
? selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedBackgroundColor : AppColor.mailboxBackgroundColor
: AppColor.bgMailboxListMail
),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: ListTile(
onTap: () {
if (_onSelectMailboxFolderClick != null) {
_onSelectMailboxFolderClick!(_mailboxNode);
}
},
contentPadding: EdgeInsets.zero,
leading: Padding(
padding: EdgeInsets.only(left: 26),
child: SvgPicture.asset(
_imagePaths.icMailboxFolder,
width: 24,
height: 24,
color: selectMode == SelectMode.ACTIVE
? AppColor.mailboxSelectedTextColor
: AppColor.mailboxTextColor,
fontWeight: mailboxDisplayed == MailboxDisplayed.mailbox ? FontWeight.bold : FontWeight.w500),
)),
trailing: Padding(
padding: EdgeInsets.only(
right: mailboxDisplayed == MailboxDisplayed.mailbox
? _responsiveUtils.isMobile(_context) ? 36 : 8
: 36,
left: mailboxDisplayed == MailboxDisplayed.mailbox ? 16 : 16),
child: _mailboxNode.hasChildren()
? GestureDetector(
onTap: () {
if (_onExpandFolderActionClick != null) {
_onExpandFolderActionClick!(_mailboxNode);
? AppColor.mailboxSelectedIconColor
: AppColor.mailboxIconColor,
fit: BoxFit.fill)),
title: Padding(
padding: EdgeInsets.only(left: 8),
child: Text(
_mailboxNode.item.name!.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15,
color: selectMode == SelectMode.ACTIVE
? AppColor.mailboxSelectedTextColor
: AppColor.mailboxTextColor,
fontWeight: mailboxDisplayed == MailboxDisplayed.mailbox ? FontWeight.bold : FontWeight.w500),
)),
trailing: Padding(
padding: EdgeInsets.only(
right: mailboxDisplayed == MailboxDisplayed.mailbox
? _responsiveUtils.isMobile(_context) ? 0 : 8
: 0,
left: 16),
child: _mailboxNode.hasChildren()
? IconButton(
color: AppColor.primaryColor,
icon: SvgPicture.asset(
_mailboxNode.expandMode == ExpandMode.EXPAND ? _imagePaths.icExpandFolder : _imagePaths.icFolderArrow,
color: selectMode == SelectMode.ACTIVE
? AppColor.mailboxSelectedIconColor
: AppColor.mailboxIconColor,
fit: BoxFit.fill),
onPressed: () {
if (_onExpandFolderActionClick != null) {
_onExpandFolderActionClick!(_mailboxNode);
}
}
},
child: SvgPicture.asset(
_mailboxNode.expandMode == ExpandMode.EXPAND ? _imagePaths.icExpandFolder : _imagePaths.icFolderArrow,
width: _mailboxNode.expandMode == ExpandMode.EXPAND ? 8 : 12,
height: _mailboxNode.expandMode == ExpandMode.EXPAND ? 8 : 12,
color: selectMode == SelectMode.ACTIVE
? AppColor.mailboxSelectedIconColor
: AppColor.mailboxIconColor,
fit: BoxFit.fill),
)
: SizedBox.shrink())
)
: SizedBox.shrink())
)
)
)
);
@@ -14,17 +14,13 @@ class MailboxTileBuilder {
final PresentationMailbox _presentationMailbox;
final SelectMode selectMode;
final BuildContext _context;
final ImagePaths _imagePaths;
final ResponsiveUtils _responsiveUtils;
final MailboxDisplayed mailboxDisplayed;
OnOpenMailboxActionClick? _onOpenMailboxActionClick;
MailboxTileBuilder(
this._context,
this._imagePaths,
this._responsiveUtils,
this._presentationMailbox,
{
this.selectMode = SelectMode.INACTIVE,
@@ -53,8 +49,6 @@ class MailboxTileBuilder {
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: ListTile(
focusColor: AppColor.primaryLightColor,
hoverColor: AppColor.primaryLightColor,
contentPadding: EdgeInsets.zero,
onTap: () => {
if (_onOpenMailboxActionClick != null) {
@@ -62,10 +56,7 @@ class MailboxTileBuilder {
}
},
leading: Padding(
padding: EdgeInsets.only(left: mailboxDisplayed == MailboxDisplayed.mailbox
? _responsiveUtils.isMobile(_context) ? 40 : 20
: 40
),
padding: EdgeInsets.only(left: 24),
child: SvgPicture.asset(
'${_presentationMailbox.getMailboxIcon(_imagePaths)}',
width: 24,
@@ -89,7 +80,7 @@ class MailboxTileBuilder {
)),
trailing: mailboxDisplayed == MailboxDisplayed.mailbox
? Padding(
padding: EdgeInsets.only(right: _responsiveUtils.isMobile(_context) ? 36 : 24, left: 16),
padding: EdgeInsets.only(right: 24, left: 16),
child: Text(
'${_presentationMailbox.getCountUnReadEmails()}',
maxLines: 1,
@@ -38,7 +38,6 @@ class ThreadBindings extends Bindings {
Get.lazyPut(() => MarkAsMultipleEmailReadInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MoveToMailboxInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MoveMultipleEmailToMailboxInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MarkAsMultipleEmailReadInteractor(Get.find<MarkAsEmailReadInteractor>()));
Get.lazyPut(() => MarkAsStarEmailInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MarkAsStarMultipleEmailInteractor(Get.find<EmailRepository>()));
Get.put(ThreadController(
@@ -48,7 +47,6 @@ class ThreadBindings extends Bindings {
Get.find<MarkAsMultipleEmailReadInteractor>(),
Get.find<AppToast>(),
Get.find<MoveMultipleEmailToMailboxInteractor>(),
Get.find<MarkAsEmailImportantInteractor>(),
Get.find<MarkAsStarEmailInteractor>(),
Get.find<MarkAsStarMultipleEmailInteractor>(),
));
@@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_comparator.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_comparator_property.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
@@ -16,11 +17,9 @@ import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_request.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_important_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_important_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
@@ -47,7 +46,6 @@ class ThreadController extends BaseController {
final ResponsiveUtils responsiveUtils;
final ScrollController listEmailController;
final MoveMultipleEmailToMailboxInteractor _moveMultipleEmailToMailboxInteractor;
final MarkAsEmailImportantInteractor _markAsEmailImportantInteractor;
final MarkAsStarEmailInteractor _markAsStarEmailInteractor;
final MarkAsStarMultipleEmailInteractor _markAsStarMultipleEmailInteractor;
@@ -71,7 +69,6 @@ class ThreadController extends BaseController {
this._markAsMultipleEmailReadInteractor,
this._appToast,
this._moveMultipleEmailToMailboxInteractor,
this._markAsEmailImportantInteractor,
this._markAsStarEmailInteractor,
this._markAsStarMultipleEmailInteractor,
);
@@ -102,23 +99,9 @@ class ThreadController extends BaseController {
} else if (success is MoveToMailboxSuccess) {
_refreshListEmail();
mailboxDashBoardController.clearState();
}
});
} else {
mailboxDashBoardController.viewState.value.map((success) {
if (success is MarkAsEmailReadSuccess ||
success is MarkAsMultipleEmailReadAllSuccess ||
success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
_refreshListEmail();
}
});
}
});
mailboxDashBoardController.viewState.listen((state) {
state.map((success) {
if (success is MarkAsStarEmailSuccess) {
} else if (success is MarkAsStarEmailSuccess) {
_refreshListEmail();
mailboxDashBoardController.clearState();
}
});
});
@@ -155,8 +138,6 @@ class ThreadController extends BaseController {
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
_moveSelectedMultipleEmailToMailboxSuccess(success);
} else if (success is MarkAsEmailImportantSuccess) {
_markAsEmailImportantSuccess(success);
} else if (success is MarkAsStarEmailSuccess) {
_markAsStarEmailSuccess(success);
} else if (success is MarkAsStarMultipleEmailAllSuccess
@@ -173,27 +154,14 @@ class ThreadController extends BaseController {
void _getAllEmailSuccess(Success success) {
if (success is GetAllEmailSuccess) {
emailList.addAll(success.emailList);
if (loadMoreState.value == LoadMoreState.LOADING) {
emailList.addAll(success.emailList);
} else {
emailList.value = success.emailList;
}
lastGetTotal = emailList.length;
loadMoreState.value = success.emailList.isEmpty ? LoadMoreState.COMPLETED : LoadMoreState.IDLE;
mailboxDashBoardController.viewState.value.map((success) {
if (success is MarkAsStarEmailSuccess) {
_updateValueCurrentEmail();
mailboxDashBoardController.clearState();
}
});
}
}
void _updateValueCurrentEmail() {
if (mailboxDashBoardController.selectedEmail.value != null) {
try {
final newSelectedEmail = emailList.firstWhere(
(email) => email.id == mailboxDashBoardController.selectedEmail.value!.id,
orElse: null);
mailboxDashBoardController.setSelectedEmail(newSelectedEmail);
} catch(e){}
}
}
@@ -237,7 +205,6 @@ class ThreadController extends BaseController {
loadMoreState.value = LoadMoreState.IDLE;
positionCurrent = 0;
dispatchState(Right(LoadingState()));
emailList.value = <PresentationEmail>[];
final accountId = mailboxDashBoardController.accountId.value;
@@ -311,7 +278,6 @@ class ThreadController extends BaseController {
final newLimit = emailList.isNotEmpty ? UnsignedInt(emailList.length) : ThreadConstants.defaultLimit;
loadMoreState.value = LoadMoreState.IDLE;
dispatchState(Right(LoadingState()));
emailList.value = <PresentationEmail>[];
final accountId = mailboxDashBoardController.accountId.value;
@@ -331,7 +297,7 @@ class ThreadController extends BaseController {
popBack();
}
final readAction = isEmailAllRead(listPresentationEmail) ? ReadActions.markAsUnread : ReadActions.markAsRead;
final readAction = isAllEmailRead(listPresentationEmail) ? ReadActions.markAsUnread : ReadActions.markAsRead;
final accountId = mailboxDashBoardController.accountId.value;
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
@@ -459,7 +425,16 @@ class ThreadController extends BaseController {
}
}
void markAsEmailImportant(PresentationEmail presentationEmail) {
void openPopupMenuSelectedEmail(BuildContext context, RelativeRect position, List<PopupMenuItem> popupMenuItems) async {
await showMenu(
context: context,
position: position,
color: Colors.white,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
items: popupMenuItems);
}
void markAsStarEmail(PresentationEmail presentationEmail) {
final accountId = mailboxDashBoardController.accountId.value;
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
@@ -73,13 +73,17 @@ class ThreadView extends GetWidget<ThreadController> {
return Obx(() => Padding(
padding: EdgeInsets.only(left: 15, right: 12),
child: (AppBarThreadSelectModeActiveBuilder(
context,
imagePaths,
controller.getListEmailSelected())
context,
imagePaths,
controller.getListEmailSelected(),
responsiveUtils)
..addCloseActionClick(() => controller.cancelSelectEmail())
..addRemoveEmailActionClick((listEmail) => {})
..addOnMarkAsEmailReadActionClick((listEmail) => controller.markAsSelectedEmailRead(listEmail))
..addOpenContextMenuActionClick((listEmail) => controller.openContextMenuSelectedEmail(context, _contextMenuEmailActionTile(context, listEmail))))
..addOpenContextMenuActionClick((listEmail) =>
controller.openContextMenuSelectedEmail(context, _contextMenuEmailActionTile(context, listEmail)))
..addOnOpenPopupMenuActionClick((listEmail, position) =>
controller.openPopupMenuSelectedEmail(context, position, _popupMenuEmailActionTile(context, listEmail))))
.build()));
}
@@ -114,9 +118,6 @@ class ThreadView extends GetWidget<ThreadController> {
listEmail)
..onActionClick((data) => {}))
.build();
AppLocalizations.of(context).move_to_trash, listEmail)
..onActionClick((data) => {}))
.build();
}
Widget _moveToMailboxAction(BuildContext context, List<PresentationEmail> listEmail) {
@@ -133,12 +134,6 @@ class ThreadView extends GetWidget<ThreadController> {
final markStarAction = controller.isAllEmailMarkAsStar(listEmail) ? MarkStarAction.unMarkStar : MarkStarAction.markStar;
return (EmailContextMenuActionBuilder(
Key('mark_as_flag_context_menu_action'),
SvgPicture.asset(imagePaths.icFlag, width: 24, height: 24, fit: BoxFit.fill),
AppLocalizations.of(context).mark_as_flag,
listEmail)
..onActionClick((data) => {}))
.build();
Key('mark_as_star_context_menu_action'),
SvgPicture.asset(
markStarAction == MarkStarAction.markStar ? imagePaths.icFlag : imagePaths.icFlagged,
@@ -161,9 +156,16 @@ class ThreadView extends GetWidget<ThreadController> {
listEmail)
..onActionClick((data) => {}))
.build();
AppLocalizations.of(context).move_to_spam, listEmail)
..onActionClick((data) => {}))
.build();
}
List<PopupMenuItem> _popupMenuEmailActionTile(BuildContext context, List<PresentationEmail> listEmail) {
return [
PopupMenuItem(child: _moveToTrashAction(context, listEmail)),
PopupMenuItem(child: _moveToMailboxAction(context, listEmail)),
PopupMenuItem(child: _markAsReadAction(context, listEmail)),
PopupMenuItem(child: _markAsStarAction(context, listEmail)),
PopupMenuItem(child: _moveToSpamAction(context, listEmail)),
];
}
Widget _buildLoadingView() {
@@ -173,8 +175,8 @@ class ThreadView extends GetWidget<ThreadController> {
? Center(child: Padding(
padding: EdgeInsets.only(top: 16, bottom: 16),
child: SizedBox(
width: 30,
height: 30,
width: 24,
height: 24,
child: CircularProgressIndicator(color: AppColor.primaryColor))))
: SizedBox.shrink()));
}
@@ -184,8 +186,8 @@ class ThreadView extends GetWidget<ThreadController> {
? Center(child: Padding(
padding: EdgeInsets.only(top: 16, bottom: 16),
child: SizedBox(
width: 30,
height: 30,
width: 24,
height: 24,
child: CircularProgressIndicator(color: AppColor.primaryColor))))
: SizedBox.shrink());
}
@@ -237,7 +239,8 @@ class ThreadView extends GetWidget<ThreadController> {
responsiveUtils,
controller.currentSelectMode.value)
..onOpenEmailAction((selectedEmail) => controller.previewEmail(context, selectedEmail))
..onSelectEmailAction((selectedEmail) => controller.selectEmail(context, selectedEmail)))
..onSelectEmailAction((selectedEmail) => controller.selectEmail(context, selectedEmail))
..addOnMarkAsStarEmailActionClick((selectedEmail) => controller.markAsStarEmail(selectedEmail)))
.build()),
));
}
@@ -9,18 +9,21 @@ typedef OnCloseActionClick = void Function();
typedef OnMarkAsEmailReadActionClick = void Function(List<PresentationEmail> listEmail);
typedef OnRemoveEmailActionClick = void Function(List<PresentationEmail> listEmail);
typedef OnOpenContextMenuActionClick = void Function(List<PresentationEmail> listEmail);
typedef OnOpenPopupMenuActionClick = void Function(List<PresentationEmail> listEmail, RelativeRect position);
class AppBarThreadSelectModeActiveBuilder {
OnCloseActionClick? _onCloseActionClick;
OnMarkAsEmailReadActionClick? _onMarkAsEmailReadActionClick;
OnRemoveEmailActionClick? _onRemoveEmailActionClick;
OnOpenContextMenuActionClick? _onOpenContextMenuActionClick;
OnOpenPopupMenuActionClick? _onOpenPopupMenuActionClick;
final BuildContext _context;
final ImagePaths _imagePaths;
final List<PresentationEmail> _listEmail;
final ResponsiveUtils _responsiveUtils;
AppBarThreadSelectModeActiveBuilder(this._context, this._imagePaths, this._listEmail);
AppBarThreadSelectModeActiveBuilder(this._context, this._imagePaths, this._listEmail, this._responsiveUtils);
void addCloseActionClick(OnCloseActionClick onCloseActionClick) {
_onCloseActionClick = onCloseActionClick;
@@ -38,6 +41,10 @@ class AppBarThreadSelectModeActiveBuilder {
_onOpenContextMenuActionClick = onOpenContextMenuActionClick;
}
void addOnOpenPopupMenuActionClick(OnOpenPopupMenuActionClick onOpenPopupMenuActionClick) {
_onOpenPopupMenuActionClick = onOpenPopupMenuActionClick;
}
Widget build() {
return Container(
key: Key('app_bar_thread_select_mode_active'),
@@ -104,6 +111,18 @@ class AppBarThreadSelectModeActiveBuilder {
if (_onOpenContextMenuActionClick != null) {
_onOpenContextMenuActionClick!(_listEmail);
}})
.onTapActionClick((details) {
if (_onOpenPopupMenuActionClick != null && !_responsiveUtils.isMobile(_context)) {
final screenSize = MediaQuery.of(_context).size;
final offset = details.globalPosition;
final position = RelativeRect.fromLTRB(
offset.dx,
offset.dy,
screenSize.width - offset.dx,
screenSize.height - offset.dy,
);
_onOpenPopupMenuActionClick!(_listEmail, position);
}})
.build(),
]
);
@@ -21,6 +21,10 @@ extension ListEmailIdExtension on List<EmailId> {
final Map<Id, PatchObject> maps = {};
forEach((emailId) {
maps[emailId.id] = currentMailboxId.generateMoveToMailboxActionPath(destinationMailboxId);
});
return maps;
}
Map<Id, PatchObject> generateMapUpdateObjectMarkAsStar(MarkStarAction markStarAction) {
final Map<Id, PatchObject> maps = {};
forEach((emailId) {
@@ -1,7 +1,5 @@
import 'package:core/core.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
extension PresentationEmailExtension on PresentationEmail {
@@ -17,11 +15,9 @@ extension PresentationEmailExtension on PresentationEmail {
}
PresentationEmail toggleSelect() {
PresentationEmail toUpdatedPresentationEmail({Map<KeyWordIdentifier, bool>? newKeywords}) {
return PresentationEmail(
id,
keywords: keywords,
keywords: newKeywords ?? keywords,
size: size,
receivedAt: receivedAt,
hasAttachment: hasAttachment,
@@ -73,22 +69,4 @@ extension PresentationEmailExtension on PresentationEmail {
replyTo: replyTo
);
}
Email toEmail() {
return Email(
id,
keywords: keywords,
size: size,
receivedAt: receivedAt,
hasAttachment: hasAttachment,
preview: preview,
subject: subject,
sentAt: sentAt,
from: from,
to: to,
cc: cc,
bcc: bcc,
replyTo: replyTo
);
}
}
-1
View File
@@ -25,7 +25,6 @@ export 'email/email_address_cache.dart';
export 'email/read_actions.dart';
export 'email/attachment.dart';
export 'email/move_action.dart';
export 'email/important_action.dart';
export 'email/mark_star_action.dart';
// Extensions