TF-460 Separate the header of MailboxDashboard on the browser
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class Action with EquatableMixin {}
|
||||
|
||||
abstract class UIAction extends Action {}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
mixin AppLoaderMixin {
|
||||
|
||||
Widget get loadingWidget {
|
||||
return Center(child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: CupertinoActivityIndicator(color: AppColor.colorLoading)));
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ mixin PopupContextMenuActionMixin {
|
||||
context: context,
|
||||
position: position ?? RelativeRect.fromLTRB(16, 40, 16, 16),
|
||||
color: Colors.white,
|
||||
elevation: 5,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
||||
elevation: 4,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
items: popupMenuItems);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ import 'package:tmail_ui_user/features/composer/presentation/model/screen_displa
|
||||
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
||||
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
@@ -782,7 +782,7 @@ class ComposerController extends BaseController {
|
||||
|
||||
void closeComposerWeb() {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.none);
|
||||
mailboxDashBoardController.dispatchAction(CloseComposeEmailAction());
|
||||
}
|
||||
|
||||
void displayScreenTypeComposerAction(ScreenDisplayMode displayMode) {
|
||||
@@ -798,7 +798,7 @@ class ComposerController extends BaseController {
|
||||
|
||||
void deleteComposer() {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.none);
|
||||
mailboxDashBoardController.dispatchAction(CloseComposeEmailAction());
|
||||
}
|
||||
|
||||
void toggleDisplayAttachments() {
|
||||
|
||||
@@ -23,11 +23,6 @@ import 'package:tmail_ui_user/features/login/domain/repository/credential_reposi
|
||||
|
||||
class EmailBindings extends BaseBindings {
|
||||
|
||||
@override
|
||||
void dependencies() {
|
||||
super.dependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsController() {
|
||||
Get.put(EmailController(
|
||||
|
||||
@@ -35,9 +35,9 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_dialog_builder.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
@@ -86,7 +86,7 @@ class EmailController extends BaseController {
|
||||
@override
|
||||
void onInit() {
|
||||
mailboxDashBoardController.selectedEmail.listen((presentationEmail) {
|
||||
log('EmailController::onReady(): ${presentationEmail.toString()}');
|
||||
log('EmailController::onReady(): selectedEmail: ${presentationEmail.toString()}');
|
||||
if (_currentEmailId != presentationEmail?.id) {
|
||||
_currentEmailId = presentationEmail?.id;
|
||||
_resetToOriginalValue();
|
||||
@@ -546,8 +546,8 @@ class EmailController extends BaseController {
|
||||
emailAddress: emailAddress,
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role);
|
||||
if (kIsWeb) {
|
||||
if (mailboxDashBoardController.dashBoardAction != DashBoardAction.compose) {
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.compose, arguments: arguments);
|
||||
if (mailboxDashBoardController.dashBoardAction.value is! ComposeEmailAction) {
|
||||
mailboxDashBoardController.dispatchAction(ComposeEmailAction(arguments: arguments));
|
||||
}
|
||||
} else {
|
||||
push(AppRoutes.COMPOSER, arguments: arguments);
|
||||
@@ -565,8 +565,8 @@ class EmailController extends BaseController {
|
||||
emailAddress: emailAddress,
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role);
|
||||
if (kIsWeb) {
|
||||
if (mailboxDashBoardController.dashBoardAction != DashBoardAction.compose) {
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.compose, arguments: arguments);
|
||||
if (mailboxDashBoardController.dashBoardAction.value is! ComposeEmailAction) {
|
||||
mailboxDashBoardController.dispatchAction(ComposeEmailAction(arguments: arguments));
|
||||
}
|
||||
if (Get.currentRoute == AppRoutes.EMAIL) {
|
||||
popBack();
|
||||
@@ -629,8 +629,8 @@ class EmailController extends BaseController {
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role);
|
||||
|
||||
if (kIsWeb) {
|
||||
if (mailboxDashBoardController.dashBoardAction != DashBoardAction.compose) {
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.compose, arguments: arguments);
|
||||
if (mailboxDashBoardController.dashBoardAction.value is! ComposeEmailAction) {
|
||||
mailboxDashBoardController.dispatchAction(ComposeEmailAction(arguments: arguments));
|
||||
}
|
||||
if (Get.currentRoute == AppRoutes.EMAIL) {
|
||||
popBack();
|
||||
@@ -643,8 +643,8 @@ class EmailController extends BaseController {
|
||||
|
||||
void composeEmailAction() {
|
||||
if (kIsWeb) {
|
||||
if (mailboxDashBoardController.dashBoardAction != DashBoardAction.compose) {
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.compose, arguments: ComposerArguments());
|
||||
if (mailboxDashBoardController.dashBoardAction.value is! ComposeEmailAction) {
|
||||
mailboxDashBoardController.dispatchAction(ComposeEmailAction(arguments: ComposerArguments()));
|
||||
}
|
||||
if (Get.currentRoute == AppRoutes.EMAIL) {
|
||||
popBack();
|
||||
|
||||
@@ -15,11 +15,10 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_w
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.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/presentation/user_setting_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
|
||||
class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectionMixin {
|
||||
class EmailView extends GetView with NetworkConnectionMixin {
|
||||
|
||||
final emailController = Get.find<EmailController>();
|
||||
final responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
@@ -27,6 +26,8 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
static const int LIMIT_ADDRESS_DISPLAY = 1;
|
||||
|
||||
EmailView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
@@ -37,58 +38,22 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
child: Scaffold(
|
||||
backgroundColor: responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white,
|
||||
body: Stack(children: [
|
||||
Container(
|
||||
padding: EdgeInsets.zero,
|
||||
margin: EdgeInsets.zero,
|
||||
decoration: responsiveUtils.isTabletLarge(context)
|
||||
? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0)))
|
||||
: null,
|
||||
child: SafeArea(
|
||||
right: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
|
||||
left: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (responsiveUtils.isDesktop(context))
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.only(right: 10, top: 16, bottom: 10),
|
||||
child: _buildHeader(context)),
|
||||
Expanded(child: _buildBody(context)),
|
||||
]
|
||||
)
|
||||
),
|
||||
),
|
||||
Row(children: [
|
||||
if ((!kIsWeb && !responsiveUtils.isMobile(context)) || (kIsWeb && responsiveUtils.isTabletLarge(context)))
|
||||
const VerticalDivider(color: AppColor.lineItemListColor, width: 1, thickness: 0.2),
|
||||
Expanded(child: SafeArea(
|
||||
right: responsiveUtils.isLandscapeMobile(context),
|
||||
left: responsiveUtils.isLandscapeMobile(context),
|
||||
child: _buildBody(context)))
|
||||
]),
|
||||
Obx(() => !emailController.mailboxDashBoardController.isNetworkConnectionAvailable() && (responsiveUtils.isMobile(context) || responsiveUtils.isTablet(context))
|
||||
? Align(alignment: Alignment.bottomCenter, child: buildNetworkConnectionWidget(context))
|
||||
: SizedBox.shrink()),
|
||||
: const SizedBox.shrink()),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
return Row(children: [
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
child: (AvatarBuilder()
|
||||
..text(emailController.mailboxDashBoardController.userProfile.value?.getAvatarText() ?? '')
|
||||
..backgroundColor(Colors.white)
|
||||
..textColor(Colors.black)
|
||||
..context(context)
|
||||
..addOnTapAvatarActionWithPositionClick((position) => openUserSettingAction(
|
||||
context,
|
||||
position,
|
||||
popupMenuUserSettingActionTile(context, () => emailController.mailboxDashBoardController.logoutAction())))
|
||||
..addBoxShadows([BoxShadow(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))])
|
||||
..size(48))
|
||||
.build()),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildBody(BuildContext context) {
|
||||
return Container(
|
||||
decoration: responsiveUtils.isDesktop(context)
|
||||
@@ -97,17 +62,17 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
|
||||
color: Colors.white)
|
||||
: null,
|
||||
margin: responsiveUtils.isDesktop(context) ? EdgeInsets.all(16) : EdgeInsets.zero,
|
||||
padding: responsiveUtils.isDesktop(context) ? EdgeInsets.only(top: 5, bottom: 5, left: 5, right: 3) : EdgeInsets.zero,
|
||||
margin: responsiveUtils.isDesktop(context) ? const EdgeInsets.all(16) : EdgeInsets.zero,
|
||||
padding: responsiveUtils.isDesktop(context) ? const EdgeInsets.only(top: 5, bottom: 5, left: 5, right: 3) : EdgeInsets.zero,
|
||||
child: Column(children: [
|
||||
_buildAppBar(context),
|
||||
if (responsiveUtils.isDesktop(context)) SizedBox(height: 5),
|
||||
if (responsiveUtils.isDesktop(context)) const SizedBox(height: 5),
|
||||
Obx(() => emailController.currentEmail != null && !responsiveUtils.isDesktop(context)
|
||||
? _buildDivider() : SizedBox.shrink()),
|
||||
? _buildDivider() : const SizedBox.shrink()),
|
||||
Expanded(child: _buildEmailBody(context)),
|
||||
Obx(() => emailController.currentEmail != null
|
||||
? Divider(color: AppColor.colorDividerEmailView, height: 1)
|
||||
: SizedBox.shrink()),
|
||||
? const Divider(color: AppColor.colorDividerEmailView, height: 1)
|
||||
: const SizedBox.shrink()),
|
||||
_buildBottomBar(context),
|
||||
])
|
||||
);
|
||||
@@ -115,13 +80,13 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _buildDivider({EdgeInsets? edgeInsets}){
|
||||
return Padding(
|
||||
padding: edgeInsets ?? EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Divider(color: AppColor.colorDividerEmailView, height: 0.5));
|
||||
padding: edgeInsets ?? const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: const Divider(color: AppColor.colorDividerEmailView, height: 0.5));
|
||||
}
|
||||
|
||||
Widget _buildAppBar(BuildContext context) {
|
||||
return Obx(() => Padding(
|
||||
padding: EdgeInsets.only(top: 6),
|
||||
padding: const EdgeInsets.only(top: 6),
|
||||
child: (AppBarMailWidgetBuilder(context, imagePaths, responsiveUtils, emailController.currentEmail, emailController.currentMailbox)
|
||||
..onBackActionClick(() => emailController.backToThreadView(context))
|
||||
..addOnEmailActionClick((email, action) => emailController.handleEmailAction(context, email, action))
|
||||
@@ -154,7 +119,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
return _buildEmailMessage(context);
|
||||
} else {
|
||||
return SingleChildScrollView(
|
||||
physics : ClampingScrollPhysics(),
|
||||
physics : const ClampingScrollPhysics(),
|
||||
child: Container(
|
||||
margin: EdgeInsets.zero,
|
||||
width: double.infinity,
|
||||
@@ -176,12 +141,12 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
return Text(
|
||||
AppLocalizations.of(context).no_mail_selected,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 25, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold));
|
||||
style: const TextStyle(fontSize: 25, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold));
|
||||
}
|
||||
|
||||
Widget _buildEmailSubject(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(right: 16),
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: SelectableText(
|
||||
'${emailController.mailboxDashBoardController.selectedEmail.value?.getEmailTitle()}',
|
||||
maxLines: kIsWeb ? 3 : null,
|
||||
@@ -196,7 +161,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _buildEmailMessage(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 16, right: 16, top: 10),
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 10),
|
||||
alignment: Alignment.center,
|
||||
color: Colors.white,
|
||||
child: LayoutBuilder(
|
||||
@@ -209,22 +174,22 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
Expanded(child: _buildEmailSubject(context)),
|
||||
_buildEmailTime(context),
|
||||
]),
|
||||
if (responsiveUtils.isDesktop(context)) SizedBox(height: 20),
|
||||
if (!responsiveUtils.isDesktop(context)) _buildDivider(edgeInsets: EdgeInsets.only(top: 16)),
|
||||
if (responsiveUtils.isDesktop(context)) const SizedBox(height: 20),
|
||||
if (!responsiveUtils.isDesktop(context)) _buildDivider(edgeInsets: const EdgeInsets.only(top: 16)),
|
||||
Obx(() => emailController.currentEmail != null
|
||||
? _buildEmailAddress(
|
||||
context,
|
||||
emailController.currentEmail!,
|
||||
emailController.emailAddressExpandMode.value,
|
||||
emailController.isDisplayFullEmailAddress.value)
|
||||
: SizedBox.shrink()),
|
||||
_buildDivider(edgeInsets: EdgeInsets.only(top: 8)),
|
||||
: const SizedBox.shrink()),
|
||||
_buildDivider(edgeInsets: const EdgeInsets.only(top: 8)),
|
||||
_buildAttachments(context),
|
||||
if (kIsWeb)
|
||||
Expanded(child: _buildEmailContent(context, constraints))
|
||||
else
|
||||
_buildEmailContent(context, constraints),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
);
|
||||
})
|
||||
@@ -240,7 +205,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
pattern: emailController.currentEmail?.receivedAt?.value.toLocal().toPatternForEmailView())}',
|
||||
maxLines: 1,
|
||||
overflow:TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 13, color: AppColor.colorTime)));
|
||||
style: const TextStyle(fontSize: 13, color: AppColor.colorTime)));
|
||||
}
|
||||
|
||||
Widget _buildEmailAddress(BuildContext context, PresentationEmail email, ExpandMode expandMode, bool isDisplayFull) {
|
||||
@@ -251,15 +216,15 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
if (email.from.numberEmailAddress() > 0)
|
||||
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.from, isDisplayFull),
|
||||
if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND)
|
||||
_buildDivider(edgeInsets: EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
_buildDivider(edgeInsets: const EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND)
|
||||
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.to, isDisplayFull),
|
||||
if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
|
||||
_buildDivider(edgeInsets: EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
_buildDivider(edgeInsets: const EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
|
||||
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.cc, isDisplayFull),
|
||||
if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
|
||||
_buildDivider(edgeInsets: EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
_buildDivider(edgeInsets: const EdgeInsets.only(top: kIsWeb ? 8 : 4, bottom: 4)),
|
||||
if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
|
||||
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.bcc, isDisplayFull),
|
||||
],
|
||||
@@ -277,10 +242,10 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: kIsWeb ? 10: 20),
|
||||
padding: const EdgeInsets.only(top: kIsWeb ? 10: 20),
|
||||
child: Text(
|
||||
'${prefixEmailAddress.asName(context)}:',
|
||||
style: TextStyle(fontSize: 14, color: AppColor.colorEmailAddressPrefix))),
|
||||
style: const TextStyle(fontSize: 14, color: AppColor.colorEmailAddressPrefix))),
|
||||
Expanded(child: _buildEmailAddressWidget(
|
||||
context,
|
||||
presentationEmail,
|
||||
@@ -302,26 +267,26 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
) {
|
||||
final displayedEmailAddress = isDisplayFull ? listEmailAddress : listEmailAddress.sublist(0, LIMIT_ADDRESS_DISPLAY);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 4),
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Wrap(
|
||||
children: [
|
||||
...displayedEmailAddress.map((emailAddress) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: GestureDetector(
|
||||
onTap: () => emailController.openEmailAddressDialog(context, emailAddress),
|
||||
child: Chip(
|
||||
labelPadding: EdgeInsets.only(left: 8, right: 8, bottom: 2),
|
||||
label: Text('${emailAddress.asString()}', maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
labelStyle: TextStyle(color: AppColor.colorNameEmail, fontSize: 15, fontWeight: FontWeight.normal),
|
||||
labelPadding: const EdgeInsets.only(left: 8, right: 8, bottom: 2),
|
||||
label: Text(emailAddress.asString(), maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
labelStyle: const TextStyle(color: AppColor.colorNameEmail, fontSize: 15, fontWeight: FontWeight.normal),
|
||||
backgroundColor: AppColor.colorEmailAddressTag,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
side: BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
|
||||
side: const BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
|
||||
),
|
||||
avatar: (AvatarBuilder()
|
||||
..text('${emailAddress.asString().characters.first.toUpperCase()}')
|
||||
..addTextStyle(TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w600))
|
||||
..text(emailAddress.asString().characters.first.toUpperCase())
|
||||
..addTextStyle(const TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w600))
|
||||
..avatarColor(emailAddress.avatarColors))
|
||||
.build(),
|
||||
),
|
||||
@@ -341,14 +306,14 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.transparent,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 4, left: 16),
|
||||
padding: const EdgeInsets.only(top: 4, left: 16),
|
||||
child: TextButton(
|
||||
onPressed: () => emailController.toggleDisplayEmailAddressAction(),
|
||||
child: Text(
|
||||
emailController.isExpandEmailAddress
|
||||
? AppLocalizations.of(context).hide
|
||||
: AppLocalizations.of(context).details,
|
||||
style: TextStyle(fontSize: 15, color: AppColor.colorTextButton, fontWeight: FontWeight.normal),
|
||||
style: const TextStyle(fontSize: 15, color: AppColor.colorTextButton, fontWeight: FontWeight.normal),
|
||||
),
|
||||
)
|
||||
)
|
||||
@@ -366,15 +331,15 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
return GestureDetector(
|
||||
onTap: () => emailController.showFullEmailAddress(),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Chip(
|
||||
labelPadding: EdgeInsets.symmetric(horizontal: 8),
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
label: Text('+${_getRemainCountAddressReceiver(email)}', maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
labelStyle: TextStyle(color: AppColor.colorTextButton, fontSize: 15, fontWeight: FontWeight.normal),
|
||||
labelStyle: const TextStyle(color: AppColor.colorTextButton, fontSize: 15, fontWeight: FontWeight.normal),
|
||||
backgroundColor: AppColor.colorEmailAddressTag,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
side: BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
|
||||
side: const BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -383,15 +348,15 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _buildAttachments(BuildContext context) {
|
||||
return Obx(() => emailController.viewState.value.fold(
|
||||
(failure) => SizedBox.shrink(),
|
||||
(failure) => const SizedBox.shrink(),
|
||||
(success) {
|
||||
if (success is LoadingState) {
|
||||
return SizedBox.shrink();
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
final attachments = emailController.attachments.listAttachmentsDisplayedOutSide;
|
||||
return attachments.isNotEmpty
|
||||
? _buildAttachmentsBody(context, attachments)
|
||||
: SizedBox.shrink();
|
||||
: const SizedBox.shrink();
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -424,7 +389,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
padding: EdgeInsets.zero,
|
||||
child: _buildAttachmentsHeader(context, attachments)),
|
||||
GridView.builder(
|
||||
key: Key('list_attachment'),
|
||||
key: const Key('list_attachment'),
|
||||
primary: false,
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(top: isExpand ? 0 : 16, bottom: 16),
|
||||
@@ -483,18 +448,18 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${AppLocalizations.of(context).count_attachment(attachments.length)}',
|
||||
style: TextStyle(fontSize: 12, color: AppColor.baseTextColor)),
|
||||
AppLocalizations.of(context).count_attachment(attachments.length),
|
||||
style: const TextStyle(fontSize: 12, color: AppColor.baseTextColor)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Text(
|
||||
'(${filesize(attachments.totalSize(), 1)})',
|
||||
style: TextStyle(fontSize: 12, color: AppColor.nameUserColor, fontWeight: FontWeight.w500)))
|
||||
style: const TextStyle(fontSize: 12, color: AppColor.nameUserColor, fontWeight: FontWeight.w500)))
|
||||
],
|
||||
),
|
||||
if (attachments.length > 2)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: IconButton(
|
||||
icon: SvgPicture.asset(imagePaths.icExpandAttachment,
|
||||
width: 20,
|
||||
@@ -508,10 +473,10 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _buildEmailContent(BuildContext context, BoxConstraints constraints) {
|
||||
return Obx(() => emailController.viewState.value.fold(
|
||||
(failure) => SizedBox.shrink(),
|
||||
(failure) => const SizedBox.shrink(),
|
||||
(success) {
|
||||
if (success is LoadingState) {
|
||||
return Align(alignment: Alignment.topCenter, child: Padding(
|
||||
return const Align(alignment: Alignment.topCenter, child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
@@ -535,7 +500,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
mailtoDelegate: (uri) async => emailController.openMailToLink(uri));
|
||||
}
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -550,15 +515,15 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _markAsEmailUnreadAction(BuildContext context, PresentationEmail email) {
|
||||
return (EmailActionCupertinoActionSheetActionBuilder(
|
||||
Key('mark_as_unread_action'),
|
||||
const Key('mark_as_unread_action'),
|
||||
SvgPicture.asset(imagePaths.icUnreadEmail, width: 28, height: 28, fit: BoxFit.fill, color: AppColor.colorTextButton),
|
||||
AppLocalizations.of(context).mark_as_unread,
|
||||
email,
|
||||
iconLeftPadding: responsiveUtils.isMobile(context)
|
||||
? EdgeInsets.only(left: 12, right: 16)
|
||||
: EdgeInsets.only(right: 12),
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: responsiveUtils.isMobile(context)
|
||||
? EdgeInsets.only(right: 12)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero)
|
||||
..onActionClick((email) => emailController.handleEmailAction(context, email, EmailActionType.markAsUnread)))
|
||||
.build();
|
||||
@@ -566,7 +531,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
Widget _markAsEmailSpamOrUnSpamAction(BuildContext context, PresentationEmail email) {
|
||||
return (EmailActionCupertinoActionSheetActionBuilder(
|
||||
Key('mark_as_spam_or_un_spam_action'),
|
||||
const Key('mark_as_spam_or_un_spam_action'),
|
||||
SvgPicture.asset(
|
||||
emailController.currentMailbox?.isSpam == true ? imagePaths.icNotSpam : imagePaths.icSpam,
|
||||
width: 28, height: 28, fit: BoxFit.fill, color: AppColor.colorTextButton),
|
||||
@@ -575,10 +540,10 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
: AppLocalizations.of(context).mark_as_spam,
|
||||
email,
|
||||
iconLeftPadding: responsiveUtils.isMobile(context)
|
||||
? EdgeInsets.only(left: 12, right: 16)
|
||||
: EdgeInsets.only(right: 12),
|
||||
? const EdgeInsets.only(left: 12, right: 16)
|
||||
: const EdgeInsets.only(right: 12),
|
||||
iconRightPadding: responsiveUtils.isMobile(context)
|
||||
? EdgeInsets.only(right: 12)
|
||||
? const EdgeInsets.only(right: 12)
|
||||
: EdgeInsets.zero)
|
||||
..onActionClick((email) => emailController.handleEmailAction(context, email,
|
||||
emailController.currentMailbox?.isSpam == true ? EmailActionType.unSpam : EmailActionType.moveToSpam)))
|
||||
@@ -587,8 +552,8 @@ class EmailView extends GetView with UserSettingPopupMenuMixin, NetworkConnectio
|
||||
|
||||
List<PopupMenuEntry> _popupMenuEmailActionTile(BuildContext context, PresentationEmail email) {
|
||||
return [
|
||||
PopupMenuItem(padding: EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailUnreadAction(context, email)),
|
||||
PopupMenuItem(padding: EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailSpamOrUnSpamAction(context, email)),
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailUnreadAction(context, email)),
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: _markAsEmailSpamOrUnSpamAction(context, email)),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnBackActionClick = void Function();
|
||||
@@ -44,12 +44,12 @@ class AppBarMailWidgetBuilder {
|
||||
|
||||
Widget build() {
|
||||
return Container(
|
||||
key: Key('app_bar_messenger_widget'),
|
||||
key: const Key('app_bar_messenger_widget'),
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.zero,
|
||||
margin: EdgeInsets.zero,
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData(padding: EdgeInsets.zero),
|
||||
data: const MediaQueryData(padding: EdgeInsets.zero),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@@ -83,10 +83,10 @@ class AppBarMailWidgetBuilder {
|
||||
return Transform(
|
||||
transform: Matrix4.translationValues(-10.0, 0.0, 0.0),
|
||||
child: Text(
|
||||
'${_currentMailbox?.name?.name.capitalizeFirstEach ?? ''}',
|
||||
_currentMailbox?.name?.name.capitalizeFirstEach ?? '',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 17, color: AppColor.colorTextButton))
|
||||
style: const TextStyle(fontSize: 17, color: AppColor.colorTextButton))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class AppBarMailWidgetBuilder {
|
||||
}
|
||||
}),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 10, right: 16),
|
||||
padding: const EdgeInsets.only(left: 10, right: 16),
|
||||
child: buildIconWebHasPosition(
|
||||
_context,
|
||||
tooltip: AppLocalizations.of(_context).more,
|
||||
|
||||
@@ -106,64 +106,24 @@ class MailboxController extends BaseMailboxController {
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
mailboxDashBoardController.accountId.listen((accountId) {
|
||||
if (accountId != null) {
|
||||
getAllMailboxAction(accountId);
|
||||
}
|
||||
});
|
||||
_onMailboxDashBoardListener();
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
mailboxDashBoardController.viewState.listen((state) {
|
||||
state.fold(
|
||||
(failure) {
|
||||
if (failure is EmptyTrashFolderFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
}
|
||||
},
|
||||
(success) {
|
||||
if (success is MarkAsMultipleEmailReadAllSuccess
|
||||
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|
||||
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is DeleteMultipleEmailsPermanentlyAllSuccess
|
||||
|| success is DeleteMultipleEmailsPermanentlyHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is EmptyTrashFolderSuccess) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is MarkAsEmailReadSuccess
|
||||
|| success is MoveToMailboxSuccess
|
||||
|| success is DeleteEmailPermanentlySuccess
|
||||
|| success is SaveEmailAsDraftsSuccess
|
||||
|| success is RemoveEmailDraftsSuccess
|
||||
|| success is SendEmailSuccess
|
||||
|| success is UpdateEmailDraftsSuccess) {
|
||||
refreshMailboxChanges();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
_openMailboxEventController.stream.throttleTime(const Duration(milliseconds: 800)).listen((event) {
|
||||
_openMailboxEventController.stream.throttleTime(Duration(milliseconds: 800)).listen((event) {
|
||||
_handleOpenMailbox(event.buildContext, event.presentationMailbox);
|
||||
});
|
||||
|
||||
_initCollapseMailboxCategories();
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
mailboxDashBoardController.accountId.close();
|
||||
mailboxDashBoardController.viewState.close();
|
||||
searchInputController.dispose();
|
||||
searchFocus.dispose();
|
||||
super.onClose();
|
||||
@@ -216,6 +176,50 @@ class MailboxController extends BaseMailboxController {
|
||||
@override
|
||||
void onError(error) {}
|
||||
|
||||
void _onMailboxDashBoardListener() {
|
||||
mailboxDashBoardController.accountId.listen((accountId) {
|
||||
log('MailboxController::_onMailboxDashBoardListener(): accountId: $accountId');
|
||||
if (accountId != null) {
|
||||
getAllMailboxAction(accountId);
|
||||
}
|
||||
});
|
||||
|
||||
mailboxDashBoardController.viewState.listen((state) {
|
||||
log('MailboxController::_onMailboxDashBoardListener(): viewState: $viewState');
|
||||
state.fold((failure) {
|
||||
if (failure is EmptyTrashFolderFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
}
|
||||
}, (success) {
|
||||
if (success is MarkAsMultipleEmailReadAllSuccess ||
|
||||
success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is MoveMultipleEmailToMailboxAllSuccess ||
|
||||
success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is DeleteMultipleEmailsPermanentlyAllSuccess ||
|
||||
success is DeleteMultipleEmailsPermanentlyHasSomeEmailFailure) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is EmptyTrashFolderSuccess) {
|
||||
mailboxDashBoardController.clearState();
|
||||
refreshMailboxChanges();
|
||||
} else if (success is MarkAsEmailReadSuccess ||
|
||||
success is MoveToMailboxSuccess ||
|
||||
success is DeleteEmailPermanentlySuccess ||
|
||||
success is SaveEmailAsDraftsSuccess ||
|
||||
success is RemoveEmailDraftsSuccess ||
|
||||
success is SendEmailSuccess ||
|
||||
success is UpdateEmailDraftsSuccess) {
|
||||
refreshMailboxChanges();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _initCollapseMailboxCategories() {
|
||||
if (currentContext != null) {
|
||||
if (kIsWeb && (_responsiveUtils.isMobile(currentContext!)) || _responsiveUtils.isTablet(currentContext!)) {
|
||||
|
||||
@@ -25,11 +25,12 @@ class MailboxView extends GetWidget<MailboxController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Drawer(
|
||||
elevation: _responsiveUtils.isDesktop(context) ? 0 : 16.0,
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: Column(
|
||||
children: [
|
||||
_buildLogoApp(context),
|
||||
if (!_responsiveUtils.isDesktop(context)) _buildLogoApp(context),
|
||||
if (!_responsiveUtils.isDesktop(context)) const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
|
||||
Expanded(child: Container(
|
||||
padding: EdgeInsets.zero,
|
||||
@@ -75,7 +76,7 @@ class MailboxView extends GetWidget<MailboxController> {
|
||||
bottom: _responsiveUtils.isDesktop(context) ? 25 : 16,
|
||||
left: _responsiveUtils.isDesktop(context) ? 32 : 16),
|
||||
child: Row(children: [
|
||||
(SloganBuilder(arrangedByHorizontal: true)
|
||||
(SloganBuilder(arrangedByHorizontal: true)
|
||||
..setSloganText(AppLocalizations.of(context).app_name)
|
||||
..setSloganTextAlign(TextAlign.center)
|
||||
..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold))
|
||||
|
||||
@@ -65,7 +65,7 @@ class UserInformationWidgetBuilder {
|
||||
child: TextButton(
|
||||
onPressed: () => _onLogoutActionClick?.call(),
|
||||
child: Text(
|
||||
AppLocalizations.of(_context).logout,
|
||||
AppLocalizations.of(_context).manage_account,
|
||||
style: const TextStyle(fontSize: 14, color: AppColor.colorTextButton),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/email/email_action_type.dart';
|
||||
import 'package:model/email/filter_message_option.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||
import 'package:tmail_ui_user/main/routes/router_arguments.dart';
|
||||
|
||||
class DashBoardAction extends UIAction {
|
||||
static final idle = DashBoardAction();
|
||||
|
||||
DashBoardAction() : super();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class ComposeEmailAction extends DashBoardAction {
|
||||
|
||||
RouterArguments? arguments;
|
||||
|
||||
ComposeEmailAction({this.arguments});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [arguments];
|
||||
}
|
||||
|
||||
class CloseComposeEmailAction extends DashBoardAction {
|
||||
|
||||
CloseComposeEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class RefreshAllEmailAction extends DashBoardAction {
|
||||
|
||||
RefreshAllEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class SelectionAllEmailAction extends DashBoardAction {
|
||||
|
||||
SelectionAllEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class CancelSelectionAllEmailAction extends DashBoardAction {
|
||||
|
||||
CancelSelectionAllEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class MarkAsReadAllEmailAction extends DashBoardAction {
|
||||
|
||||
MarkAsReadAllEmailAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class FilterMessageAction extends DashBoardAction {
|
||||
|
||||
BuildContext context;
|
||||
FilterMessageOption option;
|
||||
|
||||
FilterMessageAction(this.context, this.option);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [option];
|
||||
}
|
||||
|
||||
class HandleEmailActionTypeAction extends DashBoardAction {
|
||||
|
||||
BuildContext context;
|
||||
EmailActionType emailAction;
|
||||
List<PresentationEmail> listEmailSelected;
|
||||
|
||||
HandleEmailActionTypeAction(this.context, this.listEmailSelected, this.emailAction);
|
||||
|
||||
@override
|
||||
List<Object> get props => [listEmailSelected, emailAction];
|
||||
}
|
||||
|
||||
class GoToSettingsAction extends DashBoardAction {
|
||||
|
||||
GoToSettingsAction();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension FilterMessageOptionExtension on FilterMessageOption {
|
||||
|
||||
String getName(BuildContext context) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return AppLocalizations.of(context).unread;
|
||||
case FilterMessageOption.attachments:
|
||||
return AppLocalizations.of(context).with_attachments;
|
||||
case FilterMessageOption.starred:
|
||||
return AppLocalizations.of(context).starred;
|
||||
}
|
||||
}
|
||||
|
||||
String getIcon(ImagePaths imagePaths) {
|
||||
switch(this) {
|
||||
case FilterMessageOption.all:
|
||||
return '';
|
||||
case FilterMessageOption.unread:
|
||||
return imagePaths.icUnread;
|
||||
case FilterMessageOption.attachments:
|
||||
return imagePaths.icAttachment;
|
||||
case FilterMessageOption.starred:
|
||||
return imagePaths.icStar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
|
||||
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
|
||||
@@ -35,7 +36,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_p
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
|
||||
@@ -68,9 +69,12 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
final userProfile = Rxn<UserProfile>();
|
||||
final searchState = SearchState.initial().obs;
|
||||
final suggestionSearch = <String>[].obs;
|
||||
final dashBoardAction = DashBoardAction.none.obs;
|
||||
final dashBoardAction = Rxn<UIAction>();
|
||||
final routePath = AppRoutes.MAILBOX_DASHBOARD.obs;
|
||||
final appInformation = Rxn<PackageInfo>();
|
||||
final currentSelectMode = SelectMode.INACTIVE.obs;
|
||||
final filterMessageOption = FilterMessageOption.all.obs;
|
||||
final listEmailSelected = <PresentationEmail>[].obs;
|
||||
|
||||
SearchQuery? searchQuery;
|
||||
Session? sessionCurrent;
|
||||
@@ -96,12 +100,12 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
log('MailboxDashBoardController::onReady()');
|
||||
dispatchRoute(AppRoutes.THREAD);
|
||||
_setSessionCurrent();
|
||||
_getUserProfile();
|
||||
_initPackageInfo();
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -257,9 +261,9 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
|
||||
bool get isDrawerOpen => scaffoldKey.currentState?.isDrawerOpen == true;
|
||||
|
||||
bool isSearchActive() {
|
||||
return searchState.value.searchStatus == SearchStatus.ACTIVE;
|
||||
}
|
||||
bool isSearchActive() => searchState.value.searchStatus == SearchStatus.ACTIVE;
|
||||
|
||||
bool isSelectionEnabled() => currentSelectMode.value == SelectMode.ACTIVE;
|
||||
|
||||
void enableSearch() {
|
||||
searchState.value = searchState.value.enableSearchState();
|
||||
@@ -361,16 +365,14 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchDashBoardAction(DashBoardAction action, {RouterArguments? arguments}) {
|
||||
switch(action) {
|
||||
case DashBoardAction.none:
|
||||
routerArguments = null;
|
||||
Get.delete<ComposerController>();
|
||||
break;
|
||||
case DashBoardAction.compose:
|
||||
routerArguments = arguments;
|
||||
ComposerBindings().dependencies();
|
||||
break;
|
||||
void dispatchAction(UIAction action) {
|
||||
log('MailboxDashBoardController::dispatchAction(): ${action.runtimeType}');
|
||||
if (action is ComposeEmailAction) {
|
||||
routerArguments = action.arguments;
|
||||
ComposerBindings().dependencies();
|
||||
} else if (action is CloseComposeEmailAction) {
|
||||
routerArguments = null;
|
||||
Get.delete<ComposerController>();
|
||||
}
|
||||
dashBoardAction.value = action;
|
||||
}
|
||||
@@ -402,8 +404,8 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
|
||||
void composeEmailAction() {
|
||||
if (kIsWeb) {
|
||||
if (dashBoardAction.value != DashBoardAction.compose) {
|
||||
dispatchDashBoardAction(DashBoardAction.compose, arguments: ComposerArguments());
|
||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||
dispatchAction(ComposeEmailAction(arguments: ComposerArguments()));
|
||||
}
|
||||
} else {
|
||||
push(AppRoutes.COMPOSER, arguments: ComposerArguments());
|
||||
@@ -412,8 +414,8 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
|
||||
void goToComposer(ComposerArguments arguments) {
|
||||
if (kIsWeb) {
|
||||
if (dashBoardAction.value != DashBoardAction.compose) {
|
||||
dispatchDashBoardAction(DashBoardAction.compose, arguments: arguments);
|
||||
if (dashBoardAction.value is! ComposeEmailAction) {
|
||||
dispatchAction(ComposeEmailAction(arguments: arguments));
|
||||
}
|
||||
} else {
|
||||
push(AppRoutes.COMPOSER, arguments: arguments);
|
||||
@@ -434,6 +436,14 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
goToLogin();
|
||||
}
|
||||
|
||||
void clearDashBoardAction() {
|
||||
dashBoardAction.value = DashBoardAction.idle;
|
||||
}
|
||||
|
||||
void goToSettings() {
|
||||
dispatchAction(GoToSettingsAction());
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
_emailReceiveManager.closeEmailReceiveManagerStream();
|
||||
|
||||
@@ -5,10 +5,10 @@ import 'package:tmail_ui_user/features/base/mixin/network_connection_mixin.dart'
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
|
||||
@@ -28,19 +28,16 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
? SizedBox(child: MailboxView(), width: double.infinity)
|
||||
: SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeDrawerWidthMobileTablet),
|
||||
tablet: SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeDrawerWidthMobileTablet),
|
||||
tabletLarge: const SizedBox.shrink(),
|
||||
desktop: const SizedBox.shrink()
|
||||
tabletLarge: SizedBox.shrink(),
|
||||
),
|
||||
drawerEnableOpenDragGesture: _responsiveUtils.isMobile(context) || _responsiveUtils.isTablet(context),
|
||||
body: Stack(children: [
|
||||
ResponsiveWidget(
|
||||
responsiveUtils: _responsiveUtils,
|
||||
desktop: _buildLargeScreenView(context),
|
||||
tabletLarge: _buildLargeScreenView(context),
|
||||
tablet: ThreadView(),
|
||||
mobile: ThreadView()
|
||||
),
|
||||
Obx(() => controller.dashBoardAction.value == DashBoardAction.compose
|
||||
Obx(() => controller.dashBoardAction.value is ComposeEmailAction
|
||||
? ComposerView()
|
||||
: const SizedBox.shrink()),
|
||||
Obx(() => controller.isNetworkConnectionAvailable()
|
||||
@@ -50,7 +47,7 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildThreadAndEmailContainer(BuildContext context) {
|
||||
Widget _wrapContainerForThreadAndEmail(BuildContext context) {
|
||||
switch(AppSetting.readingPane) {
|
||||
case ReadingPane.noSplit:
|
||||
return Obx(() {
|
||||
@@ -97,7 +94,7 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeDrawerWidthMobileTablet),
|
||||
Expanded(child: _buildThreadAndEmailContainer(context))
|
||||
Expanded(child: _wrapContainerForThreadAndEmail(context))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,44 +1,100 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/network_connection_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/filter_email_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
|
||||
class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with NetworkConnectionMixin {
|
||||
class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with NetworkConnectionMixin,
|
||||
UserSettingPopupMenuMixin, FilterEmailPopupMenuMixin {
|
||||
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
MailboxDashBoardView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (controller.isDrawerOpen && (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context))) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
controller.closeDrawer();
|
||||
});
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
key: controller.scaffoldKey,
|
||||
backgroundColor: Colors.white,
|
||||
drawer: ResponsiveWidget(
|
||||
responsiveUtils: _responsiveUtils,
|
||||
mobile: SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeDrawerWidthWeb),
|
||||
tablet: SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeDrawerWidthWeb),
|
||||
tabletLarge: const SizedBox.shrink(),
|
||||
desktop: const SizedBox.shrink()
|
||||
tabletLarge: const SizedBox.shrink()
|
||||
),
|
||||
drawerEnableOpenDragGesture: _responsiveUtils.isMobile(context) || _responsiveUtils.isTablet(context),
|
||||
body: Stack(children: [
|
||||
ResponsiveWidget(
|
||||
responsiveUtils: _responsiveUtils,
|
||||
desktop: _buildLargeScreenView(context),
|
||||
tabletLarge: _buildLargeScreenView(context),
|
||||
tablet: ThreadView(),
|
||||
desktop: Column(children: [
|
||||
Row(children: [
|
||||
Container(width: 256, color: Colors.white,
|
||||
padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32),
|
||||
child: Row(children: [
|
||||
(SloganBuilder(arrangedByHorizontal: true)
|
||||
..setSloganText(AppLocalizations.of(context).app_name)
|
||||
..setSloganTextAlign(TextAlign.center)
|
||||
..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold))
|
||||
..setSizeLogo(24)
|
||||
..setLogo(_imagePaths.icLogoTMail))
|
||||
.build(),
|
||||
Obx(() {
|
||||
if (controller.appInformation.value != null) {
|
||||
return Padding(padding: const EdgeInsets.only(top: 6),
|
||||
child: Text(
|
||||
'v.${controller.appInformation.value!.version}',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500),
|
||||
));
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
])
|
||||
),
|
||||
Expanded(child: Padding(
|
||||
padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48),
|
||||
child: _buildRightHeader(context)))
|
||||
]),
|
||||
Expanded(child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeMenuWidthWeb),
|
||||
Expanded(child: _wrapContainerForThreadAndEmail(context))
|
||||
],
|
||||
))
|
||||
]),
|
||||
tabletLarge: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeMenuWidthWeb),
|
||||
Expanded(child: _wrapContainerForThreadAndEmail(context))
|
||||
],
|
||||
),
|
||||
mobile: ThreadView()
|
||||
),
|
||||
Obx(() => controller.dashBoardAction.value == DashBoardAction.compose
|
||||
Obx(() => controller.dashBoardAction.value is ComposeEmailAction
|
||||
? ComposerView()
|
||||
: const SizedBox.shrink()),
|
||||
Obx(() => controller.isNetworkConnectionAvailable()
|
||||
@@ -48,7 +104,7 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildThreadAndEmailContainer(BuildContext context) {
|
||||
Widget _wrapContainerForThreadAndEmail(BuildContext context) {
|
||||
switch(AppSetting.readingPane) {
|
||||
case ReadingPane.noSplit:
|
||||
return Obx(() {
|
||||
@@ -84,19 +140,267 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildLargeScreenView(BuildContext context) {
|
||||
if (controller.isDrawerOpen && (_responsiveUtils.isDesktop(context) || _responsiveUtils.isTabletLarge(context))) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
controller.closeDrawer();
|
||||
});
|
||||
}
|
||||
Widget _buildRightHeader(BuildContext context) {
|
||||
return Row(children: [
|
||||
Obx(() {
|
||||
if (controller.isSelectionEnabled()) {
|
||||
return _buildListButtonTopBarSelection(context);
|
||||
} else {
|
||||
return controller.isSearchActive()
|
||||
? _buildListButtonTopBarSearchActive(context)
|
||||
: _buildListButtonTopBar(context);
|
||||
}
|
||||
}),
|
||||
const SizedBox(width: 16),
|
||||
Obx(() => !controller.isSearchActive() ? const Spacer() : const SizedBox.shrink()),
|
||||
Obx(() => controller.isSearchActive() ? Expanded(child: _buildSearchForm(context)) : const SizedBox.shrink()),
|
||||
Obx(() => !controller.isSearchActive()
|
||||
? (SearchBarView(_imagePaths)
|
||||
..hintTextSearch(AppLocalizations.of(context).search_emails)
|
||||
..maxSizeWidth(240)
|
||||
..addOnOpenSearchViewAction(() => controller.enableSearch()))
|
||||
.build()
|
||||
: const SizedBox.shrink()),
|
||||
Obx(() => !controller.isSearchActive() ? const SizedBox(width: 16) : const SizedBox.shrink()),
|
||||
(AvatarBuilder()
|
||||
..text(controller.userProfile.value?.getAvatarText() ?? '')
|
||||
..backgroundColor(Colors.white)
|
||||
..textColor(Colors.black)
|
||||
..context(context)
|
||||
..addOnTapAvatarActionWithPositionClick((position) =>
|
||||
controller.openPopupMenuAction(context, position, popupMenuUserSettingActionTile(context,
|
||||
controller.userProfile.value,
|
||||
onLogoutAction: () => controller.logoutAction(),
|
||||
onSettingAction: () => controller.goToSettings())))
|
||||
..addBoxShadows([const BoxShadow(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))])
|
||||
..size(48))
|
||||
.build(),
|
||||
const SizedBox(width: 16)
|
||||
]);
|
||||
}
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(child: MailboxView(), width: _responsiveUtils.defaultSizeMenuWidthWeb),
|
||||
Expanded(child: _buildThreadAndEmailContainer(context))
|
||||
],
|
||||
);
|
||||
Widget _buildListButtonTopBar(BuildContext context) {
|
||||
return Row(children: [
|
||||
(ButtonBuilder(_imagePaths.icRefresh)
|
||||
..key(const Key('button_reload_thread'))
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(EdgeInsets.zero)
|
||||
..size(16)
|
||||
..radiusSplash(10)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 8, vertical: 8))
|
||||
..onPressActionClick(() => controller.dispatchAction(RefreshAllEmailAction())))
|
||||
.build(),
|
||||
const SizedBox(width: 16),
|
||||
(ButtonBuilder(_imagePaths.icSelectAll)
|
||||
..key(const Key('button_select_all'))
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..radiusSplash(10)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => controller.dispatchAction(SelectionAllEmailAction()))
|
||||
..text(AppLocalizations.of(context).select_all, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 16),
|
||||
(ButtonBuilder(_imagePaths.icMarkAllAsRead)
|
||||
..key(const Key('button_mark_all_as_read'))
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => controller.dispatchAction(MarkAsReadAllEmailAction()))
|
||||
..text(AppLocalizations.of(context).mark_all_as_read, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 16),
|
||||
Obx(() => (ButtonBuilder(_imagePaths.icFilterWeb)
|
||||
..key(const Key('button_filter_messages'))
|
||||
..context(context)
|
||||
..decoration(BoxDecoration(borderRadius: BorderRadius.circular(10), color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..textStyle(TextStyle(
|
||||
fontSize: 12,
|
||||
color: controller.filterMessageOption.value == FilterMessageOption.all
|
||||
? AppColor.colorTextButtonHeaderThread
|
||||
: AppColor.colorNameEmail,
|
||||
fontWeight: controller.filterMessageOption.value == FilterMessageOption.all
|
||||
? FontWeight.normal
|
||||
: FontWeight.w500))
|
||||
..addIconAction(Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: SvgPicture.asset(_imagePaths.icArrowDown, fit: BoxFit.fill)))
|
||||
..addOnPressActionWithPositionClick((position) => controller.openPopupMenuAction(context, position,
|
||||
popupMenuFilterEmailActionTile(context,
|
||||
controller.filterMessageOption.value,
|
||||
(option) => controller.dispatchAction(FilterMessageAction(context, option)))))
|
||||
..text(controller.filterMessageOption.value == FilterMessageOption.all
|
||||
? AppLocalizations.of(context).filter_messages
|
||||
: controller.filterMessageOption.value.getTitle(context), isVertical: false))
|
||||
.build()),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListButtonTopBarSearchActive(BuildContext context) {
|
||||
return Row(children: [
|
||||
(ButtonBuilder(_imagePaths.icSelectAll)
|
||||
..key(const Key('button_select_all'))
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..radiusSplash(10)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => controller.dispatchAction(SelectionAllEmailAction()))
|
||||
..text(AppLocalizations.of(context).select_all, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 16),
|
||||
(ButtonBuilder(_imagePaths.icMarkAllAsRead)
|
||||
..key(const Key('button_mark_all_as_read'))
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => controller.dispatchAction(MarkAsReadAllEmailAction()))
|
||||
..text(AppLocalizations.of(context).mark_all_as_read, isVertical: false))
|
||||
.build(),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListButtonTopBarSelection(BuildContext context) {
|
||||
return Row(children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icCloseComposer, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).cancel,
|
||||
onTap: () => controller.dispatchAction(CancelSelectionAllEmailAction())),
|
||||
Obx(() => Text(
|
||||
AppLocalizations.of(context).count_email_selected(controller.listEmailSelected.length),
|
||||
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorTextButton))),
|
||||
const SizedBox(width: 30),
|
||||
Obx(() => buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.listEmailSelected.isAllEmailRead
|
||||
? _imagePaths.icRead
|
||||
: _imagePaths.icUnread,
|
||||
fit: BoxFit.fill),
|
||||
tooltip: controller.listEmailSelected.isAllEmailRead
|
||||
? AppLocalizations.of(context).mark_as_unread
|
||||
: AppLocalizations.of(context).mark_as_read,
|
||||
onTap: () => controller.dispatchAction(
|
||||
HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
controller.listEmailSelected.isAllEmailRead
|
||||
? EmailActionType.markAsUnread
|
||||
: EmailActionType.markAsRead)))),
|
||||
Obx(() => buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.listEmailSelected.isAllEmailStarred
|
||||
? _imagePaths.icUnStar
|
||||
: _imagePaths.icStar,
|
||||
fit: BoxFit.fill),
|
||||
tooltip: controller.listEmailSelected.isAllEmailStarred
|
||||
? AppLocalizations.of(context).un_star
|
||||
: AppLocalizations.of(context).star,
|
||||
onTap: () => controller.dispatchAction(
|
||||
HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
controller.listEmailSelected.isAllEmailStarred
|
||||
? EmailActionType.markAsStarred
|
||||
: EmailActionType.unMarkAsStarred)))),
|
||||
Obx(() {
|
||||
if (controller.selectedMailbox.value?.isDrafts == false) {
|
||||
return buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).move,
|
||||
onTap: () => controller.dispatchAction(
|
||||
HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
EmailActionType.moveToMailbox)));
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Obx(() {
|
||||
if (controller.selectedMailbox.value?.isDrafts == false) {
|
||||
return buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.selectedMailbox.value?.isSpam == true
|
||||
? _imagePaths.icNotSpam
|
||||
: _imagePaths.icSpam,
|
||||
fit: BoxFit.fill),
|
||||
tooltip: controller.selectedMailbox.value?.isSpam == true
|
||||
? AppLocalizations.of(context).un_spam
|
||||
: AppLocalizations.of(context).mark_as_spam,
|
||||
onTap: () {
|
||||
if (controller.selectedMailbox.value?.isSpam == true) {
|
||||
return controller.dispatchAction(
|
||||
HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
EmailActionType.unSpam));
|
||||
} else {
|
||||
return controller.dispatchAction(
|
||||
HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
EmailActionType.moveToSpam));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Obx(() => buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icDelete, fit: BoxFit.fill),
|
||||
tooltip: controller.selectedMailbox.value?.isTrash == true
|
||||
? AppLocalizations.of(context).delete_permanently
|
||||
: AppLocalizations.of(context).move_to_trash,
|
||||
onTap: () {
|
||||
if (controller.selectedMailbox.value?.isTrash == true) {
|
||||
return controller.dispatchAction(HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
EmailActionType.deletePermanently));
|
||||
} else {
|
||||
return controller.dispatchAction(HandleEmailActionTypeAction(context,
|
||||
controller.listEmailSelected,
|
||||
EmailActionType.moveToTrash));
|
||||
}
|
||||
})),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildSearchForm(BuildContext context) {
|
||||
return (SearchAppBarWidget(context, _imagePaths, _responsiveUtils,
|
||||
controller.searchQuery,
|
||||
controller.searchFocus,
|
||||
controller.searchInputController,
|
||||
suggestionSearch: controller.suggestionSearch)
|
||||
..addDecoration(const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar))
|
||||
..setMargin(const EdgeInsets.only(right: 10))
|
||||
..setHeightSearchBar(45)
|
||||
..setHintText(AppLocalizations.of(context).search_mail)
|
||||
..addOnCancelSearchPressed(() => controller.disableSearch())
|
||||
..addOnClearTextSearchAction(() => controller.clearSearchText())
|
||||
..addOnTextChangeSearchAction((query) => controller.addSuggestionSearch(query))
|
||||
..addOnSearchTextAction((query) => controller.searchEmail(context, query)))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/filter_message_option_extension.dart';
|
||||
|
||||
mixin FilterEmailPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
List<PopupMenuEntry> popupMenuFilterEmailActionTile(BuildContext context,
|
||||
FilterMessageOption optionSelected, Function(FilterMessageOption)? onCallBack) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _filterEmailAction(context, optionSelected, FilterMessageOption.attachments, onCallBack)),
|
||||
PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _filterEmailAction(context, optionSelected, FilterMessageOption.unread, onCallBack)),
|
||||
PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _filterEmailAction(context, optionSelected, FilterMessageOption.starred, onCallBack)),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _filterEmailAction(BuildContext context, FilterMessageOption optionSelected,
|
||||
FilterMessageOption option, Function(FilterMessageOption)? onCallBack) {
|
||||
return InkWell(
|
||||
onTap: () => onCallBack?.call(option == optionSelected ? FilterMessageOption.all : option),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
||||
child: SizedBox(
|
||||
child: Row(children: [
|
||||
SvgPicture.asset(option.getIcon(_imagePaths),
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.fill,
|
||||
color: option != FilterMessageOption.starred ? AppColor.colorTextButton : null),
|
||||
SizedBox(width: 12),
|
||||
Expanded(child: Text(
|
||||
option.getName(context),
|
||||
style: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w500))),
|
||||
if (optionSelected == option)
|
||||
SizedBox(width: 12),
|
||||
if (optionSelected == option)
|
||||
SvgPicture.asset(_imagePaths.icFilterSelected, width: 16, height: 16, fit: BoxFit.fill),
|
||||
])
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
mixin UserSettingPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
List<PopupMenuEntry> popupMenuUserSettingActionTile(BuildContext context, UserProfile? userProfile,
|
||||
{Function? onLogoutAction, Function? onSettingAction}) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
enabled: false,
|
||||
padding: EdgeInsets.zero,
|
||||
child: _userInformation(context, userProfile)),
|
||||
PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _settingAction(context, onSettingAction)),
|
||||
PopupMenuDivider(height: 0.5),
|
||||
PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
child: _logoutAction(context, onLogoutAction)),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _userInformation(BuildContext context, UserProfile? userProfile) {
|
||||
if (userProfile != null) {
|
||||
return SizedBox(
|
||||
width: 300,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
||||
title: Text(userProfile.email, maxLines: 1, style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: AppColor.colorHintSearchBar,
|
||||
fontWeight: FontWeight.normal))),
|
||||
);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
|
||||
Widget _settingAction(BuildContext context, Function? onCallBack) {
|
||||
return PopupMenuItemWidget(
|
||||
_imagePaths.icSetting,
|
||||
AppLocalizations.of(context).settings,
|
||||
() => onCallBack?.call());
|
||||
}
|
||||
|
||||
Widget _logoutAction(BuildContext context, Function? onCallBack) {
|
||||
return PopupMenuItemWidget(
|
||||
_imagePaths.icLogout,
|
||||
AppLocalizations.of(context).sign_out,
|
||||
() => onCallBack?.call());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
enum DashBoardAction {
|
||||
none,
|
||||
compose
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
mixin UserSettingPopupMenuMixin {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
void openUserSettingAction(BuildContext context, RelativeRect? position, List<PopupMenuEntry> popupMenuItems) async {
|
||||
await showMenu(
|
||||
context: context,
|
||||
position: position ?? const RelativeRect.fromLTRB(16, 40, 16, 16),
|
||||
color: Colors.white,
|
||||
elevation: 5,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
||||
items: popupMenuItems);
|
||||
}
|
||||
|
||||
List<PopupMenuEntry> popupMenuUserSettingActionTile(BuildContext context, Function? onCallBack) {
|
||||
return [
|
||||
PopupMenuItem(padding: const EdgeInsets.symmetric(horizontal: 8), child: logoutAction(context, onCallBack)),
|
||||
];
|
||||
}
|
||||
|
||||
Widget logoutAction(BuildContext context, Function? onCallBack) {
|
||||
return (AppActionSheetActionBuilder(
|
||||
const Key('logout_action'),
|
||||
SvgPicture.asset(_imagePaths.icCloseMailbox, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
AppLocalizations.of(context).logout,
|
||||
iconLeftPadding:const EdgeInsets.only(right: 12))
|
||||
..onActionClick((option) => onCallBack?.call()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
|
||||
class AppSetting {
|
||||
static ReadingPane readingPane = ReadingPane.noSplit;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
|
||||
|
||||
class AppSetting {
|
||||
static ReadingPane readingPane = ReadingPane.noSplit;
|
||||
}
|
||||
@@ -36,8 +36,8 @@ import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_int
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/get_email_request.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
|
||||
@@ -91,8 +91,6 @@ class ThreadController extends BaseController {
|
||||
|
||||
final emailList = <PresentationEmail>[].obs;
|
||||
final emailListSearch = <PresentationEmail>[].obs;
|
||||
final currentSelectMode = SelectMode.INACTIVE.obs;
|
||||
final filterMessageOption = FilterMessageOption.all.obs;
|
||||
|
||||
bool canLoadMore = true;
|
||||
bool canSearchMore = true;
|
||||
@@ -131,50 +129,20 @@ class ThreadController extends BaseController {
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
_onMailboxDashBoardListener();
|
||||
super.onInit();
|
||||
mailboxDashBoardController.selectedMailbox.listen((selectedMailbox) {
|
||||
if (_currentMailboxId != selectedMailbox?.id) {
|
||||
log('ThreadController::onReady(): selectMailbox: ${selectedMailbox?.name?.name}(${selectedMailbox?.id})');
|
||||
_currentMailboxId = selectedMailbox?.id;
|
||||
_resetToOriginalValue();
|
||||
_getAllEmail();
|
||||
}
|
||||
});
|
||||
super.onInit();
|
||||
dispatchState(Right(LoadingState()));
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
dispatchState(Right(LoadingState()));
|
||||
super.onReady();
|
||||
mailboxDashBoardController.viewState.listen((state) {
|
||||
state.map((success) {
|
||||
if (success is SearchEmailNewQuery){
|
||||
mailboxDashBoardController.clearState();
|
||||
_searchEmail();
|
||||
} else if (success is MarkAsEmailReadSuccess
|
||||
|| success is MoveToMailboxSuccess
|
||||
|| success is MarkAsStarEmailSuccess
|
||||
|| success is DeleteEmailPermanentlySuccess
|
||||
|| success is SaveEmailAsDraftsSuccess
|
||||
|| success is RemoveEmailDraftsSuccess
|
||||
|| success is SendEmailSuccess
|
||||
|| success is UpdateEmailDraftsSuccess) {
|
||||
_refreshEmailChanges();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mailboxDashBoardController.searchState.listen((state) {
|
||||
if (state.searchStatus == SearchStatus.INACTIVE) {
|
||||
emailListSearch.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
mailboxDashBoardController.selectedMailbox.close();
|
||||
mailboxDashBoardController.dashBoardAction.close();
|
||||
mailboxDashBoardController.viewState.close();
|
||||
mailboxDashBoardController.searchState.close();
|
||||
listEmailController.dispose();
|
||||
@@ -214,6 +182,7 @@ class ThreadController extends BaseController {
|
||||
void onDone() {
|
||||
viewState.value.fold(
|
||||
(failure) {
|
||||
log('ThreadController::onDone(): failure: $failure');
|
||||
if (failure is MarkAsMultipleEmailReadAllFailure
|
||||
|| failure is MarkAsMultipleEmailReadFailure) {
|
||||
_markAsReadSelectedMultipleEmailFailure(failure);
|
||||
@@ -229,6 +198,7 @@ class ThreadController extends BaseController {
|
||||
(success) {
|
||||
if (success is MarkAsMultipleEmailReadAllSuccess
|
||||
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||
log('ThreadController::onDone(): success: $success');
|
||||
_markAsReadSelectedMultipleEmailSuccess(success);
|
||||
} else if (success is MoveMultipleEmailToMailboxAllSuccess
|
||||
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
|
||||
@@ -257,6 +227,69 @@ class ThreadController extends BaseController {
|
||||
@override
|
||||
void onError(error) {}
|
||||
|
||||
void _onMailboxDashBoardListener() {
|
||||
mailboxDashBoardController.selectedMailbox.listen((selectedMailbox) {
|
||||
log('ThreadController::_onMailboxDashBoardListener(): selectMailbox: ${selectedMailbox?.name?.name}(${selectedMailbox?.id})');
|
||||
if (_currentMailboxId != selectedMailbox?.id) {
|
||||
_currentMailboxId = selectedMailbox?.id;
|
||||
_resetToOriginalValue();
|
||||
_getAllEmail();
|
||||
}
|
||||
});
|
||||
|
||||
mailboxDashBoardController.searchState.listen((state) {
|
||||
log('ThreadController::_onMailboxDashBoardListener(): searchState: $state');
|
||||
if (state.searchStatus == SearchStatus.INACTIVE) {
|
||||
emailListSearch.clear();
|
||||
} else if (state.searchStatus == SearchStatus.ACTIVE) {
|
||||
cancelSelectEmail();
|
||||
}
|
||||
});
|
||||
|
||||
mailboxDashBoardController.dashBoardAction.listen((action) {
|
||||
log('ThreadController::_onMailboxDashBoardListener(): dashBoardAction: ${action.runtimeType}');
|
||||
if (action is RefreshAllEmailAction) {
|
||||
refreshAllEmail();
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} else if (action is MarkAsReadAllEmailAction) {
|
||||
markAsReadAllEmails();
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} if (action is SelectionAllEmailAction) {
|
||||
setSelectAllEmailAction();
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} if (action is CancelSelectionAllEmailAction) {
|
||||
cancelSelectEmail();
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} if (action is FilterMessageAction) {
|
||||
filterMessagesAction(action.context, action.option);
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
} if (action is HandleEmailActionTypeAction) {
|
||||
log('ThreadController::_onMailboxDashBoardListener(): ${action.listEmailSelected.length}');
|
||||
pressEmailSelectionAction(action.context, action.emailAction, action.listEmailSelected);
|
||||
mailboxDashBoardController.clearDashBoardAction();
|
||||
}
|
||||
});
|
||||
|
||||
mailboxDashBoardController.viewState.listen((state) {
|
||||
log('ThreadController::_onMailboxDashBoardListener(): viewState: $state');
|
||||
state.map((success) {
|
||||
if (success is SearchEmailNewQuery){
|
||||
mailboxDashBoardController.clearState();
|
||||
_searchEmail();
|
||||
} else if (success is MarkAsEmailReadSuccess
|
||||
|| success is MoveToMailboxSuccess
|
||||
|| success is MarkAsStarEmailSuccess
|
||||
|| success is DeleteEmailPermanentlySuccess
|
||||
|| success is SaveEmailAsDraftsSuccess
|
||||
|| success is RemoveEmailDraftsSuccess
|
||||
|| success is SendEmailSuccess
|
||||
|| success is UpdateEmailDraftsSuccess) {
|
||||
_refreshEmailChanges();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _getAllEmail() {
|
||||
if (_accountId != null) {
|
||||
_getAllEmailAction(_accountId!, mailboxId: _currentMailboxId);
|
||||
@@ -303,7 +336,7 @@ class ThreadController extends BaseController {
|
||||
sort: _sortOrder,
|
||||
emailFilter: EmailFilter(
|
||||
filter: _getFilterCondition(),
|
||||
filterOption: filterMessageOption.value,
|
||||
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
||||
mailboxId: mailboxId ?? _currentMailboxId),
|
||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||
@@ -311,7 +344,7 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
EmailFilterCondition _getFilterCondition({bool isLoadMore = false}) {
|
||||
switch(filterMessageOption.value) {
|
||||
switch(mailboxDashBoardController.filterMessageOption.value) {
|
||||
case FilterMessageOption.all:
|
||||
return EmailFilterCondition(
|
||||
inMailbox: mailboxDashBoardController.selectedMailbox.value?.id,
|
||||
@@ -350,7 +383,7 @@ class ThreadController extends BaseController {
|
||||
sort: _sortOrder,
|
||||
emailFilter: EmailFilter(
|
||||
filter: _getFilterCondition(),
|
||||
filterOption: filterMessageOption.value,
|
||||
filterOption: mailboxDashBoardController.filterMessageOption.value,
|
||||
mailboxId: _currentMailboxId),
|
||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||
@@ -359,6 +392,7 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _refreshEmailChanges() {
|
||||
log('ThreadController::_refreshEmailChanges(): ');
|
||||
if (isSearchActive()) {
|
||||
if (_accountId != null && searchQuery != null) {
|
||||
final limit = emailListSearch.isNotEmpty ? UnsignedInt(emailListSearch.length) : ThreadConstants.defaultLimit;
|
||||
@@ -379,7 +413,7 @@ class ThreadController extends BaseController {
|
||||
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||
inMailboxId: _currentMailboxId,
|
||||
filterOption: filterMessageOption.value
|
||||
filterOption: mailboxDashBoardController.filterMessageOption.value
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -439,16 +473,18 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
if (_isUnSelectedAll()) {
|
||||
currentSelectMode.value = SelectMode.INACTIVE;
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
||||
mailboxDashBoardController.listEmailSelected.clear();
|
||||
} else {
|
||||
if (currentSelectMode.value == SelectMode.INACTIVE) {
|
||||
currentSelectMode.value = SelectMode.ACTIVE;
|
||||
if (mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) {
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
||||
}
|
||||
mailboxDashBoardController.listEmailSelected.value = listEmailSelected;
|
||||
}
|
||||
}
|
||||
|
||||
void enableSelectionEmail() {
|
||||
currentSelectMode.value = SelectMode.ACTIVE;
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
||||
}
|
||||
|
||||
void setSelectAllEmailAction() {
|
||||
@@ -457,7 +493,8 @@ class ThreadController extends BaseController {
|
||||
} else {
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.ACTIVE)).toList();
|
||||
}
|
||||
currentSelectMode.value = SelectMode.ACTIVE;
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.ACTIVE;
|
||||
mailboxDashBoardController.listEmailSelected.value = listEmailSelected;
|
||||
}
|
||||
|
||||
List<PresentationEmail> get listEmailSelected {
|
||||
@@ -477,20 +514,28 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void cancelSelectEmail() {
|
||||
if (isSearchActive()) {
|
||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
} else {
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
emailListSearch.value = emailListSearch.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
|
||||
mailboxDashBoardController.listEmailSelected.clear();
|
||||
}
|
||||
|
||||
void markAsReadAllEmails() {
|
||||
final listEmail = isSearchActive() ? emailListSearch.allEmailUnread : emailList.allEmailUnread;
|
||||
log('ThreadController::markAsReadAllEmails(): ${listEmail.length}');
|
||||
if (listEmail.isNotEmpty) {
|
||||
markAsReadSelectedMultipleEmail(listEmail);
|
||||
}
|
||||
currentSelectMode.value = SelectMode.INACTIVE;
|
||||
}
|
||||
|
||||
void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail) {
|
||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listPresentationEmail: ${listPresentationEmail.length}');
|
||||
final readAction = listPresentationEmail.isAllEmailRead ? ReadActions.markAsUnread : ReadActions.markAsRead;
|
||||
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
|
||||
if (_accountId != null && mailboxCurrent != null) {
|
||||
cancelSelectEmail();
|
||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||
log('ThreadController::markAsReadSelectedMultipleEmail(): listEmail: ${listEmail.length}');
|
||||
consumeState(_markAsMultipleEmailReadInteractor.execute(_accountId!, listEmail, readAction));
|
||||
}
|
||||
}
|
||||
@@ -515,7 +560,7 @@ class ThreadController extends BaseController {
|
||||
message: message,
|
||||
icon: readActions == ReadActions.markAsUnread ? _imagePaths.icUnreadToast : _imagePaths.icReadToast);
|
||||
}
|
||||
|
||||
log('ThreadController::_markAsReadSelectedMultipleEmailSuccess(): _refreshEmailChanges');
|
||||
_refreshEmailChanges();
|
||||
}
|
||||
|
||||
@@ -549,8 +594,15 @@ class ThreadController extends BaseController {
|
||||
void filterMessagesAction(BuildContext context, FilterMessageOption filterOption) {
|
||||
popBack();
|
||||
|
||||
final newFilterOption = filterMessageOption.value == filterOption ? FilterMessageOption.all : filterOption;
|
||||
filterMessageOption.value = newFilterOption;
|
||||
final newFilterOption = mailboxDashBoardController.filterMessageOption.value == filterOption
|
||||
? FilterMessageOption.all
|
||||
: filterOption;
|
||||
|
||||
log('ThreadController::filterMessagesAction(): newFilterOption: $newFilterOption');
|
||||
|
||||
mailboxDashBoardController.filterMessageOption.value = newFilterOption;
|
||||
|
||||
log('ThreadController::filterMessagesAction(): filterMessageOption: ${mailboxDashBoardController.filterMessageOption}');
|
||||
|
||||
_appToast.showToastWithIcon(
|
||||
currentOverlayContext!,
|
||||
@@ -737,10 +789,10 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void markAsStarSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail) {
|
||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||
final starAction = listPresentationEmail.isAllEmailStarred ? MarkStarAction.unMarkStar : MarkStarAction.markStar;
|
||||
if (_accountId != null) {
|
||||
cancelSelectEmail();
|
||||
final listEmail = listPresentationEmail.map((presentationEmail) => presentationEmail.toEmail()).toList();
|
||||
consumeState(_markAsStarMultipleEmailInteractor.execute(_accountId!, listEmail, starAction));
|
||||
}
|
||||
}
|
||||
@@ -840,9 +892,10 @@ class ThreadController extends BaseController {
|
||||
_isLoadingMore = false;
|
||||
}
|
||||
|
||||
bool isSelectionEnabled() => currentSelectMode.value == SelectMode.ACTIVE;
|
||||
bool isSelectionEnabled() => mailboxDashBoardController.currentSelectMode.value == SelectMode.ACTIVE;
|
||||
|
||||
void pressEmailSelectionAction(BuildContext context, EmailActionType actionType, List<PresentationEmail> selectionEmail) {
|
||||
log('ThreadController::pressEmailSelectionAction(): selectionEmail: ${selectionEmail.length}');
|
||||
switch(actionType) {
|
||||
case EmailActionType.markAsRead:
|
||||
case EmailActionType.markAsUnread:
|
||||
@@ -1115,9 +1168,8 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
|
||||
void _deleteMultipleEmailsPermanently(List<PresentationEmail> emailList) {
|
||||
cancelSelectEmail();
|
||||
|
||||
final listEmailIds = emailList.map((email) => email.id).toList();
|
||||
cancelSelectEmail();
|
||||
if ( _accountId != null && listEmailIds.isNotEmpty) {
|
||||
consumeState(_deleteMultipleEmailsPermanentlyInteractor.execute(_accountId!, listEmailIds));
|
||||
}
|
||||
@@ -1188,7 +1240,7 @@ class ThreadController extends BaseController {
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role);
|
||||
|
||||
if (kIsWeb) {
|
||||
mailboxDashBoardController.dispatchDashBoardAction(DashBoardAction.compose, arguments: arguments);
|
||||
mailboxDashBoardController.dispatchAction(ComposeEmailAction(arguments: arguments));
|
||||
} else {
|
||||
push(AppRoutes.COMPOSER, arguments: arguments);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.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/presentation/user_setting_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart';
|
||||
@@ -21,7 +19,7 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_ba
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/suggestion_box_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMixin {
|
||||
class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin {
|
||||
|
||||
final _responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
@@ -44,11 +42,6 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (_responsiveUtils.isDesktop(context))
|
||||
Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 32),
|
||||
child: _buildHeader(context)),
|
||||
Obx(() => !controller.isSearchActive() && !_responsiveUtils.isDesktop(context)
|
||||
? _buildAppBarNormal(context)
|
||||
: const SizedBox.shrink()),
|
||||
@@ -92,154 +85,6 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
return Row(children: [
|
||||
Obx(() => !controller.isSelectionEnabled() ? _buildListButtonTopBar(context) : const SizedBox.shrink()),
|
||||
Obx(() => controller.isSelectionEnabled() ? _buildListButtonSelectionForDesktop(context) : const SizedBox.shrink()),
|
||||
const SizedBox(width: 16),
|
||||
Obx(() => !controller.isSearchActive() ? const Spacer() : const SizedBox.shrink()),
|
||||
Expanded(child: _buildSearchInputFormForDesktop(context)),
|
||||
_buildSearchButtonViewForDesktop(context),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: (AvatarBuilder()
|
||||
..text(controller.mailboxDashBoardController.userProfile.value?.getAvatarText() ?? '')
|
||||
..backgroundColor(Colors.white)
|
||||
..textColor(Colors.black)
|
||||
..context(context)
|
||||
..addOnTapAvatarActionWithPositionClick((position) => openUserSettingAction(
|
||||
context,
|
||||
position,
|
||||
popupMenuUserSettingActionTile(context, () => controller.mailboxDashBoardController.logoutAction())))
|
||||
..addBoxShadows([const BoxShadow(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))])
|
||||
..size(48))
|
||||
.build()),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListButtonTopBar(BuildContext context) {
|
||||
return Row(children: [
|
||||
if (!controller.isSearchActive())
|
||||
(ButtonBuilder(_imagePaths.icRefresh)
|
||||
..key(const Key('button_reload_thread'))
|
||||
..decoration(BoxDecoration(borderRadius: BorderRadius.circular(10), color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(EdgeInsets.zero)
|
||||
..size(16)
|
||||
..radiusSplash(10)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 8, vertical: 8))
|
||||
..onPressActionClick(() => controller.refreshAllEmail()))
|
||||
.build(),
|
||||
if (!controller.isSearchActive()) const SizedBox(width: 16),
|
||||
(ButtonBuilder(_imagePaths.icSelectAll)
|
||||
..key(const Key('button_select_all'))
|
||||
..decoration(BoxDecoration(borderRadius: BorderRadius.circular(10), color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..radiusSplash(10)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => controller.setSelectAllEmailAction())
|
||||
..text(AppLocalizations.of(context).select_all, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 16),
|
||||
(ButtonBuilder(_imagePaths.icMarkAllAsRead)
|
||||
..key(const Key('button_mark_all_as_read'))
|
||||
..decoration(BoxDecoration(borderRadius: BorderRadius.circular(10), color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..textStyle(const TextStyle(fontSize: 12, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() {
|
||||
final listEmail = controller.isSearchActive()
|
||||
? controller.emailListSearch.allEmailUnread
|
||||
: controller.emailList.allEmailUnread;
|
||||
|
||||
if (listEmail.isNotEmpty) {
|
||||
controller.markAsReadSelectedMultipleEmail(listEmail);
|
||||
}
|
||||
})
|
||||
..text(AppLocalizations.of(context).mark_all_as_read, isVertical: false))
|
||||
.build(),
|
||||
if (!controller.isSearchActive()) const SizedBox(width: 16),
|
||||
if (!controller.isSearchActive())
|
||||
(ButtonBuilder(_imagePaths.icFilterWeb)
|
||||
..key(const Key('button_filter_messages'))
|
||||
..context(context)
|
||||
..decoration(BoxDecoration(borderRadius: BorderRadius.circular(10), color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 8))
|
||||
..size(16)
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..textStyle(TextStyle(
|
||||
fontSize: 12,
|
||||
color: controller.filterMessageOption.value == FilterMessageOption.all ? AppColor.colorTextButtonHeaderThread : AppColor.colorNameEmail,
|
||||
fontWeight: controller.filterMessageOption.value == FilterMessageOption.all ? FontWeight.normal : FontWeight.w500))
|
||||
..addIconAction(Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: SvgPicture.asset(_imagePaths.icArrowDown, fit: BoxFit.fill)))
|
||||
..addOnPressActionWithPositionClick((position) =>
|
||||
controller.openFilterMessagesForTablet(
|
||||
context,
|
||||
position,
|
||||
_popupMenuEmailActionTile(context, controller.filterMessageOption.value)))
|
||||
..text(controller.filterMessageOption.value == FilterMessageOption.all
|
||||
? AppLocalizations.of(context).filter_messages
|
||||
: controller.filterMessageOption.value.getTitle(context), isVertical: false))
|
||||
.build(),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListButtonSelectionForDesktop(BuildContext context) {
|
||||
return Row(children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icCloseComposer, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).cancel,
|
||||
onTap: () => controller.cancelSelectEmail()),
|
||||
Text(
|
||||
AppLocalizations.of(context).count_email_selected(controller.listEmailSelected.length),
|
||||
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorTextButton),),
|
||||
const SizedBox(width: 30),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(controller.listEmailSelected.isAllEmailRead ? _imagePaths.icUnread : _imagePaths.icRead, fit: BoxFit.fill),
|
||||
tooltip: controller.listEmailSelected.isAllEmailRead ? AppLocalizations.of(context).mark_as_unread : AppLocalizations.of(context).mark_as_read,
|
||||
onTap: () => controller.pressEmailSelectionAction(
|
||||
context,
|
||||
controller.listEmailSelected.isAllEmailRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead,
|
||||
controller.listEmailSelected)),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(controller.listEmailSelected.isAllEmailStarred ? _imagePaths.icUnStar : _imagePaths.icStar, fit: BoxFit.fill),
|
||||
tooltip: controller.listEmailSelected.isAllEmailStarred ? AppLocalizations.of(context).un_star : AppLocalizations.of(context).star,
|
||||
onTap: () => controller.pressEmailSelectionAction(
|
||||
context,
|
||||
controller.listEmailSelected.isAllEmailStarred ? EmailActionType.markAsStarred : EmailActionType.unMarkAsStarred,
|
||||
controller.listEmailSelected)),
|
||||
if (controller.currentMailbox?.isDrafts == false)
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icMove, fit: BoxFit.fill),
|
||||
tooltip: AppLocalizations.of(context).move,
|
||||
onTap: () => controller.pressEmailSelectionAction(context, EmailActionType.moveToMailbox, controller.listEmailSelected)),
|
||||
if (controller.currentMailbox?.isDrafts == false)
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(controller.currentMailbox?.isSpam == true ? _imagePaths.icNotSpam : _imagePaths.icSpam,
|
||||
fit: BoxFit.fill),
|
||||
tooltip: controller.currentMailbox?.isSpam == true ? AppLocalizations.of(context).un_spam : AppLocalizations.of(context).mark_as_spam,
|
||||
onTap: () => controller.currentMailbox?.isSpam == true
|
||||
? controller.pressEmailSelectionAction(context, EmailActionType.unSpam, controller.listEmailSelected)
|
||||
: controller.pressEmailSelectionAction(context, EmailActionType.moveToSpam, controller.listEmailSelected)),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icDelete, fit: BoxFit.fill),
|
||||
tooltip: controller.currentMailbox?.isTrash == true
|
||||
? AppLocalizations.of(context).delete_permanently
|
||||
: AppLocalizations.of(context).move_to_trash,
|
||||
onTap: () => controller.currentMailbox?.isTrash == true
|
||||
? controller.deleteSelectionEmailsPermanently(context, DeleteActionType.multiple, selectedEmails: controller.listEmailSelected)
|
||||
: controller.pressEmailSelectionAction(context, EmailActionType.moveToTrash, controller.listEmailSelected)),
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListButtonSelectionForMobile(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.isSelectionEnabled() && !_responsiveUtils.isDesktop(context) && controller.listEmailSelected.isNotEmpty) {
|
||||
@@ -292,54 +137,6 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchButtonViewForDesktop(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (!controller.isSearchActive() && _responsiveUtils.isDesktop(context)) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: (SearchBarView(_imagePaths)
|
||||
..hintTextSearch(AppLocalizations.of(context).search_emails)
|
||||
..maxSizeWidth(240)
|
||||
..addOnOpenSearchViewAction(() => controller.enableSearch(context)))
|
||||
.build());
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchInputFormForDesktop(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (controller.isSearchActive() && _responsiveUtils.isDesktop(context)) {
|
||||
return _buildSearchFormForDesktop(context);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchFormForDesktop(BuildContext context) {
|
||||
return (SearchAppBarWidget(
|
||||
context,
|
||||
_imagePaths,
|
||||
_responsiveUtils,
|
||||
controller.searchQuery,
|
||||
controller.mailboxDashBoardController.searchFocus,
|
||||
controller.mailboxDashBoardController.searchInputController,
|
||||
suggestionSearch: controller.mailboxDashBoardController.suggestionSearch,)
|
||||
..addDecoration(const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar))
|
||||
..setMargin(const EdgeInsets.only(right: 10))
|
||||
..setHeightSearchBar(45)
|
||||
..setHintText(AppLocalizations.of(context).search_mail)
|
||||
..addOnCancelSearchPressed(() => controller.disableSearch())
|
||||
..addOnClearTextSearchAction(() => controller.mailboxDashBoardController.clearSearchText())
|
||||
..addOnTextChangeSearchAction((query) => controller.mailboxDashBoardController.addSuggestionSearch(query))
|
||||
..addOnSearchTextAction((query) => controller.mailboxDashBoardController.searchEmail(context, query)))
|
||||
.build();
|
||||
}
|
||||
|
||||
Widget _buildSearchForm(BuildContext context) {
|
||||
return (SearchAppBarWidget(
|
||||
context,
|
||||
@@ -366,19 +163,18 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
_responsiveUtils,
|
||||
controller.mailboxDashBoardController.selectedMailbox.value,
|
||||
controller.listEmailSelected,
|
||||
controller.currentSelectMode.value,
|
||||
controller.filterMessageOption.value)
|
||||
controller.mailboxDashBoardController.currentSelectMode.value,
|
||||
controller.mailboxDashBoardController.filterMessageOption.value)
|
||||
..addOpenMailboxMenuActionClick(() => controller.openMailboxLeftMenu())
|
||||
..addOnEditThreadAction(() => controller.enableSelectionEmail())
|
||||
..addOnEmailSelectionAction((actionType, selectionEmail) =>
|
||||
controller.pressEmailSelectionAction(context, actionType, selectionEmail))
|
||||
..addOnFilterEmailAction((filterMessageOption, position) =>
|
||||
_responsiveUtils.isMobileDevice(context)
|
||||
? controller.openFilterMessagesCupertinoActionSheet(
|
||||
? controller.openContextMenuAction(
|
||||
context,
|
||||
_filterMessagesCupertinoActionTile(context, filterMessageOption),
|
||||
cancelButton: _buildCupertinoActionCancelButton(context))
|
||||
: controller.openFilterMessagesForTablet(
|
||||
_filterMessagesCupertinoActionTile(context, filterMessageOption))
|
||||
: controller.openPopupMenuAction(
|
||||
context,
|
||||
position,
|
||||
_popupMenuEmailActionTile(context, filterMessageOption)))
|
||||
@@ -423,15 +219,6 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
];
|
||||
}
|
||||
|
||||
Widget _buildCupertinoActionCancelButton(BuildContext context) {
|
||||
return CupertinoActionSheetAction(
|
||||
child: Text(
|
||||
AppLocalizations.of(context).cancel,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 20, color: AppColor.colorTextButton)),
|
||||
onPressed: () => controller.closeFilterMessageActionSheet(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _filterMessageWithAttachmentsAction(BuildContext context, FilterMessageOption optionCurrent) {
|
||||
return (FilterMessageCupertinoActionSheetActionBuilder(
|
||||
const Key('filter_attachment_action'),
|
||||
@@ -502,36 +289,27 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
(success) {
|
||||
if (controller.isSearchActive()) {
|
||||
return success is SearchingState
|
||||
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: _loadingWidget)
|
||||
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget)
|
||||
: const SizedBox.shrink();
|
||||
} else {
|
||||
return success is LoadingState
|
||||
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: _loadingWidget)
|
||||
? Padding(padding: const EdgeInsets.symmetric(vertical: 16), child: loadingWidget)
|
||||
: const SizedBox.shrink();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Widget get _loadingWidget {
|
||||
return const Center(child: Padding(
|
||||
padding: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: CupertinoActivityIndicator(color: AppColor.colorTextButton))));
|
||||
}
|
||||
|
||||
Widget _buildLoadingViewLoadMore() {
|
||||
return Obx(() => controller.viewState.value.fold(
|
||||
(failure) => const SizedBox.shrink(),
|
||||
(success) {
|
||||
if (controller.isSearchActive()) {
|
||||
return success is SearchingMoreState
|
||||
? Padding(padding: const EdgeInsets.only(bottom: 16), child: _loadingWidget)
|
||||
? Padding(padding: const EdgeInsets.only(bottom: 16), child: loadingWidget)
|
||||
: const SizedBox.shrink();
|
||||
} else {
|
||||
return success is LoadingMoreState
|
||||
? Padding(padding: const EdgeInsets.only(bottom: 16), child: _loadingWidget)
|
||||
? Padding(padding: const EdgeInsets.only(bottom: 16), child: loadingWidget)
|
||||
: const SizedBox.shrink();
|
||||
}
|
||||
}));
|
||||
@@ -566,7 +344,7 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
}
|
||||
|
||||
Widget _buildResultListEmail(BuildContext context, List<PresentationEmail> listPresentationEmail) {
|
||||
if (controller.currentSelectMode.value == SelectMode.INACTIVE) {
|
||||
if (controller.mailboxDashBoardController.currentSelectMode.value == SelectMode.INACTIVE) {
|
||||
return listPresentationEmail.isNotEmpty
|
||||
? RefreshIndicator(
|
||||
color: AppColor.colorTextButton,
|
||||
@@ -608,7 +386,7 @@ class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMi
|
||||
context,
|
||||
listPresentationEmail[index],
|
||||
controller.currentMailbox?.role,
|
||||
controller.currentSelectMode.value,
|
||||
controller.mailboxDashBoardController.currentSelectMode.value,
|
||||
controller.mailboxDashBoardController.searchState.value.searchStatus,
|
||||
controller.searchQuery)
|
||||
..addOnPressEmailActionClick((action, email) => controller.pressEmailAction(context, action, email))
|
||||
|
||||
@@ -98,7 +98,7 @@ class AppBarThreadWidgetBuilder {
|
||||
AppLocalizations.of(_context).count_email_selected(_listSelectionEmail.length),
|
||||
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorTextButton))),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_listSelectionEmail.isAllEmailRead ? _imagePaths.icUnread : _imagePaths.icRead, fit: BoxFit.fill),
|
||||
icon: SvgPicture.asset(_listSelectionEmail.isAllEmailRead ? _imagePaths.icRead : _imagePaths.icUnread, fit: BoxFit.fill),
|
||||
tooltip: _listSelectionEmail.isAllEmailRead ? AppLocalizations.of(_context).unread : AppLocalizations.of(_context).read,
|
||||
onTap: () => _onEmailSelectionAction?.call(
|
||||
_listSelectionEmail.isAllEmailRead ? EmailActionType.markAsUnread : EmailActionType.markAsRead,
|
||||
|
||||
@@ -52,21 +52,31 @@ class EmailTileBuilder {
|
||||
data: ThemeData(splashColor: Colors.transparent, highlightColor: Colors.transparent),
|
||||
child: ResponsiveWidget(
|
||||
responsiveUtils: _responsiveUtils,
|
||||
mobile: _buildListTile(),
|
||||
desktop: Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE ? const EdgeInsets.only(top: 3, left: 8, right: 8) : EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE ? const EdgeInsets.symmetric(vertical: 8) : EdgeInsets.zero,
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: null,
|
||||
child: _buildListTileForDesktop(),
|
||||
),
|
||||
mobile: _wrapContainerForTile(_buildListTile()),
|
||||
desktop: _wrapContainerForTile(_buildListTileForDesktop()),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _wrapContainerForTile(Widget tile) {
|
||||
if (_responsiveUtils.isDesktop(_context)) {
|
||||
return Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE ? EdgeInsets.only(top: 3, left: 8, right: 8) : EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE ? EdgeInsets.symmetric(vertical: 8) : EdgeInsets.zero,
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(borderRadius: BorderRadius.circular(14), color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: null,
|
||||
child: tile);
|
||||
} else {
|
||||
return Container(
|
||||
margin: EdgeInsets.zero,
|
||||
padding: EdgeInsets.only(bottom: 10, left: 16, right: 16),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(0), color: Colors.white),
|
||||
alignment: Alignment.center,
|
||||
child: tile);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildListTile() {
|
||||
return Container(
|
||||
margin: EdgeInsets.zero,
|
||||
|
||||
@@ -51,54 +51,37 @@ class EmailTileBuilder {
|
||||
data: ThemeData(splashColor: Colors.transparent, highlightColor: Colors.transparent),
|
||||
child: ResponsiveWidget(
|
||||
responsiveUtils: _responsiveUtils,
|
||||
mobile: Container(
|
||||
mobile: _wrapContainerForTile(_buildListTile()),
|
||||
tablet: _wrapContainerForTile(_buildListTileTablet()),
|
||||
desktop: _wrapContainerForTile(_buildListTileForDesktop()),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _wrapContainerForTile(Widget tile) {
|
||||
if (_responsiveUtils.isDesktop(_context)) {
|
||||
return Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE ? EdgeInsets.only(top: 3, left: 8, right: 8) : EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE ? EdgeInsets.symmetric(vertical: 8) : EdgeInsets.zero,
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(borderRadius: BorderRadius.circular(14), color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: null,
|
||||
child: tile,
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 3, left: 16, right: 16)
|
||||
? EdgeInsets.only(top: 3, left: 16, right: 16)
|
||||
: EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 8, bottom: 16, right: 8)
|
||||
: const EdgeInsets.only(bottom: 10, left: 16, right: 16),
|
||||
? EdgeInsets.only(top: 8, bottom: 16, right: 8)
|
||||
: EdgeInsets.only(bottom: 10, left: 16, right: 16),
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(borderRadius: BorderRadius.circular(14), color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: BoxDecoration(borderRadius: BorderRadius.circular(0), color: Colors.white),
|
||||
alignment: Alignment.center,
|
||||
child: _buildListTile()),
|
||||
tablet: Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 3, left: 16, right: 16)
|
||||
: EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 8, bottom: 16, right: 8)
|
||||
: const EdgeInsets.only(bottom: 10, left: 16, right: 16),
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(borderRadius: BorderRadius.circular(14), color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: BoxDecoration(borderRadius: BorderRadius.circular(0), color: Colors.white),
|
||||
alignment: Alignment.center,
|
||||
child: _buildListTileTabletLarge()),
|
||||
tabletLarge: Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 3, left: 16, right: 16)
|
||||
: EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE
|
||||
? const EdgeInsets.only(top: 8, bottom: 16, right: 8)
|
||||
: const EdgeInsets.only(bottom: 10, left: 16, right: 16),
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(borderRadius: BorderRadius.circular(14), color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: BoxDecoration(borderRadius: BorderRadius.circular(0), color: Colors.white),
|
||||
alignment: Alignment.center,
|
||||
child: _buildListTileTabletLarge()),
|
||||
desktop: Container(
|
||||
margin: _selectModeAll == SelectMode.ACTIVE ? const EdgeInsets.only(top: 3, left: 8, right: 8) : EdgeInsets.zero,
|
||||
padding: _selectModeAll == SelectMode.ACTIVE ? const EdgeInsets.symmetric(vertical: 8) : EdgeInsets.zero,
|
||||
decoration: _selectModeAll == SelectMode.ACTIVE && _presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
color: AppColor.colorItemEmailSelectedDesktop)
|
||||
: null,
|
||||
child: _buildListTileForDesktop(),
|
||||
),
|
||||
)
|
||||
);
|
||||
child: tile);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildListTile() {
|
||||
@@ -208,7 +191,7 @@ class EmailTileBuilder {
|
||||
]);
|
||||
}
|
||||
|
||||
Widget _buildListTileTabletLarge() {
|
||||
Widget _buildListTileTablet() {
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||
return InkWell(
|
||||
onTap: () => _emailActionClick?.call(EmailActionType.preview, _presentationEmail),
|
||||
@@ -523,11 +506,13 @@ class EmailTileBuilder {
|
||||
TextStyle? textStyle
|
||||
}) {
|
||||
if (_selectModeAll == SelectMode.ACTIVE) {
|
||||
return Tooltip(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(_presentationEmail.selectMode == SelectMode.ACTIVE ? _imagePaths.icSelected : _imagePaths.icUnSelected, fit: BoxFit.fill)),
|
||||
message: AppLocalizations.of(_context).select);
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
_presentationEmail.selectMode == SelectMode.ACTIVE
|
||||
? _imagePaths.icSelected
|
||||
: _imagePaths.icUnSelected,
|
||||
fit: BoxFit.fill));
|
||||
} else {
|
||||
return Container(
|
||||
width: iconSize ?? 48,
|
||||
|
||||
Reference in New Issue
Block a user