diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 1f8f06920..1e34f850f 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -376,7 +376,7 @@ class ComposerController extends BaseController { final sentDate = presentationEmail.sentAt; final emailAddress = presentationEmail.from.listEmailAddressToString(isFullEmailAddress: true); return AppLocalizations.of(context).header_email_quoted( - sentDate.formatDate(pattern: 'MMM d, y h:mm a', locale: locale), + sentDate.formatDateToLocal(pattern: 'MMM d, y h:mm a', locale: locale), emailAddress); case EmailActionType.forward: var headerQuoted = '------- ${AppLocalizations.of(context).forwarded_message} -------'.addNewLineTag(); @@ -397,7 +397,7 @@ class ComposerController extends BaseController { if (sentDate != null) { headerQuoted = headerQuoted .append('${AppLocalizations.of(context).date}: ') - .append(sentDate.formatDate(pattern: 'MMM d, y h:mm a', locale: locale)) + .append(sentDate.formatDateToLocal(pattern: 'MMM d, y h:mm a', locale: locale)) .addNewLineTag(); } if (fromEmailAddress.isNotEmpty) { diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index b11ee43c7..c100bd173 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -61,7 +61,7 @@ class EmailView extends GetWidget with NetworkConnectionMixin { child: Column(children: [ _buildAppBar(context), Obx(() { - if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true && + if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsValid == true && (responsiveUtils.isMobile(context) || responsiveUtils.isTablet(context) || responsiveUtils.isLandscapeMobile(context))) { diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart index e42ac31fc..8e7dc907f 100644 --- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart +++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart @@ -96,7 +96,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView { SizedBox(child: MailboxView(), width: responsiveUtils.defaultSizeMenu), Expanded(child: Column(children: [ Obx(() { - if (controller.vacationResponse.value?.vacationResponderIsReady == true) { + if (controller.vacationResponse.value?.vacationResponderIsValid == true) { return VacationNotificationMessageWidget( margin: const EdgeInsets.only(top: 16, right: 16), vacationResponse: controller.vacationResponse.value!, diff --git a/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart b/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart index 24f88a873..c35878135 100644 --- a/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart +++ b/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart @@ -3,8 +3,10 @@ import 'package:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart'; +import 'package:model/model.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/model/vacation/vacation_presentation.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'; extension VacationResponseExtension on VacationResponse { @@ -26,14 +28,48 @@ extension VacationResponseExtension on VacationResponse { ); } + bool get vacationResponderIsValid { + return vacationResponderIsReady && !vacationResponderIsStopped; + } + 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) { + if (startDate != null && (startDate.isBefore(currentDate) || + startDate.isAtSameMomentAs(currentDate))) { + return true; + } else { + return false; + } + } + return false; + } + + bool get vacationResponderIsWaiting { + if (isEnabled == true) { + final currentDate = DateTime.now().toUtc(); + log('VacationResponseExtension::vacationResponderIsWaiting(): currentDate: $currentDate'); + final startDate = fromDate?.value.toUtc(); + log('VacationResponseExtension::vacationResponderIsWaiting(): startDate: $startDate'); + if (startDate != null && startDate.isAfter(currentDate)) { + return true; + } else { + return false; + } + } + return false; + } + + bool get vacationResponderIsStopped { + if (isEnabled == true) { + final currentDate = DateTime.now().toUtc(); + log('VacationResponseExtension::vacationResponderIsStopped(): currentDate: $currentDate'); + final endDate = toDate?.value.toUtc(); + log('VacationResponseExtension::vacationResponderIsStopped(): endDate: $endDate'); + if (endDate != null && endDate.isBefore(currentDate)) { return true; } else { return false; @@ -59,4 +95,22 @@ extension VacationResponseExtension on VacationResponse { htmlBody: htmlBody ?? this.htmlBody ); } + + String getNotificationMessage(BuildContext context) { + if (vacationResponderIsValid) { + return AppLocalizations.of(context).yourVacationResponderIsEnabled; + } else if (vacationResponderIsWaiting) { + return AppLocalizations.of(context).messageEnableVacationResponderAutomatically( + fromDate.formatDate( + pattern: 'MMM d, y h:mm a', + locale: Localizations.localeOf(context).toLanguageTag())); + } else if (vacationResponderIsStopped) { + return AppLocalizations.of(context).messageDisableVacationResponderAutomatically( + toDate.formatDate( + pattern: 'MMM d, y h:mm a', + locale: Localizations.localeOf(context).toLanguageTag())); + } else { + return ''; + } + } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart index 1bbcb4cfe..2774d9e84 100644 --- a/lib/features/manage_account/presentation/manage_account_dashboard_view.dart +++ b/lib/features/manage_account/presentation/manage_account_dashboard_view.dart @@ -85,7 +85,7 @@ class ManageAccountDashBoardView extends GetWidget controller.disableVacationResponder()); + } else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true + || controller.vacationResponse.value?.vacationResponderIsStopped == true) + && controller.accountMenuItemSelected.value == AccountMenuItem.vacation) { + return VacationNotificationMessageWidget( + margin: const EdgeInsets.only( + top: 16, + left: BuildUtils.isWeb ? 24 : 16, + right: BuildUtils.isWeb ? 24 : 16), + vacationResponse: controller.vacationResponse.value!, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + backgroundColor: Colors.yellow, + fontWeight: FontWeight.normal, + leadingIcon: const Padding( + padding: EdgeInsets.only(right: 16), + child: Icon(Icons.timer, size: 20), + )); } else { return const SizedBox.shrink(); } @@ -111,7 +127,7 @@ class ManageAccountDashBoardView extends GetWidget controller.disableVacationResponder()); + } else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true + || controller.vacationResponse.value?.vacationResponderIsStopped == true) + && controller.accountMenuItemSelected.value == AccountMenuItem.vacation) { + 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!, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + fontWeight: FontWeight.normal, + backgroundColor: Colors.yellow, + leadingIcon: const Padding( + padding: EdgeInsets.only(right: 16), + child: Icon(Icons.timer, size: 20), + )); } else { return const SizedBox.shrink(); } diff --git a/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart b/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart index 71d83a52c..1ce627ded 100644 --- a/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart +++ b/lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart @@ -2,6 +2,7 @@ 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/features/manage_account/presentation/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; typedef DisableVacationResponderAction = Function(); @@ -13,6 +14,9 @@ class VacationNotificationMessageWidget extends StatelessWidget { final EdgeInsets? margin; final EdgeInsets? padding; final double? radius; + final Widget? leadingIcon; + final Color? backgroundColor; + final FontWeight? fontWeight; const VacationNotificationMessageWidget({ super.key, @@ -21,6 +25,9 @@ class VacationNotificationMessageWidget extends StatelessWidget { this.radius, this.margin, this.padding, + this.leadingIcon, + this.backgroundColor, + this.fontWeight, }); @override @@ -28,31 +35,33 @@ class VacationNotificationMessageWidget extends StatelessWidget { return Container( width: double.infinity, margin: margin ?? const EdgeInsets.symmetric(horizontal: 16), - padding: padding ?? const EdgeInsets.only(top: 5, bottom: 5, left: 16), + padding: padding ?? const EdgeInsets.only(left: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(radius ?? 5), - color: AppColor.colorVacationNotificationMessageBackground, + color: backgroundColor ?? AppColor.colorVacationNotificationMessageBackground, ), child: Row(children: [ + if (leadingIcon != null) leadingIcon!, Expanded( child: Text( - AppLocalizations.of(context).yourVacationResponderIsEnabled, - style: const TextStyle( + vacationResponse.getNotificationMessage(context), + style: TextStyle( color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, + fontSize: 13, + fontWeight: fontWeight ?? FontWeight.w500, ))), - 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()) + if (action != null) + buildTextButton( + AppLocalizations.of(context).disable.allInCaps, + textStyle: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 13, + color: AppColor.colorTextButton), + backgroundColor: Colors.transparent, + width: 128, + height: 44, + radius: 10, + onTap: () => action!.call()) ]), ); } diff --git a/lib/features/thread/presentation/thread_view.dart b/lib/features/thread/presentation/thread_view.dart index bb450c579..0ab4224b3 100644 --- a/lib/features/thread/presentation/thread_view.dart +++ b/lib/features/thread/presentation/thread_view.dart @@ -63,7 +63,7 @@ class ThreadView extends GetWidget with AppLoaderMixin, ... [ _buildAppBarNormal(context), Obx(() { - if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsReady == true) { + if (controller.mailboxDashBoardController.vacationResponse.value?.vacationResponderIsValid == true) { return Padding( padding: const EdgeInsets.only(bottom: 16), child: VacationNotificationMessageWidget( diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index a935d77e3..b64d3b322 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-08-18T16:16:05.548805", + "@@last_modified": "2022-08-18T17:02:08.322535", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -2017,5 +2017,25 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "messageEnableVacationResponderAutomatically": "Your vacation responder will be activated on {startDate}", + "@messageEnableVacationResponderAutomatically": { + "type": "text", + "placeholders_order": [ + "startDate" + ], + "placeholders": { + "startDate": {} + } + }, + "messageDisableVacationResponderAutomatically": "Your vacation responder stopped on {endDate}", + "@messageDisableVacationResponderAutomatically": { + "type": "text", + "placeholders_order": [ + "endDate" + ], + "placeholders": { + "endDate": {} + } } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 2816a1210..1f93f6c73 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2092,4 +2092,18 @@ class AppLocalizations { name: 'yourVacationResponderIsDisabledSuccessfully', ); } + + String messageEnableVacationResponderAutomatically(String startDate) { + return Intl.message( + 'Your vacation responder will be activated on $startDate', + name: 'messageEnableVacationResponderAutomatically', + args: [startDate]); + } + + String messageDisableVacationResponderAutomatically(String endDate) { + return Intl.message( + 'Your vacation responder stopped on $endDate', + name: 'messageDisableVacationResponderAutomatically', + args: [endDate]); + } } \ No newline at end of file diff --git a/model/lib/extensions/presentation_email_extension.dart b/model/lib/extensions/presentation_email_extension.dart index 80e7d1407..a200f2373 100644 --- a/model/lib/extensions/presentation_email_extension.dart +++ b/model/lib/extensions/presentation_email_extension.dart @@ -18,7 +18,7 @@ extension PresentationEmailExtension on PresentationEmail { String getReceivedAt(String newLocale, {String? pattern}) { final emailTime = receivedAt; if (emailTime != null) { - return emailTime.formatDate( + return emailTime.formatDateToLocal( pattern: pattern ?? emailTime.value.toLocal().toPattern(), locale: newLocale); } diff --git a/model/lib/extensions/utc_date_extension.dart b/model/lib/extensions/utc_date_extension.dart index 3174de5f1..324ac65eb 100644 --- a/model/lib/extensions/utc_date_extension.dart +++ b/model/lib/extensions/utc_date_extension.dart @@ -3,11 +3,19 @@ import 'package:jmap_dart_client/jmap/core/utc_date.dart'; extension UTCDateExtension on UTCDate? { - String formatDate({String pattern = 'yMMMd', String locale = 'en_US'}) { + String formatDateToLocal({String pattern = 'yMMMd', String locale = 'en_US'}) { if (this != null) { return DateFormat(pattern, locale).format(this!.value.toLocal()); } else { return ''; } } + + String formatDate({String pattern = 'yMMMd', String locale = 'en_US'}) { + if (this != null) { + return DateFormat(pattern, locale).format(this!.value); + } else { + return ''; + } + } } \ No newline at end of file