TF-1414: [Presentation] Create new UI and implement get AllMailBox and Subscribe Mailbox

This commit is contained in:
HuyNguyen
2023-02-11 19:19:02 +07:00
committed by Dat Vu
parent c93dbda2bb
commit 34fedb9e3f
17 changed files with 836 additions and 7 deletions
+5
View File
@@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/c
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/tmail_autocomplete_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forwarding_interactors_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_interactor_bindings.dart';
import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart';
import 'package:tmail_ui_user/features/push_notification/presentation/config/fcm_configuration.dart';
@@ -163,6 +164,10 @@ abstract class BaseController extends GetxController
}
}
void injectMailboxVisibilityBindings() {
MailboxVisibilityInteractorBindings().dependencies();
}
void injectFCMBindings(Session? session, AccountId? accountId) async {
try {
requireCapability(session!, accountId!, [FirebaseCapability.fcmIdentifier]);
@@ -0,0 +1,20 @@
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart';
class MailboxVisibilityBindings extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => MailboxVisibilityController(
Get.find<TreeBuilder>(),
Get.find<VerifyNameInteractor>()
));
_bindingsUtils();
}
void _bindingsUtils() {
Get.lazyPut(() => TreeBuilder());
}
}
@@ -0,0 +1,63 @@
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/interactors_bindings.dart';
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart';
import 'package:tmail_ui_user/features/caching/state_cache_client.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_impl/mailbox_cache_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart';
import 'package:tmail_ui_user/features/mailbox/data/repository/mailbox_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:core/data/model/source_type/data_source_type.dart';
class MailboxVisibilityInteractorBindings extends InteractorsBindings {
@override
void bindingsDataSource() {
Get.lazyPut<MailboxDataSource>(() => Get.find<MailboxDataSourceImpl>());
Get.lazyPut<StateDataSource>(() => Get.find<StateDataSourceImpl>());
}
@override
void bindingsDataSourceImpl() {
Get.lazyPut(() => MailboxDataSourceImpl(
Get.find<MailboxAPI>(),
Get.find<MailboxIsolateWorker>(),
Get.find<RemoteExceptionThrower>()));
Get.lazyPut(() => MailboxCacheDataSourceImpl(
Get.find<MailboxCacheManager>(),
Get.find<CacheExceptionThrower>()));
Get.lazyPut(() => StateDataSourceImpl(Get.find<StateCacheClient>(), Get.find<CacheExceptionThrower>()));
}
@override
void bindingsInteractor() {
Get.lazyPut(() => GetAllMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => RefreshAllMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubscribeMailboxInteractor(Get.find<MailboxRepository>()));
}
@override
void bindingsRepository() {
Get.lazyPut<MailboxRepository>(() => Get.find<MailboxRepositoryImpl>());
}
@override
void bindingsRepositoryImpl() {
Get.lazyPut(() => MailboxRepositoryImpl(
{
DataSourceType.network: Get.find<MailboxDataSource>(),
DataSourceType.local: Get.find<MailboxCacheDataSourceImpl>()
},
Get.find<StateDataSource>(),
));
}
}
@@ -0,0 +1,197 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/subscribe_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories_expand_mode.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class MailboxVisibilityController extends BaseMailboxController {
GetAllMailboxInteractor? _getAllMailboxInteractor;
RefreshAllMailboxInteractor? _refreshAllMailboxInteractor;
SubscribeMailboxInteractor? _subscribeMailboxInteractor;
final _accountDashBoardController = Get.find<ManageAccountDashBoardController>();
final _appToast = Get.find<AppToast>();
final _imagePaths = Get.find<ImagePaths>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
final mailboxCategoriesExpandMode = MailboxCategoriesExpandMode.initial().obs;
final mailboxListScrollController = ScrollController();
Map<Role, MailboxId> mapDefaultMailboxIdByRole = {};
Map<MailboxId, PresentationMailbox> mapMailboxById = {};
PresentationMailbox? outboxMailbox;
jmap.State? _currentMailboxState;
MailboxVisibilityController(
TreeBuilder treeBuilder,
VerifyNameInteractor verifyNameInteractor,
) : super(treeBuilder, verifyNameInteractor);
@override
void onInit() {
super.onInit();
try {
_getAllMailboxInteractor = Get.find<GetAllMailboxInteractor>();
_refreshAllMailboxInteractor = Get.find<RefreshAllMailboxInteractor>();
_subscribeMailboxInteractor = Get.find<SubscribeMailboxInteractor>();
} catch (e) {
logError('MailboxVisibilityController::onInit(): ${e.toString()}');
}
}
@override
void onDone() {
viewState.value.fold((failure) {}, (success) {
if (success is GetAllMailboxSuccess) {
_currentMailboxState = success.currentMailboxState;
_buildMailboxTreeHasSubscribed(success.mailboxList);
} else if (success is RefreshChangesAllMailboxSuccess) {
_currentMailboxState = success.currentMailboxState;
_refreshMailboxTreeHasSubscribed(success.mailboxList);
} else if (success is SubscribeMailboxSuccess) {
_subscribeMailboxSuccess(success);
}
});
}
@override
void onReady() {
final _session = _accountDashBoardController.sessionCurrent.value;
final _accountId = _accountDashBoardController.accountId.value;
if(_session != null && _accountId != null) {
getAllMailboxAction(_session, _accountId);
}
super.onReady();
}
void getAllMailboxAction(Session session, AccountId accountId) async {
if(_getAllMailboxInteractor != null){
consumeState(_getAllMailboxInteractor!.execute(session, accountId));
}
}
void refreshMailboxChanges({jmap.State? currentMailboxState}) {
log('MailboxVisibilityController::refreshMailboxChanges(): currentMailboxState: $currentMailboxState');
final newMailboxState = currentMailboxState ?? _currentMailboxState;
log('MailboxVisibilityController::refreshMailboxChanges(): newMailboxState: $newMailboxState');
final session = _accountDashBoardController.sessionCurrent.value;
final accountId = _accountDashBoardController.accountId.value;
if (accountId != null && session != null && newMailboxState != null) {
consumeState(_refreshAllMailboxInteractor!.execute(session, accountId, newMailboxState));
}
}
void _buildMailboxTreeHasSubscribed(List<PresentationMailbox> mailboxList) async {
final _mailboxList = mailboxList;
await buildTree(_mailboxList);
}
void _refreshMailboxTreeHasSubscribed(List<PresentationMailbox> mailboxList) async {
final _mailboxList = mailboxList;
await refreshTree(_mailboxList);
}
void subscribeMailbox(MailboxNode mailboxNode) {
final _mailboxSubscribeState = mailboxNode.item.isSubscribedMailbox
? MailboxSubscribeState.disabled : MailboxSubscribeState.enabled;
final _mailboxSubscribeStateAction = mailboxNode.item.isSubscribedMailbox
? MailboxSubscribeAction.unSubscribe : MailboxSubscribeAction.subscribe;
if (mailboxNode.item.isSubscribedMailbox) {
_subscribeMailboxAction(
SubscribeMailboxRequest(
mailboxNode.item.id,
_mailboxSubscribeState,
_mailboxSubscribeStateAction,
)
);
}
}
void _subscribeMailboxAction(SubscribeMailboxRequest subscribeMailboxRequest) {
final _accountId = _accountDashBoardController.accountId.value;
if (_accountId != null) {
consumeState(_subscribeMailboxInteractor!.execute(_accountId, subscribeMailboxRequest));
}
}
void toggleMailboxCategories(MailboxCategories categories) {
switch(categories) {
case MailboxCategories.exchange:
final newExpandMode = mailboxCategoriesExpandMode.value.defaultMailbox == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
mailboxCategoriesExpandMode.value.defaultMailbox = newExpandMode;
mailboxCategoriesExpandMode.refresh();
break;
case MailboxCategories.personalMailboxes:
final newExpandMode = mailboxCategoriesExpandMode.value.personalMailboxes == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
mailboxCategoriesExpandMode.value.personalMailboxes = newExpandMode;
mailboxCategoriesExpandMode.refresh();
break;
case MailboxCategories.teamMailboxes:
final newExpandMode = mailboxCategoriesExpandMode.value.teamMailboxes == ExpandMode.EXPAND ? ExpandMode.COLLAPSE : ExpandMode.EXPAND;
mailboxCategoriesExpandMode.value.teamMailboxes = newExpandMode;
mailboxCategoriesExpandMode.refresh();
break;
case MailboxCategories.appGrid:
break;
}
}
void _subscribeMailboxSuccess(SubscribeMailboxSuccess subscribeMailboxSuccess) {
if (subscribeMailboxSuccess.subscribeAction == MailboxSubscribeAction.unSubscribe
&& currentOverlayContext != null
&& currentContext != null) {
_appToast.showBottomToast(
currentOverlayContext!,
AppLocalizations.of(currentContext!).toastMsgHideMailboxSuccess,
actionName: AppLocalizations.of(currentContext!).undo,
onActionClick: () {
_subscribeMailboxAction(
SubscribeMailboxRequest(
subscribeMailboxSuccess.mailboxId,
MailboxSubscribeState.enabled,
MailboxSubscribeAction.undo)
);
},
leadingIcon: SvgPicture.asset(
_imagePaths.icFolderMailbox,
width: 24,
height: 24,
color: Colors.white,
fit: BoxFit.fill),
backgroundColor: AppColor.toastSuccessBackgroundColor,
textColor: Colors.white,
textActionColor: Colors.white,
actionIcon: SvgPicture.asset(_imagePaths.icUndo),
maxWidth: _responsiveUtils.getMaxWidthToast(currentContext!));
}
refreshMailboxChanges(currentMailboxState: subscribeMailboxSuccess.currentMailboxState);
}
}
@@ -0,0 +1,196 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/list/tree_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_categories.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_folder_tile_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/widgets/mailbox_visibility_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class MailboxVisibilityView extends GetWidget<MailboxVisibilityController> with AppLoaderMixin {
final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>();
MailboxVisibilityView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: _responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: Container(
width: double.infinity,
margin: _responsiveUtils.isWebDesktop(context)
? const EdgeInsets.all(24)
: EdgeInsets.symmetric(horizontal: SettingsUtils.getHorizontalPadding(context, _responsiveUtils)),
color: _responsiveUtils.isWebDesktop(context) ? null : Colors.white,
decoration: _responsiveUtils.isWebDesktop(context)
? BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: Colors.white)
: null,
child: ClipRRect(
borderRadius: BorderRadius.circular(
_responsiveUtils.isWebDesktop(context) ? 20 : 0),
child: Padding(
padding: const EdgeInsets.only(top: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_responsiveUtils.isWebDesktop(context))...[
const MailboxVisibilityHeaderWidget(),
_buildLoadingView(),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
),
],
Expanded(child: _buildListMailbox(context)),
]
),
),
),
),
);
}
Widget _buildLoadingView() {
return Obx(() => controller.viewState.value.fold(
(failure) => const SizedBox.shrink(),
(success) => success is LoadingState
? const Center(
child: Padding(
padding: EdgeInsets.only(top: 16),
child: SizedBox(
height: 24,
width: 24,
child: CupertinoActivityIndicator(
color: AppColor.colorTextButton,
),
)),
)
: const SizedBox.shrink()));
}
Widget _buildListMailbox(BuildContext context) {
return SingleChildScrollView(
controller: controller.mailboxListScrollController,
key: const PageStorageKey('mailbox_list'),
physics: const ClampingScrollPhysics(),
child: Column(children: [
Obx(() => controller.defaultMailboxIsNotEmpty
? _buildMailboxCategory(context, MailboxCategories.exchange, controller.defaultRootNode)
: const SizedBox.shrink()),
const SizedBox(height: 13),
Obx(() => controller.teamMailboxesIsNotEmpty
? _buildMailboxCategory(context, MailboxCategories.teamMailboxes, controller.teamMailboxesRootNode)
: const SizedBox.shrink()),
const SizedBox(height: 8),
Obx(() => controller.personalMailboxIsNotEmpty
? _buildMailboxCategory(context, MailboxCategories.personalMailboxes, controller.personalRootNode)
: const SizedBox.shrink()),
])
);
}
Widget _buildHeaderMailboxCategory(BuildContext context, MailboxCategories categories) {
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(children: [
buildIconWeb(
splashRadius: 5,
iconPadding: EdgeInsets.zero,
minSize: 12,
icon: SvgPicture.asset(
categories.getExpandMode(controller.mailboxCategoriesExpandMode.value) == ExpandMode.EXPAND
? _imagePaths.icExpandFolder
: _imagePaths.icCollapseFolder,
color: AppColor.primaryColor,
fit: BoxFit.fill),
tooltip: AppLocalizations.of(context).collapse,
onTap: () => controller.toggleMailboxCategories(categories)),
Expanded(child: Text(categories.getTitle(context),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 17,
color: Colors.black,
fontWeight: FontWeight.bold))),
]));
}
Widget _buildMailboxCategory(BuildContext context, MailboxCategories categories, MailboxNode mailboxNode) {
if (categories == MailboxCategories.exchange) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: _responsiveUtils.isDesktop(context) ? 24 : 0),
child: _buildBodyMailboxCategory(context, categories, mailboxNode),
);
}
return Padding(
padding: EdgeInsets.symmetric(horizontal: _responsiveUtils.isDesktop(context) ? 24 : 0),
child: Column(children: [
_buildHeaderMailboxCategory(context, categories),
AnimatedContainer(
duration: const Duration(milliseconds: 400),
child: categories.getExpandMode(controller.mailboxCategoriesExpandMode.value) == ExpandMode.EXPAND
? _buildBodyMailboxCategory(context, categories, mailboxNode)
: const Offstage())
]),
);
}
Widget _buildBodyMailboxCategory(
BuildContext context,
MailboxCategories categories,
MailboxNode mailboxNode,
) {
final lastNode = mailboxNode.childrenItems?.last;
return Container(
padding: EdgeInsets.only(
right: _responsiveUtils.isDesktop(context) ? 0 : 12,
left: _responsiveUtils.isDesktop(context) ? 0 : 12),
child: TreeView(
key: Key('${categories.keyValue}_mailbox_list'),
children: _buildListChildTileWidget(
context,
mailboxNode,
lastNode: lastNode)));
}
List<Widget> _buildListChildTileWidget(
BuildContext context,
MailboxNode parentNode,
{MailboxNode? lastNode}
) {
return parentNode.childrenItems
?.map((mailboxNode) => mailboxNode.hasChildren()
? TreeViewChild(
context,
key: const Key('children_tree_mailbox_child'),
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
parent: Obx(() => controller.defaultMailboxIsNotEmpty ? (MailBoxVisibilityFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode)
..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
..addOnSubscribeMailboxActionClick((mailboxNode) => controller.subscribeMailbox(mailboxNode)))
.build(context) : const SizedBox.shrink()) ,
children: _buildListChildTileWidget(context, mailboxNode)
).build()
: Obx(() => controller.defaultMailboxIsNotEmpty ? (MailBoxVisibilityFolderTileBuilder(context, _imagePaths, mailboxNode, lastNode: lastNode)
..addOnExpandFolderActionClick((mailboxNode) => controller.toggleMailboxFolder(mailboxNode))
..addOnSubscribeMailboxActionClick((mailboxNode) => controller.subscribeMailbox(mailboxNode)))
.build(context) : const SizedBox.shrink())).toList() ?? <Widget>[];
}
}
@@ -0,0 +1,258 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:tmail_ui_user/features/mailbox/domain/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnExpandFolderActionClick = void Function(MailboxNode);
typedef OnSubscribeMailboxActionClick = void Function(MailboxNode);
class MailBoxVisibilityFolderTileBuilder {
final MailboxNode _mailboxNode;
final BuildContext _context;
final ImagePaths _imagePaths;
final MailboxNode? lastNode;
final MailboxActions? mailboxActions;
OnSubscribeMailboxActionClick? _onSubscribeMailboxActionClick;
OnExpandFolderActionClick? _onExpandFolderActionClick;
bool isHoverItem = false;
MailBoxVisibilityFolderTileBuilder(
this._context,
this._imagePaths,
this._mailboxNode, {
this.lastNode,
this.mailboxActions,
});
void addOnExpandFolderActionClick(OnExpandFolderActionClick onExpandFolderActionClick) {
_onExpandFolderActionClick = onExpandFolderActionClick;
}
void addOnSubscribeMailboxActionClick(OnSubscribeMailboxActionClick onSubscribeMailboxActionClick) {
_onSubscribeMailboxActionClick = onSubscribeMailboxActionClick;
}
Widget build(BuildContext context) => _buildMailboxItem(context);
Widget _buildMailboxItem(BuildContext context) {
if (BuildUtils.isWeb) {
return Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent),
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return InkWell(
onTap: () {},
onHover: (value) => setState(() => isHoverItem = value),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: backgroundColorItem),
padding: EdgeInsets.only(
left: _mailboxNode.item.hasRole() ? 0 : 4,
right: 4,
top: 8,
bottom: 8),
margin: const EdgeInsets.only(bottom: 4),
child: Row(
children: [
_buildLeadingMailboxItem(),
const SizedBox(width: 4),
Expanded(child: _buildTitleFolderItem()),
if (!_mailboxNode.item.hasRole())
_buildSubscribeMailboxItem(context, _mailboxNode),
const SizedBox(width: 32),
]),
),
);
}),
);
} else {
return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(14)),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: _mailboxNode.hasChildren() ? 8 : 15),
child: Row(
crossAxisAlignment:
_mailboxNode.item.isTeamMailboxes
? CrossAxisAlignment.start
: CrossAxisAlignment.center,
children: [
if (_mailboxNode.item.isTeamMailboxes)
const SizedBox(width: 16),
_buildLeadingMailboxItem(),
const SizedBox(width: 8),
Expanded(child: _buildTitleFolderItem()),
if (!_mailboxNode.item.hasRole())
_buildSubscribeMailboxItem(context, _mailboxNode),
]),
),
]));
}
}
Widget _buildLeadingMailboxItem() {
if (BuildUtils.isWeb) {
return Row(mainAxisSize: MainAxisSize.min, children: [
if (_mailboxNode.hasChildren() && _mailboxNode.item.isPersonal)
Row(
children: [
const SizedBox(width: 8),
buildIconWeb(
icon: SvgPicture.asset(
_mailboxNode.expandMode == ExpandMode.EXPAND
? _imagePaths.icExpandFolder
: _imagePaths.icCollapseFolder,
color: _mailboxNode.expandMode == ExpandMode.EXPAND
? AppColor.colorExpandMailbox
: AppColor.colorCollapseMailbox,
fit: BoxFit.fill),
minSize: 12,
splashRadius: 10,
iconPadding: EdgeInsets.zero,
tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND
? AppLocalizations.of(_context).collapse
: AppLocalizations.of(_context).expand,
onTap: () => _onExpandFolderActionClick?.call(_mailboxNode)),
],
)
else
SizedBox(width: _mailboxNode.item.isPersonal ? 32 : 24),
Transform(
transform: Matrix4.translationValues(-4.0, 0.0, 0.0),
child: _buildLeadingIconTeamMailboxes()),
]);
} else {
return Row(mainAxisSize: MainAxisSize.min, children: [
if (_mailboxNode.hasChildren())
Row(
children: [
SizedBox(width: _mailboxNode.item.hasRole() ? 0 : 0),
if (!_mailboxNode.item.isTeamMailboxes)
buildIconWeb(
icon: SvgPicture.asset(
_mailboxNode.expandMode == ExpandMode.EXPAND
? _imagePaths.icExpandFolder
: _imagePaths.icCollapseFolder,
color: _mailboxNode.expandMode == ExpandMode.EXPAND
? AppColor.colorExpandMailbox
: AppColor.colorCollapseMailbox,
fit: BoxFit.fill),
minSize: 12,
splashRadius: 10,
iconPadding: EdgeInsets.zero,
tooltip: _mailboxNode.expandMode == ExpandMode.EXPAND
? AppLocalizations.of(_context).collapse
: AppLocalizations.of(_context).expand,
onTap: () => _onExpandFolderActionClick?.call(_mailboxNode)),
],
)
else
const SizedBox(width: 24),
_buildLeadingIconTeamMailboxes(),
]);
}
}
Widget _buildLeadingIconTeamMailboxes() {
if (!_mailboxNode.item.isPersonal) {
return _buildLeadingIconForChildOfTeamMailboxes();
} else {
return _buildMailboxIcon();
}
}
Widget _buildLeadingIconForChildOfTeamMailboxes() {
if (_mailboxNode.item.hasParentId()) {
return _buildMailboxIcon();
} else {
return const SizedBox();
}
}
Color get backgroundColorItem {
if (BuildUtils.isWeb && isHoverItem) {
return AppColor.colorBgMailboxSelected;
} else {
return Colors.white;
}
}
Widget _buildTitleFolderItem() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_mailboxNode.item.name?.name ?? '',
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: TextStyle(
fontSize: _mailboxNode.item.isTeamMailboxes ? 16 : 15,
color: _mailboxNode.item.isSubscribedMailbox
? _getColorTextTitleFolderItem()
: AppColor.colorItemAlreadySelected,
fontWeight: _mailboxNode.item.isTeamMailboxes
? FontWeight.w500
: FontWeight.normal),
),
if (_mailboxNode.item.isTeamMailboxes)
Text(
_mailboxNode.item.emailTeamMailBoxes ?? '',
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: const TextStyle(
fontSize: 13,
color: AppColor.colorEmailAddressFull,
fontWeight: FontWeight.w400),
),
],
);
}
Color _getColorTextTitleFolderItem() {
if (_mailboxNode.item.isTeamMailboxes) {
return Colors.black;
} else {
return AppColor.colorNameEmail;
}
}
Widget _buildMailboxIcon() {
return SvgPicture.asset(_mailboxNode.item.getMailboxIcon(_imagePaths),
width: BuildUtils.isWeb ? 20 : 24,
height: BuildUtils.isWeb ? 20 : 24,
color: !_mailboxNode.item.isSubscribedMailbox
? AppColor.colorDeleteContactIcon
: null,
fit: BoxFit.fill);
}
Widget _buildSubscribeMailboxItem(BuildContext context, MailboxNode _mailboxNode) {
return InkWell(
onTap: () => _onSubscribeMailboxActionClick?.call(_mailboxNode),
child: Text(
_mailboxNode.item.isSubscribedMailbox
? AppLocalizations.of(context).hide
: AppLocalizations.of(context).show,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: const TextStyle(
fontSize: 15, color: Colors.blue, fontWeight: FontWeight.normal),
),
);
}
}
@@ -0,0 +1,30 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class MailboxVisibilityHeaderWidget extends StatelessWidget {
const MailboxVisibilityHeaderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).mailboxVisibility,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black)),
const SizedBox(height: 4),
Text(AppLocalizations.of(context).mailboxVisibilitySubtitle,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: AppColor.colorSettingExplanation))
]),
);
}
}
@@ -26,6 +26,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/action/dashbo
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forward_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/bindings/mailbox_visibility_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart';
@@ -103,6 +104,7 @@ class ManageAccountDashBoardController extends ReloadableController {
injectAutoCompleteBindings(sessionCurrent.value, accountId.value);
injectForwardBindings(sessionCurrent.value, accountId.value);
injectRuleFilterBindings(sessionCurrent.value, accountId.value);
injectMailboxVisibilityBindings();
injectVacationBindings(sessionCurrent.value, accountId.value);
_getVacationResponse();
}
@@ -117,6 +119,7 @@ class ManageAccountDashBoardController extends ReloadableController {
injectAutoCompleteBindings(sessionCurrent.value, accountId.value);
injectForwardBindings(sessionCurrent.value, accountId.value);
injectRuleFilterBindings(sessionCurrent.value, accountId.value);
injectMailboxVisibilityBindings();
injectVacationBindings(sessionCurrent.value, accountId.value);
_getVacationResponse();
if (arguments.menuSettingCurrent != null) {
@@ -182,12 +185,15 @@ class ManageAccountDashBoardController extends ReloadableController {
void selectAccountMenuItem(AccountMenuItem newAccountMenuItem) {
clearInputFormView();
if(newAccountMenuItem == AccountMenuItem.emailRules) {
if (newAccountMenuItem == AccountMenuItem.emailRules) {
EmailRulesBindings().dependencies();
}
if(newAccountMenuItem == AccountMenuItem.forward) {
if (newAccountMenuItem == AccountMenuItem.forward) {
ForwardBindings().dependencies();
}
if (newAccountMenuItem == AccountMenuItem.mailboxVisibility) {
MailboxVisibilityBindings().dependencies();
}
accountMenuItemSelected.value = newAccountMenuItem;
if (isMenuDrawerOpen) {
closeMenuDrawer();
@@ -205,12 +211,15 @@ class ManageAccountDashBoardController extends ReloadableController {
}
void _goToSettingMenuCurrent(AccountMenuItem accountMenuItem) {
if(accountMenuItem == AccountMenuItem.emailRules) {
if (accountMenuItem == AccountMenuItem.emailRules) {
EmailRulesBindings().dependencies();
}
if(accountMenuItem == AccountMenuItem.forward) {
if (accountMenuItem == AccountMenuItem.forward) {
ForwardBindings().dependencies();
}
if (accountMenuItem == AccountMenuItem.mailboxVisibility) {
MailboxVisibilityBindings().dependencies();
}
accountMenuItemSelected.value = accountMenuItem;
if (currentContext != null &&
!_responsiveUtils.isDesktop(currentContext!)) {
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.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/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
@@ -179,6 +180,8 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
}
case AccountMenuItem.vacation:
return VacationView();
case AccountMenuItem.mailboxVisibility:
return MailboxVisibilityView();
default:
return const SizedBox.shrink();
}
@@ -46,7 +46,12 @@ class ManageAccountMenuController extends BaseController {
if (dashBoardController.checkAvailableVacationInSession()) {
listAccountMenuItem.add(AccountMenuItem.vacation);
}
listAccountMenuItem.add(AccountMenuItem.languageAndRegion);
listAccountMenuItem.addAll(
[
AccountMenuItem.mailboxVisibility,
AccountMenuItem.languageAndRegion
]
);
}
@override
@@ -105,6 +105,20 @@ class SettingsFirstLevelView extends GetWidget<SettingsController> {
return const SizedBox.shrink();
}
}),
Column(children: [
SettingFirstLevelTileBuilder(
AccountMenuItem.mailboxVisibility.getName(context),
AccountMenuItem.mailboxVisibility.getIcon(_imagePaths),
subtitle: AppLocalizations.of(context).mailboxVisibilitySubtitle,
() => controller.selectSettings(AccountMenuItem.mailboxVisibility)
),
Divider(
color: AppColor.colorDividerComposer,
height: 1,
indent: SettingsUtils.getHorizontalPadding(context, _responsiveUtils),
endIndent: SettingsUtils.getHorizontalPadding(context, _responsiveUtils)
),
]),
SettingFirstLevelTileBuilder(
AccountMenuItem.languageAndRegion.getName(context),
AccountMenuItem.languageAndRegion.getIcon(_imagePaths),
@@ -11,6 +11,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/e
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/mailbox_visibility/mailbox_visibility_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_first_level_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
@@ -193,13 +194,13 @@ class SettingsView extends GetWidget<SettingsController> {
case AccountMenuItem.languageAndRegion:
return LanguageAndRegionView();
case AccountMenuItem.emailRules:
if(controller.manageAccountDashboardController.checkAvailableRuleFilterInSession()){
if (controller.manageAccountDashboardController.checkAvailableRuleFilterInSession()) {
return EmailRulesView();
} else {
return const SizedBox.shrink();
}
case AccountMenuItem.forward:
if(controller.manageAccountDashboardController.checkAvailableForwardInSession()){
if (controller.manageAccountDashboardController.checkAvailableForwardInSession()) {
return ForwardView();
} else {
return const SizedBox.shrink();
@@ -210,6 +211,8 @@ class SettingsView extends GetWidget<SettingsController> {
} else {
return const SizedBox.shrink();
}
case AccountMenuItem.mailboxVisibility:
return MailboxVisibilityView();
default:
return const SizedBox.shrink();
}
@@ -9,6 +9,7 @@ enum AccountMenuItem {
emailRules,
forward,
vacation,
mailboxVisibility,
none;
String getIcon(ImagePaths imagePaths) {
@@ -23,6 +24,8 @@ enum AccountMenuItem {
return imagePaths.icForward;
case AccountMenuItem.vacation:
return imagePaths.icVacation;
case AccountMenuItem.mailboxVisibility:
return imagePaths.icMailboxVisibility;
case AccountMenuItem.none:
return imagePaths.icProfiles;
}
@@ -40,6 +43,8 @@ enum AccountMenuItem {
return AppLocalizations.of(context).forwarding;
case AccountMenuItem.vacation:
return AppLocalizations.of(context).vacation;
case AccountMenuItem.mailboxVisibility:
return AppLocalizations.of(context).mailboxVisibility;
case AccountMenuItem.none:
return AppLocalizations.of(context).profiles;
}