From cb673e3ac765973d9dee4dc5d137de56eda02c67 Mon Sep 17 00:00:00 2001 From: hieubt Date: Thu, 21 Dec 2023 15:56:14 +0700 Subject: [PATCH] TF-2101 Add suggestion item widget for input field with suggestion (cherry picked from commit 5bccd801e221ff22925be4c62f0f5e2f2b5f0bf6) --- .../avatar_suggestion_item_widget_styles.dart | 13 +++ .../suggestion_item_widget_styles.dart | 30 ++++++ .../avatar_suggestion_item_widget.dart | 35 +++++++ .../suggestion_item_widget.dart | 91 +++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 lib/features/email_recovery/presentation/styles/text_input_field/avatar_suggestion_item_widget_styles.dart create mode 100644 lib/features/email_recovery/presentation/styles/text_input_field/suggestion_item_widget_styles.dart create mode 100644 lib/features/email_recovery/presentation/widgets/text_input_field/avatar_suggestion_item_widget.dart create mode 100644 lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_item_widget.dart diff --git a/lib/features/email_recovery/presentation/styles/text_input_field/avatar_suggestion_item_widget_styles.dart b/lib/features/email_recovery/presentation/styles/text_input_field/avatar_suggestion_item_widget_styles.dart new file mode 100644 index 000000000..c04390959 --- /dev/null +++ b/lib/features/email_recovery/presentation/styles/text_input_field/avatar_suggestion_item_widget_styles.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class AvatarSuggestionItemWidgetStyles { + static const double width = 40.0; + static const double height = 40.0; + static const double borderWidth = 1.0; + + static const TextStyle textStyle = TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w400 + ); +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_item_widget_styles.dart b/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_item_widget_styles.dart new file mode 100644 index 000000000..399764375 --- /dev/null +++ b/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_item_widget_styles.dart @@ -0,0 +1,30 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class SuggestionItemWidgetStyles { + static const double iconSelectedSize = 24.0; + + static const EdgeInsetsGeometry margin = EdgeInsets.all(8.0); + static const EdgeInsetsGeometry contentPaddingDuplicated = EdgeInsets.symmetric( + horizontal: 8.0 + ); + static const EdgeInsetsGeometry contentPaddingValid = EdgeInsets.symmetric( + horizontal: 16.0 + ); + + static const BoxDecoration decoration = BoxDecoration( + color: AppColor.colorBgMenuItemDropDownSelected, + borderRadius: BorderRadius.all(Radius.circular(20)) + ); + + static const TextStyle subTitleTextOriginStyle = TextStyle( + color: AppColor.colorHintSearchBar, + fontSize: 13, + fontWeight: FontWeight.normal + ); + static const TextStyle subTitleWordSearchedStyle = TextStyle( + color: Colors.black, + fontSize: 13, + fontWeight: FontWeight.bold + ); +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_suggestion_item_widget.dart b/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_suggestion_item_widget.dart new file mode 100644 index 000000000..f7eed318a --- /dev/null +++ b/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_suggestion_item_widget.dart @@ -0,0 +1,35 @@ +import 'package:core/core.dart'; +import 'package:core/presentation/extensions/color_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, + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_item_widget.dart b/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_item_widget.dart new file mode 100644 index 000000000..a8126b39c --- /dev/null +++ b/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_item_widget.dart @@ -0,0 +1,91 @@ +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:get/get.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:model/model.dart'; +import 'package:super_tag_editor/widgets/rich_text_widget.dart'; +import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/suggestion_item_widget_styles.dart'; +import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/avatar_suggestion_item_widget.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/suggesstion_email_address.dart'; + +typedef OnSelectedRecipientSuggestionAction = void Function(EmailAddress emailAddress); + +class SuggestionItemWidget extends StatelessWidget { + final SuggestionEmailState suggestionState; + final EmailAddress emailAddress; + final String? suggestionValid; + final bool highlight; + final OnSelectedRecipientSuggestionAction? onSelectedAction; + + final _imagePaths = Get.find(); + + SuggestionItemWidget({ + super.key, + required this.suggestionState, + required this.emailAddress, + this.highlight = false, + this.suggestionValid, + this.onSelectedAction, + }); + + @override + Widget build(BuildContext context) { + if (suggestionState == SuggestionEmailState.duplicated) { + return Container( + margin: SuggestionItemWidgetStyles.margin, + decoration: SuggestionItemWidgetStyles.decoration, + child: Material( + type: MaterialType.transparency, + child: ListTile( + contentPadding: SuggestionItemWidgetStyles.contentPaddingDuplicated, + leading: AvatarSuggestionItemWidget(emailAddress: emailAddress), + title: RichTextWidget( + textOrigin: emailAddress.asString(), + wordSearched: suggestionValid ?? '' + ), + subtitle: emailAddress.displayName.isNotEmpty + ? RichTextWidget( + textOrigin: emailAddress.emailAddress, + wordSearched: suggestionValid ?? '', + styleTextOrigin: SuggestionItemWidgetStyles.subTitleTextOriginStyle, + styleWordSearched: SuggestionItemWidgetStyles.subTitleWordSearchedStyle, + ) + : null, + trailing: SvgPicture.asset( + _imagePaths.icFilterSelected, + width: SuggestionItemWidgetStyles.iconSelectedSize, + height: SuggestionItemWidgetStyles.iconSelectedSize, + fit: BoxFit.fill, + ), + ), + ), + ); + } else { + return Container( + color: highlight ? AppColor.colorItemSelected : Colors.white, + child: Material( + type: MaterialType.transparency, + child: ListTile( + contentPadding: SuggestionItemWidgetStyles.contentPaddingValid, + leading: AvatarSuggestionItemWidget(emailAddress: emailAddress), + title: RichTextWidget( + textOrigin: emailAddress.asString(), + wordSearched: suggestionValid ?? '' + ), + subtitle: emailAddress.displayName.isNotEmpty + ? RichTextWidget( + textOrigin: emailAddress.emailAddress, + wordSearched: suggestionValid ?? '', + styleTextOrigin: SuggestionItemWidgetStyles.subTitleTextOriginStyle, + styleWordSearched: SuggestionItemWidgetStyles.subTitleWordSearchedStyle + ) + : null, + onTap: () => onSelectedAction?.call(emailAddress), + ), + ), + ); + } + } +} \ No newline at end of file