diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index c9c5235fc..e06c46c45 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -340,7 +340,9 @@ class EmailView extends GetWidget { final attachments = controller.attachments.listAttachmentsDisplayedOutSide; if (attachments.isNotEmpty) { return EmailAttachmentsWidget( + responsiveUtils: responsiveUtils, attachments: attachments, + imagePaths: imagePaths, onDragStarted: () { log('EmailView::_buildEmailMessage:onDragStarted:'); controller.mailboxDashBoardController.enableDraggableApp(); @@ -356,6 +358,7 @@ class EmailView extends GetWidget { controller.exportAttachment(context, attachment); } }, + onTapShowAllAttachmentFile: () => controller.openAttachmentList(context, attachments), ); } else { return const SizedBox.shrink(); diff --git a/lib/features/email/presentation/styles/attachment/attachment_item_widget_style.dart b/lib/features/email/presentation/styles/attachment/attachment_item_widget_style.dart index 9410d7d4f..043e3ea46 100644 --- a/lib/features/email/presentation/styles/attachment/attachment_item_widget_style.dart +++ b/lib/features/email/presentation/styles/attachment/attachment_item_widget_style.dart @@ -3,15 +3,16 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:flutter/material.dart'; class AttachmentItemWidgetStyle { - static const double radius = 10; + static const double radius = 8; static const double mobileWidth = 224; - static const double width = 250; - static const double height = 60; - static const double iconSize = 44; + static const double width = 260; + static const double height = 36; + static const double iconSize = 20; static const double space = 8; - static const double downloadIconSize = 24; + static const double downloadIconSize = 20; + static const double attachmentNameMaxWidth = 130; - static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.only(end: 12); + static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.only(end: 0); static const EdgeInsetsGeometry contentPadding = EdgeInsetsDirectional.all(8); static const Color borderColor = AppColor.attachmentFileBorderColor; diff --git a/lib/features/email/presentation/styles/email_attachments_styles.dart b/lib/features/email/presentation/styles/email_attachments_styles.dart index 51a17130a..15f3aec9c 100644 --- a/lib/features/email/presentation/styles/email_attachments_styles.dart +++ b/lib/features/email/presentation/styles/email_attachments_styles.dart @@ -8,16 +8,21 @@ class EmailAttachmentsStyles { static const double headerSpace = 4; static const double marginHeader = 6; static const double buttonTextSize = 13; + static const double buttonMoreAttachmentsTextSize = 14; static const double buttonBorderRadius = 8; static const double listSpace = 12; - static const double listHeight = 60; + static const double listHeight = 36; + static const double mobileListHeight = 100; + static const double moreAttachmentsButtonPadding = 8; static const Color headerTextColor = AppColor.colorTitleHeaderAttachment; static const Color headerIconColor = AppColor.colorAttachmentIcon; static const Color buttonTextColor = AppColor.primaryColor; + static const Color ButtonMoreAttachmentsTextColor = AppColor.colorLabelMoreAttachmentsButton; static const FontWeight headerFontWeight = FontWeight.w400; static const FontWeight buttonFontWeight = FontWeight.w400; + static const FontWeight buttonMoreAttachmentsFontWeight = FontWeight.w500; static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.symmetric(vertical: 12, horizontal: 16); static const EdgeInsetsGeometry buttonPadding = EdgeInsets.symmetric(vertical: 8, horizontal: 12); diff --git a/lib/features/email/presentation/widgets/attachment_item_widget.dart b/lib/features/email/presentation/widgets/attachment_item_widget.dart index 8150eb238..e818a18a4 100644 --- a/lib/features/email/presentation/widgets/attachment_item_widget.dart +++ b/lib/features/email/presentation/widgets/attachment_item_widget.dart @@ -1,7 +1,6 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; -import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:extended_text/extended_text.dart'; import 'package:filesize/filesize.dart'; @@ -20,7 +19,6 @@ class AttachmentItemWidget extends StatelessWidget { final OnDownloadAttachmentFileActionClick? downloadAttachmentAction; final _imagePaths = Get.find(); - final _responsiveUtils = Get.find(); AttachmentItemWidget({ Key? key, @@ -30,29 +28,26 @@ class AttachmentItemWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: AttachmentItemWidgetStyle.padding, - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () => downloadAttachmentAction?.call(attachment), - customBorder: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(AttachmentItemWidgetStyle.radius)) + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () => downloadAttachmentAction?.call(attachment), + customBorder: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(AttachmentItemWidgetStyle.radius)) + ), + child: Container( + padding: AttachmentItemWidgetStyle.contentPadding, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(AttachmentItemWidgetStyle.radius)), + border: Border.all(color: AttachmentItemWidgetStyle.borderColor), ), - child: Container( - padding: AttachmentItemWidgetStyle.contentPadding, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(AttachmentItemWidgetStyle.radius)), - border: Border.all(color: AttachmentItemWidgetStyle.borderColor), - ), - width: _responsiveUtils.isMobile(context) - ? AttachmentItemWidgetStyle.mobileWidth - : AttachmentItemWidgetStyle.width, - height: AttachmentItemWidgetStyle.height, - child: Stack( - children: [ - Positioned.fill( - child: Row(children: [ + width: AttachmentItemWidgetStyle.width, + height: AttachmentItemWidgetStyle.height, + child: Stack( + children: [ + Positioned.fill( + child: Row( + children: [ SvgPicture.asset( attachment.getIcon(_imagePaths), width: AttachmentItemWidgetStyle.iconSize, @@ -60,26 +55,29 @@ class AttachmentItemWidget extends StatelessWidget { fit: BoxFit.fill ), const SizedBox(width: AttachmentItemWidgetStyle.space), - Expanded(child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + Expanded(child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - ExtendedText( - (attachment.name ?? ''), - maxLines: 1, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - overflowWidget: TextOverflowWidget( - position: Directionality.maybeOf(context) == TextDirection.rtl - ? TextOverflowPosition.start - : TextOverflowPosition.end, - child: const Text( - "...", - style: AttachmentItemWidgetStyle.dotsLabelTextStyle, + SizedBox( + width: AttachmentItemWidgetStyle.attachmentNameMaxWidth, + child: ExtendedText( + (attachment.name ?? ''), + maxLines: 1, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + overflowWidget: TextOverflowWidget( + position: Directionality.maybeOf(context) == TextDirection.rtl + ? TextOverflowPosition.start + : TextOverflowPosition.end, + child: const Text( + "...", + style: AttachmentItemWidgetStyle.dotsLabelTextStyle, + ), ), + style: AttachmentItemWidgetStyle.labelTextStyle, ), - style: AttachmentItemWidgetStyle.labelTextStyle, ), - const SizedBox(height: 4), Text( filesize(attachment.size?.value), maxLines: 1, @@ -88,29 +86,26 @@ class AttachmentItemWidget extends StatelessWidget { style: AttachmentItemWidgetStyle.sizeLabelTextStyle, ) ] - )) - ]), - ), - Align( - alignment: AlignmentDirectional.bottomEnd, - child: Material( - color: Colors.transparent, - child: InkWell( - customBorder: const CircleBorder(), - child: SvgPicture.asset( - _imagePaths.icDownloadAttachment, - width: AttachmentItemWidgetStyle.downloadIconSize, - height: AttachmentItemWidgetStyle.downloadIconSize, - colorFilter: AttachmentItemWidgetStyle.downloadIconColor.asFilter(), - fit: BoxFit.fill + )), + Material( + color: Colors.transparent, + child: InkWell( + customBorder: const CircleBorder(), + child: SvgPicture.asset( + _imagePaths.icDownloadAttachment, + width: AttachmentItemWidgetStyle.downloadIconSize, + height: AttachmentItemWidgetStyle.downloadIconSize, + colorFilter: AttachmentItemWidgetStyle.downloadIconColor.asFilter(), + fit: BoxFit.fill + ), + onTap: () => downloadAttachmentAction?.call(attachment) ), - onTap: () => downloadAttachmentAction?.call(attachment) ), - ), + ] ), - ] - ) - ), + ), + ] + ) ), ), ); diff --git a/lib/features/email/presentation/widgets/email_attachments_widget.dart b/lib/features/email/presentation/widgets/email_attachments_widget.dart index d979593d1..0bdbe6d9d 100644 --- a/lib/features/email/presentation/widgets/email_attachments_widget.dart +++ b/lib/features/email/presentation/widgets/email_attachments_widget.dart @@ -1,46 +1,52 @@ +import 'package:core/presentation/action/action_callback_define.dart'; import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:core/utils/platform_info.dart'; import 'package:filesize/filesize.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:get/get.dart'; import 'package:model/email/attachment.dart'; import 'package:model/extensions/list_attachment_extension.dart'; -import 'package:tmail_ui_user/features/base/widget/custom_scroll_behavior.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/email_attachments_styles.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/draggable_attachment_item_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -class EmailAttachmentsWidget extends StatefulWidget { +class EmailAttachmentsWidget extends StatelessWidget { final List attachments; final OnDragAttachmentStarted? onDragStarted; final OnDragAttachmentEnd? onDragEnd; final OnDownloadAttachmentFileActionClick? downloadAttachmentAction; + final ResponsiveUtils responsiveUtils; + final ImagePaths imagePaths; + final OnTapActionCallback? onTapShowAllAttachmentFile; const EmailAttachmentsWidget({ super.key, required this.attachments, + required this.responsiveUtils, + required this.imagePaths, this.onDragStarted, this.onDragEnd, - this.downloadAttachmentAction + this.downloadAttachmentAction, + this.onTapShowAllAttachmentFile, }); - @override - State createState() => _EmailAttachmentsWidgetState(); -} - -class _EmailAttachmentsWidgetState extends State { - - final _imagePaths = Get.find(); - - bool _isDisplayAll = false; - @override Widget build(BuildContext context) { + int getItemCount() { + if (attachments.length <= 2) { + return attachments.length; + } + if (attachments.length == 3) { + return responsiveUtils.isDesktop(context) ? attachments.length : 2; + } + return responsiveUtils.isDesktop(context) ? 4 : 2; + } + int hideItemsCount = attachments.length - getItemCount(); return Padding( padding: EmailAttachmentsStyles.padding, child: Column( @@ -53,7 +59,7 @@ class _EmailAttachmentsWidgetState extends State { children: [ const SizedBox(width: EmailAttachmentsStyles.headerSpace), SvgPicture.asset( - _imagePaths.icAttachment, + imagePaths.icAttachment, width: EmailAttachmentsStyles.headerIconSize, height: EmailAttachmentsStyles.headerIconSize, colorFilter: EmailAttachmentsStyles.headerIconColor.asFilter(), @@ -63,8 +69,8 @@ class _EmailAttachmentsWidgetState extends State { Expanded( child: Text( AppLocalizations.of(context).titleHeaderAttachment( - widget.attachments.length, - filesize(widget.attachments.totalSize(), 1) + attachments.length, + filesize(attachments.totalSize(), 1) ), style: const TextStyle( fontSize: EmailAttachmentsStyles.headerTextSize, @@ -77,11 +83,9 @@ class _EmailAttachmentsWidgetState extends State { ] ) ), - if (widget.attachments.length > 2) + if (attachments.length > 2) TMailButtonWidget( - text: _isDisplayAll - ? AppLocalizations.of(context).hide - : AppLocalizations.of(context).showAll, + text: AppLocalizations.of(context).showAll, backgroundColor: Colors.transparent, borderRadius: EmailAttachmentsStyles.buttonBorderRadius, padding: EmailAttachmentsStyles.buttonPadding, @@ -90,59 +94,66 @@ class _EmailAttachmentsWidgetState extends State { color: EmailAttachmentsStyles.buttonTextColor, fontWeight: EmailAttachmentsStyles.buttonFontWeight ), - onTapActionCallback: () => setState(() => _isDisplayAll = !_isDisplayAll), + onTapActionCallback: onTapShowAllAttachmentFile, ) ], ), const SizedBox(height: EmailAttachmentsStyles.marginHeader), - if (_isDisplayAll) - Wrap( - runSpacing: EmailAttachmentsStyles.listSpace, - children: widget.attachments - .map((attachment) { - if (PlatformInfo.isWeb) { - return DraggableAttachmentItemWidget( - attachment: attachment, - onDragStarted: widget.onDragStarted, - onDragEnd: widget.onDragEnd, - downloadAttachmentAction: widget.downloadAttachmentAction, - ); - } else { - return AttachmentItemWidget( - attachment: attachment, - downloadAttachmentAction: widget.downloadAttachmentAction - ); - } - }) - .toList() - ) - else - SizedBox( - height: EmailAttachmentsStyles.listHeight, - child: ScrollConfiguration( - behavior: CustomScrollBehavior(), - child: ListView.builder( - shrinkWrap: true, - scrollDirection: Axis.horizontal, - itemCount: widget.attachments.length, - itemBuilder: (context, index) { - if (PlatformInfo.isWeb) { - return DraggableAttachmentItemWidget( - attachment: widget.attachments[index], - onDragStarted: widget.onDragStarted, - onDragEnd: widget.onDragEnd, - downloadAttachmentAction: widget.downloadAttachmentAction - ); - } else { - return AttachmentItemWidget( - attachment: widget.attachments[index], - downloadAttachmentAction: widget.downloadAttachmentAction - ); - } - } + SizedBox( + height: responsiveUtils.isMobile(context) ? EmailAttachmentsStyles.mobileListHeight : EmailAttachmentsStyles.listHeight, + child: Row( + children: [ + Flexible( + child: ListView.separated( + shrinkWrap: true, + scrollDirection: responsiveUtils.isMobile(context) ? Axis.vertical : Axis.horizontal, + itemCount: getItemCount(), + itemBuilder: (context, index) { + if (PlatformInfo.isWeb) { + return DraggableAttachmentItemWidget( + attachment: attachments[index], + onDragStarted: onDragStarted, + onDragEnd: onDragEnd, + downloadAttachmentAction: downloadAttachmentAction + ); + } else { + return AttachmentItemWidget( + attachment: attachments[index], + downloadAttachmentAction: downloadAttachmentAction + ); + } + }, + separatorBuilder: (context, index) { + if (responsiveUtils.isMobile(context)) { + return const SizedBox(height: EmailAttachmentsStyles.listSpace); + } else { + return const SizedBox(width: EmailAttachmentsStyles.listSpace); + } + }, + ), ), - ) - ), + if (hideItemsCount != 0) + Container( + padding: EdgeInsets.only(bottom: responsiveUtils.isMobile(context) ? EmailAttachmentsStyles.moreAttachmentsButtonPadding : 0), + alignment: responsiveUtils.isMobile(context) + ? Alignment.bottomRight + : Alignment.centerRight, + child: TMailButtonWidget( + text: AppLocalizations.of(context).moreAttachments(hideItemsCount), + backgroundColor: Colors.transparent, + borderRadius: EmailAttachmentsStyles.buttonBorderRadius, + padding: EmailAttachmentsStyles.buttonPadding, + textStyle: const TextStyle( + fontSize: EmailAttachmentsStyles.buttonMoreAttachmentsTextSize, + color: EmailAttachmentsStyles.ButtonMoreAttachmentsTextColor, + fontWeight: EmailAttachmentsStyles.buttonMoreAttachmentsFontWeight, + ), + onTapActionCallback: onTapShowAllAttachmentFile, + ), + ), + ] + ) + ), ], ), );