TF-381 Apply new UI EmailView for browser

This commit is contained in:
dab246
2022-03-22 13:34:03 +07:00
committed by Dat H. Pham
parent dc35d5e5a0
commit c2f6434686
22 changed files with 300 additions and 256 deletions
@@ -33,7 +33,7 @@ class ResponsiveUtils {
bool isMobile(BuildContext context) => getDeviceWidth(context) < minTabletWidth; bool isMobile(BuildContext context) => getDeviceWidth(context) < minTabletWidth;
bool isTablet(BuildContext context) => getDeviceWidth(context) >= minTabletWidth && getDeviceWidth(context) < minDesktopWidth; bool isTablet(BuildContext context) => getDeviceWidth(context) >= minTabletWidth && getDeviceWidth(context) < minTabletLargeWidth;
bool isDesktop(BuildContext context) => getDeviceWidth(context) >= minDesktopWidth; bool isDesktop(BuildContext context) => getDeviceWidth(context) >= minDesktopWidth;
@@ -105,7 +105,7 @@ class ButtonBuilder {
_onPressActionWithPositionClick?.call(position); _onPressActionWithPositionClick?.call(position);
} }
}, },
borderRadius: BorderRadius.all(Radius.circular(_radiusSplash ?? 0)), borderRadius: BorderRadius.all(Radius.circular(_radiusSplash ?? 20)),
child: Container( child: Container(
key: _key, key: _key,
alignment: Alignment.center, alignment: Alignment.center,
@@ -10,6 +10,7 @@ Widget buildIconWeb({
IconWebCallback? onTap, IconWebCallback? onTap,
EdgeInsets? iconPadding, EdgeInsets? iconPadding,
double? iconSize, double? iconSize,
double? splashRadius,
}) { }) {
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,
@@ -18,7 +19,7 @@ Widget buildIconWeb({
icon: icon, icon: icon,
iconSize: iconSize, iconSize: iconSize,
padding: iconPadding ?? EdgeInsets.all(8.0), padding: iconPadding ?? EdgeInsets.all(8.0),
splashRadius: 20, splashRadius: splashRadius ?? 20,
tooltip: tooltip, tooltip: tooltip,
onPressed: onTap) onPressed: onTap)
); );
@@ -27,9 +28,10 @@ Widget buildIconWeb({
Widget buildIconWebHasPosition(BuildContext context, { Widget buildIconWebHasPosition(BuildContext context, {
required Widget icon, required Widget icon,
String? tooltip, String? tooltip,
IconWebHasPositionCallback? onTap IconWebHasPositionCallback? onTapDown,
IconWebCallback? onTap,
}) { }) {
return GestureDetector( return InkWell(
onTapDown: (detail) { onTapDown: (detail) {
final screenSize = MediaQuery.of(context).size; final screenSize = MediaQuery.of(context).size;
final offset = detail.globalPosition; final offset = detail.globalPosition;
@@ -39,10 +41,12 @@ Widget buildIconWebHasPosition(BuildContext context, {
screenSize.width - offset.dx, screenSize.width - offset.dx,
screenSize.height - offset.dy, screenSize.height - offset.dy,
); );
onTap?.call(position); onTapDown?.call(position);
}, },
onTap: () => onTap?.call(),
borderRadius: BorderRadius.all(Radius.circular(35)),
child: Tooltip( child: Tooltip(
message: tooltip, message: tooltip ?? '',
child: icon, child: icon,
) )
); );
@@ -200,27 +200,18 @@ class DestinationPickerView extends GetWidget<DestinationPickerController> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(14),
color: Colors.white), color: Colors.white),
margin: EdgeInsets.only(left: 16, right: 16, top: _getTopPaddingListMailbox(context, actions)), margin: EdgeInsets.only(left: 16, right: 16, top: 10),
child: _buildDefaultMailbox(context)), child: _buildDefaultMailbox(context)),
SizedBox(height: 20),
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(14),
color: Colors.white), color: Colors.white),
margin: EdgeInsets.only(left: 16, right: 16, top: 4, bottom: 30), margin: EdgeInsets.only(left: 16, right: 16, top: 10, bottom: 20),
child: _buildFolderMailbox(context)), child: _buildFolderMailbox(context)),
] ]
); );
} }
double _getTopPaddingListMailbox(BuildContext context, MailboxActions? actions) {
if (actions == MailboxActions.create) {
return (_responsiveUtils.isMobile(context) || _responsiveUtils.isMobileDevice(context)) ? 20.0 : 5.0;
} else {
return (_responsiveUtils.isMobile(context) || _responsiveUtils.isMobileDevice(context)) ? 16.0 : 10.0;
}
}
Widget _buildDefaultMailbox(BuildContext context) { Widget _buildDefaultMailbox(BuildContext context) {
return Obx(() => controller.defaultMailboxTree.value.root.childrenItems?.isNotEmpty ?? false return Obx(() => controller.defaultMailboxTree.value.root.childrenItems?.isNotEmpty ?? false
? Transform( ? Transform(
@@ -36,7 +36,6 @@ class AppBarDestinationPickerBuilder {
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero), data: MediaQueryData(padding: EdgeInsets.zero),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
_buildBackButton(), _buildBackButton(),
@@ -48,16 +47,27 @@ class AppBarDestinationPickerBuilder {
} }
Widget _buildBackButton() { Widget _buildBackButton() {
return Material( if (_mailboxAction == MailboxActions.create) {
borderRadius: BorderRadius.circular(12), if (_responsiveUtils.isMobile(_context)) {
color: Colors.transparent, return Material(
child: _responsiveUtils.isMobile(_context) color: Colors.transparent,
? IconButton( shape: CircleBorder(),
color: _mailboxAction == MailboxActions.create ? AppColor.colorTextButton : AppColor.baseTextColor, child: IconButton(
icon: _getBackIcon(), splashRadius: 20,
onPressed: () => _onCloseActionClick?.call()) icon: SvgPicture.asset(_imagePaths.icBack, color: AppColor.colorTextButton, fit: BoxFit.fill),
: SizedBox(width: 40, height: 40) onPressed: () => _onCloseActionClick?.call()));
); } else {
return SizedBox(width: 40, height: 40);
}
} else {
return Material(
color: Colors.transparent,
shape: CircleBorder(),
child: IconButton(
splashRadius: 20,
icon: SvgPicture.asset(_imagePaths.icComposerClose, color: AppColor.baseTextColor, fit: BoxFit.fill),
onPressed: () => _onCloseActionClick?.call()));
}
} }
Widget _buildTitle() { Widget _buildTitle() {
@@ -80,12 +90,4 @@ class AppBarDestinationPickerBuilder {
return _responsiveUtils.isMobile(_context) ? TextAlign.start : TextAlign.center; return _responsiveUtils.isMobile(_context) ? TextAlign.start : TextAlign.center;
} }
} }
Widget _getBackIcon() {
if (_mailboxAction == MailboxActions.create) {
return SvgPicture.asset(_imagePaths.icBack, fit: BoxFit.fill);
} else {
return SvgPicture.asset(_imagePaths.icComposerClose, fit: BoxFit.fill);
}
}
} }
+72 -24
View File
@@ -17,10 +17,11 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mai
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_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/email/presentation/widgets/email_content_item_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_item_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_place_holder_loading_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_place_holder_loading_widget.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:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:filesize/filesize.dart'; import 'package:filesize/filesize.dart';
class EmailView extends GetView { class EmailView extends GetView with UserSettingPopupMenuMixin {
final emailController = Get.find<EmailController>(); final emailController = Get.find<EmailController>();
final responsiveUtils = Get.find<ResponsiveUtils>(); final responsiveUtils = Get.find<ResponsiveUtils>();
@@ -31,11 +32,11 @@ class EmailView extends GetView {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white,
body: Container( body: Container(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
decoration: !(responsiveUtils.isMobile(context) && responsiveUtils.isMobileDevice(context)) decoration: responsiveUtils.isTabletLarge(context)
? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0))) ? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0)))
: null, : null,
child: SafeArea( child: SafeArea(
@@ -44,15 +45,12 @@ class EmailView extends GetView {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
_buildAppBar(context), if (responsiveUtils.isDesktop(context))
Obx(() => emailController.currentEmail != null Container(
? _buildDivider() color: Colors.white,
: SizedBox.shrink()), padding: EdgeInsets.only(right: 10, top: 16, bottom: 10),
Expanded(child: _buildEmailBody(context)), child: _buildHeader(context)),
Obx(() => emailController.currentEmail != null Expanded(child: _buildBody(context)),
? Divider(color: AppColor.colorDividerEmailView, height: 1)
: SizedBox.shrink()),
_buildBottomBar(context),
] ]
) )
), ),
@@ -60,6 +58,52 @@ class EmailView extends GetView {
); );
} }
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)
? BoxDecoration(
borderRadius: BorderRadius.circular(20),
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,
child: Column(children: [
_buildAppBar(context),
if (responsiveUtils.isDesktop(context)) SizedBox(height: 5),
Obx(() => emailController.currentEmail != null && !responsiveUtils.isDesktop(context)
? _buildDivider() : SizedBox.shrink()),
Expanded(child: _buildEmailBody(context)),
Obx(() => emailController.currentEmail != null
? Divider(color: AppColor.colorDividerEmailView, height: 1)
: SizedBox.shrink()),
_buildBottomBar(context),
])
);
}
Widget _buildDivider({EdgeInsets? edgeInsets}){ Widget _buildDivider({EdgeInsets? edgeInsets}){
return Padding( return Padding(
padding: edgeInsets ?? EdgeInsets.symmetric(horizontal: 16), padding: edgeInsets ?? EdgeInsets.symmetric(horizontal: 16),
@@ -129,12 +173,15 @@ class EmailView extends GetView {
style: TextStyle(fontSize: 25, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold)); style: TextStyle(fontSize: 25, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold));
} }
Widget _buildEmailSubject() { Widget _buildEmailSubject(BuildContext context) {
return Padding( return Padding(
padding: EdgeInsets.only(right: 16), padding: EdgeInsets.only(right: 16),
child: Text( child: Text(
'${emailController.mailboxDashBoardController.selectedEmail.value?.getEmailTitle()}', '${emailController.mailboxDashBoardController.selectedEmail.value?.getEmailTitle()}',
style: TextStyle(fontSize: 20, color: AppColor.colorNameEmail) style: TextStyle(
fontSize: 20,
color: AppColor.colorNameEmail,
fontWeight: responsiveUtils.isDesktop(context) ? FontWeight.w500 : FontWeight.normal)
)); ));
} }
@@ -153,18 +200,19 @@ class EmailView extends GetView {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Expanded(child: _buildEmailSubject()), Expanded(child: _buildEmailSubject(context)),
_buildEmailTime(context), _buildEmailTime(context),
]), ]),
_buildDivider(edgeInsets: EdgeInsets.only(top: 16)), if (responsiveUtils.isDesktop(context)) SizedBox(height: 20),
if (!responsiveUtils.isDesktop(context)) _buildDivider(edgeInsets: EdgeInsets.only(top: 16)),
Obx(() => emailController.currentEmail != null Obx(() => emailController.currentEmail != null
? _buildEmailAddress( ? _buildEmailAddress(
context, context,
emailController.currentEmail!, emailController.currentEmail!,
emailController.emailAddressExpandMode.value, emailController.emailAddressExpandMode.value,
emailController.isDisplayFullEmailAddress.value) emailController.isDisplayFullEmailAddress.value)
: SizedBox.shrink()), : SizedBox.shrink()),
_buildDivider(edgeInsets: EdgeInsets.only(top: 4)), _buildDivider(edgeInsets: EdgeInsets.only(top: 8)),
_buildAttachments(context), _buildAttachments(context),
_buildListEmailContent(context, constraints), _buildListEmailContent(context, constraints),
], ],
@@ -193,15 +241,15 @@ class EmailView extends GetView {
if (email.from.numberEmailAddress() > 0) if (email.from.numberEmailAddress() > 0)
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.from, isDisplayFull), _buildEmailAddressByPrefix(context, email, PrefixEmailAddress.from, isDisplayFull),
if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND) if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND)
_buildDivider(edgeInsets: EdgeInsets.only(top: 4)), _buildDivider(edgeInsets: EdgeInsets.only(top: 8, bottom: 4)),
if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND) if (email.to.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND)
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.to, isDisplayFull), _buildEmailAddressByPrefix(context, email, PrefixEmailAddress.to, isDisplayFull),
if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull) if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
_buildDivider(edgeInsets: EdgeInsets.only(top: 4)), _buildDivider(edgeInsets: EdgeInsets.only(top: 8, bottom: 4)),
if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull) if (email.cc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.cc, isDisplayFull), _buildEmailAddressByPrefix(context, email, PrefixEmailAddress.cc, isDisplayFull),
if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull) if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
_buildDivider(edgeInsets: EdgeInsets.only(top: 4)), _buildDivider(edgeInsets: EdgeInsets.only(top: 8, bottom: 4)),
if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull) if (email.bcc.numberEmailAddress() > 0 && expandMode == ExpandMode.EXPAND && isDisplayFull)
_buildEmailAddressByPrefix(context, email, PrefixEmailAddress.bcc, isDisplayFull), _buildEmailAddressByPrefix(context, email, PrefixEmailAddress.bcc, isDisplayFull),
], ],
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:model/model.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/app_setting.dart';
import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart'; import 'package:tmail_ui_user/features/setting/presentation/model/reading_pane.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnBackActionClick = void Function(); typedef OnBackActionClick = void Function();
typedef OnEmailActionClick = void Function(PresentationEmail, EmailActionType); typedef OnEmailActionClick = void Function(PresentationEmail, EmailActionType);
@@ -50,7 +51,6 @@ class AppBarMailWidgetBuilder {
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero), data: MediaQueryData(padding: EdgeInsets.zero),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
if (_conditionShow(_context)) if (_conditionShow(_context))
@@ -74,9 +74,10 @@ class AppBarMailWidgetBuilder {
} }
Widget _buildBackButton() { Widget _buildBackButton() {
return IconButton( return buildIconWeb(
icon: SvgPicture.asset(_imagePaths.icBack, width: 20, height: 20, color: AppColor.colorTextButton, fit: BoxFit.fill), icon: SvgPicture.asset(_imagePaths.icBack, width: 18, height: 18, color: AppColor.colorTextButton, fit: BoxFit.fill),
onPressed: () => _onBackActionClick?.call() tooltip: AppLocalizations.of(_context).back,
onTap: () => _onBackActionClick?.call()
); );
} }
@@ -93,71 +94,42 @@ class AppBarMailWidgetBuilder {
Widget _buildListOptionButton() { Widget _buildListOptionButton() {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
IconButton( buildIconWeb(
key: Key('button_move_to_mailbox_email'), icon: SvgPicture.asset(_imagePaths.icMoveEmail, fit: BoxFit.fill),
icon: SvgPicture.asset(_imagePaths.icMoveEmail, color: AppColor.colorButton, fit: BoxFit.fill), tooltip: AppLocalizations.of(_context).move_to_mailbox,
onPressed: () { onTap: () {
if (_presentationEmail != null) { if (_presentationEmail != null) {
_onEmailActionClick?.call(_presentationEmail!, EmailActionType.move); _onEmailActionClick?.call(_presentationEmail!, EmailActionType.move);
} }
}), }),
IconButton( buildIconWeb(
key: Key('button_mark_as_star_email'), icon: SvgPicture.asset((_presentationEmail != null && _presentationEmail!.isFlaggedEmail()) ? _imagePaths.icStar : _imagePaths.icUnStar, fit: BoxFit.fill),
icon: SvgPicture.asset( tooltip: (_presentationEmail != null && _presentationEmail!.isFlaggedEmail())
(_presentationEmail != null && _presentationEmail!.isFlaggedEmail()) ? AppLocalizations.of(_context).mark_as_unstar
? _imagePaths.icStar : AppLocalizations.of(_context).mark_as_star,
: _imagePaths.icUnStar, onTap: () {
fit: BoxFit.fill),
onPressed: () {
if (_presentationEmail != null) { if (_presentationEmail != null) {
_onEmailActionClick?.call(_presentationEmail!, _onEmailActionClick?.call(_presentationEmail!, _presentationEmail!.isFlaggedEmail() ? EmailActionType.markAsUnStar : EmailActionType.markAsStar);
_presentationEmail!.isFlaggedEmail() ? EmailActionType.markAsUnStar : EmailActionType.markAsStar);
} }
}), }),
IconButton( Padding(
key: Key('button_delete_email'), padding: EdgeInsets.only(left: 10, right: 16),
icon: SvgPicture.asset(_imagePaths.icDeleteEmail, color: AppColor.colorButton, fit: BoxFit.fill), child: buildIconWebHasPosition(
onPressed: () { _context,
if (_presentationEmail != null) { tooltip: AppLocalizations.of(_context).more,
_onEmailActionClick?.call(_presentationEmail!, EmailActionType.delete); icon: SvgPicture.asset(_imagePaths.icMore, fit: BoxFit.fill),
} onTap: () {
}), if (_presentationEmail != null && _responsiveUtils.isMobile(_context)) {
_buildMoreButton(), _onMoreActionClick?.call(_presentationEmail!, null);
}
},
onTapDown: (position) {
if (_presentationEmail != null && !_responsiveUtils.isMobile(_context)) {
_onMoreActionClick?.call(_presentationEmail!, position);
}
})),
] ]
); );
} }
Widget _buildMoreButton() {
return Material(
key: Key('button_more_email'),
borderRadius: BorderRadius.circular(12),
color: Colors.transparent,
child: Padding(
padding: EdgeInsets.only(left: 10, right: 16),
child: GestureDetector(
onTap: () {
if (_presentationEmail != null && _responsiveUtils.isMobileDevice(_context)) {
_onMoreActionClick?.call(_presentationEmail!, null);
}
},
child: SvgPicture.asset(_imagePaths.icMore, color: AppColor.colorButton, fit: BoxFit.fill),
onTapDown: (detail) {
if (_presentationEmail != null && !_responsiveUtils.isMobileDevice(_context)) {
final screenSize = MediaQuery.of(_context).size;
final offset = detail.globalPosition;
final position = RelativeRect.fromLTRB(
offset.dx,
offset.dy,
screenSize.width - offset.dx,
screenSize.height - offset.dy,
);
_onMoreActionClick?.call(_presentationEmail!, position);
}
})
)
);
}
} }
@@ -91,22 +91,23 @@ class BottomBarMailWidgetBuilder {
}}) }})
..text(AppLocalizations.of(_context).forward, isVertical: _responsiveUtils.isMobile(_context))) ..text(AppLocalizations.of(_context).forward, isVertical: _responsiveUtils.isMobile(_context)))
.build(), .build(),
(ButtonBuilder(_imagePaths.icNewMessage) if (!_responsiveUtils.isDesktop(_context))
..key(Key('button_new_message')) (ButtonBuilder(_imagePaths.icNewMessage)
..size(20) ..key(Key('button_new_message'))
..paddingIcon(EdgeInsets.only( ..size(20)
top: _responsiveUtils.isMobileDevice(_context) ? 10 : 16, ..paddingIcon(EdgeInsets.only(
bottom: _responsiveUtils.isMobileDevice(_context) ? 8 : 16, top: _responsiveUtils.isMobileDevice(_context) ? 10 : 16,
right: 5)) bottom: _responsiveUtils.isMobileDevice(_context) ? 8 : 16,
..textStyle(TextStyle( right: 5))
fontSize: _responsiveUtils.isMobileDevice(_context) ? 12 : 16, ..textStyle(TextStyle(
color: AppColor.colorTextButton)) fontSize: _responsiveUtils.isMobileDevice(_context) ? 12 : 16,
..onPressActionClick(() { color: AppColor.colorTextButton))
if (_onPressEmailActionClick != null) { ..onPressActionClick(() {
_onPressEmailActionClick!(EmailActionType.compose); if (_onPressEmailActionClick != null) {
}}) _onPressEmailActionClick!(EmailActionType.compose);
..text(AppLocalizations.of(_context).new_message, isVertical: _responsiveUtils.isMobile(_context))) }})
.build() ..text(AppLocalizations.of(_context).new_message, isVertical: _responsiveUtils.isMobile(_context)))
.build()
] ]
); );
} }
@@ -54,10 +54,10 @@ class EmailContentItemBuilder {
} }
case EmailContentType.textPlain: case EmailContentType.textPlain:
return Padding( return Padding(
padding: EdgeInsets.zero, padding: EdgeInsets.only(top: 20),
child: Text( child: Text(
_emailContent.content, _emailContent.content,
style: TextStyle(fontSize: 14, color: AppColor.colorNameEmail))); style: TextStyle(fontSize: 14, color: AppColor.colorNameEmail, fontWeight: FontWeight.normal)));
case EmailContentType.other: case EmailContentType.other:
return SizedBox.shrink(); return SizedBox.shrink();
} }
@@ -2,11 +2,9 @@ import 'package:core/core.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/caching/state_cache_client.dart'; import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart'; import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart';
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart';
@@ -44,7 +42,6 @@ class MailboxBindings extends BaseBindings {
void bindingsController() { void bindingsController() {
Get.put(MailboxController( Get.put(MailboxController(
Get.find<GetAllMailboxInteractor>(), Get.find<GetAllMailboxInteractor>(),
Get.find<DeleteCredentialInteractor>(),
Get.find<RefreshAllMailboxInteractor>(), Get.find<RefreshAllMailboxInteractor>(),
Get.find<CreateNewMailboxInteractor>(), Get.find<CreateNewMailboxInteractor>(),
Get.find<SearchMailboxInteractor>(), Get.find<SearchMailboxInteractor>(),
@@ -56,7 +53,6 @@ class MailboxBindings extends BaseBindings {
Get.find<AppToast>(), Get.find<AppToast>(),
Get.find<ImagePaths>(), Get.find<ImagePaths>(),
Get.find<ResponsiveUtils>(), Get.find<ResponsiveUtils>(),
Get.find<CachingManager>(),
)); ));
} }
@@ -75,7 +71,6 @@ class MailboxBindings extends BaseBindings {
@override @override
void bindingsInteractor() { void bindingsInteractor() {
Get.lazyPut(() => DeleteCredentialInteractor(Get.find<CredentialRepository>()));
Get.lazyPut(() => GetAllMailboxInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => GetAllMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => RefreshAllMailboxInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => RefreshAllMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => CreateNewMailboxInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => CreateNewMailboxInteractor(Get.find<MailboxRepository>()));
@@ -12,12 +12,10 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:rxdart/transformers.dart'; import 'package:rxdart/transformers.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart'; import 'package:tmail_ui_user/features/base/base_mailbox_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'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_state.dart';
@@ -59,7 +57,6 @@ class MailboxController extends BaseMailboxController {
final mailboxDashBoardController = Get.find<MailboxDashBoardController>(); final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
final GetAllMailboxInteractor _getAllMailboxInteractor; final GetAllMailboxInteractor _getAllMailboxInteractor;
final DeleteCredentialInteractor _deleteCredentialInteractor;
final RefreshAllMailboxInteractor _refreshAllMailboxInteractor; final RefreshAllMailboxInteractor _refreshAllMailboxInteractor;
final CreateNewMailboxInteractor _createNewMailboxInteractor; final CreateNewMailboxInteractor _createNewMailboxInteractor;
final SearchMailboxInteractor _searchMailboxInteractor; final SearchMailboxInteractor _searchMailboxInteractor;
@@ -70,7 +67,6 @@ class MailboxController extends BaseMailboxController {
final AppToast _appToast; final AppToast _appToast;
final ImagePaths _imagePaths; final ImagePaths _imagePaths;
final ResponsiveUtils responsiveUtils; final ResponsiveUtils responsiveUtils;
final CachingManager _cachingManager;
final listMailboxSearched = <PresentationMailbox>[].obs; final listMailboxSearched = <PresentationMailbox>[].obs;
final searchState = SearchState.initial().obs; final searchState = SearchState.initial().obs;
@@ -87,7 +83,6 @@ class MailboxController extends BaseMailboxController {
MailboxController( MailboxController(
this._getAllMailboxInteractor, this._getAllMailboxInteractor,
this._deleteCredentialInteractor,
this._refreshAllMailboxInteractor, this._refreshAllMailboxInteractor,
this._createNewMailboxInteractor, this._createNewMailboxInteractor,
this._searchMailboxInteractor, this._searchMailboxInteractor,
@@ -99,7 +94,6 @@ class MailboxController extends BaseMailboxController {
this._appToast, this._appToast,
this._imagePaths, this._imagePaths,
this.responsiveUtils, this.responsiveUtils,
this._cachingManager,
) : super(treeBuilder); ) : super(treeBuilder);
@override @override
@@ -283,14 +277,6 @@ class MailboxController extends BaseMailboxController {
_openMailboxEventController.add(OpenMailboxViewEvent(context, presentationMailboxSelected)); _openMailboxEventController.add(OpenMailboxViewEvent(context, presentationMailboxSelected));
} }
void _deleteCredential() async {
await _deleteCredentialInteractor.execute();
}
void _clearAllCache() async {
await _cachingManager.clearAll();
}
void goToCreateNewMailboxView() async { void goToCreateNewMailboxView() async {
final accountId = mailboxDashBoardController.accountId.value; final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null) { if (accountId != null) {
@@ -612,12 +598,6 @@ class MailboxController extends BaseMailboxController {
mailboxDashBoardController.closeDrawer(); mailboxDashBoardController.closeDrawer();
} }
void logoutAction() {
_deleteCredential();
_clearAllCache();
pushAndPopAll(AppRoutes.LOGIN);
}
@override @override
void dispose() { void dispose() {
_openMailboxEventController.close(); _openMailboxEventController.close();
@@ -198,7 +198,7 @@ class MailboxView extends GetWidget<MailboxController> {
_imagePaths, _imagePaths,
context, context,
controller.mailboxDashBoardController.userProfile.value) controller.mailboxDashBoardController.userProfile.value)
..addOnLogoutAction(() => controller.logoutAction())) ..addOnLogoutAction(() => controller.mailboxDashBoardController.logoutAction()))
.build())); .build()));
} }
@@ -71,15 +71,14 @@ class MailBoxFolderTileBuilder {
trailing: _mailboxNode.hasChildren() trailing: _mailboxNode.hasChildren()
? Padding( ? Padding(
padding: EdgeInsets.only(right: 0, left: 16), padding: EdgeInsets.only(right: 0, left: 16),
child: IconButton( child: buildIconWeb(
padding: EdgeInsets.zero,
color: AppColor.primaryColor,
icon: SvgPicture.asset( icon: SvgPicture.asset(
_mailboxNode.expandMode == ExpandMode.EXPAND ? _imagePaths.icExpandFolder : _imagePaths.icFolderArrow, _mailboxNode.expandMode == ExpandMode.EXPAND ? _imagePaths.icExpandFolder : _imagePaths.icFolderArrow,
color: AppColor.colorArrowUserMailbox, color: AppColor.colorArrowUserMailbox,
fit: BoxFit.fill), fit: BoxFit.fill),
onPressed: () => _onExpandFolderActionClick?.call(_mailboxNode) splashRadius: 15,
)) tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND ? AppLocalizations.of(_context).collapse : AppLocalizations.of(_context).expand,
onTap: () => _onExpandFolderActionClick?.call(_mailboxNode)))
: null : null
), ),
Padding( Padding(
@@ -9,12 +9,14 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.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'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; 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/get_user_profile_interactor.dart';
@@ -35,6 +37,8 @@ class MailboxDashBoardController extends ReloadableController {
final AppToast _appToast = Get.find<AppToast>(); final AppToast _appToast = Get.find<AppToast>();
final ImagePaths _imagePaths = Get.find<ImagePaths>(); final ImagePaths _imagePaths = Get.find<ImagePaths>();
final RemoveEmailDraftsInteractor _removeEmailDraftsInteractor = Get.find<RemoveEmailDraftsInteractor>(); final RemoveEmailDraftsInteractor _removeEmailDraftsInteractor = Get.find<RemoveEmailDraftsInteractor>();
final DeleteCredentialInteractor _deleteCredentialInteractor = Get.find<DeleteCredentialInteractor>();
final CachingManager _cachingManager = Get.find<CachingManager>();
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
final selectedMailbox = Rxn<PresentationMailbox>(); final selectedMailbox = Rxn<PresentationMailbox>();
@@ -179,6 +183,8 @@ class MailboxDashBoardController extends ReloadableController {
scaffoldKey.currentState?.openEndDrawer(); scaffoldKey.currentState?.openEndDrawer();
} }
bool get isDrawerOpen => scaffoldKey.currentState?.isDrawerOpen == true;
bool isSearchActive() { bool isSearchActive() {
return searchState.value.searchStatus == SearchStatus.ACTIVE; return searchState.value.searchStatus == SearchStatus.ACTIVE;
} }
@@ -273,6 +279,20 @@ class MailboxDashBoardController extends ReloadableController {
} }
} }
void _deleteCredential() async {
await _deleteCredentialInteractor.execute();
}
void _clearAllCache() async {
await _cachingManager.clearAll();
}
void logoutAction() {
_deleteCredential();
if (!kIsWeb) _clearAllCache();
pushAndPopAll(AppRoutes.LOGIN);
}
@override @override
void onClose() { void onClose() {
searchInputController.dispose(); searchInputController.dispose();
@@ -22,32 +22,18 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> {
key: controller.scaffoldKey, key: controller.scaffoldKey,
drawer: ResponsiveWidget( drawer: ResponsiveWidget(
responsiveUtils: _responsiveUtils, responsiveUtils: _responsiveUtils,
mobile: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context)), mobile: Container(child: MailboxView(),
width: _responsiveUtils.isPortrait(context) ? _responsiveUtils.getSizeScreenWidth(context) : _responsiveUtils.getSizeScreenWidth(context) / 2),
tablet: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context) / 2), tablet: Container(child: MailboxView(), width: _responsiveUtils.getSizeScreenWidth(context) / 2),
tabletLarge: SizedBox.shrink(),
desktop: SizedBox.shrink() desktop: SizedBox.shrink()
), ),
drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context), drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context),
body: Stack(children: [ body: Stack(children: [
ResponsiveWidget( ResponsiveWidget(
responsiveUtils: _responsiveUtils, responsiveUtils: _responsiveUtils,
desktop: Container( desktop: _buildDesktopView(context),
child: Row( tabletLarge: _buildTabletLargeView(context),
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(flex: 1, child: MailboxView()),
Expanded(flex: 3, child: _buildThreadAndEmailContainer(context)),
],
),
),
tabletLarge: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(flex: 2, child: MailboxView()),
Expanded(flex: 4, child: _buildThreadAndEmailContainer(context)),
],
),
),
tablet: ThreadView(), tablet: ThreadView(),
mobile: ThreadView() mobile: ThreadView()
), ),
@@ -93,4 +79,40 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> {
return SizedBox.shrink(); return SizedBox.shrink();
} }
} }
Widget _buildDesktopView(BuildContext context) {
if (controller.isDrawerOpen && _responsiveUtils.isDesktop(context)) {
WidgetsBinding.instance?.addPostFrameCallback((_) {
controller.closeDrawer();
});
}
return Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(flex: 1, child: MailboxView()),
Expanded(flex: 3, child: _buildThreadAndEmailContainer(context)),
],
),
);
}
Widget _buildTabletLargeView(BuildContext context) {
if (controller.isDrawerOpen && _responsiveUtils.isTabletLarge(context)) {
WidgetsBinding.instance?.addPostFrameCallback((_) {
controller.closeDrawer();
});
}
return Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(flex: 2, child: MailboxView()),
Expanded(flex: 4, child: _buildThreadAndEmailContainer(context)),
],
),
);
}
} }
@@ -0,0 +1,37 @@
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 ?? 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: EdgeInsets.symmetric(horizontal: 8), child: logoutAction(context, onCallBack)),
];
}
Widget logoutAction(BuildContext context, Function? onCallBack) {
return (AppActionSheetActionBuilder(
Key('logout_action'),
SvgPicture.asset(_imagePaths.icCloseMailbox, color: AppColor.colorTextButton, fit: BoxFit.fill),
AppLocalizations.of(context).logout,
iconLeftPadding:EdgeInsets.only(right: 12))
..onActionClick((option) => onCallBack?.call()))
.build();
}
}
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
@@ -40,7 +41,7 @@ class SessionController extends GetxController {
void _goToLogin() { void _goToLogin() {
_deleteCredential(); _deleteCredential();
_clearAllCache(); if (!kIsWeb) _clearAllCache();
pushAndPop(AppRoutes.LOGIN); pushAndPop(AppRoutes.LOGIN);
} }
@@ -1,8 +1,6 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart'; import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/caching/state_cache_client.dart'; import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart'; import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
@@ -15,9 +13,6 @@ import 'package:tmail_ui_user/features/email/domain/repository/email_repository.
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart';
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart';
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
@@ -58,8 +53,6 @@ class ThreadBindings extends BaseBindings {
Get.find<LoadMoreEmailsInMailboxInteractor>(), Get.find<LoadMoreEmailsInMailboxInteractor>(),
Get.find<SearchEmailInteractor>(), Get.find<SearchEmailInteractor>(),
Get.find<SearchMoreEmailInteractor>(), Get.find<SearchMoreEmailInteractor>(),
Get.find<DeleteCredentialInteractor>(),
Get.find<CachingManager>(),
)); ));
} }
@@ -97,19 +90,16 @@ class ThreadBindings extends BaseBindings {
Get.lazyPut(() => LoadMoreEmailsInMailboxInteractor(Get.find<ThreadRepository>())); Get.lazyPut(() => LoadMoreEmailsInMailboxInteractor(Get.find<ThreadRepository>()));
Get.lazyPut(() => SearchEmailInteractor(Get.find<ThreadRepository>())); Get.lazyPut(() => SearchEmailInteractor(Get.find<ThreadRepository>()));
Get.lazyPut(() => SearchMoreEmailInteractor(Get.find<ThreadRepository>())); Get.lazyPut(() => SearchMoreEmailInteractor(Get.find<ThreadRepository>()));
Get.lazyPut(() => DeleteCredentialInteractor(Get.find<CredentialRepository>()));
} }
@override @override
void bindingsRepository() { void bindingsRepository() {
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
Get.lazyPut<ThreadRepository>(() => Get.find<ThreadRepositoryImpl>()); Get.lazyPut<ThreadRepository>(() => Get.find<ThreadRepositoryImpl>());
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>()); Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
} }
@override @override
void bindingsRepositoryImpl() { void bindingsRepositoryImpl() {
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
Get.lazyPut(() => ThreadRepositoryImpl( Get.lazyPut(() => ThreadRepositoryImpl(
{ {
DataSourceType.network: Get.find<ThreadDataSource>(), DataSourceType.network: Get.find<ThreadDataSource>(),
@@ -15,7 +15,6 @@ import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/base_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'; import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart'; import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
@@ -26,7 +25,6 @@ import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_sta
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.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/domain/state/remove_email_drafts_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
@@ -72,8 +70,6 @@ class ThreadController extends BaseController {
final LoadMoreEmailsInMailboxInteractor _loadMoreEmailsInMailboxInteractor; final LoadMoreEmailsInMailboxInteractor _loadMoreEmailsInMailboxInteractor;
final SearchEmailInteractor _searchEmailInteractor; final SearchEmailInteractor _searchEmailInteractor;
final SearchMoreEmailInteractor _searchMoreEmailInteractor; final SearchMoreEmailInteractor _searchMoreEmailInteractor;
final DeleteCredentialInteractor _deleteCredentialInteractor;
final CachingManager _cachingManager;
final emailList = <PresentationEmail>[].obs; final emailList = <PresentationEmail>[].obs;
final emailListSearch = <PresentationEmail>[].obs; final emailListSearch = <PresentationEmail>[].obs;
@@ -107,8 +103,6 @@ class ThreadController extends BaseController {
this._loadMoreEmailsInMailboxInteractor, this._loadMoreEmailsInMailboxInteractor,
this._searchEmailInteractor, this._searchEmailInteractor,
this._searchMoreEmailInteractor, this._searchMoreEmailInteractor,
this._deleteCredentialInteractor,
this._cachingManager,
); );
@override @override
@@ -752,30 +746,6 @@ class ThreadController extends BaseController {
} }
} }
void openUserSettingAction(BuildContext context, RelativeRect? position, List<PopupMenuEntry> popupMenuItems) async {
await showMenu(
context: context,
position: position ?? RelativeRect.fromLTRB(16, 40, 16, 16),
color: Colors.white,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
items: popupMenuItems);
}
void _deleteCredential() async {
await _deleteCredentialInteractor.execute();
}
void _clearAllCache() async {
await _cachingManager.clearAll();
}
void logoutAction() {
_deleteCredential();
_clearAllCache();
pushAndPopAll(AppRoutes.LOGIN);
}
void composeEmailAction() { void composeEmailAction() {
mailboxDashBoardController.composeEmailAction(); mailboxDashBoardController.composeEmailAction();
} }
@@ -4,11 +4,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:model/model.dart'; import 'package:model/model.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_email_state.dart';
import 'package:tmail_ui_user/features/thread/domain/state/search_more_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/extensions/filter_message_option_extension.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart'; import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_action_sheet_action_builder.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart';
@@ -17,7 +17,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/features/thread/presentation/widgets/suggestion_box_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class ThreadView extends GetWidget<ThreadController> { class ThreadView extends GetWidget<ThreadController> with UserSettingPopupMenuMixin {
final _responsiveUtils = Get.find<ResponsiveUtils>(); final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>(); final _imagePaths = Get.find<ImagePaths>();
@@ -92,8 +92,10 @@ class ThreadView extends GetWidget<ThreadController> {
..backgroundColor(Colors.white) ..backgroundColor(Colors.white)
..textColor(Colors.black) ..textColor(Colors.black)
..context(context) ..context(context)
..addOnTapAvatarActionWithPositionClick((position) => ..addOnTapAvatarActionWithPositionClick((position) => openUserSettingAction(
controller.openUserSettingAction(context, position, _popupMenuUserSettingActionTile(context))) context,
position,
popupMenuUserSettingActionTile(context, () => controller.mailboxDashBoardController.logoutAction())))
..addBoxShadows([BoxShadow( ..addBoxShadows([BoxShadow(
color: AppColor.colorShadowBgContentEmail, color: AppColor.colorShadowBgContentEmail,
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))]) spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))])
@@ -631,20 +633,4 @@ class ThreadView extends GetWidget<ThreadController> {
} }
}); });
} }
List<PopupMenuEntry> _popupMenuUserSettingActionTile(BuildContext context) {
return [
PopupMenuItem(padding: EdgeInsets.symmetric(horizontal: 8), child: _logoutAction(context)),
];
}
Widget _logoutAction(BuildContext context) {
return (AppActionSheetActionBuilder(
Key('logout_action'),
SvgPicture.asset(_imagePaths.icCloseMailbox, color: AppColor.colorTextButton, fit: BoxFit.fill),
AppLocalizations.of(context).logout,
iconLeftPadding:EdgeInsets.only(right: 12))
..onActionClick((option) => controller.logoutAction()))
.build();
}
} }
@@ -178,9 +178,9 @@ class AppBarThreadWidgetBuilder {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
GestureDetector( GestureDetector(
onTap: () => !_responsiveUtils.isDesktop(_context) ? _onOpenListMailboxActionClick?.call() : null, onTap: () => !_responsiveUtils.isTabletLarge(_context) ? _onOpenListMailboxActionClick?.call() : null,
child: Padding( child: Padding(
padding: !_responsiveUtils.isDesktop(_context) ? EdgeInsets.zero : EdgeInsets.only(bottom: 8, top: 8), padding: !_responsiveUtils.isTabletLarge(_context) ? EdgeInsets.zero : EdgeInsets.only(bottom: 8, top: 8),
child: Container( child: Container(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
@@ -191,14 +191,14 @@ class AppBarThreadWidgetBuilder {
overflow: GetPlatform.isWeb ? TextOverflow.clip : TextOverflow.ellipsis, overflow: GetPlatform.isWeb ? TextOverflow.clip : TextOverflow.ellipsis,
style: TextStyle(fontSize: 21, color: AppColor.colorNameEmail, fontWeight: FontWeight.w700)) style: TextStyle(fontSize: 21, color: AppColor.colorNameEmail, fontWeight: FontWeight.w700))
))), ))),
if (!_responsiveUtils.isDesktop(_context)) if (!_responsiveUtils.isTabletLarge(_context))
Transform( Transform(
transform: Matrix4.translationValues(-8.0, 0.0, 0.0), transform: Matrix4.translationValues(-8.0, 0.0, 0.0),
child: IconButton( child: IconButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
color: AppColor.baseTextColor, color: AppColor.baseTextColor,
icon: SvgPicture.asset(_imagePaths.icChevronDown, width: 20, height: 16, fit: BoxFit.fill), icon: SvgPicture.asset(_imagePaths.icChevronDown, width: 20, height: 16, fit: BoxFit.fill),
onPressed: () => !_responsiveUtils.isDesktop(_context) ? _onOpenListMailboxActionClick?.call() : null)) onPressed: () => !_responsiveUtils.isTabletLarge(_context) ? _onOpenListMailboxActionClick?.call() : null))
] ]
); );
} }
@@ -208,9 +208,9 @@ class AppBarThreadWidgetBuilder {
var widthSiblingsWidget = 220; var widthSiblingsWidget = 220;
if (_responsiveUtils.isTablet(_context)) { if (_responsiveUtils.isTablet(_context)) {
width = width * 0.7; width = width * 0.7;
widthSiblingsWidget = 300; widthSiblingsWidget = 250;
} else if (_responsiveUtils.isTabletLarge(_context)) { } else if (_responsiveUtils.isTabletLarge(_context)) {
width = width * 0.35; width = width * 0.6;
widthSiblingsWidget = 250; widthSiblingsWidget = 250;
} else if (_responsiveUtils.isDesktop(_context)) { } else if (_responsiveUtils.isDesktop(_context)) {
width = width * 0.25; width = width * 0.25;
@@ -862,4 +862,30 @@ class AppLocalizations {
name: 'select', name: 'select',
); );
} }
String get more {
return Intl.message(
'More',
name: 'more',
);
}
String get back {
return Intl.message(
'Back',
name: 'back',
);
}
String get expand {
return Intl.message(
'Expand',
name: 'expand');
}
String get collapse {
return Intl.message(
'Collapse',
name: 'collapse');
}
} }