Skip to content

Commit 387b401

Browse files
committed
TF-4069 Automatically reply should be deactivated vacation after end date
1 parent 38d64c4 commit 387b401

File tree

9 files changed

+116
-74
lines changed

9 files changed

+116
-74
lines changed

lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,12 +2020,16 @@ class MailboxDashBoardController extends ReloadableController
20202020
downloadController.deleteDownloadTask(taskId);
20212021
}
20222022

2023-
void disableVacationResponder() {
2023+
void disableVacationResponder(VacationResponse vacationResponse) {
20242024
if (accountId.value != null && _updateVacationInteractor != null) {
2025-
final vacationDisabled = vacationResponse.value != null
2026-
? vacationResponse.value!.copyWith(isEnabled: false)
2027-
: VacationResponse(isEnabled: false);
2028-
consumeState(_updateVacationInteractor!.execute(accountId.value!, vacationDisabled));
2025+
consumeState(_updateVacationInteractor!.execute(
2026+
accountId.value!,
2027+
vacationResponse.clearAllExceptHtmlBody(),
2028+
));
2029+
} else {
2030+
consumeState(
2031+
Stream.value(Left(UpdateVacationFailure(ParametersIsNullException()))),
2032+
);
20292033
}
20302034
}
20312035

lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,12 +605,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
605605

606606
Widget _buildVacationNotificationMessage(BuildContext context) {
607607
return Obx(() {
608-
if (controller.vacationResponse.value?.vacationResponderIsValid == true) {
608+
final vacation = controller.vacationResponse.value;
609+
if (vacation?.vacationResponderIsValid == true) {
609610
return VacationNotificationMessageWidget(
610611
margin: VacationNotificationMessageWidgetStyle.bannerMargin,
611-
vacationResponse: controller.vacationResponse.value!,
612+
vacationResponse: vacation!,
612613
actionGotoVacationSetting: controller.goToVacationSetting,
613-
actionEndNow: controller.disableVacationResponder);
614+
actionEndNow: controller.disableVacationResponder,
615+
);
614616
} else {
615617
return const SizedBox.shrink();
616618
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
2+
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
3+
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
4+
5+
extension HandleVacationResponseExtension on ManageAccountDashBoardController {
6+
void syncVacationResponse(VacationResponse? newVacation) {
7+
if (newVacation?.vacationResponderIsStopped == true) {
8+
automaticallyDeactivateVacation(newVacation!);
9+
} else {
10+
setUpVacation(newVacation);
11+
}
12+
}
13+
14+
void setUpVacation(VacationResponse? newVacation) {
15+
vacationResponse.value = newVacation;
16+
}
17+
18+
void automaticallyDeactivateVacation(VacationResponse vacationResponse) {
19+
disableVacationResponder(vacationResponse);
20+
}
21+
}

lib/features/manage_account/presentation/extensions/vacation_response_extension.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ extension VacationResponseExtension on VacationResponse {
8787
htmlBody: htmlBody ?? this.htmlBody
8888
);
8989
}
90+
91+
VacationResponse clearAllExceptHtmlBody() {
92+
return VacationResponse(isEnabled: false, htmlBody: htmlBody);
93+
}
9094

9195
String getNotificationMessage(BuildContext context) {
9296
if (vacationResponderIsValid) {

lib/features/manage_account/presentation/manage_account_dashboard_controller.dart

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import 'package:back_button_interceptor/back_button_interceptor.dart';
32
import 'package:core/core.dart';
43
import 'package:dartz/dartz.dart';
@@ -18,6 +17,7 @@ import 'package:tmail_ui_user/features/base/mixin/own_email_address_mixin.dart';
1817
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
1918
import 'package:tmail_ui_user/features/base/widget/dialog_picker/color_dialog_picker.dart';
2019
import 'package:tmail_ui_user/features/base/widget/dialog_picker/date_time_dialog_picker.dart';
20+
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
2121
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
2222
import 'package:tmail_ui_user/features/manage_account/domain/state/export_trace_log_state.dart';
2323
import 'package:tmail_ui_user/features/manage_account/domain/state/get_all_vacation_state.dart';
@@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vac
2727
import 'package:tmail_ui_user/features/manage_account/presentation/action/dashboard_setting_action.dart';
2828
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_bindings.dart';
2929
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/export_trace_log_extension.dart';
30+
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/handle_vacation_response_extension.dart';
3031
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
3132
import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forward_bindings.dart';
3233
import 'package:tmail_ui_user/features/manage_account/presentation/identities/identity_bindings.dart';
@@ -80,9 +81,7 @@ class ManageAccountDashBoardController extends ReloadableController
8081
@override
8182
void handleSuccessViewState(Success success) {
8283
if (success is GetAllVacationSuccess) {
83-
if (success.listVacationResponse.isNotEmpty) {
84-
vacationResponse.value = success.listVacationResponse.first;
85-
}
84+
syncVacationResponse(success.listVacationResponse.firstOrNull);
8685
} else if (success is UpdateVacationSuccess) {
8786
_handleUpdateVacationSuccess(success);
8887
} else if (success is ExportTraceLogSuccess) {
@@ -96,6 +95,8 @@ class ManageAccountDashBoardController extends ReloadableController
9695
void handleFailureViewState(Failure failure) {
9796
if (failure is ExportTraceLogFailure) {
9897
handleExportTraceLogFailure(failure);
98+
} else if (failure is UpdateVacationFailure) {
99+
setUpVacation(null);
99100
} else {
100101
super.handleFailureViewState(failure);
101102
}
@@ -178,10 +179,6 @@ class ManageAccountDashBoardController extends ReloadableController
178179
}
179180
}
180181

181-
void updateVacationResponse(VacationResponse? newVacation) {
182-
vacationResponse.value = newVacation;
183-
}
184-
185182
void selectAccountMenuItem(AccountMenuItem newAccountMenuItem) {
186183
settingsPageLevel.value = newAccountMenuItem == AccountMenuItem.none
187184
? SettingsPageLevel.universal
@@ -292,25 +289,28 @@ class ManageAccountDashBoardController extends ReloadableController
292289
}
293290
}
294291

295-
void disableVacationResponder() {
292+
void disableVacationResponder(VacationResponse vacation) {
296293
if (accountId.value != null && _updateVacationInteractor != null) {
297-
final vacationDisabled = vacationResponse.value != null
298-
? vacationResponse.value!.copyWith(isEnabled: false)
299-
: VacationResponse(isEnabled: false);
300-
consumeState(_updateVacationInteractor!.execute(accountId.value!, vacationDisabled));
294+
consumeState(_updateVacationInteractor!.execute(
295+
accountId.value!,
296+
vacation.clearAllExceptHtmlBody(),
297+
));
298+
} else {
299+
consumeState(
300+
Stream.value(Left(UpdateVacationFailure(ParametersIsNullException()))),
301+
);
301302
}
302303
}
303304

304305
void _handleUpdateVacationSuccess(UpdateVacationSuccess success) {
305-
if (success.listVacationResponse.isNotEmpty) {
306-
if (currentContext != null && currentOverlayContext != null) {
307-
appToast.showToastSuccessMessage(
308-
currentOverlayContext!,
309-
AppLocalizations.of(currentContext!).yourVacationResponderIsDisabledSuccessfully);
310-
}
311-
vacationResponse.value = success.listVacationResponse.first;
312-
log('ManageAccountDashBoardController::_handleUpdateVacationSuccess(): $vacationResponse');
306+
if (success.listVacationResponse.isNotEmpty &&
307+
currentContext != null &&
308+
currentOverlayContext != null) {
309+
appToast.showToastSuccessMessage(
310+
currentOverlayContext!,
311+
AppLocalizations.of(currentContext!).yourVacationResponderIsDisabledSuccessfully);
313312
}
313+
setUpVacation(success.listVacationResponse.firstOrNull);
314314
}
315315

316316
bool inVacationSettings() {

lib/features/manage_account/presentation/manage_account_dashboard_view.dart

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
2929

3030
@override
3131
Widget build(BuildContext context) {
32+
final isWebDesktop = controller.responsiveUtils.isWebDesktop(context);
3233
return Portal(
3334
child: Scaffold(
34-
backgroundColor: controller.responsiveUtils.isWebDesktop(context)
35+
backgroundColor: isWebDesktop
3536
? AppColor.colorBgDesktop
3637
: Colors.white,
3738
drawerEnableOpenDragGesture: false,
@@ -82,32 +83,34 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
8283
color: AppColor.colorBgDesktop,
8384
child: Column(children: [
8485
Obx(() {
85-
if (controller.vacationResponse.value?.vacationResponderIsValid == true) {
86+
final vacation = controller.vacationResponse.value;
87+
88+
if (vacation?.vacationResponderIsValid == true) {
8689
return VacationNotificationMessageWidget(
8790
margin: EdgeInsetsDirectional.only(
88-
start: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
91+
start: isWebDesktop ? 0 : 16,
8992
end: 16,
90-
top: controller.responsiveUtils.isWebDesktop(context) ? 16 : 0,
91-
bottom: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
93+
top: isWebDesktop ? 16 : 0,
94+
bottom: isWebDesktop ? 0 : 16,
9295
),
9396
fromAccountDashBoard: true,
94-
vacationResponse: controller.vacationResponse.value!,
97+
vacationResponse: vacation!,
9598
actionGotoVacationSetting: !controller.inVacationSettings()
9699
? () => controller.selectAccountMenuItem(AccountMenuItem.vacation)
97100
: null,
98-
actionEndNow: controller.disableVacationResponder);
99-
} else if ((controller.vacationResponse.value?.vacationResponderIsWaiting == true
100-
|| controller.vacationResponse.value?.vacationResponderIsStopped == true)
101-
&& controller.accountMenuItemSelected.value == AccountMenuItem.vacation) {
101+
actionEndNow: controller.disableVacationResponder,
102+
);
103+
} else if (vacation?.vacationResponderIsWaiting == true &&
104+
controller.inVacationSettings()) {
102105
return VacationNotificationMessageWidget(
103106
margin: EdgeInsetsDirectional.only(
104-
start: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
107+
start: isWebDesktop ? 0 : 16,
105108
end: 16,
106-
top: controller.responsiveUtils.isWebDesktop(context) ? 16 : 0,
107-
bottom: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
109+
top: isWebDesktop ? 16 : 0,
110+
bottom: isWebDesktop ? 0 : 16,
108111
),
109112
fromAccountDashBoard: true,
110-
vacationResponse: controller.vacationResponse.value!,
113+
vacationResponse: vacation!,
111114
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
112115
leadingIcon: const Padding(
113116
padding: EdgeInsetsDirectional.only(end: 12),

lib/features/manage_account/presentation/menu/settings/settings_view.dart

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,36 @@ class SettingsView extends GetWidget<SettingsController> {
4040
controller.showExportTraceLogConfirmDialog(context),
4141
)),
4242
Obx(() {
43-
if (controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsValid == true) {
43+
final dashboard = controller.manageAccountDashboardController;
44+
final vacation = dashboard.vacationResponse.value;
45+
final isWebDesktop = controller.responsiveUtils.isWebDesktop(context);
46+
47+
if (vacation?.vacationResponderIsValid == true) {
4448
return VacationNotificationMessageWidget(
4549
margin: EdgeInsetsDirectional.only(
4650
start: 12,
4751
end: 12,
48-
top: controller.responsiveUtils.isWebDesktop(context) ? 8 : 0,
49-
bottom: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
52+
top: isWebDesktop ? 8 : 0,
53+
bottom: isWebDesktop ? 0 : 16,
5054
),
5155
fromAccountDashBoard: true,
52-
vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!,
53-
actionGotoVacationSetting: !controller.manageAccountDashboardController.inVacationSettings()
54-
? () => controller.manageAccountDashboardController.selectAccountMenuItem(AccountMenuItem.vacation)
56+
vacationResponse: vacation!,
57+
actionGotoVacationSetting: !dashboard.inVacationSettings()
58+
? () => dashboard.selectAccountMenuItem(AccountMenuItem.vacation)
5559
: null,
56-
actionEndNow: controller.manageAccountDashboardController.disableVacationResponder
60+
actionEndNow: dashboard.disableVacationResponder
5761
);
58-
} else if ((controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsWaiting == true
59-
|| controller.manageAccountDashboardController.vacationResponse.value?.vacationResponderIsStopped == true)
60-
&& controller.manageAccountDashboardController.inVacationSettings()) {
62+
} else if (vacation?.vacationResponderIsWaiting == true &&
63+
dashboard.inVacationSettings()) {
6164
return VacationNotificationMessageWidget(
6265
margin: EdgeInsetsDirectional.only(
6366
start: 12,
6467
end: 12,
65-
top: controller.responsiveUtils.isWebDesktop(context) ? 8 : 0,
66-
bottom: controller.responsiveUtils.isWebDesktop(context) ? 0 : 16,
68+
top: isWebDesktop ? 8 : 0,
69+
bottom: isWebDesktop ? 0 : 16,
6770
),
6871
fromAccountDashBoard: true,
69-
vacationResponse: controller.manageAccountDashboardController.vacationResponse.value!,
72+
vacationResponse: vacation!,
7073
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
7174
leadingIcon: const Padding(
7275
padding: EdgeInsetsDirectional.only(end: 12),

lib/features/manage_account/presentation/vacation/vacation_controller.dart

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import 'package:rich_text_composer/views/commons/constants.dart';
88
import 'package:tmail_ui_user/features/base/base_controller.dart';
99
import 'package:tmail_ui_user/features/base/widget/dialog_picker/date_time_dialog_picker.dart';
1010
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
11+
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/null_session_or_accountid_exception.dart';
1112
import 'package:tmail_ui_user/features/manage_account/domain/state/update_vacation_state.dart';
1213
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_vacation_interactor.dart';
14+
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/handle_vacation_response_extension.dart';
1315
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
1416
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
1517
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
@@ -223,7 +225,7 @@ class VacationController extends BaseController {
223225
_updateVacationAction(newVacationResponse);
224226
} else {
225227
final vacationDisabled = currentVacation != null
226-
? currentVacation!.copyWith(isEnabled: false)
228+
? currentVacation!.clearAllExceptHtmlBody()
227229
: VacationResponse(isEnabled: false);
228230
log('VacationController::saveVacation(): vacationDisabled: $vacationDisabled');
229231
_updateVacationAction(vacationDisabled);
@@ -234,26 +236,28 @@ class VacationController extends BaseController {
234236
final accountId = _accountDashBoardController.accountId.value;
235237
if (accountId != null) {
236238
consumeState(_updateVacationInteractor.execute(accountId, vacationResponse));
239+
} else {
240+
consumeState(
241+
Stream.value(Left(UpdateVacationFailure(NullSessionOrAccountIdException()))),
242+
);
237243
}
238244
}
239245

240246
void _handleUpdateVacationSuccess(UpdateVacationSuccess success) {
241-
if (success.listVacationResponse.isNotEmpty) {
242-
if (currentOverlayContext != null && currentContext != null) {
243-
appToast.showToastSuccessMessage(
244-
currentOverlayContext!,
245-
AppLocalizations.of(currentContext!).vacationSettingSaved);
246-
}
247-
currentVacation = success.listVacationResponse.first;
248-
log('VacationController::_handleUpdateVacationSuccess(): $currentVacation');
249-
250-
if (currentVacation != null) {
251-
final newVacationPresentation = currentVacation!.toVacationPresentation();
252-
_initializeValueForVacation(newVacationPresentation);
253-
}
247+
if (success.listVacationResponse.isNotEmpty &&
248+
currentOverlayContext != null &&
249+
currentContext != null) {
250+
appToast.showToastSuccessMessage(
251+
currentOverlayContext!,
252+
AppLocalizations.of(currentContext!).vacationSettingSaved);
253+
}
254254

255-
_accountDashBoardController.updateVacationResponse(currentVacation);
255+
currentVacation = success.listVacationResponse.firstOrNull;
256+
if (currentVacation != null) {
257+
final newVacationPresentation = currentVacation!.toVacationPresentation();
258+
_initializeValueForVacation(newVacationPresentation);
256259
}
260+
_accountDashBoardController.setUpVacation(currentVacation);
257261
}
258262

259263
void updateMessageHtmlText(String? text) => _vacationMessageHtmlText = text;

lib/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
66
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
77
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
88

9-
typedef EndNowVacationSettingAction = Function();
9+
typedef EndNowVacationSettingAction = Function(VacationResponse vacation);
1010
typedef GoToVacationSettingAction = Function();
1111

1212
class VacationNotificationMessageWidget extends StatelessWidget {
@@ -93,7 +93,8 @@ class VacationNotificationMessageWidget extends StatelessWidget {
9393
maxWidth: 180,
9494
maxLines: 1,
9595
tooltipMessage: AppLocalizations.of(context).endNow,
96-
onTapActionCallback: actionEndNow),
96+
onTapActionCallback: () => actionEndNow?.call(vacationResponse),
97+
),
9798
if (actionGotoVacationSetting != null)
9899
TMailButtonWidget.fromText(
99100
text: AppLocalizations.of(context).vacationSetting,
@@ -148,7 +149,7 @@ class VacationNotificationMessageWidget extends StatelessWidget {
148149
maxWidth: 180,
149150
maxLines: 1,
150151
tooltipMessage: AppLocalizations.of(context).endNow,
151-
onTapActionCallback: actionEndNow
152+
onTapActionCallback: () => actionEndNow?.call(vacationResponse),
152153
),
153154
),
154155
if (actionGotoVacationSetting != null)

0 commit comments

Comments
 (0)