From ba29dadea665f7746639a41948920528b436ea40 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 1 Jun 2023 14:26:13 +0700 Subject: [PATCH] TF-1813 Display list sending email in SendingQueueView (cherry picked from commit 16699d68fa52d5a8dd450c68c64220def1d6a142) --- .../presentation/mailbox_dashboard_view.dart | 19 ++- .../presentation/model/dashboard_routes.dart | 3 +- .../bindings/sending_queue_bindings.dart | 15 +++ .../sending_queue_interactor_bindings.dart | 49 ++++++++ .../sending_queue_controller.dart | 22 ++++ .../presentation/sending_queue_view.dart | 60 +++++++++ .../widgets/app_bar_sending_queue_widget.dart | 73 +++++++++++ .../banner_message_sending_queue_widget.dart | 47 +++++++ .../widgets/sending_email_tile_widget.dart | 115 ++++++++++++++++++ 9 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart create mode 100644 lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart create mode 100644 lib/features/sending_queue/presentation/sending_queue_controller.dart create mode 100644 lib/features/sending_queue/presentation/sending_queue_view.dart create mode 100644 lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart create mode 100644 lib/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart create mode 100644 lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart index 944c593f7..e1af34905 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart @@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/base_mailbox_dashboard_view.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart'; import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_view.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart'; class MailboxDashBoardView extends BaseMailboxDashBoardView { @@ -33,7 +34,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { child: Scaffold( drawerEnableOpenDragGesture: responsiveUtils.hasLeftMenuDrawerActive(context), body: Obx(() { - final bodyView = controller.searchController.isSearchEmailRunning + var bodyView = controller.searchController.isSearchEmailRunning ? EmailView() : bodyLandscapeTablet; @@ -54,6 +55,22 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { mobile: EmailView()); case DashboardRoutes.searchEmail: return SafeArea(child: SearchEmailView()); + case DashboardRoutes.sendingQueue: + bodyView = Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: ResponsiveUtils.defaultSizeLeftMenuMobile, + child: _buildScaffoldHaveDrawer(body: const SendingQueueView())), + Expanded(child: EmailView()), + ], + ); + return ResponsiveWidget( + responsiveUtils: responsiveUtils, + desktop: bodyView, + tabletLarge: bodyView, + landscapeTablet: bodyView, + mobile: _buildScaffoldHaveDrawer(body: const SendingQueueView())); case DashboardRoutes.waiting: return const Center( child: SizedBox( diff --git a/lib/features/mailbox_dashboard/presentation/model/dashboard_routes.dart b/lib/features/mailbox_dashboard/presentation/model/dashboard_routes.dart index 82d208a90..65b7a3120 100644 --- a/lib/features/mailbox_dashboard/presentation/model/dashboard_routes.dart +++ b/lib/features/mailbox_dashboard/presentation/model/dashboard_routes.dart @@ -3,5 +3,6 @@ enum DashboardRoutes { thread, emailDetailed, searchEmail, - waiting + waiting, + sendingQueue; } \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart b/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart new file mode 100644 index 000000000..25cac8699 --- /dev/null +++ b/lib/features/sending_queue/presentation/bindings/sending_queue_bindings.dart @@ -0,0 +1,15 @@ + +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart'; + +class SendingQueueBindings extends Bindings { + + @override + void dependencies() { + _bindingsController(); + } + + void _bindingsController() { + Get.put(SendingQueueController()); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart b/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart new file mode 100644 index 000000000..568f16ac9 --- /dev/null +++ b/lib/features/sending_queue/presentation/bindings/sending_queue_interactor_bindings.dart @@ -0,0 +1,49 @@ + +import 'package:core/utils/file_utils.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/base/interactors_bindings.dart'; +import 'package:tmail_ui_user/features/email/data/datasource_impl/email_hive_cache_datasource_impl.dart'; +import 'package:tmail_ui_user/features/sending_queue/data/repository/sending_queue_repository_impl.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart'; +import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart'; +import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart'; +import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart'; +import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_manager.dart'; +import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart'; +import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart'; +import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; +import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart'; + +class SendingQueueInteractorBindings extends InteractorsBindings { + + @override + void bindingsDataSource() {} + + @override + void bindingsDataSourceImpl() { + Get.lazyPut(() => EmailHiveCacheDataSourceImpl( + Get.find(), + Get.find(), + Get.find(), + Get.find(), + Get.find(), + Get.find(), + Get.find(), + Get.find())); + } + + @override + void bindingsInteractor() { + Get.lazyPut(() => GetAllSendingEmailInteractor(Get.find())); + } + + @override + void bindingsRepository() { + Get.lazyPut(() => Get.find()); + } + + @override + void bindingsRepositoryImpl() { + Get.lazyPut(() => SendingQueueRepositoryImpl(Get.find())); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/sending_queue_controller.dart b/lib/features/sending_queue/presentation/sending_queue_controller.dart new file mode 100644 index 000000000..13c54bb0c --- /dev/null +++ b/lib/features/sending_queue/presentation/sending_queue_controller.dart @@ -0,0 +1,22 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; +import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + +class SendingQueueController extends BaseController { + + final dashboardController = getBinding(); + + final listSendingEmailController = ScrollController(); + + void openMailboxMenu() { + dashboardController!.openMailboxMenuDrawer(); + } + + @override + void onClose() { + listSendingEmailController.dispose(); + super.onClose(); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/sending_queue_view.dart b/lib/features/sending_queue/presentation/sending_queue_view.dart new file mode 100644 index 000000000..eda810c45 --- /dev/null +++ b/lib/features/sending_queue/presentation/sending_queue_view.dart @@ -0,0 +1,60 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; +import 'package:tmail_ui_user/features/base/mixin/compose_floating_button_mixin.dart'; +import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart'; +import 'package:tmail_ui_user/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart'; + +class SendingQueueView extends GetWidget + with AppLoaderMixin, + ComposeFloatingButtonMixin { + + const SendingQueueView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: GestureDetector( + onTap: FocusScope.of(context).unfocus, + child: SafeArea( + child: Column( + children: [ + AppBarSendingQueueWidget(onOpenMailboxMenu: controller.openMailboxMenu), + const Divider(color: AppColor.colorDividerComposer, height: 1), + const BannerMessageSendingQueueWidget(), + Expanded(child: _buildListSendingEmails(context)) + ] + ), + ), + ), + floatingActionButton: buildComposeFloatingButton( + context, + controller.listSendingEmailController, + onTap: () => controller.dashboardController!.goToComposer(ComposerArguments()) + ), + ); + } + + Widget _buildListSendingEmails(BuildContext context) { + return Obx(() { + if (controller.dashboardController!.listSendingEmails.isNotEmpty) { + return ListView.builder( + controller: controller.listSendingEmailController, + padding: EdgeInsets.zero, + itemCount: controller.dashboardController!.listSendingEmails.length, + itemBuilder: (context, index) => SendingEmailTileWidget( + sendingEmail: controller.dashboardController!.listSendingEmails[index] + ) + ); + } else { + return const SizedBox.shrink(); + } + }); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart b/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart new file mode 100644 index 000000000..63887b65d --- /dev/null +++ b/lib/features/sending_queue/presentation/widgets/app_bar_sending_queue_widget.dart @@ -0,0 +1,73 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/style_utils.dart'; +import 'package:core/presentation/views/button/icon_button_web.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:model/mailbox/select_mode.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/utils/app_utils.dart'; + +class AppBarSendingQueueWidget extends StatelessWidget { + + final VoidCallback? onBackAction; + final VoidCallback? onOpenMailboxMenu; + final SelectMode selectMode; + + const AppBarSendingQueueWidget({ + super.key, + this.onBackAction, + this.onOpenMailboxMenu, + this.selectMode = SelectMode.INACTIVE, + }); + + @override + Widget build(BuildContext context) { + final imagePaths = Get.find(); + + return Container( + height: 52, + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + children: [ + if (selectMode == SelectMode.INACTIVE) + buildIconWeb( + icon: SvgPicture.asset( + imagePaths.icMenuMailbox, + colorFilter: AppColor.colorTextButton.asFilter(), + fit: BoxFit.fill + ), + tooltip: AppLocalizations.of(context).openMailboxMenu, + onTap: onOpenMailboxMenu + ) + else + buildIconWeb( + icon: SvgPicture.asset( + AppUtils.isDirectionRTL(context) ? imagePaths.icCollapseFolder : imagePaths.icBack, + colorFilter: AppColor.colorTextButton.asFilter(), + fit: BoxFit.fill + ), + tooltip: AppLocalizations.of(context).back, + onTap: onBackAction + ), + Expanded(child: Text( + AppLocalizations.of(context).sendingQueue, + maxLines: 1, + textAlign: TextAlign.center, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + style: const TextStyle( + fontSize: 21, + color: Colors.black, + fontWeight: FontWeight.bold + ) + )), + const SizedBox(width: 50) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart b/lib/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart new file mode 100644 index 000000000..14a5c57d3 --- /dev/null +++ b/lib/features/sending_queue/presentation/widgets/banner_message_sending_queue_widget.dart @@ -0,0 +1,47 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:tmail_ui_user/main/routes/route_navigation.dart'; + +class BannerMessageSendingQueueWidget extends StatelessWidget { + + const BannerMessageSendingQueueWidget({super.key}); + + @override + Widget build(BuildContext context) { + final imagePath = getBinding(); + + return Container( + margin: const EdgeInsets.only(top: 16, left: 16, right: 16), + padding: const EdgeInsets.all(16), + decoration: const BoxDecoration( + color: AppColor.colorBannerMessageSendingQueue, + borderRadius: BorderRadius.all(Radius.circular(8)) + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + imagePath!.icMailboxSendingQueue, + fit: BoxFit.fill, + width: 20, + height: 20, + colorFilter: AppColor.colorTitleSendingItem.asFilter(), + ), + const SizedBox(width: 8), + Expanded(child: Text( + AppLocalizations.of(context).bannerMessageSendingQueueView, + style: const TextStyle( + fontSize: 15, + color: Colors.black, + fontWeight: FontWeight.normal + ) + )) + ] + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart new file mode 100644 index 000000000..6424971db --- /dev/null +++ b/lib/features/sending_queue/presentation/widgets/sending_email_tile_widget.dart @@ -0,0 +1,115 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/extensions/string_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/style_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:model/extensions/presentation_email_extension.dart'; +import 'package:model/model.dart'; +import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class SendingEmailTileWidget extends StatelessWidget { + + final SendingEmail sendingEmail; + + const SendingEmailTileWidget({ + super.key, + required this.sendingEmail + }); + + @override + Widget build(BuildContext context) { + final imagePath = Get.find(); + + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () => {}, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Row( + children: [ + SvgPicture.asset( + sendingEmail.presentationEmail.numberOfAllEmailAddress() == 1 + ? imagePath.icAvatarPersonal + : imagePath.icAvatarGroup, + fit: BoxFit.fill, + width: 60, + height: 60, + ), + const SizedBox(width: 8), + Expanded(child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + Expanded(child: Text( + AppLocalizations.of(context).titleRecipientSendingEmail(sendingEmail.presentationEmail.recipientsName()).withUnicodeCharacter, + softWrap: CommonTextStyle.defaultSoftWrap, + overflow: CommonTextStyle.defaultTextOverFlow, + maxLines: 1, + style: const TextStyle( + fontSize: 15, + color: AppColor.colorTitleSendingItem, + fontWeight: FontWeight.w600 + ) + )), + if (sendingEmail.email.attachments != null && sendingEmail.email.attachments!.isNotEmpty) + Padding( + padding: const EdgeInsets.only(left: 8), + child: SvgPicture.asset( + imagePath.icAttachment, + width: 20, + height: 20, + fit: BoxFit.fill + ) + ), + Padding( + padding: const EdgeInsets.only(left: 8), + child: Text( + sendingEmail.getCreateTimeAt(Localizations.localeOf(context).toLanguageTag()), + maxLines: 1, + softWrap: CommonTextStyle.defaultSoftWrap, + overflow: CommonTextStyle.defaultTextOverFlow, + style: const TextStyle( + fontSize: 13, + color: AppColor.colorTitleSendingItem, + fontWeight: FontWeight.normal + ) + ) + ) + ]), + const SizedBox(height: 8), + Text( + sendingEmail.presentationEmail.getEmailTitle().withUnicodeCharacter, + softWrap: CommonTextStyle.defaultSoftWrap, + overflow: CommonTextStyle.defaultTextOverFlow, + maxLines: 1, + style: const TextStyle( + fontSize: 13, + color: AppColor.colorTitleSendingItem, + fontWeight: FontWeight.normal + ) + ), + ] + )) + ]), + ), + const Padding( + padding: EdgeInsets.only(left: 84, right: 8), + child: Divider( + color: AppColor.lineItemListColor, + height: 1, + thickness: 0.2 + ), + ) + ], + ), + ), + ); + } +} \ No newline at end of file