From 67865fd1a2352cd9e25535493d5413ad64c3f670 Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 9 Sep 2022 19:11:52 +0700 Subject: [PATCH] TF-888 Apply new design for vacation on desktop --- assets/images/ic_vacation.svg | 11 +- .../extensions/color_extension.dart | 4 +- .../views/text/input_decoration_builder.dart | 7 +- .../base/widget/border_button_field.dart | 31 +- .../widget/text_input_decoration_builder.dart | 53 ++ .../base/widget/text_input_field_builder.dart | 69 ++ .../extensions/datetime_extension.dart | 3 +- .../vacation_response_extension.dart | 1 + .../menu/manage_account_menu_controller.dart | 4 +- .../model/vacation/vacation_presentation.dart | 10 +- .../vacation/vacation_controller.dart | 25 +- .../presentation/vacation/vacation_view.dart | 674 +++++++----------- lib/l10n/intl_messages.arb | 50 +- lib/main/localizations/app_localizations.dart | 55 +- 14 files changed, 518 insertions(+), 479 deletions(-) create mode 100644 lib/features/base/widget/text_input_decoration_builder.dart create mode 100644 lib/features/base/widget/text_input_field_builder.dart diff --git a/assets/images/ic_vacation.svg b/assets/images/ic_vacation.svg index 745286afd..0672c4a34 100644 --- a/assets/images/ic_vacation.svg +++ b/assets/images/ic_vacation.svg @@ -1,3 +1,12 @@ - + + + + + + + + diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index d2b383d6d..df4cd6129 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -120,7 +120,7 @@ extension AppColor on Color { static const colorBgMenuItemDropDownSelected = Color(0x80DEE2E7); static const colorButtonCancelDialog = Color(0x0D000000); static const colorShadowComposerButton = Color(0x99007AFF); - static const colorBackgroundTagFilter = Color(0x6D7885); + static const colorBackgroundTagFilter = Color(0xFF6D7885); static const colorDefaultRichTextButton = Color(0xFF99A2AD); static const colorFocusRichTextButton = Color(0x146D7885); static const colorStyleBlockQuote = Color(0xFFEEEEEE); @@ -141,6 +141,8 @@ extension AppColor on Color { static const colorVacationNotificationMessageBackground = Color(0x2999A2AD); static const colorDeletePermanentlyButton = Color(0xffE64646); static const colorDefaultButton = Color(0xff9AA1AD); + static const colorVacationSettingExplanation = Color(0xFF686E76); + static const colorBackgroundVacationSettingField = Color(0xFFF2F3F5); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], diff --git a/core/lib/presentation/views/text/input_decoration_builder.dart b/core/lib/presentation/views/text/input_decoration_builder.dart index 1b9846262..9225bbbd9 100644 --- a/core/lib/presentation/views/text/input_decoration_builder.dart +++ b/core/lib/presentation/views/text/input_decoration_builder.dart @@ -13,6 +13,11 @@ abstract class InputDecorationBuilder { OutlineInputBorder? focusBorder; String? errorText; TextStyle? errorTextStyle; + Color? fillColor; + + void setFillColor(Color? newColor) { + fillColor = newColor; + } void setPrefixText(String? newPrefixText) { prefixText = newPrefixText; @@ -74,7 +79,7 @@ abstract class InputDecorationBuilder { errorText: errorText, errorStyle: errorTextStyle, enabledBorder: enabledBorder, - focusedBorder: focusBorder + focusedBorder: focusBorder, ); } } \ No newline at end of file diff --git a/lib/features/base/widget/border_button_field.dart b/lib/features/base/widget/border_button_field.dart index 1485265e1..3ad5ce8fe 100644 --- a/lib/features/base/widget/border_button_field.dart +++ b/lib/features/base/widget/border_button_field.dart @@ -1,10 +1,7 @@ import 'package:core/presentation/extensions/color_extension.dart'; -import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/datetime_extension.dart'; typedef OnTapActionCallback = Function(T? value); @@ -18,9 +15,12 @@ class BorderButtonField extends StatelessWidget { final MouseCursor? mouseCursor; final String? hintText; final bool isEmpty; + final Color? backgroundColor; + final String? label; const BorderButtonField({ super.key, + this.label, this.value, this.tapActionCallback, this.icon, @@ -28,13 +28,12 @@ class BorderButtonField extends StatelessWidget { this.mouseCursor, this.hintText, this.isEmpty = false, + this.backgroundColor, }); @override Widget build(BuildContext context) { - final _imagePaths = Get.find(); - - return InkWell( + final buttonField = InkWell( onTap: () => tapActionCallback?.call(value), mouseCursor: mouseCursor, child: Container( @@ -43,9 +42,9 @@ class BorderButtonField extends StatelessWidget { borderRadius: BorderRadius.circular(10), border: Border.all( color: _getBorderColor(), - width: 1), - color: Colors.white), - padding: const EdgeInsets.only(left: 12, right: 10), + width: 0.5), + color: backgroundColor ?? Colors.white), + padding: const EdgeInsets.symmetric(horizontal: 12), child: Row(children: [ Expanded(child: Text( _getName(context, value), @@ -54,10 +53,22 @@ class BorderButtonField extends StatelessWidget { softWrap: CommonTextStyle.defaultSoftWrap, overflow: CommonTextStyle.defaultTextOverFlow, )), - icon ?? SvgPicture.asset(_imagePaths.icDropDown) + if (icon != null) icon! ]), ), ); + if (label != null) { + return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text(label!, style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: AppColor.colorContentEmail)), + const SizedBox(height: 8), + buttonField + ]); + } else { + return buttonField; + } } TextStyle? _getTextStyle(T? value) { diff --git a/lib/features/base/widget/text_input_decoration_builder.dart b/lib/features/base/widget/text_input_decoration_builder.dart new file mode 100644 index 000000000..cbfdbacad --- /dev/null +++ b/lib/features/base/widget/text_input_decoration_builder.dart @@ -0,0 +1,53 @@ + +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; + +class TextInputDecorationBuilder extends InputDecorationBuilder { + + @override + InputDecoration build() { + return InputDecoration( + enabledBorder: enabledBorder ?? const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide( + width: 0.5, + color: AppColor.colorInputBorderCreateMailbox)), + focusedBorder: enabledBorder ?? const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide( + width: 0.5, + color: AppColor.colorTextButton)), + errorBorder: errorBorder ?? const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide( + width: 0.5, + color: AppColor.colorInputBorderErrorVerifyName)), + focusedErrorBorder: errorBorder ?? const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide( + width: 0.5, + color: AppColor.colorInputBorderErrorVerifyName)), + prefixText: prefixText, + labelText: labelText, + floatingLabelBehavior: FloatingLabelBehavior.never, + labelStyle: labelStyle ?? const TextStyle( + color: Colors.black, + fontSize: 16), + hintText: hintText, + isDense: true, + hintStyle: hintStyle ?? const TextStyle( + color: AppColor.loginTextFieldHintColor, + fontSize: 16), + contentPadding: contentPadding ?? const EdgeInsets.symmetric( + horizontal: 12, + vertical: 12), + errorText: errorText, + errorStyle: errorTextStyle ?? const TextStyle( + color: AppColor.colorInputBorderErrorVerifyName, + fontSize: 13), + filled: true, + fillColor: errorText?.isNotEmpty == true + ? AppColor.colorInputBackgroundErrorVerifyName + : fillColor ?? AppColor.colorInputBackgroundCreateMailbox); + } +} \ No newline at end of file diff --git a/lib/features/base/widget/text_input_field_builder.dart b/lib/features/base/widget/text_input_field_builder.dart new file mode 100644 index 000000000..eed04de4a --- /dev/null +++ b/lib/features/base/widget/text_input_field_builder.dart @@ -0,0 +1,69 @@ + +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/base/widget/text_input_decoration_builder.dart'; + +typedef OnChangeInputAction = Function(String? value); + +class TextInputFieldBuilder extends StatelessWidget { + + final String? label; + final String? error; + final String? hint; + final TextEditingController? editingController; + final FocusNode? focusNode; + final TextInputType? inputType; + final bool isMandatory; + final int? minLines; + final int? maxLines; + final Color? backgroundColor; + final OnChangeInputAction? onChangeInputAction; + + const TextInputFieldBuilder({ + Key? key, + this.label, + this.hint, + this.error, + this.isMandatory = false, + this.editingController, + this.focusNode, + this.inputType, + this.minLines, + this.maxLines, + this.backgroundColor, + this.onChangeInputAction, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (label != null) + ...[ + Text(isMandatory ? '${label!}*' : label!, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: AppColor.colorContentEmail)), + const SizedBox(height: 8) + ], + (TextFieldBuilder() + ..onChange((value) => onChangeInputAction?.call(value)) + ..textInputAction(TextInputAction.next) + ..addController(editingController ?? TextEditingController()) + ..addFocusNode(focusNode) + ..textStyle(const TextStyle(color: Colors.black, fontSize: 16)) + ..keyboardType(inputType ?? TextInputType.text) + ..minLines(minLines) + ..maxLines(maxLines) + ..textDecoration((TextInputDecorationBuilder() + ..setContentPadding(const EdgeInsets.symmetric( + vertical: BuildUtils.isWeb ? 16 : 12, + horizontal: 12)) + ..setHintText(hint) + ..setFillColor(backgroundColor) + ..setErrorText(error)) + .build())) + .build() + ]); + } +} \ No newline at end of file diff --git a/lib/features/manage_account/presentation/extensions/datetime_extension.dart b/lib/features/manage_account/presentation/extensions/datetime_extension.dart index 6134d90e7..ce96ccf18 100644 --- a/lib/features/manage_account/presentation/extensions/datetime_extension.dart +++ b/lib/features/manage_account/presentation/extensions/datetime_extension.dart @@ -23,8 +23,7 @@ extension TimeOfDayExtension on TimeOfDay? { String formatTime(BuildContext context) { if (this != null) { - return MaterialLocalizations.of(context) - .formatTimeOfDay(this!, alwaysUse24HourFormat: true); + return MaterialLocalizations.of(context).formatTimeOfDay(this!); } return ''; } 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 c35878135..130a1b74b 100644 --- a/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart +++ b/lib/features/manage_account/presentation/extensions/vacation_response_extension.dart @@ -24,6 +24,7 @@ extension VacationResponseExtension on VacationResponse { ? TimeOfDay.fromDateTime(toDate!.value.toUtc()) : null, messageBody: textBody ?? htmlBody, + subject: subject, vacationStopEnabled: toDate != null ); } diff --git a/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart b/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart index 892136e05..13802bec1 100644 --- a/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart +++ b/lib/features/manage_account/presentation/menu/manage_account_menu_controller.dart @@ -13,8 +13,8 @@ class ManageAccountMenuController extends BaseController { final listAccountMenuItem = RxList([ AccountMenuItem.profiles, - AccountMenuItem.languageAndRegion, AccountMenuItem.vacation, + AccountMenuItem.languageAndRegion, ]); void _initWorker() { @@ -43,8 +43,8 @@ class ManageAccountMenuController extends BaseController { if (dashBoardController.checkAvailableForwardInSession()) { listAccountMenuItem.add(AccountMenuItem.forward); } - listAccountMenuItem.add(AccountMenuItem.languageAndRegion); listAccountMenuItem.add(AccountMenuItem.vacation); + listAccountMenuItem.add(AccountMenuItem.languageAndRegion); } @override diff --git a/lib/features/manage_account/presentation/model/vacation/vacation_presentation.dart b/lib/features/manage_account/presentation/model/vacation/vacation_presentation.dart index 08ade0039..d392267b6 100644 --- a/lib/features/manage_account/presentation/model/vacation/vacation_presentation.dart +++ b/lib/features/manage_account/presentation/model/vacation/vacation_presentation.dart @@ -13,6 +13,7 @@ class VacationPresentation with EquatableMixin { final DateTime? endDate; final TimeOfDay? endTime; final String? messageBody; + final String? subject; final bool vacationStopEnabled; VacationPresentation({ @@ -22,6 +23,7 @@ class VacationPresentation with EquatableMixin { this.endDate, this.endTime, this.messageBody, + this.subject, this.vacationStopEnabled = false, }); @@ -36,6 +38,7 @@ class VacationPresentation with EquatableMixin { DateTime? endDate, TimeOfDay? endTime, String? messageBody, + String? subject, bool? vacationStopEnabled, }) { return VacationPresentation( @@ -45,6 +48,7 @@ class VacationPresentation with EquatableMixin { endDate: endDate ?? this.endDate, endTime: endTime ?? this.endTime, messageBody: messageBody ?? this.messageBody, + subject: subject ?? this.subject, vacationStopEnabled: vacationStopEnabled ?? this.vacationStopEnabled ); } @@ -71,7 +75,8 @@ class VacationPresentation with EquatableMixin { endDate, endTime, vacationStopEnabled, - messageBody + messageBody, + subject, ]; } @@ -81,7 +86,8 @@ extension VacationPresentationExtension on VacationPresentation { isEnabled: isEnabled, fromDate: fromDate != null ? UTCDate(fromDate!) : null, toDate: toDate != null ? UTCDate(toDate!) : null, - textBody: messageBody + textBody: messageBody, + subject: subject, ); } } \ No newline at end of file diff --git a/lib/features/manage_account/presentation/vacation/vacation_controller.dart b/lib/features/manage_account/presentation/vacation/vacation_controller.dart index 27d852419..f1594c08c 100644 --- a/lib/features/manage_account/presentation/vacation/vacation_controller.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_controller.dart @@ -32,7 +32,8 @@ class VacationController extends BaseController { final vacationPresentation = VacationPresentation.initialize().obs; final errorMessageBody = Rxn(); - final TextEditingController messageBodyEditorController = TextEditingController(); + final messageTextController = TextEditingController(); + final subjectTextController = TextEditingController(); VacationResponse? currentVacation; late Worker vacationWorker; @@ -78,7 +79,8 @@ class VacationController extends BaseController { currentVacation = vacation; final newVacationPresentation = currentVacation?.toVacationPresentation(); vacationPresentation.value = newVacationPresentation ?? VacationPresentation.initialize(); - messageBodyEditorController.text = newVacationPresentation?.messageBody ?? ''; + messageTextController.text = newVacationPresentation?.messageBody ?? ''; + subjectTextController.text = newVacationPresentation?.subject ?? ''; } }); } @@ -98,7 +100,8 @@ class VacationController extends BaseController { if (currentVacation != null) { final newVacationPresentation = currentVacation!.toVacationPresentation(); vacationPresentation.value = newVacationPresentation; - messageBodyEditorController.text = newVacationPresentation.messageBody ?? ''; + messageTextController.text = newVacationPresentation.messageBody ?? ''; + subjectTextController.text = newVacationPresentation.subject ?? ''; } } } @@ -177,7 +180,7 @@ class VacationController extends BaseController { textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom(primary: AppColor.primaryColor))), child: MediaQuery( - data: const MediaQueryData(alwaysUse24HourFormat: true), + data: const MediaQueryData(alwaysUse24HourFormat: false), child: child!), ); } @@ -236,7 +239,7 @@ class VacationController extends BaseController { return; } - final messageBody = messageBodyEditorController.text; + final messageBody = messageTextController.text; if (messageBody.isEmpty) { _appToast.showToastWithIcon( context, @@ -246,7 +249,11 @@ class VacationController extends BaseController { return; } - final newVacationPresentation = vacationPresentation.value.copyWidth(messageBody: messageBody); + final subjectVacation = subjectTextController.text; + + final newVacationPresentation = vacationPresentation.value.copyWidth( + messageBody: messageBody, + subject: subjectVacation); log('VacationController::saveVacation(): newVacationPresentation: $newVacationPresentation'); final newVacationResponse = newVacationPresentation.toVacationResponse(); log('VacationController::saveVacation(): newVacationResponse: $newVacationResponse'); @@ -281,7 +288,8 @@ class VacationController extends BaseController { if (currentVacation != null) { final newVacationPresentation = currentVacation!.toVacationPresentation(); vacationPresentation.value = newVacationPresentation; - messageBodyEditorController.text = newVacationPresentation.messageBody ?? ''; + messageTextController.text = newVacationPresentation.messageBody ?? ''; + subjectTextController.text = newVacationPresentation.subject ?? ''; } _accountDashBoardController.updateVacationResponse(currentVacation); @@ -290,7 +298,8 @@ class VacationController extends BaseController { @override void onClose() { - messageBodyEditorController.dispose(); + messageTextController.dispose(); + subjectTextController.dispose(); vacationWorker.dispose(); super.onClose(); } diff --git a/lib/features/manage_account/presentation/vacation/vacation_view.dart b/lib/features/manage_account/presentation/vacation/vacation_view.dart index 577910438..0ffbd3049 100644 --- a/lib/features/manage_account/presentation/vacation/vacation_view.dart +++ b/lib/features/manage_account/presentation/vacation/vacation_view.dart @@ -4,11 +4,11 @@ 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/base/widget/text_input_field_builder.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.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/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/main/localizations/app_localizations.dart'; class VacationView extends GetWidget { @@ -39,448 +39,260 @@ class VacationView extends GetWidget { color: Colors.white) : null, padding: SettingsUtils.getMarginViewForSettingDetails(context, _responsiveUtils), - child: ResponsiveWidget( - responsiveUtils: _responsiveUtils, - desktop: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(children: [ - Container( - width: 200, - color: Colors.white, - child: Text( - AppLocalizations.of(context).vacationResponder, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black))), - const SizedBox(width: 16), - 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: Row(children: [ - Container( - width: 200, - color: Colors.white, - child: Text( - AppLocalizations.of(context).startDate, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.startDate, - mouseCursor: SystemMouseCursors.text, - isEmpty: !controller.isVacationDeactivated && - controller.vacationPresentation.value.startDateIsNull, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).startDate, - icon: SvgPicture.asset(_imagePaths.icCalendar), - tapActionCallback: (value) => - controller.selectDate(context, DateType.start, value)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.startTime, - mouseCursor: SystemMouseCursors.text, - isEmpty: !controller.isVacationDeactivated && - controller.vacationPresentation.value.starTimeIsNull, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noStartTime, - icon: SvgPicture.asset(_imagePaths.icClock), - tapActionCallback: (value) => - controller.selectTime(context, DateType.start, value)))), - ]), - )), - const SizedBox(height: 16), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Container( - width: 200, - color: Colors.white, - child: CheckboxListTile( - contentPadding: EdgeInsets.zero, - activeColor: AppColor.primaryColor.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0), - controlAffinity: ListTileControlAffinity.leading, - value: controller.vacationPresentation.value.vacationStopEnabled, - onChanged: (value) => - controller.updateVacationPresentation(vacationStopEnabled: value), - title: Text(AppLocalizations.of(context).vacationStopsAt, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0))), - ), - ), - )), - Obx(() => AbsorbPointer( - absorbing: !controller.canChangeEndDate, - child: Row(children: [ - Container( - width: 200, - color: Colors.white, - child: Text( - AppLocalizations.of(context).endDate, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.endDate, - mouseCursor: SystemMouseCursors.text, - isEmpty: controller.canChangeEndDate && - controller.vacationPresentation.value.endDateIsNull, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noEndDate, - icon: SvgPicture.asset(_imagePaths.icCalendar), - tapActionCallback: (value) => - controller.selectDate(context, DateType.end, value)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.endTime, - mouseCursor: SystemMouseCursors.text, - isEmpty: controller.canChangeEndDate && - controller.vacationPresentation.value.endTimeIsNull, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noEndTime, - icon: SvgPicture.asset(_imagePaths.icClock), - tapActionCallback: (value) => - controller.selectTime(context, DateType.end, value)))), - ]) - )), - const SizedBox(height: 16), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 200, - color: Colors.white, - child: Text( - AppLocalizations.of(context).messageBody, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)))), - const SizedBox(width: 16), - Expanded(child: _buildMessageBodyWidget( - context, - controller.isVacationDeactivated ? 0.5 : 1.0)) - ]), - )), - const SizedBox(height: 16), - Align( - alignment: Alignment.centerRight, - child: buildTextButton( - AppLocalizations.of(context).save, - width: 128, - height: 44, - radius: 10, - onTap: () => controller.saveVacation(context)), - ) - ] - ), - ), - mobile: SingleChildScrollView( - child: Column( + child: SingleChildScrollView( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - 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), + if (_responsiveUtils.isWebDesktop(context)) + ...[ + Text(AppLocalizations.of(context).vacation, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + color: Colors.black)), + const SizedBox(height: 8) + ], + Text(AppLocalizations.of(context).vacationSettingExplanation, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: AppColor.colorVacationSettingExplanation)), + const SizedBox(height: 24), + Row(children: [ 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))), - ), - ) - ]); - }) + return 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) + ); + }), + const SizedBox(width: 16), + Expanded( + child: Text(AppLocalizations.of(context).vacationSettingToggleButtonAutoReply, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.black) + ), + ) ]), - const SizedBox(height: 16), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - AppLocalizations.of(context).startDate, - style: TextStyle( - fontSize: 15, + const SizedBox(height: 28), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), + child: Column(children: [ + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: _responsiveUtils.isPortraitMobile(context) + ? Column(children: [ + BorderButtonField( + label: AppLocalizations.of(context).startDate, + value: controller.vacationPresentation.value.startDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && + controller.vacationPresentation.value.startDateIsNull, + hintText: AppLocalizations.of(context).startDate, + tapActionCallback: (value) => + controller.selectDate(context, DateType.start, value)), + const SizedBox(height: 18), + BorderButtonField( + label: AppLocalizations.of(context).startTime, + value: controller.vacationPresentation.value.startTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && + controller.vacationPresentation.value.starTimeIsNull, + hintText: AppLocalizations.of(context).noStartTime, + tapActionCallback: (value) => + controller.selectTime(context, DateType.start, value)), + ]) + : Row(children: [ + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).startDate, + value: controller.vacationPresentation.value.startDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && + controller.vacationPresentation.value.startDateIsNull, + hintText: AppLocalizations.of(context).startDate, + tapActionCallback: (value) => + controller.selectDate(context, DateType.start, value))), + const SizedBox(width: 24), + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).startTime, + value: controller.vacationPresentation.value.startTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: !controller.isVacationDeactivated && + controller.vacationPresentation.value.starTimeIsNull, + hintText: AppLocalizations.of(context).noStartTime, + tapActionCallback: (value) => + controller.selectTime(context, DateType.start, value))), + ]), + ), + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: Row(children: [ + Obx(() => InkWell( + onTap: () { + final value = !controller.vacationPresentation.value.vacationStopEnabled; + controller.updateVacationPresentation(vacationStopEnabled: value); + }, + child: SvgPicture.asset( + controller.vacationPresentation.value.vacationStopEnabled + ? _imagePaths.icSwitchOn + : _imagePaths.icSwitchOff, + fit: BoxFit.fill, + width: 24, + height: 24) + ) + ), + const SizedBox(width: 16), + Expanded( + child: Text(AppLocalizations.of(context).vacationStopsAt, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.black) + ), + ) + ]), + ) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: !controller.canChangeEndDate, + child: Opacity( + opacity: !controller.canChangeEndDate ? 0.3 : 1.0, + child: _responsiveUtils.isPortraitMobile(context) + ? Column(children: [ + BorderButtonField( + label: AppLocalizations.of(context).endDate, + value: controller.vacationPresentation.value.endDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && + controller.vacationPresentation.value.endDateIsNull, + hintText: AppLocalizations.of(context).noEndDate, + tapActionCallback: (value) => + controller.selectDate(context, DateType.end, value)), + const SizedBox(height: 18), + BorderButtonField( + label: AppLocalizations.of(context).endTime, + value: controller.vacationPresentation.value.endTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && + controller.vacationPresentation.value.endTimeIsNull, + hintText: AppLocalizations.of(context).noEndTime, + tapActionCallback: (value) => + controller.selectTime(context, DateType.end, value)), + ]) + : Row(children: [ + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).endDate, + value: controller.vacationPresentation.value.endDate, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && + controller.vacationPresentation.value.endDateIsNull, + hintText: AppLocalizations.of(context).noEndDate, + tapActionCallback: (value) => + controller.selectDate(context, DateType.end, value))), + const SizedBox(width: 24), + Expanded(child: BorderButtonField( + label: AppLocalizations.of(context).endTime, + value: controller.vacationPresentation.value.endTime, + mouseCursor: SystemMouseCursors.text, + backgroundColor: AppColor.colorBackgroundVacationSettingField, + isEmpty: controller.canChangeEndDate && + controller.vacationPresentation.value.endTimeIsNull, + hintText: AppLocalizations.of(context).noEndTime, + tapActionCallback: (value) => + controller.selectTime(context, DateType.end, value))), + ]), + ) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: _responsiveUtils.isPortraitMobile(context) + ? Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: TextInputFieldBuilder( + label: AppLocalizations.of(context).subject, + hint: AppLocalizations.of(context).hintSubjectInputVacationSetting, + editingController: controller.subjectTextController), + ) + : Row(children: [ + Expanded(child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: TextInputFieldBuilder( + label: AppLocalizations.of(context).subject, + hint: AppLocalizations.of(context).hintSubjectInputVacationSetting, + editingController: controller.subjectTextController), + )), + const SizedBox(width: 24), + const Expanded(child: SizedBox.shrink()) + ]) + )), + const SizedBox(height: 24), + Obx(() => AbsorbPointer( + absorbing: controller.isVacationDeactivated, + child: Opacity( + opacity: controller.isVacationDeactivated ? 0.3 : 1.0, + child: TextInputFieldBuilder( + label: AppLocalizations.of(context).message, + hint: AppLocalizations.of(context).hintMessageBodyVacation, + minLines: 10, + maxLines: null, + inputType: TextInputType.multiline, + backgroundColor: Colors.white, + error: controller.isVacationDeactivated + ? null + : controller.errorMessageBody.value, + onChangeInputAction: (value) => controller.updateMessageBody(context, value), + editingController: controller.messageTextController), + ), + )), + const SizedBox(height: 24), + Align( + alignment: Alignment.centerRight, + child: buildTextButton( + AppLocalizations.of(context).saveChanges, + textStyle: const TextStyle( + color: Colors.white, fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0))), - const SizedBox(height: 16), - Row(children: [ - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.startDate, - mouseCursor: SystemMouseCursors.text, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).startDate, - icon: SvgPicture.asset(_imagePaths.icCalendar), - tapActionCallback: (value) => - controller.selectDate(context, DateType.start, value)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.startTime, - mouseCursor: SystemMouseCursors.text, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noStartTime, - icon: SvgPicture.asset(_imagePaths.icClock), - tapActionCallback: (value) => - controller.selectTime(context, DateType.start, value)))) - ]), + fontSize: 16 + ), + width: 156, + height: 44, + radius: 10, + onTap: () => controller.saveVacation(context)), + ) ]), - )), - const SizedBox(height: 16), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: CheckboxListTile( - contentPadding: EdgeInsets.zero, - activeColor: AppColor.primaryColor.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0), - controlAffinity: ListTileControlAffinity.leading, - value: controller.vacationPresentation.value.vacationStopEnabled, - onChanged: (value) => - controller.updateVacationPresentation(vacationStopEnabled: value), - title: Text(AppLocalizations.of(context).vacationStopsAt, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0))), - ), - )), - Obx(() => AbsorbPointer( - absorbing: !controller.canChangeEndDate, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - AppLocalizations.of(context).endDate, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0))), - const SizedBox(height: 16), - Row(children: [ - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.endDate, - mouseCursor: SystemMouseCursors.text, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noEndDate, - icon: SvgPicture.asset(_imagePaths.icCalendar), - tapActionCallback: (value) => - controller.selectDate(context, DateType.end, value)))), - const SizedBox(width: 16), - Expanded(child: Obx(() => BorderButtonField( - value: controller.vacationPresentation.value.endTime, - mouseCursor: SystemMouseCursors.text, - textStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - !controller.canChangeEndDate ? 0.5 : 1.0)), - hintText: AppLocalizations.of(context).noEndTime, - icon: SvgPicture.asset(_imagePaths.icClock), - tapActionCallback: (value) => - controller.selectTime(context, DateType.end, value)))) - ]), - ]) - )), - const SizedBox(height: 16), - Obx(() => AbsorbPointer( - absorbing: controller.isVacationDeactivated, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - AppLocalizations.of(context).messageBody, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity( - controller.isVacationDeactivated ? 0.5 : 1.0))), - const SizedBox(height: 16), - _buildMessageBodyWidget( - context, - controller.isVacationDeactivated ? 0.5 : 1.0) - ]), - )), - const SizedBox(height: 16), - Align( - alignment: Alignment.centerRight, - child: buildTextButton( - AppLocalizations.of(context).save, - width: 128, - height: 44, - radius: 10, - onTap: () => controller.saveVacation(context)), ) ] - ), ), ), ), ), ); } - - Widget _buildMessageBodyWidget(BuildContext context, double opacity) { - return Obx(() { - return (TextFieldBuilder() - ..key(const Key('message_body_editor')) - ..cursorColor(Colors.black) - ..addController(controller.messageBodyEditorController) - ..textStyle(TextStyle( - fontWeight: FontWeight.normal, - color: Colors.black.withOpacity(opacity), - fontSize: 16)) - ..textDecoration((VacationInputDecorationBuilder() - ..setContentPadding(const EdgeInsets.symmetric( - vertical: BuildUtils.isWeb ? 16 : 12, - horizontal: 12)) - ..setHintStyle(TextStyle( - color: AppColor.colorHintInputCreateMailbox.withOpacity(opacity), - fontSize: 16)) - ..setErrorText(controller.isVacationDeactivated - ? null - : controller.errorMessageBody.value) - ..setHintText(AppLocalizations - .of(context) - .hintMessageBodyVacation)) - .build()) - ..onChange((value) => controller.updateMessageBody(context, value)) - ..minLines(10) - ..maxLines(null)) - .build(); - }); - } } \ No newline at end of file diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 7c71bf23d..979430d58 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-09-09T11:02:43.750933", + "@@last_modified": "2022-09-09T19:10:45.099202", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1906,12 +1906,6 @@ "placeholders_order": [], "placeholders": {} }, - "vacationResponder": "Vacation responder", - "@vacationResponder": { - "type": "text", - "placeholders_order": [], - "placeholders": {} - }, "activated": "Activated", "@activated": { "type": "text", @@ -1942,13 +1936,13 @@ "placeholders_order": [], "placeholders": {} }, - "messageBody": "Message body", - "@messageBody": { + "message": "Message", + "@message": { "type": "text", "placeholders_order": [], "placeholders": {} }, - "hintMessageBodyVacation": "Start writing your vacation message here", + "hintMessageBodyVacation": "Vacation messages", "@hintMessageBodyVacation": { "type": "text", "placeholders_order": [], @@ -2131,5 +2125,41 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "vacationSettingExplanation": "Sends an automated reply to incoming messages.", + "@vacationSettingExplanation": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "vacationSettingToggleButtonAutoReply": "Automatically reply to messages when they are received.", + "@vacationSettingToggleButtonAutoReply": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "startTime": "Start time", + "@startTime": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "endTime": "End time", + "@endTime": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "hintSubjectInputVacationSetting": "Enter subject", + "@hintSubjectInputVacationSetting": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "saveChanges": "Save changes", + "@saveChanges": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index ffb70890e..474037300 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1960,13 +1960,6 @@ class AppLocalizations { ); } - String get vacationResponder { - return Intl.message( - 'Vacation responder', - name: 'vacationResponder', - ); - } - String get activated { return Intl.message( 'Activated', @@ -2002,16 +1995,16 @@ class AppLocalizations { ); } - String get messageBody { + String get message { return Intl.message( - 'Message body', - name: 'messageBody', + 'Message', + name: 'message', ); } String get hintMessageBodyVacation { return Intl.message( - 'Start writing your vacation message here', + 'Vacation messages', name: 'hintMessageBodyVacation', ); } @@ -2197,4 +2190,44 @@ class AppLocalizations { 'You have not filled in the information completely.', name: 'toastErrorMessageWhenCreateNewRule'); } + + String get vacationSettingExplanation { + return Intl.message( + 'Sends an automated reply to incoming messages.', + name: 'vacationSettingExplanation'); + } + + String get vacationSettingToggleButtonAutoReply { + return Intl.message( + 'Automatically reply to messages when they are received.', + name: 'vacationSettingToggleButtonAutoReply'); + } + + String get startTime { + return Intl.message( + 'Start time', + name: 'startTime', + ); + } + + String get endTime { + return Intl.message( + 'End time', + name: 'endTime', + ); + } + + String get hintSubjectInputVacationSetting { + return Intl.message( + 'Enter subject', + name: 'hintSubjectInputVacationSetting', + ); + } + + String get saveChanges { + return Intl.message( + 'Save changes', + name: 'saveChanges', + ); + } } \ No newline at end of file