TF-801 Show notification message when vacation enabled

This commit is contained in:
dab246
2022-08-17 22:10:11 +07:00
committed by Dat H. Pham
parent 04b3b49c23
commit f2a72ac883
32 changed files with 531 additions and 365 deletions
+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.5711 0.714844C13.9656 0.714844 14.2854 1.03464 14.2854 1.42913L14.2859 2.25757C14.8858 2.35301 15.2742 2.50718 15.6644 2.71584C16.3628 3.08936 16.9109 3.63748 17.2844 4.33589C17.6238 4.9704 17.819 5.60025 17.8519 7.14275L17.8569 7.14341V12.3637L17.8531 12.7994C17.8239 14.3849 17.6281 15.0227 17.2844 15.6652C16.9109 16.3636 16.3628 16.9118 15.6644 17.2853C14.966 17.6588 14.2732 17.8577 12.3628 17.8577H7.63662L7.20087 17.8539C5.61534 17.8248 4.97759 17.6289 4.33505 17.2853C3.63664 16.9118 3.08852 16.3636 2.71501 15.6652C2.35643 14.9947 2.15877 14.3295 2.14353 12.5871L2.14258 7.63745V7.14341C2.18044 5.60025 2.37566 4.9704 2.71501 4.33589C3.08852 3.63748 3.63664 3.08936 4.33505 2.71584C4.72537 2.5071 5.11392 2.35289 5.71423 2.25745L5.71401 1.42913C5.71401 1.03464 6.0338 0.714844 6.42829 0.714844C6.82278 0.714844 7.14258 1.03464 7.14258 1.42913L7.14191 2.14839C7.29725 2.14508 7.46184 2.14342 7.63662 2.14342H12.3628C12.5379 2.14342 12.7027 2.14509 12.8583 2.14841L12.8569 1.42913C12.8569 1.03464 13.1767 0.714844 13.5711 0.714844ZM16.4276 8.57199H3.57115L3.57181 12.5658L3.57813 12.9721C3.6059 14.0486 3.71965 14.5145 3.97474 14.9915C4.21511 15.441 4.55931 15.7852 5.00876 16.0255C5.54185 16.3106 6.06111 16.4192 7.43451 16.4285H12.5649L12.9713 16.4221C14.0478 16.3944 14.5137 16.2806 14.9907 16.0255C15.4401 15.7852 15.7843 15.441 16.0247 14.9915C16.3098 14.4584 16.4184 13.9392 16.4276 12.5658L16.4276 8.57199ZM13.604 12.1434C13.9131 12.1434 14.1565 12.2014 14.3602 12.3104C14.564 12.4193 14.7238 12.5792 14.8328 12.7829C14.9417 12.9866 14.9997 13.23 14.9997 13.5391V13.6049C14.9997 13.914 14.9417 14.1574 14.8328 14.3611C14.7238 14.5648 14.564 14.7247 14.3602 14.8336C14.1565 14.9425 13.9131 15.0006 13.604 15.0006H13.5383C13.2292 15.0006 12.9858 14.9425 12.782 14.8336C12.5783 14.7247 12.4185 14.5648 12.3095 14.3611C12.2006 14.1574 12.1426 13.914 12.1426 13.6049V13.5391C12.1426 13.23 12.2006 12.9866 12.3095 12.7829C12.4185 12.5792 12.5783 12.4193 12.782 12.3104C12.9858 12.2014 13.2292 12.1434 13.5383 12.1434H13.604ZM12.5649 3.57265H7.43451L7.14258 3.57627V4.28627C7.14258 4.68076 6.82278 5.00056 6.42829 5.00056C6.0338 5.00056 5.71401 4.68076 5.71401 4.28627L5.71347 3.7095C5.44155 3.77229 5.22631 3.85923 5.00876 3.97558C4.55931 4.21595 4.21511 4.56014 3.97474 5.0096C3.71087 5.503 3.59823 5.98455 3.57556 7.14245L16.4233 7.14341L16.4213 7.02902C16.3935 5.95248 16.2798 5.48657 16.0247 5.0096C15.7843 4.56014 15.4401 4.21595 14.9907 3.97558C14.7732 3.85926 14.558 3.77233 14.2862 3.70954L14.2854 4.28627C14.2854 4.68076 13.9656 5.00056 13.5711 5.00056C13.1767 5.00056 12.8569 4.68076 12.8569 4.28627L12.8586 3.57641C12.7652 3.57458 12.6674 3.57334 12.5649 3.57265Z" fill="#B8C1CC"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.0001 1.66602C14.6014 1.66602 18.3334 5.39679 18.3334 9.99935C18.3334 14.6019 14.6014 18.3327 10.0001 18.3327C5.39752 18.3327 1.66675 14.6019 1.66675 9.99935C1.66675 5.39679 5.39752 1.66602 10.0001 1.66602ZM10.0001 3.33268C6.31803 3.33268 3.33341 6.3173 3.33341 9.99935C3.33341 13.6814 6.31803 16.666 10.0001 16.666C13.6811 16.666 16.6667 13.6814 16.6667 9.99935C16.6667 6.3173 13.6811 3.33268 10.0001 3.33268ZM9.44912 5.87114C9.90936 5.87114 10.2825 6.24424 10.2825 6.70448V9.89942L13.4163 10.9459C13.8523 11.0935 14.086 11.5665 13.9384 12.0025C13.7909 12.4384 13.3178 12.6722 12.8819 12.5246L9.18191 11.272C8.84351 11.1575 8.61579 10.8399 8.61579 10.4827V6.70448C8.61579 6.24424 8.98888 5.87114 9.44912 5.87114Z" fill="#B8C1CC"/>
</svg>

After

Width:  |  Height:  |  Size: 847 B

+6
View File
@@ -0,0 +1,6 @@
<svg width="52" height="32" viewBox="0 0 52 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M0 16C0 7.16344 7.16344 0 16 0H36C44.8366 0 52 7.16344 52 16C52 24.8366 44.8366 32 36 32H16C7.16344 32 0 24.8366 0 16Z"
fill="#D3D3D3" />
<rect x="2" y="2" width="28" height="28" rx="14" fill="white" />
</svg>

After

Width:  |  Height:  |  Size: 338 B

+9
View File
@@ -0,0 +1,9 @@
<svg width="52" height="32" viewBox="0 0 52 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="52" height="32" rx="16" fill="#007AFF" />
<mask id="mask0" x="0" y="0" width="52" height="32">
<rect width="52" height="32" rx="16" fill="white" />
</mask>
<g mask="url(#mask0)">
<rect x="22" y="2" width="28" height="28" rx="14" fill="white" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 373 B

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -138,6 +138,7 @@ extension AppColor on Color {
static const colorBackgroundFieldConditionRulesFilter = Color(0xFFF2F3F5);
static const colorDividerRuleFilter = Color(0xFFE7E8EC);
static const colorIconTextField = Color(0xFFB8C1CC);
static const colorVacationNotificationMessageBackground = Color(0x2999A2AD);
static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
@@ -155,6 +155,10 @@ class ImagePaths {
String get icDeleteEmailForward => _getImagePath('ic_delete_email_forward.svg');
String get icVacation => _getImagePath('ic_vacation.svg');
String get icSignOut => _getImagePath('ic_sign_out.svg');
String get icSwitchOn => _getImagePath('ic_switch_on.svg');
String get icSwitchOff => _getImagePath('ic_switch_off.svg');
String get icClock => _getImagePath('ic_clock.svg');
String get icCalendar => _getImagePath('ic_calendar.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -15,6 +15,8 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_w
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailView extends GetWidget<EmailController> with NetworkConnectionMixin {
@@ -58,6 +60,22 @@ class EmailView extends GetWidget<EmailController> with NetworkConnectionMixin {
: EdgeInsets.zero,
child: Column(children: [
_buildAppBar(context),
Obx(() {
if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true &&
(responsiveUtils.isMobile(context) ||
responsiveUtils.isTablet(context) ||
responsiveUtils.isLandscapeMobile(context))) {
return Padding(
padding: const EdgeInsets.only(bottom: 5),
child: VacationNotificationMessageWidget(
radius: 0,
margin: EdgeInsets.zero,
vacationResponse: controller.mailboxDashBoardController.vacationResponse.value!),
);
} else {
return const SizedBox.shrink();
}
}),
if (responsiveUtils.isWebDesktop(context))
const SizedBox(height: 5),
Obx(() {
@@ -66,6 +66,13 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/download/download_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource/manage_account_datasource.dart';
import 'package:tmail_ui_user/features/manage_account/data/datasource_impl/manage_account_datasource_impl.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
import 'package:tmail_ui_user/features/thread/data/datasource_impl/local_thread_datasource_impl.dart';
@@ -102,6 +109,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<DeleteEmailPermanentlyInteractor>(),
Get.find<MarkAsMailboxReadInteractor>(),
Get.find<GetComposerCacheOnWebInteractor>(),
Get.find<GetAllVacationInteractor>(),
));
Get.put(AdvancedFilterController());
}
@@ -117,6 +125,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut<AccountDatasource>(() => Get.find<HiveAccountDatasourceImpl>());
Get.lazyPut<AuthenticationOIDCDataSource>(() => Get.find<AuthenticationOIDCDataSourceImpl>());
Get.lazyPut<SessionStorageComposerDatasource>(() => Get.find<SessionStorageComposerDatasourceImpl>());
Get.lazyPut<ManageAccountDataSource>(() => Get.find<ManageAccountDataSourceImpl>());
}
@override
@@ -140,6 +149,9 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<OidcConfigurationCacheManager>()
));
Get.lazyPut(() => SessionStorageComposerDatasourceImpl());
Get.lazyPut(() => ManageAccountDataSourceImpl(
Get.find<ManageAccountAPI>(),
Get.find<LanguageCacheManager>()));
}
@override
@@ -179,6 +191,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut(() => GetComposerCacheOnWebInteractor(Get.find<ComposerCacheRepository>()));
Get.lazyPut(() => SaveComposerCacheOnWebInteractor(Get.find<ComposerCacheRepository>()));
Get.lazyPut(() => RemoveComposerCacheOnWebInteractor(Get.find<ComposerCacheRepository>()));
Get.lazyPut(() => GetAllVacationInteractor(Get.find<ManageAccountRepository>()));
}
@override
@@ -191,6 +204,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut<AccountRepository>(() => Get.find<AccountRepositoryImpl>());
Get.lazyPut<AuthenticationOIDCRepository>(() => Get.find<AuthenticationOIDCRepositoryImpl>());
Get.lazyPut<ComposerCacheRepository>(() => Get.find<ComposerCacheRepositoryImpl>());
Get.lazyPut<ManageAccountRepository>(() => Get.find<ManageAccountRepositoryImpl>());
}
@override
@@ -219,5 +233,6 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut(() => AccountRepositoryImpl(Get.find<AccountDatasource>()));
Get.lazyPut(() => AuthenticationOIDCRepositoryImpl(Get.find<AuthenticationOIDCDataSource>()));
Get.lazyPut(() => ComposerCacheRepositoryImpl(Get.find<SessionStorageComposerDatasource>()));
Get.lazyPut(() => ManageAccountRepositoryImpl(Get.find<ManageAccountDataSource>()));
}
}
@@ -13,6 +13,7 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:model/model.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
@@ -43,6 +44,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/composer_overlay_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/manage_account_arguments.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
@@ -71,6 +74,7 @@ class MailboxDashBoardController extends ReloadableController {
final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor;
final MarkAsMailboxReadInteractor _markAsMailboxReadInteractor;
final GetComposerCacheOnWebInteractor _getEmailCacheOnWebInteractor;
final GetAllVacationInteractor _getAllVacationInteractor;
final scaffoldKey = GlobalKey<ScaffoldState>();
final selectedMailbox = Rxn<PresentationMailbox>();
@@ -85,6 +89,7 @@ class MailboxDashBoardController extends ReloadableController {
final listEmailSelected = <PresentationEmail>[].obs;
final composerOverlayState = ComposerOverlayState.inActive.obs;
final viewStateMarkAsReadMailbox = Rx<Either<Failure, Success>>(Right(UIState.idle));
final vacationResponse = Rxn<VacationResponse>();
Session? sessionCurrent;
Map<Role, MailboxId> mapDefaultMailboxId = {};
@@ -106,6 +111,7 @@ class MailboxDashBoardController extends ReloadableController {
this._deleteEmailPermanentlyInteractor,
this._markAsMailboxReadInteractor,
this._getEmailCacheOnWebInteractor,
this._getAllVacationInteractor,
) : super(logoutOidcInteractor,
deleteAuthorityOidcInteractor,
getAuthenticatedAccountInteractor);
@@ -125,6 +131,7 @@ class MailboxDashBoardController extends ReloadableController {
dispatchRoute(AppRoutes.THREAD);
_setSessionCurrent();
_getUserProfile();
_getVacationResponse();
_getAppVersion();
super.onReady();
}
@@ -210,6 +217,10 @@ class MailboxDashBoardController extends ReloadableController {
} else if (success is MarkAsMailboxReadAllSuccess ||
success is MarkAsMailboxReadHasSomeEmailFailure) {
_markAsReadMailboxSuccess(success);
} else if (success is GetAllVacationSuccess) {
if (success.listVacationResponse.isNotEmpty) {
vacationResponse.value = success.listVacationResponse.first;
}
}
}
);
@@ -292,6 +303,12 @@ class MailboxDashBoardController extends ReloadableController {
appInformation.value = info;
}
void _getVacationResponse() {
if (accountId.value != null) {
consumeState(_getAllVacationInteractor.execute(accountId.value!));
}
}
MailboxId? getMailboxIdByRole(Role role) {
return mapDefaultMailboxId[role];
}
@@ -448,6 +465,7 @@ class MailboxDashBoardController extends ReloadableController {
sessionCurrent = session;
accountId.value = sessionCurrent?.accounts.keys.first;
_getUserProfile();
_getVacationResponse();
_handleComposerCache();
injectAutoCompleteBindings();
}
@@ -544,13 +562,16 @@ class MailboxDashBoardController extends ReloadableController {
dashBoardAction.value = DashBoardAction.idle;
}
void goToSettings() {
if (currentContext != null && (_responsiveUtils.isMobile(currentContext!)
|| _responsiveUtils.isTablet(currentContext!))) {
void goToSettings() async {
if (isDrawerOpen) {
closeMailboxMenuDrawer();
}
push(AppRoutes.MANAGE_ACCOUNT,
final result = await push(AppRoutes.MANAGE_ACCOUNT,
arguments: ManageAccountArguments(sessionCurrent));
if (result is VacationResponse) {
vacationResponse.value = result;
}
}
void selectQuickSearchFilter({
@@ -19,6 +19,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/download/download_task_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -93,6 +95,15 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
children: [
SizedBox(child: MailboxView(), width: responsiveUtils.defaultSizeMenu),
Expanded(child: Column(children: [
Obx(() {
if (controller.vacationResponse.value?.vacationResponderIsReady == true) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(top: 16, right: 16),
vacationResponse: controller.vacationResponse.value!);
} else {
return const SizedBox.shrink();
}
}),
_buildMarkAsMailboxReadLoading(context),
Expanded(child: Obx(() {
switch(controller.routePath.value) {
@@ -44,7 +44,7 @@ mixin UserSettingPopupMenuMixin {
Widget _settingAction(BuildContext context, Function? onCallBack) {
return PopupMenuItemWidget(
_imagePaths.icSetting,
AppLocalizations.of(context).settings,
AppLocalizations.of(context).manage_account,
() => onCallBack?.call());
}
@@ -1,38 +0,0 @@
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_bindings.dart';
class ConfigurationBindings extends BaseBindings {
@override
void dependencies() {
super.dependencies();
VacationBindings().dependencies();
}
@override
void bindingsController() {
Get.lazyPut(() => ConfigurationController());
}
@override
void bindingsDataSource() {
}
@override
void bindingsDataSourceImpl() {
}
@override
void bindingsInteractor() {
}
@override
void bindingsRepository() {
}
@override
void bindingsRepositoryImpl() {
}
}
@@ -1,11 +0,0 @@
import 'package:tmail_ui_user/features/base/base_controller.dart';
class ConfigurationController extends BaseController {
@override
void onDone() {}
@override
void onError(error) {}
}
@@ -1,81 +0,0 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/configuration_tab_type.dart';
class ConfigurationView extends GetWidget<ConfigurationController> {
final _responsiveUtils = Get.find<ResponsiveUtils>();
ConfigurationView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: _responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: Container(
margin: _responsiveUtils.isWebDesktop(context)
? const EdgeInsets.all(24)
: EdgeInsets.zero,
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(
left: BuildUtils.isWeb ? 10 : 0,
right: 10,
bottom: 10),
child: DefaultTabController(
initialIndex: 0,
length: 1,
child: Scaffold(
appBar: TabBar(
unselectedLabelColor: AppColor.colorTextButtonHeaderThread,
unselectedLabelStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: AppColor.colorTextButtonHeaderThread),
labelStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
color: AppColor.primaryColor),
labelColor: AppColor.primaryColor,
indicatorSize: TabBarIndicatorSize.label,
isScrollable: true,
indicator: const CustomIndicator(
indicatorHeight: 4,
indicatorColor: AppColor.primaryColor,
indicatorSize: CustomIndicatorSize.full),
onTap: (index) {},
tabs: ConfigurationTabType.values
.map((tab) => Tab(text: tab.getTitle(context)))
.toList()
),
body: Column(children: [
const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
Expanded(child: TabBarView(
children: [
VacationView(),
],
))
]),
)
),
),
),
),
);
}
}
@@ -1,4 +1,5 @@
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_presentation.dart';
@@ -23,4 +24,20 @@ extension VacationResponseExtension on VacationResponse {
vacationStopEnabled: toDate != null
);
}
bool get vacationResponderIsReady {
if (isEnabled == true) {
final currentDate = DateTime.now().toUtc();
log('VacationResponseExtension::vacationResponderEnabled(): currentDate: $currentDate');
final startDate = fromDate?.value.toUtc();
log('VacationResponseExtension::vacationResponderEnabled(): startDate: $startDate');
if (startDate?.isBefore(currentDate) == true ||
startDate?.isAtSameMomentAs(currentDate) == true) {
return true;
} else {
return false;
}
}
return false;
}
}
@@ -25,12 +25,13 @@ import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_
import 'package:tmail_ui_user/features/manage_account/data/network/manage_account_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/repository/manage_account_repository_impl.dart';
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/configuration_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/profiles_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_bindings.dart';
class ManageAccountDashBoardBindings extends BaseBindings {
@@ -40,7 +41,7 @@ class ManageAccountDashBoardBindings extends BaseBindings {
ManageAccountMenuBindings().dependencies();
ProfileBindings().dependencies();
LanguageAndRegionBindings().dependencies();
ConfigurationBindings().dependencies();
VacationBindings().dependencies();
}
@override
@@ -48,7 +49,8 @@ class ManageAccountDashBoardBindings extends BaseBindings {
Get.lazyPut(() => ManageAccountDashBoardController(
Get.find<LogoutOidcInteractor>(),
Get.find<DeleteAuthorityOidcInteractor>(),
Get.find<GetAuthenticatedAccountInteractor>()
Get.find<GetAuthenticatedAccountInteractor>(),
Get.find<GetAllVacationInteractor>()
));
}
@@ -91,6 +93,7 @@ class ManageAccountDashBoardBindings extends BaseBindings {
Get.find<GetCredentialInteractor>(),
Get.find<GetStoredTokenOidcInteractor>(),
));
Get.lazyPut(() => GetAllVacationInteractor(Get.find<ManageAccountRepository>()));
}
@override
@@ -6,6 +6,7 @@ import 'package:forward/forward/capability_forward.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/mail/vacation/vacation_response.dart';
import 'package:model/model.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:rule_filter/rule_filter/capability_rule_filter.dart';
@@ -13,6 +14,8 @@ import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dar
import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/get_authenticated_account_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/forward/forward_bindings.dart';
@@ -23,6 +26,8 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class ManageAccountDashBoardController extends ReloadableController {
final GetAllVacationInteractor _getAllVacationInteractor;
final menuDrawerKey = GlobalKey<ScaffoldState>(debugLabel: 'manage_account');
final appInformation = Rxn<PackageInfo>();
@@ -30,11 +35,13 @@ class ManageAccountDashBoardController extends ReloadableController {
final accountId = Rxn<AccountId>();
final accountMenuItemSelected = AccountMenuItem.profiles.obs;
final sessionCurrent = Rxn<Session>();
final vacationResponse = Rxn<VacationResponse>();
ManageAccountDashBoardController(
LogoutOidcInteractor logoutOidcInteractor,
DeleteAuthorityOidcInteractor deleteAuthorityOidcInteractor,
GetAuthenticatedAccountInteractor getAuthenticatedAccountInteractor,
this._getAllVacationInteractor,
) : super(logoutOidcInteractor,
deleteAuthorityOidcInteractor,
getAuthenticatedAccountInteractor);
@@ -53,6 +60,10 @@ class ManageAccountDashBoardController extends ReloadableController {
(success) {
if (success is GetUserProfileSuccess) {
userProfile.value = success.userProfile;
} else if (success is GetAllVacationSuccess) {
if (success.listVacationResponse.isNotEmpty) {
vacationResponse.value = success.listVacationResponse.first;
}
}
}
);
@@ -67,6 +78,7 @@ class ManageAccountDashBoardController extends ReloadableController {
sessionCurrent.value = session;
accountId.value = session.accounts.keys.first;
_getUserProfile();
_getVacationResponse();
injectAutoCompleteBindings();
}
@@ -77,6 +89,7 @@ class ManageAccountDashBoardController extends ReloadableController {
sessionCurrent.value = arguments.session;
accountId.value = sessionCurrent.value?.accounts.keys.first;
_getUserProfile();
_getVacationResponse();
injectAutoCompleteBindings();
} else {
if (kIsWeb) {
@@ -95,6 +108,16 @@ class ManageAccountDashBoardController extends ReloadableController {
userProfile.value = sessionCurrent.value != null ? UserProfile(sessionCurrent.value!.username.value) : null;
}
void _getVacationResponse() {
if (accountId.value != null) {
consumeState(_getAllVacationInteractor.execute(accountId.value!));
}
}
void updateVacationResponse(VacationResponse? newVacation) {
vacationResponse.value = newVacation;
}
void openMenuDrawer() {
menuDrawerKey.currentState?.openDrawer();
}
@@ -128,7 +151,7 @@ class ManageAccountDashBoardController extends ReloadableController {
closeMenuDrawer();
}
if (canBack(context)) {
popBack();
popBack(result: vacationResponse.value);
} else {
log('ManageAccountDashBoardController::backToMailboxDashBoard(): canBack: FALSE');
pushAndPopAll(AppRoutes.MAILBOX_DASHBOARD, arguments: sessionCurrent);
@@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/configuration/configuration_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.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';
import 'package:tmail_ui_user/features/manage_account/presentation/language_and_region/language_and_region_view.dart';
@@ -12,6 +13,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/manage_accoun
import 'package:tmail_ui_user/features/manage_account/presentation/menu/manage_account_menu_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/profiles_view.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_view.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
@@ -25,7 +27,7 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
@override
Widget build(BuildContext context) {
if (controller.isMenuDrawerOpen && _responsiveUtils.isDesktop(context)) {
if (controller.isMenuDrawerOpen && _responsiveUtils.isWebDesktop(context)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
controller.closeMenuDrawer();
});
@@ -40,61 +42,93 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
desktop: const SizedBox.shrink()
),
drawerEnableOpenDragGesture: !_responsiveUtils.isDesktop(context),
body: ResponsiveWidget(
responsiveUtils: _responsiveUtils,
desktop: Column(children: [
Row(children: [
Container(width: 256, color: Colors.white,
padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32),
child: Row(children: [
(SloganBuilder(arrangedByHorizontal: true)
..setSloganText(AppLocalizations.of(context).app_name)
..setSloganTextAlign(TextAlign.center)
..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold))
..setSizeLogo(24)
..addOnTapCallback(() => controller.backToMailboxDashBoard(context))
..setLogo(_imagePaths.icLogoTMail))
.build(),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: ResponsiveWidget(
responsiveUtils: _responsiveUtils,
desktop: Column(children: [
Row(children: [
Container(width: 256, color: Colors.white,
padding: const EdgeInsets.only(top: 25, bottom: 25, left: 32),
child: Row(children: [
(SloganBuilder(arrangedByHorizontal: true)
..setSloganText(AppLocalizations.of(context).app_name)
..setSloganTextAlign(TextAlign.center)
..setSloganTextStyle(const TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold))
..setSizeLogo(24)
..addOnTapCallback(() => controller.backToMailboxDashBoard(context))
..setLogo(_imagePaths.icLogoTMail))
.build(),
Obx(() {
if (controller.appInformation.value != null) {
return Padding(padding: const EdgeInsets.only(top: 6),
child: Text(
'v.${controller.appInformation.value!.version}',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500),
));
} else {
return const SizedBox.shrink();
}
}),
])
),
Expanded(child: Padding(
padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48),
child: _buildRightHeader(context)))
]),
Expanded(child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu),
Expanded(child: Container(
color: AppColor.colorBgDesktop,
child: Column(children: [
Obx(() {
if (controller.vacationResponse.value?.vacationResponderIsReady == true) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
top: 16,
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16),
vacationResponse: controller.vacationResponse.value!);
} else {
return const SizedBox.shrink();
}
}),
Expanded(child: _viewDisplayedOfAccountMenuItem())
]),
))
],
))
]),
mobile: SafeArea(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
? const EdgeInsets.only(left: 4, right: 8)
: const EdgeInsets.only(top: 16, left: 24, right: 32),
child: _buildAppbar(context)),
Obx(() {
if (controller.appInformation.value != null) {
return Padding(padding: const EdgeInsets.only(top: 6),
child: Text(
'v.${controller.appInformation.value!.version}',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 13, color: AppColor.colorContentEmail, fontWeight: FontWeight.w500),
));
if (controller.vacationResponse.value?.vacationResponderIsReady == true) {
return VacationNotificationMessageWidget(
margin: const EdgeInsets.only(
left: BuildUtils.isWeb ? 24 : 16,
right: BuildUtils.isWeb ? 24 : 16,
top: BuildUtils.isWeb ? 16 : 0),
vacationResponse: controller.vacationResponse.value!);
} else {
return const SizedBox.shrink();
}
}),
])
),
Expanded(child: Padding(
padding: const EdgeInsets.only(right: 10, top: 16, bottom: 10, left: 48),
child: _buildRightHeader(context)))
]),
Expanded(child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(child: ManageAccountMenuView(), width: _responsiveUtils.defaultSizeMenu),
Expanded(child: _viewDisplayedOfAccountMenuItem())
],
))
]),
mobile: SafeArea(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
? const EdgeInsets.only(left: 4, right: 8)
: const EdgeInsets.only(top: 16, left: 24, right: 32),
child: _buildAppbar(context)),
Expanded(child: Padding(
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
? const EdgeInsets.only(left: 8)
: const EdgeInsets.only(left: 24),
child: _viewDisplayedOfAccountMenuItem()))
])
)
Expanded(child: Padding(
padding: !BuildUtils.isWeb && _responsiveUtils.isPortraitMobile(context)
? const EdgeInsets.only(left: 8)
: const EdgeInsets.only(left: 24),
child: _viewDisplayedOfAccountMenuItem()))
])
)
),
),
);
}
@@ -34,27 +34,17 @@ class ManageAccountMenuController extends BaseController {
super.onInit();
}
_createListAccountMenu(){
void _createListAccountMenu(){
listAccountMenuItem.clear();
listAccountMenuItem.add(
AccountMenuItem.profiles,
);
listAccountMenuItem.add(AccountMenuItem.profiles);
if (dashBoardController.checkAvailableRuleFilterInSession()) {
listAccountMenuItem.add(
AccountMenuItem.emailRules,
);
listAccountMenuItem.add(AccountMenuItem.emailRules);
}
if (dashBoardController.checkAvailableForwardInSession()) {
listAccountMenuItem.add(
AccountMenuItem.forward,
);
listAccountMenuItem.add(AccountMenuItem.forward);
}
listAccountMenuItem.add(
AccountMenuItem.languageAndRegion,
);
listAccountMenuItem.add(
AccountMenuItem.vacation,
);
listAccountMenuItem.add(AccountMenuItem.languageAndRegion);
listAccountMenuItem.add(AccountMenuItem.vacation);
}
@override
@@ -23,7 +23,7 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
body: SafeArea(right: false, bottom: false,
child: Column(
children: [
if (!_responsiveUtils.isDesktop(context))
if (!_responsiveUtils.isWebDesktop(context))
Container(
color: Colors.white,
padding: const EdgeInsets.only(top: 16, bottom: 16, left: 16),
@@ -51,10 +51,10 @@ class ManageAccountMenuView extends GetWidget<ManageAccountMenuController> {
}),
])
),
if (!_responsiveUtils.isDesktop(context))
if (!_responsiveUtils.isWebDesktop(context))
const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2),
Expanded(child: Container(
color: _responsiveUtils.isDesktop(context) ? AppColor.colorBgDesktop : Colors.white,
color: _responsiveUtils.isWebDesktop(context) ? AppColor.colorBgDesktop : Colors.white,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: const EdgeInsets.only(left: 20, top: 24),
@@ -51,6 +51,8 @@ class AccountMenuItemTileBuilder extends StatelessWidget {
if (_menuItemSelected == _menuItem) {
return AppColor.colorBgMailboxSelected;
}
return _responsiveUtils.isDesktop(_context) ? AppColor.colorBgDesktop : Colors.white;
return _responsiveUtils.isWebDesktop(_context)
? AppColor.colorBgDesktop
: Colors.white;
}
}
@@ -20,8 +20,8 @@ enum AccountMenuItem {
return imagePaths.icEmailRules;
case AccountMenuItem.forward:
return imagePaths.icForward;
case AccountMenuItem.configuration:
return imagePaths.icConfiguration;
case AccountMenuItem.vacation:
return imagePaths.icVacation;
}
}
@@ -35,8 +35,8 @@ enum AccountMenuItem {
return AppLocalizations.of(context).emailRules;
case AccountMenuItem.forward:
return AppLocalizations.of(context).forwarding;
case AccountMenuItem.configuration:
return AppLocalizations.of(context).configuration;
case AccountMenuItem.vacation:
return AppLocalizations.of(context).vacation;
}
}
}
@@ -4,7 +4,7 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na
import 'package:tmail_ui_user/features/manage_account/domain/repository/manage_account_repository.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart';
class VacationBindings extends BaseBindings {
@@ -116,7 +116,18 @@ class VacationController extends BaseController {
initialDatePickerMode: DatePickerMode.day,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
locale: Localizations.localeOf(context)
locale: Localizations.localeOf(context),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: AppColor.primaryColor,
onPrimary: Colors.white,
onSurface: Colors.black),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(primary: AppColor.primaryColor))),
child: child!);
}
);
if (datePicked == null) {
@@ -135,9 +146,18 @@ class VacationController extends BaseController {
context: context,
initialTime: currentTime ?? TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: const MediaQueryData(alwaysUse24HourFormat: true),
child: child!);
return Theme(
data: Theme.of(context).copyWith(
colorScheme: const ColorScheme.light(
primary: AppColor.primaryColor,
onPrimary: Colors.white,
onSurface: Colors.black),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(primary: AppColor.primaryColor))),
child: MediaQuery(
data: const MediaQueryData(alwaysUse24HourFormat: true),
child: child!),
);
}
);
@@ -233,6 +253,8 @@ class VacationController extends BaseController {
final newVacationPresentation = currentVacation.toVacationPresentation();
vacationPresentation.value = newVacationPresentation;
messageBodyEditorController.text = newVacationPresentation.messageBody ?? '';
_accountDashBoardController.updateVacationResponse(currentVacation);
}
}
@@ -1,31 +1,43 @@
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/base/widget/border_button_field.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/vacation_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/configuration/vacation/widgets/vacation_input_decoration_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/vacation_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_input_decoration_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/date_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_responder_status.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:toggle_switch/toggle_switch.dart';
class VacationView extends GetWidget<VacationController> {
final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>();
VacationView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
backgroundColor: _responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
width: double.infinity,
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
height: double.infinity,
margin: _responsiveUtils.isWebDesktop(context)
? const EdgeInsets.all(24)
: EdgeInsets.zero,
decoration: _responsiveUtils.isWebDesktop(context)
? BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: Colors.white)
: null,
padding: _getPaddingView(context),
child: ResponsiveWidget(
responsiveUtils: _responsiveUtils,
desktop: SingleChildScrollView(
@@ -43,28 +55,58 @@ class VacationView extends GetWidget<VacationController> {
fontWeight: FontWeight.normal,
color: Colors.black))),
const SizedBox(width: 16),
Obx(() => ToggleSwitch(
minWidth: 150.0,
cornerRadius: 20.0,
activeBgColors: const [[Colors.green], [Colors.redAccent]],
activeFgColor: Colors.white,
inactiveBgColor: Colors.grey,
inactiveFgColor: Colors.white,
initialLabelIndex: controller.isVacationDeactivated ? 1 : 0,
totalSwitches: VacationResponderStatus.values.length,
labels: VacationResponderStatus.values
.map((status) => status.getTitle(context))
.toList(),
radiusStyle: true,
onToggle: (index) {
final newStatus = index == 0
? VacationResponderStatus.activated
: VacationResponderStatus.deactivated;
controller.updateVacationPresentation(newStatus: newStatus);
},
)),
Obx(() {
return Row(
children: [
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
controller.updateVacationPresentation(newStatus: VacationResponderStatus.deactivated);
},
child: Text(AppLocalizations.of(context).deactivated,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 1.0 : 0.3))),
),
),
Padding(
padding: const EdgeInsets.only(top: 3, right: 16, left: 16),
child: InkWell(
onTap: () {
final newStatus = controller.isVacationDeactivated
? VacationResponderStatus.activated
: VacationResponderStatus.deactivated;
controller.updateVacationPresentation(newStatus: newStatus);
},
child: SvgPicture.asset(
controller.isVacationDeactivated
? _imagePaths.icSwitchOff
: _imagePaths.icSwitchOn,
fit: BoxFit.fill,
width: 24,
height: 24)),
),
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
controller.updateVacationPresentation(newStatus: VacationResponderStatus.activated);
},
child: Text(AppLocalizations.of(context).activated,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.3 : 1.0))),
),
)
]);
})
]),
const SizedBox(height: 20),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Row(children: [
@@ -90,10 +132,7 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).startDate,
icon: const Icon(
Icons.date_range,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icCalendar),
tapActionCallback: (value) =>
controller.selectDate(context, DateType.start, value)))),
const SizedBox(width: 16),
@@ -108,15 +147,12 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noStartTime,
icon: const Icon(
Icons.timer,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icClock),
tapActionCallback: (value) =>
controller.selectTime(context, DateType.start, value)))),
]),
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Container(
@@ -164,10 +200,7 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
!controller.canChangeEndDate ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noEndDate,
icon: const Icon(
Icons.date_range,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icCalendar),
tapActionCallback: (value) =>
controller.selectDate(context, DateType.end, value)))),
const SizedBox(width: 16),
@@ -182,15 +215,12 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
!controller.canChangeEndDate ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noEndTime,
icon: const Icon(
Icons.timer,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icClock),
tapActionCallback: (value) =>
controller.selectTime(context, DateType.end, value)))),
])
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -210,7 +240,7 @@ class VacationView extends GetWidget<VacationController> {
controller.isVacationDeactivated ? 0.5 : 1.0))
]),
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Align(
alignment: Alignment.centerRight,
child: buildTextButton(
@@ -227,69 +257,66 @@ class VacationView extends GetWidget<VacationController> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_responsiveUtils.isPortraitMobile(context))
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
AppLocalizations.of(context).vacationResponder,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black)),
const SizedBox(height: 16),
Obx(() => ToggleSwitch(
minWidth: 150.0,
cornerRadius: 20.0,
activeBgColors: const [[Colors.green], [Colors.redAccent]],
activeFgColor: Colors.white,
inactiveBgColor: Colors.grey,
inactiveFgColor: Colors.white,
initialLabelIndex: controller.isVacationDeactivated ? 1 : 0,
totalSwitches: VacationResponderStatus.values.length,
labels: VacationResponderStatus.values
.map((status) => status.getTitle(context))
.toList(),
radiusStyle: true,
onToggle: (index) {
final newStatus = index == 0
? VacationResponderStatus.activated
: VacationResponderStatus.deactivated;
controller.updateVacationPresentation(newStatus: newStatus);
},
))
])
else
Row(children: [
Expanded(
child: Text(
AppLocalizations.of(context).vacationResponder,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black)),
),
const SizedBox(width: 16),
Obx(() => ToggleSwitch(
minWidth: 150.0,
cornerRadius: 20.0,
activeBgColors: const [[Colors.green], [Colors.redAccent]],
activeFgColor: Colors.white,
inactiveBgColor: Colors.grey,
inactiveFgColor: Colors.white,
initialLabelIndex: controller.isVacationDeactivated ? 1 : 0,
totalSwitches: VacationResponderStatus.values.length,
labels: VacationResponderStatus.values
.map((status) => status.getTitle(context))
.toList(),
radiusStyle: true,
onToggle: (index) {
final newStatus = index == 0
? VacationResponderStatus.activated
: VacationResponderStatus.deactivated;
controller.updateVacationPresentation(newStatus: newStatus);
},
))
]),
const SizedBox(height: 20),
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
AppLocalizations.of(context).vacationResponder,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black)),
const SizedBox(height: 10),
Obx(() {
return Row(
children: [
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
controller.updateVacationPresentation(newStatus: VacationResponderStatus.deactivated);
},
child: Text(AppLocalizations.of(context).deactivated,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 1.0 : 0.3))),
),
),
Padding(
padding: const EdgeInsets.only(top: 3, right: 16, left: 16),
child: InkWell(
onTap: () {
final newStatus = controller.isVacationDeactivated
? VacationResponderStatus.activated
: VacationResponderStatus.deactivated;
controller.updateVacationPresentation(newStatus: newStatus);
},
child: SvgPicture.asset(
controller.isVacationDeactivated
? _imagePaths.icSwitchOff
: _imagePaths.icSwitchOn,
fit: BoxFit.fill,
width: 24,
height: 24)),
),
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
controller.updateVacationPresentation(newStatus: VacationResponderStatus.activated);
},
child: Text(AppLocalizations.of(context).activated,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.normal,
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.3 : 1.0))),
),
)
]);
})
]),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -311,10 +338,7 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).startDate,
icon: const Icon(
Icons.date_range,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icCalendar),
tapActionCallback: (value) =>
controller.selectDate(context, DateType.start, value)))),
const SizedBox(width: 16),
@@ -327,16 +351,13 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
controller.isVacationDeactivated ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noStartTime,
icon: const Icon(
Icons.timer,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icClock),
tapActionCallback: (value) =>
controller.selectTime(context, DateType.start, value))))
]),
]),
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: CheckboxListTile(
@@ -376,10 +397,7 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
!controller.canChangeEndDate ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noEndDate,
icon: const Icon(
Icons.date_range,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icCalendar),
tapActionCallback: (value) =>
controller.selectDate(context, DateType.end, value)))),
const SizedBox(width: 16),
@@ -392,16 +410,13 @@ class VacationView extends GetWidget<VacationController> {
color: Colors.black.withOpacity(
!controller.canChangeEndDate ? 0.5 : 1.0)),
hintText: AppLocalizations.of(context).noEndTime,
icon: const Icon(
Icons.timer,
color: AppColor.colorIconTextField,
size: 20),
icon: SvgPicture.asset(_imagePaths.icClock),
tapActionCallback: (value) =>
controller.selectTime(context, DateType.end, value))))
]),
])
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Obx(() => AbsorbPointer(
absorbing: controller.isVacationDeactivated,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -418,7 +433,7 @@ class VacationView extends GetWidget<VacationController> {
controller.isVacationDeactivated ? 0.5 : 1.0)
]),
)),
const SizedBox(height: 20),
const SizedBox(height: 16),
Align(
alignment: Alignment.centerRight,
child: buildTextButton(
@@ -462,9 +477,25 @@ class VacationView extends GetWidget<VacationController> {
.hintMessageBodyVacation))
.build())
..onChange((value) => controller.updateMessageBody(context, value))
..minLines(8)
..minLines(10)
..maxLines(null))
.build();
});
}
EdgeInsets _getPaddingView(BuildContext context) {
if (BuildUtils.isWeb) {
if (_responsiveUtils.isDesktop(context)) {
return const EdgeInsets.all(16);
} else {
return const EdgeInsets.only(top: 16, bottom: 16, left: 0, right: 24);
}
} else {
if (_responsiveUtils.isPortraitMobile(context)) {
return const EdgeInsets.only(top: 16, bottom: 16, left: 16, right: 24);
} else {
return const EdgeInsets.only(top: 16, bottom: 16, left: 0, right: 24);
}
}
}
}
@@ -0,0 +1,59 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef DisableVacationResponderAction = Function();
class VacationNotificationMessageWidget extends StatelessWidget {
final VacationResponse vacationResponse;
final DisableVacationResponderAction? action;
final EdgeInsets? margin;
final EdgeInsets? padding;
final double? radius;
const VacationNotificationMessageWidget({
super.key,
required this.vacationResponse,
this.action,
this.radius,
this.margin,
this.padding,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: margin ?? const EdgeInsets.symmetric(horizontal: 16),
padding: padding ?? const EdgeInsets.only(top: 5, bottom: 5, left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(radius ?? 5),
color: AppColor.colorVacationNotificationMessageBackground,
),
child: Row(children: [
Expanded(
child: Text(
AppLocalizations.of(context).yourVacationResponderIsEnabled,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold,
))),
buildTextButton(
AppLocalizations.of(context).disable.allInCaps,
textStyle: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
color: AppColor.colorTextButton),
backgroundColor: Colors.transparent,
width: 128,
height: 44,
radius: 10,
onTap: () => action?.call())
]),
);
}
}
@@ -16,6 +16,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
@@ -60,6 +62,17 @@ class ThreadView extends GetWidget<ThreadController> with AppLoaderMixin,
if ((!_responsiveUtils.isDesktop(context) && BuildUtils.isWeb) || !BuildUtils.isWeb)
... [
_buildAppBarNormal(context),
Obx(() {
if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: VacationNotificationMessageWidget(
vacationResponse: controller.mailboxDashBoardController.vacationResponse.value!),
);
} else {
return const SizedBox.shrink();
}
}),
Obx(() {
return Stack(children: [
if (!controller.isSearchActive())
+13 -7
View File
@@ -1,5 +1,5 @@
{
"@@last_modified": "2022-08-17T20:19:48.796318",
"@@last_modified": "2022-08-18T14:30:25.186365",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -1910,12 +1910,6 @@
"placeholders_order": [],
"placeholders": {}
},
"configuration": "Configuration",
"@configuration": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"vacationResponder": "Vacation responder",
"@vacationResponder": {
"type": "text",
@@ -2005,5 +1999,17 @@
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"yourVacationResponderIsEnabled": "Your vacation responder is enabled.",
"@yourVacationResponderIsEnabled": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"disable": "Disable",
"@disable": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
}
}
+14 -7
View File
@@ -1967,13 +1967,6 @@ class AppLocalizations {
);
}
String get configuration {
return Intl.message(
'Configuration',
name: 'configuration',
);
}
String get vacationResponder {
return Intl.message(
'Vacation responder',
@@ -2078,4 +2071,18 @@ class AppLocalizations {
name: 'vacationSettingSaved',
);
}
String get yourVacationResponderIsEnabled {
return Intl.message(
'Your vacation responder is enabled.',
name: 'yourVacationResponderIsEnabled',
);
}
String get disable {
return Intl.message(
'Disable',
name: 'disable',
);
}
}
-2
View File
@@ -187,8 +187,6 @@ dependencies:
byte_converter: 1.3.0
toggle_switch: 2.0.1
dev_dependencies:
flutter_test:
sdk: flutter