Apply new design for recover deleted emails
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/views/checkbox/default_labeled_checkbox.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger_mobile.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
typedef OnChangedHasAttachment = void Function(bool? value);
|
||||
|
||||
class CheckBoxHasAttachmentWidget extends StatelessWidget {
|
||||
final bool hasAttachmentValue;
|
||||
final FocusNode currentFocusNode;
|
||||
final FocusNode? nextFocusNode;
|
||||
final OnChangedHasAttachment onChanged;
|
||||
|
||||
const CheckBoxHasAttachmentWidget({
|
||||
super.key,
|
||||
required this.hasAttachmentValue,
|
||||
required this.currentFocusNode,
|
||||
required this.onChanged,
|
||||
this.nextFocusNode,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return KeyboardListener(
|
||||
focusNode: FocusNode(),
|
||||
onKeyEvent: (event) {
|
||||
if (event.logicalKey == LogicalKeyboardKey.tab) {
|
||||
nextFocusNode?.requestFocus();
|
||||
}
|
||||
},
|
||||
child: DefaultLabeledCheckbox(
|
||||
label: AppLocalizations.of(context).hasAttachment,
|
||||
focusNode: currentFocusNode,
|
||||
value: hasAttachmentValue,
|
||||
activeColor: AppColor.primaryColor,
|
||||
onChanged: onChanged,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
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:dropdown_button2/dropdown_button2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/date_selection_field/date_selection_dropdown_button_styles.dart';
|
||||
|
||||
typedef OnRecoveryTimeSelected = void Function(EmailRecoveryTimeType recoveryTime);
|
||||
|
||||
class DateSelectionDropDownButton extends StatelessWidget {
|
||||
|
||||
final ImagePaths imagePaths;
|
||||
final List<EmailRecoveryTimeType> items;
|
||||
final DateTime? startDate;
|
||||
final DateTime? endDate;
|
||||
final EmailRecoveryTimeType? recoveryTimeSelected;
|
||||
final OnRecoveryTimeSelected? onRecoveryTimeSelected;
|
||||
|
||||
const DateSelectionDropDownButton({
|
||||
super.key,
|
||||
required this.imagePaths,
|
||||
required this.items,
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
this.recoveryTimeSelected,
|
||||
this.onRecoveryTimeSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DropdownButtonHideUnderline(
|
||||
child: PointerInterceptor(
|
||||
child: DropdownButton2<EmailRecoveryTimeType>(
|
||||
isExpanded: true,
|
||||
items: items
|
||||
.map((item) => _buildItemMenu(context, item))
|
||||
.toList(),
|
||||
value: recoveryTimeSelected,
|
||||
customButton: Container(
|
||||
height: DateSelectionDropdownButtonStyles.height,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DateSelectionDropdownButtonStyles.borderRadius,
|
||||
border: Border.all(
|
||||
color: AppColor.colorInputBorderCreateMailbox,
|
||||
width: DateSelectionDropdownButtonStyles.borderWidth,
|
||||
),
|
||||
color: AppColor.colorInputBackgroundCreateMailbox
|
||||
),
|
||||
padding: DateSelectionDropdownButtonStyles.padding,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
recoveryTimeSelected?.getTitle(context, startDate: startDate, endDate: endDate) ?? '',
|
||||
style: DateSelectionDropdownButtonStyles.selectedValueTexStyle,
|
||||
maxLines: 1,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
)
|
||||
),
|
||||
SvgPicture.asset(imagePaths.icDropDown)
|
||||
]
|
||||
),
|
||||
),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
onRecoveryTimeSelected?.call(value);
|
||||
}
|
||||
},
|
||||
buttonStyleData: ButtonStyleData(
|
||||
height: DateSelectionDropdownButtonStyles.height,
|
||||
padding: DateSelectionDropdownButtonStyles.padding,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DateSelectionDropdownButtonStyles.borderRadius,
|
||||
border: Border.all(
|
||||
color: AppColor.colorInputBorderCreateMailbox,
|
||||
width: DateSelectionDropdownButtonStyles.borderWidth,
|
||||
),
|
||||
color: AppColor.colorInputBackgroundCreateMailbox
|
||||
)
|
||||
),
|
||||
dropdownStyleData: DropdownStyleData(
|
||||
maxHeight: DateSelectionDropdownButtonStyles.dropdownMaxHeight,
|
||||
decoration: DateSelectionDropdownButtonStyles.dropdownDecoration,
|
||||
elevation: DateSelectionDropdownButtonStyles.dropdownElevation,
|
||||
offset: DateSelectionDropdownButtonStyles.dropdownOffset,
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
radius: DateSelectionDropdownButtonStyles.scrollbarRadius,
|
||||
thickness: WidgetStateProperty.all<double>(DateSelectionDropdownButtonStyles.scrollbarThickness),
|
||||
thumbVisibility: WidgetStateProperty.all<bool>(true),
|
||||
),
|
||||
),
|
||||
iconStyleData: IconStyleData(
|
||||
icon: SvgPicture.asset(imagePaths.icDropDown),
|
||||
),
|
||||
menuItemStyleData: DateSelectionDropdownButtonStyles.menuItemStyleData
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DropdownMenuItem<EmailRecoveryTimeType> _buildItemMenu(
|
||||
BuildContext context,
|
||||
EmailRecoveryTimeType recoveryTime
|
||||
) {
|
||||
return DropdownMenuItem<EmailRecoveryTimeType>(
|
||||
value: recoveryTime,
|
||||
child: PointerInterceptor(
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
height: DateSelectionDropdownButtonStyles.height,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
recoveryTime.getTitle(context),
|
||||
style: DateSelectionDropdownButtonStyles.selectedValueTexStyle,
|
||||
maxLines: 1,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
)
|
||||
),
|
||||
if (recoveryTime == recoveryTimeSelected)
|
||||
SvgPicture.asset(
|
||||
imagePaths.icChecked,
|
||||
width: DateSelectionDropdownButtonStyles.checkedIconSize,
|
||||
height: DateSelectionDropdownButtonStyles.checkedIconSize,
|
||||
fit: BoxFit.fill
|
||||
)
|
||||
]
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/date_selection_field/date_selection_field_styles.dart';
|
||||
|
||||
class DateSelectionFieldMobileWidget extends StatelessWidget {
|
||||
final EmailRecoveryField field;
|
||||
final EmailRecoveryTimeType recoveryTimeSelected;
|
||||
final ImagePaths imagePaths;
|
||||
final VoidCallback? onTap;
|
||||
final DateTime? startDate;
|
||||
final DateTime? endDate;
|
||||
|
||||
const DateSelectionFieldMobileWidget({
|
||||
super.key,
|
||||
required this.field,
|
||||
required this.recoveryTimeSelected,
|
||||
required this.imagePaths,
|
||||
this.onTap,
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: DateSelectionFieldStyles.paddingMobile,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
field.getTitle(context),
|
||||
style: field.getTitleTextStyle(),
|
||||
),
|
||||
const SizedBox(height: DateSelectionFieldStyles.titleSpaceMobile),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: DateSelectionFieldStyles.height,
|
||||
decoration: const ShapeDecoration(
|
||||
color: AppColor.loginTextFieldBackgroundColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: DateSelectionFieldStyles.borderWidthMobile,
|
||||
color: AppColor.colorInputBorderCreateMailbox
|
||||
),
|
||||
borderRadius: DateSelectionFieldStyles.borderRadius
|
||||
)
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
radius: DateSelectionFieldStyles.radius,
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: DateSelectionFieldStyles.inputFieldMobilePadding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
recoveryTimeSelected.getTitle(
|
||||
context,
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
),
|
||||
style: field.getHintTextStyle(),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
imagePaths.icCalendar,
|
||||
width: DateSelectionFieldStyles.icCalendarSize,
|
||||
height: DateSelectionFieldStyles.icCalendarSize,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_time_type.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/date_selection_field/date_selection_field_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/date_selection_field/date_selection_dropdown_button.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class DateSelectionFieldWebWidget extends StatelessWidget {
|
||||
final EmailRecoveryField field;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final ImagePaths imagePaths;
|
||||
final DateTime? startDate;
|
||||
final DateTime? endDate;
|
||||
final EmailRecoveryTimeType? recoveryTimeSelected;
|
||||
final OnRecoveryTimeSelected? onRecoveryTimeSelected;
|
||||
final VoidCallback? onTapCalendar;
|
||||
final DateTime restorationHorizon;
|
||||
|
||||
const DateSelectionFieldWebWidget({
|
||||
super.key,
|
||||
required this.field,
|
||||
required this.responsiveUtils,
|
||||
required this.imagePaths,
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
this.recoveryTimeSelected,
|
||||
this.onRecoveryTimeSelected,
|
||||
this.onTapCalendar,
|
||||
required this.restorationHorizon
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: DateSelectionFieldStyles.padding,
|
||||
child: SizedBox(
|
||||
height: DateSelectionFieldStyles.height,
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: DateSelectionFieldStyles.titleWidth,
|
||||
child: Text(
|
||||
field.getTitle(context),
|
||||
style: field.getTitleTextStyle(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: DateSelectionFieldStyles.titleSpace),
|
||||
Expanded(
|
||||
child: DateSelectionDropDownButton(
|
||||
imagePaths: imagePaths,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
recoveryTimeSelected: recoveryTimeSelected,
|
||||
onRecoveryTimeSelected: onRecoveryTimeSelected,
|
||||
items: field.getSupportedTimeTypes(restorationHorizon),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: DateSelectionFieldStyles.icCalenderSpace),
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
imagePaths.icCalendarSB,
|
||||
width: DateSelectionFieldStyles.icCalendarSize,
|
||||
height: DateSelectionFieldStyles.icCalendarSize,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context).selectDate,
|
||||
iconPadding: EdgeInsets.zero,
|
||||
onTap: onTapCalendar
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+247
-132
@@ -1,153 +1,268 @@
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:core/presentation/views/checkbox/custom_icon_labeled_checkbox.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/model/filter_filter.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_autocomplete_input_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_date_drop_down_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_input_field_with_tab_key_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/email_recovery_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/email_recovery_form_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/check_box_has_attachment_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/date_selection_field/date_selection_field_web_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/extension/handle_drag_email_tag_between_field_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/limits_banner.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/list_button_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class EmailRecoveryFormDesktopBuilder extends GetWidget<EmailRecoveryController> {
|
||||
@override
|
||||
final controller = Get.find<EmailRecoveryController>();
|
||||
class EmailRecoveryFormDesktopBuilder extends StatelessWidget {
|
||||
|
||||
EmailRecoveryFormDesktopBuilder({super.key});
|
||||
final EmailRecoveryController controller;
|
||||
|
||||
const EmailRecoveryFormDesktopBuilder(this.controller, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EmailRecoveryFormStyles.padding,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
AppLocalizations.of(context).recoverDeletedMessages,
|
||||
style: EmailRecoveryFormStyles.titleTextStyle,
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black.withOpacity(0.20),
|
||||
body: GestureDetector(
|
||||
onTap: FocusScope.of(context).unfocus,
|
||||
child: Center(
|
||||
child: Card(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: EmailRecoveryFormStyles.inputAreaPadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LimitsBanner(
|
||||
bannerContent: AppLocalizations.of(context).recoverDeletedMessagesBannerContent(controller.getRestorationHorizonAsString()),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
Obx(() => DateSelectionFieldWebWidget(
|
||||
field: EmailRecoveryField.deletionDate,
|
||||
imagePaths: controller.imagePaths,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
startDate: controller.startDeletionDate.value,
|
||||
endDate: controller.endDeletionDate.value,
|
||||
recoveryTimeSelected: controller.deletionDateFieldSelected.value,
|
||||
onTapCalendar: () => controller.onSelectDeletionDateRange(context),
|
||||
onRecoveryTimeSelected: (type) => controller.onDeletionDateTypeSelected(context, type),
|
||||
restorationHorizon: controller.getRestorationHorizonAsDateTime(),
|
||||
)),
|
||||
Obx(() => DateSelectionFieldWebWidget(
|
||||
field: EmailRecoveryField.receptionDate,
|
||||
imagePaths: controller.imagePaths,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
startDate: controller.startReceptionDate.value,
|
||||
endDate: controller.endReceptionDate.value,
|
||||
recoveryTimeSelected: controller.receptionDateFieldSelected.value,
|
||||
onTapCalendar: () => controller.onSelectReceptionDateRange(context),
|
||||
onRecoveryTimeSelected: (type) => controller.onReceptionDateTypeSelected(context, type),
|
||||
restorationHorizon: controller.getRestorationHorizonAsDateTime(),
|
||||
)),
|
||||
TextInputFieldWidget(
|
||||
field: EmailRecoveryField.subject,
|
||||
textEditingController: controller.subjectFieldInputController,
|
||||
currentFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
imagePaths: controller.imagePaths,
|
||||
),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.recipientsFieldKey,
|
||||
field: EmailRecoveryField.recipients,
|
||||
listEmailAddress: controller.listRecipients,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
expandMode: controller.recipientsExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.recipientsFieldInputController,
|
||||
focusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
nextFocusNode: controller.listSenders.length != 1
|
||||
? controller.focusManager.senderFieldFocusNode
|
||||
: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.senderFieldKey,
|
||||
field: EmailRecoveryField.sender,
|
||||
listEmailAddress: controller.listSenders,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
expandMode: controller.senderExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.senderFieldInputController,
|
||||
focusNode: controller.focusManager.senderFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EmailRecoveryFormStyles.bottomAreaPadding,
|
||||
child: Row(
|
||||
width: min(
|
||||
controller.responsiveUtils.getSizeScreenWidth(context),
|
||||
576,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Stack(
|
||||
children: [
|
||||
Obx(() => CheckBoxHasAttachmentWidget(
|
||||
hasAttachmentValue: controller.hasAttachment.value,
|
||||
currentFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onChanged: (value) => controller.onChangeHasAttachment(value),
|
||||
)),
|
||||
SizedBox(width: controller.responsiveUtils.getDeviceWidth(context) * 0.04),
|
||||
Expanded(
|
||||
child: ListButtonWidget(
|
||||
onCancel: () => controller.closeView(context),
|
||||
onRestore: () => controller.onRestore(context),
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
FocusTraversalGroup(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 24
|
||||
),
|
||||
child: Text(
|
||||
appLocalizations.recoverDeletedMessages,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: ThemeUtils.textStyleM3HeadlineSmall,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
LimitsBanner(
|
||||
bannerContent: appLocalizations
|
||||
.dialogRecoverDeletedMessagesDescription(
|
||||
controller.getRestorationHorizonAsString(),
|
||||
),
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
isCenter: true,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.deletionDate.getTitle(appLocalizations),
|
||||
width: 112,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Obx(() => DefaultDateDropDownFieldWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
startDate: controller.startDeletionDate.value,
|
||||
endDate: controller.endDeletionDate.value,
|
||||
onReceiveTimeSelected: (receiveTimeType) {
|
||||
controller.onDeletionDateTypeSelected(
|
||||
context,
|
||||
receiveTimeType,
|
||||
);
|
||||
},
|
||||
onOpenDatPicker: () =>
|
||||
controller.onSelectDeletionDateRange(context),
|
||||
receiveTimeTypes: controller.deletionDateTimeTypes,
|
||||
receiveTimeTypeSelected:
|
||||
controller.deletionDateFieldSelected.value,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.receptionDate.getTitle(appLocalizations),
|
||||
width: 112,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Obx(() => DefaultDateDropDownFieldWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
startDate: controller.startReceptionDate.value,
|
||||
endDate: controller.endReceptionDate.value,
|
||||
onReceiveTimeSelected: (receiveTimeType) {
|
||||
controller.onReceptionDateTypeSelected(
|
||||
context,
|
||||
receiveTimeType,
|
||||
);
|
||||
},
|
||||
onOpenDatPicker: () =>
|
||||
controller.onSelectReceptionDateRange(context),
|
||||
receiveTimeTypes: controller.receptionDateTimeTypes,
|
||||
receiveTimeTypeSelected:
|
||||
controller.receptionDateFieldSelected.value,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.subject.getTitle(appLocalizations),
|
||||
width: 112,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: DefaultInputFieldWithTabKeyWidget(
|
||||
textEditingController: controller.subjectFieldInputController,
|
||||
currentFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
hintText: FilterField.recoverSubject.getHintText(appLocalizations),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.recipients.getTitle(appLocalizations),
|
||||
width: 112,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Obx(() => DefaultAutocompleteInputFieldWidget(
|
||||
field: FilterField.recipients,
|
||||
listEmailAddress: controller.listRecipients,
|
||||
expandMode: controller.recipientsExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
controller: controller.recipientsFieldInputController,
|
||||
focusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.senderFieldFocusNode,
|
||||
keyTagEditor: controller.recipientsFieldKey,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.sender.getTitle(appLocalizations),
|
||||
width: 112,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Obx(() => DefaultAutocompleteInputFieldWidget(
|
||||
field: FilterField.sender,
|
||||
listEmailAddress: controller.listSenders,
|
||||
expandMode: controller.senderExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
controller: controller.senderFieldInputController,
|
||||
focusNode: controller.focusManager.senderFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
keyTagEditor: controller.senderFieldKey,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Obx(() => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: CustomIconLabeledCheckbox(
|
||||
label: AppLocalizations.of(context).hasAttachment,
|
||||
svgIconPath: controller.imagePaths.icCheckboxUnselected,
|
||||
selectedSvgIconPath: controller.imagePaths.icCheckboxSelected,
|
||||
focusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
value: controller.hasAttachment.value,
|
||||
onChanged: controller.onChangeHasAttachment,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ListButtonWidget(
|
||||
onCancel: () => controller.closeView(context),
|
||||
onRestore: () => controller.onRestore(context),
|
||||
nextFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
isMobile: false,
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 37,
|
||||
vertical: 24,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
DefaultCloseButtonWidget(
|
||||
iconClose: controller.imagePaths.icCloseDialog,
|
||||
onTapActionCallback: () => controller.closeView(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: EmailRecoveryFormStyles.iconClosePositionTop,
|
||||
right: EmailRecoveryFormStyles.iconClosePositionRight,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.imagePaths.icClose,
|
||||
fit: BoxFit.fill,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
onTap: () => controller.closeView(context),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+169
-121
@@ -1,138 +1,186 @@
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:core/presentation/views/checkbox/custom_icon_labeled_checkbox.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/model/filter_filter.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_app_bar_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_autocomplete_input_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_date_drop_down_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_input_field_with_tab_key_widget.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/email_recovery_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/email_recovery_form_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/check_box_has_attachment_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/date_selection_field/date_selection_field_mobile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/extension/handle_drag_email_tag_between_field_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/limits_banner.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/list_button_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class EmailRecoveryFormMobileBuilder extends GetWidget<EmailRecoveryController> {
|
||||
@override
|
||||
final controller = Get.find<EmailRecoveryController>();
|
||||
|
||||
EmailRecoveryFormMobileBuilder({super.key});
|
||||
class EmailRecoveryFormMobileBuilder extends StatelessWidget {
|
||||
|
||||
final EmailRecoveryController controller;
|
||||
|
||||
const EmailRecoveryFormMobileBuilder(this.controller, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EmailRecoveryFormStyles.padding,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
AppLocalizations.of(context).recoverDeletedMessages,
|
||||
style: EmailRecoveryFormStyles.titleTextStyle,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LimitsBanner(
|
||||
bannerContent: AppLocalizations.of(context).recoverDeletedMessagesBannerContent(controller.getRestorationHorizonAsString()),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
Obx(() => DateSelectionFieldMobileWidget(
|
||||
field: EmailRecoveryField.deletionDate,
|
||||
recoveryTimeSelected: controller.deletionDateFieldSelected.value,
|
||||
imagePaths: controller.imagePaths,
|
||||
onTap: () => controller.onSelectDeletionDateRange(context),
|
||||
startDate: controller.startDeletionDate.value,
|
||||
endDate: controller.endDeletionDate.value,
|
||||
)),
|
||||
Obx(() => DateSelectionFieldMobileWidget(
|
||||
field: EmailRecoveryField.receptionDate,
|
||||
recoveryTimeSelected: controller.receptionDateFieldSelected.value,
|
||||
imagePaths: controller.imagePaths,
|
||||
onTap: () => controller.onSelectReceptionDateRange(context),
|
||||
startDate: controller.startReceptionDate.value,
|
||||
endDate: controller.endReceptionDate.value,
|
||||
)),
|
||||
TextInputFieldWidget(
|
||||
field: EmailRecoveryField.subject,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
imagePaths: controller.imagePaths,
|
||||
textEditingController: controller.subjectFieldInputController,
|
||||
currentFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.recipientsFieldKey,
|
||||
field: EmailRecoveryField.recipients,
|
||||
listEmailAddress: controller.listRecipients,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
focusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.senderFieldFocusNode,
|
||||
expandMode: controller.recipientsExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.recipientsFieldInputController,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.senderFieldKey,
|
||||
field: EmailRecoveryField.sender,
|
||||
listEmailAddress: controller.listSenders,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
focusNode: controller.focusManager.senderFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
expandMode: controller.senderExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.senderFieldInputController,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
Obx(() => CheckBoxHasAttachmentWidget(
|
||||
hasAttachmentValue: controller.hasAttachment.value,
|
||||
currentFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onChanged: (value) => controller.onChangeHasAttachment(value),
|
||||
))
|
||||
],
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: GestureDetector(
|
||||
onTap: FocusScope.of(context).unfocus,
|
||||
child: SafeArea(
|
||||
child: ColoredBox(
|
||||
color: Colors.white,
|
||||
child: FocusTraversalGroup(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DefaultAppBarWidget(
|
||||
title: appLocalizations.recoverDeletedMessages,
|
||||
imagePaths: controller.imagePaths,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
onBackAction: () => controller.closeView(context),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LimitsBanner(
|
||||
bannerContent: appLocalizations
|
||||
.dialogRecoverDeletedMessagesDescription(
|
||||
controller.getRestorationHorizonAsString(),
|
||||
),
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 4,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.deletionDate.getTitle(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
Obx(() => DefaultDateDropDownFieldWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
startDate: controller.startDeletionDate.value,
|
||||
endDate: controller.endDeletionDate.value,
|
||||
onReceiveTimeSelected: (receiveTimeType) {
|
||||
controller.onDeletionDateTypeSelected(
|
||||
context,
|
||||
receiveTimeType,
|
||||
);
|
||||
},
|
||||
onOpenDatPicker: () =>
|
||||
controller.onSelectDeletionDateRange(context),
|
||||
receiveTimeTypes: controller.deletionDateTimeTypes,
|
||||
receiveTimeTypeSelected:
|
||||
controller.deletionDateFieldSelected.value,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
)),
|
||||
const SizedBox(height: 15.0),
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.receptionDate.getTitle(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
Obx(() => DefaultDateDropDownFieldWidget(
|
||||
imagePaths: controller.imagePaths,
|
||||
startDate: controller.startReceptionDate.value,
|
||||
endDate: controller.endReceptionDate.value,
|
||||
onReceiveTimeSelected: (receiveTimeType) {
|
||||
controller.onReceptionDateTypeSelected(
|
||||
context,
|
||||
receiveTimeType,
|
||||
);
|
||||
},
|
||||
onOpenDatPicker: () =>
|
||||
controller.onSelectReceptionDateRange(context),
|
||||
receiveTimeTypes: controller.receptionDateTimeTypes,
|
||||
receiveTimeTypeSelected:
|
||||
controller.receptionDateFieldSelected.value,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
)),
|
||||
const SizedBox(height: 15.0),
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.subject.getTitle(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
DefaultInputFieldWithTabKeyWidget(
|
||||
textEditingController: controller.subjectFieldInputController,
|
||||
currentFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
hintText: FilterField.recoverSubject.getHintText(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.recipients.getTitle(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
Obx(() => DefaultAutocompleteInputFieldWidget(
|
||||
field: FilterField.recipients,
|
||||
listEmailAddress: controller.listRecipients,
|
||||
expandMode: controller.recipientsExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
controller: controller.recipientsFieldInputController,
|
||||
focusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.senderFieldFocusNode,
|
||||
keyTagEditor: controller.recipientsFieldKey,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
)),
|
||||
const SizedBox(height: 15.0),
|
||||
DefaultLabelFieldWidget(
|
||||
label: FilterField.sender.getTitle(appLocalizations),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
),
|
||||
Obx(() => DefaultAutocompleteInputFieldWidget(
|
||||
field: FilterField.sender,
|
||||
listEmailAddress: controller.listSenders,
|
||||
expandMode: controller.senderExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
controller: controller.senderFieldInputController,
|
||||
focusNode: controller.focusManager.senderFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
keyTagEditor: controller.senderFieldKey,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
)),
|
||||
const SizedBox(height: 15.0),
|
||||
Obx(() => CustomIconLabeledCheckbox(
|
||||
label: AppLocalizations.of(context).hasAttachment,
|
||||
svgIconPath: controller.imagePaths.icCheckboxUnselected,
|
||||
selectedSvgIconPath: controller.imagePaths.icCheckboxSelected,
|
||||
focusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
value: controller.hasAttachment.value,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
onChanged: controller.onChangeHasAttachment,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ListButtonWidget(
|
||||
onCancel: () => controller.closeView(context),
|
||||
onRestore: () => controller.onRestore(context),
|
||||
nextFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
isMobile: true,
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 44,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EmailRecoveryFormStyles.bottomAreaPadding,
|
||||
child: ListButtonWidget(
|
||||
onCancel: () => controller.closeView(context),
|
||||
onRestore: () => controller.onRestore(context),
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: EmailRecoveryFormStyles.iconClosePositionTop,
|
||||
left: EmailRecoveryFormStyles.iconClosePositionRight,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.imagePaths.icClose,
|
||||
height: 24,
|
||||
width: 24,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
onTap: () => controller.closeView(context),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/email_recovery_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/email_recovery_form_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/check_box_has_attachment_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/date_selection_field/date_selection_field_web_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/limits_banner.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/list_button_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class EmailRecoveryFormTabletBuilder extends GetWidget<EmailRecoveryController> {
|
||||
@override
|
||||
final controller = Get.find<EmailRecoveryController>();
|
||||
|
||||
EmailRecoveryFormTabletBuilder({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EmailRecoveryFormStyles.padding,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
AppLocalizations.of(context).recoverDeletedMessages,
|
||||
style: EmailRecoveryFormStyles.titleTextStyle,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: EmailRecoveryFormStyles.inputAreaPadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LimitsBanner(
|
||||
bannerContent: AppLocalizations.of(context).recoverDeletedMessagesBannerContent(controller.getRestorationHorizonAsString()),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
Obx(() => DateSelectionFieldWebWidget(
|
||||
field: EmailRecoveryField.deletionDate,
|
||||
imagePaths: controller.imagePaths,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
startDate: controller.startDeletionDate.value,
|
||||
endDate: controller.endDeletionDate.value,
|
||||
recoveryTimeSelected: controller.deletionDateFieldSelected.value,
|
||||
onTapCalendar: () => controller.onSelectDeletionDateRange(context),
|
||||
onRecoveryTimeSelected: (type) => controller.onDeletionDateTypeSelected(context, type),
|
||||
restorationHorizon: controller.getRestorationHorizonAsDateTime(),
|
||||
)),
|
||||
Obx(() => DateSelectionFieldWebWidget(
|
||||
field: EmailRecoveryField.receptionDate,
|
||||
imagePaths: controller.imagePaths,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
startDate: controller.startReceptionDate.value,
|
||||
endDate: controller.endReceptionDate.value,
|
||||
recoveryTimeSelected: controller.receptionDateFieldSelected.value,
|
||||
onTapCalendar: () => controller.onSelectReceptionDateRange(context),
|
||||
onRecoveryTimeSelected: (type) => controller.onReceptionDateTypeSelected(context, type),
|
||||
restorationHorizon: controller.getRestorationHorizonAsDateTime(),
|
||||
)),
|
||||
TextInputFieldWidget(
|
||||
field: EmailRecoveryField.subject,
|
||||
textEditingController: controller.subjectFieldInputController,
|
||||
currentFocusNode: controller.focusManager.subjectFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
imagePaths: controller.imagePaths,
|
||||
),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.recipientsFieldKey,
|
||||
field: EmailRecoveryField.recipients,
|
||||
listEmailAddress: controller.listRecipients,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
expandMode: controller.recipientsExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.recipientsFieldInputController,
|
||||
focusNode: controller.focusManager.recipientsFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.senderFieldFocusNode,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
Obx(() => TextInputFieldSuggestionWidget(
|
||||
keyTagEditor: controller.senderFieldKey,
|
||||
field: EmailRecoveryField.sender,
|
||||
listEmailAddress: controller.listSenders,
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
expandMode: controller.senderExpandMode.value,
|
||||
minInputLengthAutocomplete: controller.minInputLengthAutocomplete,
|
||||
textEditingController: controller.senderFieldInputController,
|
||||
focusNode: controller.focusManager.senderFieldFocusNode,
|
||||
nextFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
|
||||
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
|
||||
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EmailRecoveryFormStyles.bottomAreaPadding,
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(() => CheckBoxHasAttachmentWidget(
|
||||
hasAttachmentValue: controller.hasAttachment.value,
|
||||
currentFocusNode: controller.focusManager.attachmentCheckboxFocusNode,
|
||||
onChanged: (value) => controller.onChangeHasAttachment(value),
|
||||
)),
|
||||
SizedBox(width: controller.responsiveUtils.getDeviceWidth(context) * 0.04),
|
||||
Expanded(
|
||||
child: ListButtonWidget(
|
||||
onCancel: () => controller.closeView(context),
|
||||
onRestore: () => controller.onRestore(context),
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: EmailRecoveryFormStyles.iconClosePositionTop,
|
||||
right: EmailRecoveryFormStyles.iconClosePositionRight,
|
||||
child: buildIconWeb(
|
||||
icon: SvgPicture.asset(
|
||||
controller.imagePaths.icClose,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context).close,
|
||||
onTap: () => controller.closeView(context),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,32 +3,28 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class LimitsBanner extends StatelessWidget {
|
||||
final String bannerContent;
|
||||
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final bool isCenter;
|
||||
|
||||
const LimitsBanner({
|
||||
super.key,
|
||||
required this.bannerContent,
|
||||
this.isCenter = false,
|
||||
this.padding,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.yellow[400],
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
bannerContent,
|
||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
||||
fontSize: 16,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
final bodyWidget = Text(
|
||||
bannerContent,
|
||||
textAlign: isCenter ? TextAlign.center : TextAlign.start,
|
||||
style: ThemeUtils.textStyleM3BodyMedium1,
|
||||
);
|
||||
|
||||
if (padding != null) {
|
||||
return Padding(padding: padding!, child: bodyWidget);
|
||||
} else {
|
||||
return bodyWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,85 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/list_button_widget_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_action_button_widget.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ListButtonWidget extends StatelessWidget {
|
||||
final VoidCallback onCancel;
|
||||
final VoidCallback onRestore;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final bool isMobile;
|
||||
final FocusNode? nextFocusNode;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
const ListButtonWidget({
|
||||
super.key,
|
||||
required this.onCancel,
|
||||
required this.onRestore,
|
||||
required this.responsiveUtils,
|
||||
this.isMobile = false,
|
||||
this.nextFocusNode,
|
||||
this.padding,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextActionButtonWidget(
|
||||
colorButton: AppColor.colorBgSearchBar,
|
||||
colorText: AppColor.primaryColor,
|
||||
text: AppLocalizations.of(context).cancel,
|
||||
onAction: onCancel
|
||||
),
|
||||
),
|
||||
SizedBox(width: responsiveUtils.isMobile(context)
|
||||
? ListButtonWidgetStyles.mobileSpace
|
||||
: ListButtonWidgetStyles.space
|
||||
),
|
||||
Expanded(
|
||||
child: TextActionButtonWidget(
|
||||
colorButton: AppColor.primaryColor,
|
||||
colorText: Colors.white,
|
||||
text: AppLocalizations.of(context).restore,
|
||||
onAction: onRestore
|
||||
)
|
||||
)
|
||||
],
|
||||
Widget cancelButton = Container(
|
||||
constraints: !isMobile ? const BoxConstraints(minWidth: 67) : null,
|
||||
height: 48,
|
||||
child: ConfirmDialogButton(
|
||||
label: AppLocalizations.of(context).cancel,
|
||||
onTapAction: onCancel,
|
||||
),
|
||||
);
|
||||
|
||||
Widget restoreButton = Container(
|
||||
constraints: !isMobile ? const BoxConstraints(minWidth: 117) : null,
|
||||
height: 48,
|
||||
child: ConfirmDialogButton(
|
||||
label: AppLocalizations.of(context).restore,
|
||||
backgroundColor: AppColor.primaryMain,
|
||||
textColor: Colors.white,
|
||||
onTapAction: onRestore,
|
||||
),
|
||||
);
|
||||
|
||||
if (nextFocusNode != null) {
|
||||
restoreButton = KeyboardListener(
|
||||
focusNode: FocusNode(),
|
||||
onKeyEvent: (event) {
|
||||
if (event is KeyDownEvent &&
|
||||
event.logicalKey == LogicalKeyboardKey.tab) {
|
||||
nextFocusNode?.requestFocus();
|
||||
}
|
||||
},
|
||||
child: restoreButton,
|
||||
);
|
||||
}
|
||||
|
||||
Widget bodyWidget;
|
||||
|
||||
if (!isMobile) {
|
||||
bodyWidget = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Flexible(child: cancelButton),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(child: restoreButton),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
bodyWidget = Row(
|
||||
children: [
|
||||
Expanded(child: cancelButton),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: restoreButton),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if (padding != null) {
|
||||
return Padding(padding: padding!, child: bodyWidget);
|
||||
} else {
|
||||
return bodyWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_action_button_widget_styles.dart';
|
||||
|
||||
class TextActionButtonWidget extends StatelessWidget {
|
||||
final Color colorButton;
|
||||
final Color colorText;
|
||||
final String text;
|
||||
final VoidCallback onAction;
|
||||
final double? minWidth;
|
||||
|
||||
const TextActionButtonWidget({
|
||||
super.key,
|
||||
required this.colorButton,
|
||||
required this.colorText,
|
||||
required this.text,
|
||||
required this.onAction,
|
||||
this.minWidth,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return buildButtonWrapText(
|
||||
text,
|
||||
radius: TextActionButtonWidgetStyles.radius,
|
||||
height: TextActionButtonWidgetStyles.height,
|
||||
minWidth: minWidth,
|
||||
textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
||||
fontSize: TextActionButtonWidgetStyles.fontSize,
|
||||
color: colorText,
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
bgColor: colorButton,
|
||||
onTap: onAction
|
||||
);
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/extensions/string_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/avatar_suggestion_item_widget_styles.dart';
|
||||
|
||||
class AvatarSuggestionItemWidget extends StatelessWidget {
|
||||
final EmailAddress emailAddress;
|
||||
|
||||
const AvatarSuggestionItemWidget({super.key, required this.emailAddress});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: AvatarSuggestionItemWidgetStyles.width,
|
||||
height: AvatarSuggestionItemWidgetStyles.height,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColor.avatarColor,
|
||||
border: Border.all(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
width: AvatarSuggestionItemWidgetStyles.borderWidth
|
||||
)
|
||||
),
|
||||
child: Text(
|
||||
emailAddress.asString().isNotEmpty
|
||||
? emailAddress.asString().firstLetterToUpperCase
|
||||
: '',
|
||||
style: AvatarSuggestionItemWidgetStyles.textStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/avatar_tag_item_widget_styles.dart';
|
||||
|
||||
class AvatarTagItemWidget extends StatelessWidget {
|
||||
final String tagName;
|
||||
|
||||
const AvatarTagItemWidget({super.key, required this.tagName});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: AvatarTagItemWidgetStyles.size,
|
||||
height: AvatarTagItemWidgetStyles.size,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors:AppColor.mapGradientColor[_generateIndex(tagName)]
|
||||
),
|
||||
border: Border.all(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
width: AvatarTagItemWidgetStyles.borderWidth
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
tagName.isNotEmpty ? tagName[0].toUpperCase() : '',
|
||||
style: AvatarTagItemWidgetStyles.textStyle
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
int _generateIndex(String tag) {
|
||||
if (tag.isNotEmpty) {
|
||||
final codeUnits = tag.codeUnits;
|
||||
if (codeUnits.isNotEmpty) {
|
||||
final sumCodeUnits = codeUnits.sum;
|
||||
final index = sumCodeUnits % AppColor.mapGradientColor.length;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
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:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/utils/direction_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/suggestion_tag_item_widget_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/avatar_tag_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart';
|
||||
|
||||
class SuggestionTagItemWidget extends StatelessWidget {
|
||||
final bool isCollapsed;
|
||||
final bool isLatestTagFocused;
|
||||
final bool isLatestEmail;
|
||||
final EmailRecoveryField field;
|
||||
final EmailAddress currentEmailAddress;
|
||||
final List<EmailAddress> currentListEmailAddress;
|
||||
final List<EmailAddress> collapsedListEmailAddress;
|
||||
final OnDeleteTagAction? onDeleteTagAction;
|
||||
final OnShowFullListEmailAddressAction? onShowFullAction;
|
||||
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
SuggestionTagItemWidget({
|
||||
super.key,
|
||||
required this.field,
|
||||
required this.currentEmailAddress,
|
||||
required this.currentListEmailAddress,
|
||||
required this.collapsedListEmailAddress,
|
||||
this.isCollapsed = false,
|
||||
this.isLatestTagFocused = false,
|
||||
this.isLatestEmail = false,
|
||||
this.onDeleteTagAction,
|
||||
this.onShowFullAction,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.only(
|
||||
top: SuggestionTagItemWidgetStyles.paddingTop,
|
||||
end: isCollapsed
|
||||
? SuggestionTagItemWidgetStyles.paddingEndCollapsed
|
||||
: SuggestionTagItemWidgetStyles.paddingEndExpanded,
|
||||
),
|
||||
child: TextFieldTapRegion(
|
||||
child: InkWell(
|
||||
onTap: () => isCollapsed
|
||||
? onShowFullAction?.call(field)
|
||||
: null,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.grab,
|
||||
child: Chip(
|
||||
labelPadding: EdgeInsetsDirectional.symmetric(
|
||||
horizontal: SuggestionTagItemWidgetStyles.labelPaddingHorizontal,
|
||||
vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString())
|
||||
? 0
|
||||
: SuggestionTagItemWidgetStyles.labelPaddingVertical,
|
||||
),
|
||||
label: Text(
|
||||
currentEmailAddress.asString(),
|
||||
maxLines: 1,
|
||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||
),
|
||||
deleteIcon: SvgPicture.asset(
|
||||
_imagePaths.icClose,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
labelStyle: SuggestionTagItemWidgetStyles.labelStyle,
|
||||
backgroundColor: _getTagBackgroundColor(),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: SuggestionTagItemWidgetStyles.borderRadius,
|
||||
side: _getTagBorderSide(),
|
||||
),
|
||||
avatar: currentEmailAddress.emailAddress.isNotEmpty
|
||||
? AvatarTagItemWidget(tagName: currentEmailAddress.emailAddress)
|
||||
: null,
|
||||
onDeleted: () => onDeleteTagAction?.call(currentEmailAddress),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isCollapsed)
|
||||
TMailButtonWidget.fromText(
|
||||
margin: SuggestionTagItemWidgetStyles.collapsedTextMargin,
|
||||
text: '+${currentListEmailAddress.length - collapsedListEmailAddress.length}',
|
||||
onTapActionCallback: () => onShowFullAction?.call(field),
|
||||
borderRadius: SuggestionTagItemWidgetStyles.collapsedTextBorderRadius,
|
||||
textStyle: SuggestionTagItemWidgetStyles.labelStyle,
|
||||
padding: SuggestionTagItemWidgetStyles.collapsedTextPadding,
|
||||
backgroundColor: AppColor.colorEmailAddressTag,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Color _getTagBackgroundColor() {
|
||||
if (isLatestTagFocused && isLatestEmail) {
|
||||
return AppColor.colorItemRecipientSelected;
|
||||
} else {
|
||||
return AppColor.colorEmailAddressTag;
|
||||
}
|
||||
}
|
||||
|
||||
BorderSide _getTagBorderSide() {
|
||||
if (isLatestTagFocused && isLatestEmail) {
|
||||
return SuggestionTagItemWidgetStyles.latestTagBorderSide;
|
||||
} else {
|
||||
return BorderSide.none;
|
||||
}
|
||||
}
|
||||
}
|
||||
-380
@@ -1,380 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/mailbox/expand_mode.dart';
|
||||
import 'package:model/extensions/email_address_extension.dart';
|
||||
import 'package:super_tag_editor/tag_editor.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/suggestion_email_address.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_suggestion_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/text_input_suggestion_field_widget_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/suggestion_tag_item_widget.dart';
|
||||
import 'package:tmail_ui_user/main/utils/app_config.dart';
|
||||
|
||||
typedef OnSuggestionEmailAddress = Future<List<EmailAddress>> Function(String word, {int? limit});
|
||||
typedef OnUpdateListEmailAddressAction = void Function(EmailRecoveryField field, List<EmailAddress> newDate);
|
||||
typedef OnDeleteEmailAddressTypeAction = void Function(EmailRecoveryField field, EmailAddress emailAddress);
|
||||
typedef OnShowFullListEmailAddressAction = void Function(EmailRecoveryField field);
|
||||
typedef OnDeleteTagAction = void Function(EmailAddress emailAddress);
|
||||
|
||||
class TextInputFieldSuggestionWidget extends StatefulWidget {
|
||||
final EmailRecoveryField field;
|
||||
final List<EmailAddress> listEmailAddress;
|
||||
final ExpandMode expandMode;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final FocusNode? focusNode;
|
||||
final GlobalKey? keyTagEditor;
|
||||
final FocusNode? nextFocusNode;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final EdgeInsetsGeometry? margin;
|
||||
final OnSuggestionEmailAddress? onSuggestionEmailAddress;
|
||||
final OnUpdateListEmailAddressAction? onUpdateListEmailAddressAction;
|
||||
final OnDeleteEmailAddressTypeAction? onDeleteEmailAddressTypeAction;
|
||||
final OnShowFullListEmailAddressAction? onShowFullListEmailAddressAction;
|
||||
final OnDeleteTagAction? onDeleteTagAction;
|
||||
final TextEditingController? textEditingController;
|
||||
final VoidCallback? onCreateAction;
|
||||
final int minInputLengthAutocomplete;
|
||||
|
||||
const TextInputFieldSuggestionWidget({
|
||||
super.key,
|
||||
required this.field,
|
||||
required this.listEmailAddress,
|
||||
required this.responsiveUtils,
|
||||
this.expandMode = ExpandMode.EXPAND,
|
||||
this.minInputLengthAutocomplete = AppConfig.defaultMinInputLengthAutocomplete,
|
||||
this.focusNode,
|
||||
this.keyTagEditor,
|
||||
this.nextFocusNode,
|
||||
this.padding,
|
||||
this.margin,
|
||||
this.onSuggestionEmailAddress,
|
||||
this.onUpdateListEmailAddressAction,
|
||||
this.onDeleteEmailAddressTypeAction,
|
||||
this.onShowFullListEmailAddressAction,
|
||||
this.onDeleteTagAction,
|
||||
this.textEditingController,
|
||||
this.onCreateAction,
|
||||
});
|
||||
|
||||
@override
|
||||
State<TextInputFieldSuggestionWidget> createState() => _TextInputFieldSuggestionWidgetState();
|
||||
}
|
||||
|
||||
class _TextInputFieldSuggestionWidgetState extends State<TextInputFieldSuggestionWidget> {
|
||||
final _imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
bool _lastTagFocused = false;
|
||||
late List<EmailAddress> _currentListEmailAddress;
|
||||
Timer? _gapBetweenTagChangedAndFindSuggestion;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_currentListEmailAddress = widget.listEmailAddress;
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant TextInputFieldSuggestionWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.listEmailAddress != oldWidget.listEmailAddress) {
|
||||
_currentListEmailAddress = widget.listEmailAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: TextInputSuggestionFieldWidgetStyles.padding,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final title = SizedBox(
|
||||
width: TextInputSuggestionFieldWidgetStyles.titleWidth,
|
||||
child: Text(
|
||||
widget.field.getTitle(context),
|
||||
style: widget.field.getTitleTextStyle(),
|
||||
),
|
||||
);
|
||||
final inputField = StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return TagEditor<SuggestionEmailAddress>(
|
||||
key: widget.keyTagEditor,
|
||||
length: _collapsedListEmailAddress.length,
|
||||
controller: widget.textEditingController,
|
||||
focusNodeKeyboard: widget.focusNode,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputAction: TextInputAction.done,
|
||||
debounceDuration: const Duration(milliseconds: 150),
|
||||
enabled: widget.field == EmailRecoveryField.sender && _currentListEmailAddress.length == 1
|
||||
? false
|
||||
: true,
|
||||
inputDecoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
border: TextInputSuggestionFieldWidgetStyles.border,
|
||||
hintText: widget.field.getHintText(context),
|
||||
hintStyle: widget.field.getHintTextStyle(),
|
||||
isDense: true,
|
||||
contentPadding: _currentListEmailAddress.isNotEmpty
|
||||
? TextInputSuggestionFieldWidgetStyles.contentPadding
|
||||
: TextInputSuggestionFieldWidgetStyles.emptyListContentPadding,
|
||||
),
|
||||
padding: _currentListEmailAddress.isNotEmpty
|
||||
? TextInputSuggestionFieldWidgetStyles.inputFieldPadding
|
||||
: EdgeInsets.zero,
|
||||
borderRadius: TextInputSuggestionFieldWidgetStyles.borderRadius,
|
||||
borderSize: TextInputSuggestionFieldWidgetStyles.borderSize,
|
||||
focusedBorderColor: AppColor.primaryColor,
|
||||
enableBorder: true,
|
||||
enableBorderColor: AppColor.colorInputBorderCreateMailbox,
|
||||
minTextFieldWidth: TextInputSuggestionFieldWidgetStyles.minTextFieldWidth,
|
||||
resetTextOnSubmitted: true,
|
||||
autoScrollToInput: false,
|
||||
suggestionsBoxElevation: TextInputSuggestionFieldWidgetStyles.suggestionsBoxElevation,
|
||||
suggestionsBoxBackgroundColor: Colors.white,
|
||||
suggestionsBoxRadius: TextInputSuggestionFieldWidgetStyles.suggestionsBoxRadius,
|
||||
suggestionsBoxMaxHeight: TextInputSuggestionFieldWidgetStyles.suggestionsBoxMaxHeight,
|
||||
suggestionItemHeight: TextInputSuggestionFieldWidgetStyles.suggestionBoxItemHeight,
|
||||
suggestionBoxWidth: _getSuggestionBoxWidth(constraints.maxWidth),
|
||||
textStyle: TextInputSuggestionFieldWidgetStyles.inputFieldTextStyle,
|
||||
onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, setState),
|
||||
onDeleteTagAction: () => _handleDeleteLatestTagAction.call(setState),
|
||||
onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, setState),
|
||||
onSubmitted: (value) => _handleSubmitTagAction.call(value, setState),
|
||||
tagBuilder: (context, index) {
|
||||
final currentEmailAddress = _currentListEmailAddress.elementAt(index);
|
||||
final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last;
|
||||
return SuggestionTagItemWidget(
|
||||
field: widget.field,
|
||||
currentEmailAddress: currentEmailAddress,
|
||||
currentListEmailAddress: _currentListEmailAddress,
|
||||
collapsedListEmailAddress: _collapsedListEmailAddress,
|
||||
isLatestEmail: isLatestEmail,
|
||||
isCollapsed: _isCollapse,
|
||||
isLatestTagFocused: _lastTagFocused,
|
||||
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, setState),
|
||||
onShowFullAction: widget.onShowFullListEmailAddressAction,
|
||||
);
|
||||
},
|
||||
onTagChanged: (tag) => _handleOnTagChangeAction.call(tag, setState),
|
||||
findSuggestions: (queryString) => _findSuggestions(
|
||||
queryString,
|
||||
limit: AppConfig.defaultLimitAutocomplete,
|
||||
),
|
||||
isLoadMoreOnlyOnce: true,
|
||||
isLoadMoreReplaceAllOld: false,
|
||||
loadMoreSuggestions: _findSuggestions,
|
||||
suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) {
|
||||
return RecipientSuggestionItemWidget(
|
||||
imagePaths: _imagePaths,
|
||||
suggestionState: suggestionEmailAddress.state,
|
||||
emailAddress: suggestionEmailAddress.emailAddress,
|
||||
suggestionValid: suggestionValid,
|
||||
highlight: highlight,
|
||||
onSelectedAction: (emailAddress) {
|
||||
setState(() => _currentListEmailAddress.add(emailAddress));
|
||||
_updateListEmailAddressAction();
|
||||
tagEditorState.resetTextField();
|
||||
tagEditorState.closeSuggestionBox();
|
||||
},
|
||||
);
|
||||
},
|
||||
onHandleKeyEventAction: (event) {
|
||||
if (event is KeyDownEvent) {
|
||||
switch (event.logicalKey) {
|
||||
case LogicalKeyboardKey.tab:
|
||||
widget.nextFocusNode?.requestFocus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (widget.responsiveUtils.isMobile(context)) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
title,
|
||||
const SizedBox(height: TextInputSuggestionFieldWidgetStyles.spaceMobile),
|
||||
inputField,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
title,
|
||||
const SizedBox(width: TextInputSuggestionFieldWidgetStyles.space),
|
||||
Expanded(
|
||||
child: inputField,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool get _isCollapse => _currentListEmailAddress.length > 1 && widget.expandMode == ExpandMode.COLLAPSE;
|
||||
|
||||
List<EmailAddress> get _collapsedListEmailAddress => _isCollapse
|
||||
? _currentListEmailAddress.sublist(0, 1)
|
||||
: _currentListEmailAddress;
|
||||
|
||||
double? _getSuggestionBoxWidth(double maxWidth) {
|
||||
if (maxWidth < ResponsiveUtils.minTabletWidth) {
|
||||
final newWidth = min(maxWidth, 300.0);
|
||||
return newWidth;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void _handleFocusTagAction(bool focused, StateSetter stateSetter) {
|
||||
if (mounted) {
|
||||
stateSetter(() => _lastTagFocused = focused);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDeleteLatestTagAction(StateSetter stateSetter) {
|
||||
if (_currentListEmailAddress.isNotEmpty) {
|
||||
stateSetter(_currentListEmailAddress.removeLast);
|
||||
_updateListEmailAddressAction();
|
||||
}
|
||||
}
|
||||
|
||||
void _updateListEmailAddressAction() {
|
||||
widget.onUpdateListEmailAddressAction?.call(
|
||||
widget.field,
|
||||
_currentListEmailAddress
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSelectOptionAction(
|
||||
SuggestionEmailAddress suggestionEmailAddress,
|
||||
StateSetter stateSetter
|
||||
) {
|
||||
if (!_isDuplicated(suggestionEmailAddress.emailAddress.emailAddress)) {
|
||||
stateSetter(() => _currentListEmailAddress.add(suggestionEmailAddress.emailAddress));
|
||||
_updateListEmailAddressAction();
|
||||
}
|
||||
}
|
||||
|
||||
bool _isDuplicated(String inputEmail) {
|
||||
if (inputEmail.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
return _currentListEmailAddress
|
||||
.map((emailAddress) => emailAddress.email)
|
||||
.whereNotNull()
|
||||
.contains(inputEmail);
|
||||
}
|
||||
|
||||
void _handleSubmitTagAction(
|
||||
String value,
|
||||
StateSetter stateSetter
|
||||
) {
|
||||
final textTrim = value.trim();
|
||||
if (textTrim.isEmpty) {
|
||||
widget.onCreateAction?.call();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isDuplicated(textTrim)) {
|
||||
stateSetter(() => _currentListEmailAddress.add(EmailAddress(null, textTrim)));
|
||||
_updateListEmailAddressAction();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDeleteTagAction(EmailAddress emailAddress, StateSetter stateSetter) {
|
||||
if (_currentListEmailAddress.isNotEmpty) {
|
||||
stateSetter(() => _currentListEmailAddress.remove(emailAddress));
|
||||
_updateListEmailAddressAction();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleOnTagChangeAction(
|
||||
String value,
|
||||
StateSetter stateSetter
|
||||
) {
|
||||
final textTrim = value.trim();
|
||||
if (!_isDuplicated(textTrim)) {
|
||||
stateSetter(() => _currentListEmailAddress.add(EmailAddress(null, textTrim)));
|
||||
_updateListEmailAddressAction();
|
||||
}
|
||||
_gapBetweenTagChangedAndFindSuggestion = Timer(
|
||||
const Duration(seconds: 1),
|
||||
_handleGapBetweenTagChangedAndFindSuggestion
|
||||
);
|
||||
}
|
||||
|
||||
void _handleGapBetweenTagChangedAndFindSuggestion() {
|
||||
log('_TextFieldAutocompleteEmailAddressWebState::_handleGapBetweenTagChangedAndFindSuggestion:Timeout');
|
||||
}
|
||||
|
||||
FutureOr<List<SuggestionEmailAddress>> _findSuggestions(String query, {int? limit}) async {
|
||||
if (_gapBetweenTagChangedAndFindSuggestion?.isActive ?? false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
final processedQuery = query.trim();
|
||||
if (processedQuery.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
final tmailSuggestion = List<SuggestionEmailAddress>.empty(growable: true);
|
||||
if (
|
||||
processedQuery.length >= widget.minInputLengthAutocomplete
|
||||
&& widget.onSuggestionEmailAddress != null
|
||||
) {
|
||||
final listEmailAddress = await widget.onSuggestionEmailAddress!(
|
||||
processedQuery,
|
||||
limit: limit,
|
||||
);
|
||||
log('_TextFieldAutocompleteEmailAddressWebState::_findSuggestions: listEmailAddress: $listEmailAddress');
|
||||
final listSuggestionEmailAddress = listEmailAddress.map((emailAddress) => _toSuggestionEmailAddress(emailAddress, _currentListEmailAddress));
|
||||
tmailSuggestion.addAll(listSuggestionEmailAddress);
|
||||
}
|
||||
|
||||
tmailSuggestion.addAll(_matchedSuggestionEmailAddress(processedQuery, _currentListEmailAddress));
|
||||
|
||||
final currentTextOnTextField = widget.textEditingController?.text ?? '';
|
||||
if (currentTextOnTextField.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return tmailSuggestion.toSet().toList();
|
||||
}
|
||||
|
||||
SuggestionEmailAddress _toSuggestionEmailAddress(EmailAddress item, List<EmailAddress> addedEmailAddresses) {
|
||||
if (addedEmailAddresses.contains(item)) {
|
||||
return SuggestionEmailAddress(item, state: SuggestionEmailState.duplicated);
|
||||
} else {
|
||||
return SuggestionEmailAddress(item);
|
||||
}
|
||||
}
|
||||
|
||||
Iterable<SuggestionEmailAddress> _matchedSuggestionEmailAddress(String query, List<EmailAddress> addedEmailAddress) {
|
||||
return addedEmailAddress
|
||||
.where((addedMail) => addedMail.emailAddress.contains(query))
|
||||
.map((emailAddress) => SuggestionEmailAddress(
|
||||
emailAddress,
|
||||
state: SuggestionEmailState.duplicated
|
||||
));
|
||||
}
|
||||
}
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/views/text/text_field_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger_mobile.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/text_input_field_widget_styles.dart';
|
||||
|
||||
typedef OnTextSubmitted = void Function(String text)?;
|
||||
|
||||
class TextInputFieldWidget extends StatelessWidget {
|
||||
final EmailRecoveryField field;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final ImagePaths imagePaths;
|
||||
final TextEditingController textEditingController;
|
||||
final VoidCallback? onTap;
|
||||
final MouseCursor? mouseCursor;
|
||||
final FocusNode? currentFocusNode;
|
||||
final FocusNode? nextFocusNode;
|
||||
final OnTextSubmitted? onTextSubmitted;
|
||||
|
||||
const TextInputFieldWidget({
|
||||
super.key,
|
||||
required this.field,
|
||||
required this.responsiveUtils,
|
||||
required this.imagePaths,
|
||||
required this.textEditingController,
|
||||
this.onTap,
|
||||
this.mouseCursor,
|
||||
this.currentFocusNode,
|
||||
this.nextFocusNode,
|
||||
this.onTextSubmitted,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final title = SizedBox(
|
||||
width: responsiveUtils.isMobile(context)
|
||||
? null
|
||||
: TextInputFieldWidgetStyles.titleWidth,
|
||||
child: Text(
|
||||
field.getTitle(context),
|
||||
style: field.getTitleTextStyle(),
|
||||
),
|
||||
);
|
||||
final inputField = TextFieldBuilder(
|
||||
controller: textEditingController,
|
||||
readOnly: false,
|
||||
mouseCursor: mouseCursor,
|
||||
maxLines: 1,
|
||||
textInputAction: TextInputAction.next,
|
||||
textStyle: TextInputFieldWidgetStyles.inputtedTextStyle,
|
||||
onTap: onTap,
|
||||
onTextSubmitted: onTextSubmitted,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
contentPadding: TextInputFieldWidgetStyles.contentPadding,
|
||||
enabledBorder: TextInputFieldWidgetStyles.enableBorder,
|
||||
border: TextInputFieldWidgetStyles.border,
|
||||
focusedBorder: TextInputFieldWidgetStyles.focusedBorder,
|
||||
hintText: field.getHintText(context),
|
||||
hintStyle: field.getHintTextStyle(),
|
||||
),
|
||||
);
|
||||
|
||||
return KeyboardListener(
|
||||
focusNode: currentFocusNode ?? FocusNode(),
|
||||
onKeyEvent: (event) {
|
||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.tab) {
|
||||
nextFocusNode?.requestFocus();
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: TextInputFieldWidgetStyles.padding,
|
||||
child: responsiveUtils.isMobile(context)
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
title,
|
||||
const SizedBox(height: TextInputFieldWidgetStyles.spaceMobile),
|
||||
inputField,
|
||||
]
|
||||
)
|
||||
: SizedBox(
|
||||
height: 44,
|
||||
child: Row(
|
||||
children: [
|
||||
title,
|
||||
const SizedBox(width: TextInputFieldWidgetStyles.space),
|
||||
Expanded(
|
||||
child: inputField,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user