diff --git a/lib/features/email_recovery/presentation/styles/text_input_field/avatar_tag_item_widget_styles.dart b/lib/features/email_recovery/presentation/styles/text_input_field/avatar_tag_item_widget_styles.dart new file mode 100644 index 000000000..2b6d4a4e4 --- /dev/null +++ b/lib/features/email_recovery/presentation/styles/text_input_field/avatar_tag_item_widget_styles.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class AvatarTagItemWidgetStyles { + static const double size = 24.0; + static const double borderWidth = 0.21; + + static const TextStyle textStyle = TextStyle( + color: Colors.white, + fontSize: 8.57, + fontWeight: FontWeight.w600 + ); +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_tag_item_widget_styles.dart b/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_tag_item_widget_styles.dart new file mode 100644 index 000000000..b0816bf27 --- /dev/null +++ b/lib/features/email_recovery/presentation/styles/text_input_field/suggestion_tag_item_widget_styles.dart @@ -0,0 +1,32 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class SuggestionTagItemWidgetStyles { + static const double paddingTop = 4.5; + static const double paddingEndCollapsed = 40.0; + static const double paddingEndExpanded = 0.0; + static const double labelPaddingHorizontal = 4.0; + static const double labelPaddingVertical = 2.0; + static const double collapsedTextBorderRadius = 10.0; + + static const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10)); + + static const EdgeInsetsGeometry collapsedTextMargin = EdgeInsets.only( + top: 5.5, + ); + static const EdgeInsetsGeometry collapsedTextPadding = EdgeInsetsDirectional.symmetric( + vertical: 5, + horizontal: 8, + ); + + static const BorderSide latestTagBorderSide = BorderSide( + color: AppColor.primaryColor, + width: 1, + ); + + static const TextStyle labelStyle = TextStyle( + color: Colors.black, + fontSize: 17, + fontWeight: FontWeight.w400 + ); +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_tag_item_widget.dart b/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_tag_item_widget.dart new file mode 100644 index 000000000..2ee8908c2 --- /dev/null +++ b/lib/features/email_recovery/presentation/widgets/text_input_field/avatar_tag_item_widget.dart @@ -0,0 +1,47 @@ +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; + } +} \ No newline at end of file diff --git a/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_tag_item_widget.dart b/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_tag_item_widget.dart new file mode 100644 index 000000000..58b804158 --- /dev/null +++ b/lib/features/email_recovery/presentation/widgets/text_input_field/suggestion_tag_item_widget.dart @@ -0,0 +1,122 @@ +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 currentListEmailAddress; + final List collapsedListEmailAddress; + final OnDeleteTagAction? onDeleteTagAction; + final OnShowFullListEmailAddressAction? onShowFullAction; + + final _imagePaths = Get.find(); + + 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; + } + } +} \ No newline at end of file