TF-3454 Download all attachments as ZIP

This commit is contained in:
DatDang
2025-02-07 14:38:53 +07:00
committed by Dat H. Pham
parent 636df94458
commit f66e1460e4
34 changed files with 1175 additions and 100 deletions
@@ -1,11 +1,10 @@
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
class AttachmentListActionButtonBuilder extends StatelessWidget {
final String? name;
final TextStyle? textStyle;
final Color? bgColor;
final Color? borderColor;
final Function? action;
const AttachmentListActionButtonBuilder({
@@ -13,32 +12,19 @@ class AttachmentListActionButtonBuilder extends StatelessWidget {
this.name,
this.textStyle,
this.bgColor,
this.borderColor,
this.action
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => action?.call(),
child: Container(
padding: AttachmentListStyles.buttonsPadding,
decoration: BoxDecoration(
color: bgColor,
borderRadius: AttachmentListStyles.buttonRadius,
border: Border.all(
width: borderColor != null ? AttachmentListStyles.buttonBorderWidth : 0,
color: borderColor ?? Colors.transparent
)
),
child: Center(
child: Text(
name ?? '',
textAlign: TextAlign.center,
style: textStyle
),
),
),
return buildButtonWrapText(
name ?? '',
radius: 10,
height: 44,
textStyle: textStyle,
bgColor: bgColor,
onTap: () => action?.call(),
padding: const EdgeInsets.symmetric(horizontal: 16),
);
}
}
@@ -1,3 +1,4 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
@@ -118,13 +119,16 @@ class AttachmentListBottomSheetBodyBuilder extends StatelessWidget {
Padding(
padding: AttachmentListStyles.actionButtonsRowPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (onDownloadAllButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).downloadAll,
bgColor: AttachmentListStyles.downloadAllButtonColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle
bgColor: AppColor.primaryColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
color: Colors.white,
),
action: onDownloadAllButtonAction,
),
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
@@ -132,7 +136,6 @@ class AttachmentListBottomSheetBodyBuilder extends StatelessWidget {
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).close,
bgColor: AttachmentListStyles.cancelButtonColor,
borderColor: AttachmentListStyles.cancelButtonBorderColor,
textStyle: AttachmentListStyles.cancelButtonTextStyle
)
],
@@ -33,7 +33,7 @@ class AttachmentListBottomSheetBuilder {
_statusBarHeight = Get.statusBarHeight / MediaQuery.of(_context).devicePixelRatio;
}
void onDownloadAllButtonAction(OnDownloadAllButtonAction onDownloadAllButtonAction) {
void onDownloadAllButtonAction(OnDownloadAllButtonAction? onDownloadAllButtonAction) {
_onDownloadAllButtonAction = onDownloadAllButtonAction;
}
@@ -1,3 +1,4 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
@@ -124,13 +125,16 @@ class AttachmentListDialogBodyBuilder extends StatelessWidget {
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (onDownloadAllButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).downloadAll,
bgColor: AttachmentListStyles.downloadAllButtonColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle
bgColor: AppColor.primaryColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
color: Colors.white,
),
action: onDownloadAllButtonAction,
),
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
@@ -138,7 +142,6 @@ class AttachmentListDialogBodyBuilder extends StatelessWidget {
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).close,
bgColor: AttachmentListStyles.cancelButtonColor,
borderColor: AttachmentListStyles.cancelButtonBorderColor,
textStyle: AttachmentListStyles.cancelButtonTextStyle
)
],
@@ -0,0 +1,99 @@
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:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/email_attachments_styles.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class AttachmentsInfo extends StatelessWidget {
const AttachmentsInfo({
super.key,
required this.imagePaths,
required this.numberOfAttachments,
required this.totalSizeInfo,
required this.responsiveUtils,
this.onTapShowAllAttachmentFile,
this.downloadAllEnabled = false,
this.onTapDownloadAllButton,
});
final ImagePaths imagePaths;
final int numberOfAttachments;
final String totalSizeInfo;
final ResponsiveUtils responsiveUtils;
final VoidCallback? onTapShowAllAttachmentFile;
final bool downloadAllEnabled;
final VoidCallback? onTapDownloadAllButton;
@override
Widget build(BuildContext context) {
List<Widget> attachmentsAmountAndSize = [
SvgPicture.asset(
imagePaths.icAttachment,
width: EmailAttachmentsStyles.headerIconSize,
height: EmailAttachmentsStyles.headerIconSize,
colorFilter: EmailAttachmentsStyles.headerIconColor.asFilter(),
fit: BoxFit.fill
),
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
Text(
AppLocalizations.of(context).titleHeaderAttachment(
numberOfAttachments,
totalSizeInfo,
),
style: const TextStyle(
fontSize: EmailAttachmentsStyles.headerTextSize,
fontWeight: EmailAttachmentsStyles.headerFontWeight,
color: EmailAttachmentsStyles.headerTextColor
)
),
];
final showAllAttachments = (numberOfAttachments > 2)
? TMailButtonWidget(
text: AppLocalizations.of(context).showAll,
backgroundColor: Colors.transparent,
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
padding: EmailAttachmentsStyles.buttonPadding,
textStyle: const TextStyle(
fontSize: EmailAttachmentsStyles.buttonTextSize,
color: EmailAttachmentsStyles.buttonTextColor,
fontWeight: EmailAttachmentsStyles.buttonFontWeight
),
onTapActionCallback: onTapShowAllAttachmentFile,
)
: const SizedBox.shrink();
List<Widget> downloadAllAttachments = downloadAllEnabled && !responsiveUtils.isMobile(context)
? [
const Spacer(),
TMailButtonWidget(
text: AppLocalizations.of(context).downloadAll,
icon: imagePaths.icDownloadAll,
iconAlignment: TextDirection.rtl,
backgroundColor: Colors.transparent,
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
padding: EmailAttachmentsStyles.buttonPadding,
textStyle: const TextStyle(
fontSize: EmailAttachmentsStyles.buttonTextSize,
color: EmailAttachmentsStyles.buttonTextColor,
fontWeight: EmailAttachmentsStyles.buttonFontWeight
),
onTapActionCallback: onTapDownloadAllButton,
),
]
: const [];
return Row(
children: [
...attachmentsAmountAndSize,
if (!PlatformInfo.isWeb) const Spacer(),
showAllAttachments,
...downloadAllAttachments,
],
);
}
}
@@ -1,16 +1,15 @@
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:model/email/attachment.dart';
import 'package:model/extensions/list_attachment_extension.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/attachments_info.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';
@@ -24,6 +23,8 @@ class EmailAttachmentsWidget extends StatelessWidget {
final ResponsiveUtils responsiveUtils;
final ImagePaths imagePaths;
final OnTapActionCallback? onTapShowAllAttachmentFile;
final bool showDownloadAllAttachmentsButton;
final OnTapActionCallback? onTapDownloadAllButton;
const EmailAttachmentsWidget({
super.key,
@@ -35,6 +36,8 @@ class EmailAttachmentsWidget extends StatelessWidget {
this.downloadAttachmentAction,
this.viewAttachmentAction,
this.onTapShowAllAttachmentFile,
this.showDownloadAllAttachmentsButton = false,
this.onTapDownloadAllButton,
});
@override
@@ -46,51 +49,14 @@ class EmailAttachmentsWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Row(
children: [
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
SvgPicture.asset(
imagePaths.icAttachment,
width: EmailAttachmentsStyles.headerIconSize,
height: EmailAttachmentsStyles.headerIconSize,
colorFilter: EmailAttachmentsStyles.headerIconColor.asFilter(),
fit: BoxFit.fill
),
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
Expanded(
child: Text(
AppLocalizations.of(context).titleHeaderAttachment(
attachments.length,
filesize(attachments.totalSize, 1)
),
style: const TextStyle(
fontSize: EmailAttachmentsStyles.headerTextSize,
fontWeight: EmailAttachmentsStyles.headerFontWeight,
color: EmailAttachmentsStyles.headerTextColor
)
)
),
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
]
)
),
if (attachments.length > 2)
TMailButtonWidget(
text: AppLocalizations.of(context).showAll,
backgroundColor: Colors.transparent,
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
padding: EmailAttachmentsStyles.buttonPadding,
textStyle: const TextStyle(
fontSize: EmailAttachmentsStyles.buttonTextSize,
color: EmailAttachmentsStyles.buttonTextColor,
fontWeight: EmailAttachmentsStyles.buttonFontWeight
),
onTapActionCallback: onTapShowAllAttachmentFile,
)
],
AttachmentsInfo(
imagePaths: imagePaths,
numberOfAttachments: attachments.length,
totalSizeInfo: filesize(attachments.totalSize, 1),
responsiveUtils: responsiveUtils,
onTapShowAllAttachmentFile: onTapShowAllAttachmentFile,
downloadAllEnabled: showDownloadAllAttachmentsButton,
onTapDownloadAllButton: onTapDownloadAllButton,
),
const SizedBox(height: EmailAttachmentsStyles.marginHeader),
Row(
@@ -121,7 +87,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
}).toList(),
),
),
if (hideItemsCount > 0)
if (hideItemsCount > 0 && !responsiveUtils.isMobile(context))
TMailButtonWidget(
text: AppLocalizations.of(context).moreAttachments(hideItemsCount),
backgroundColor: Colors.transparent,
@@ -137,6 +103,42 @@ class EmailAttachmentsWidget extends StatelessWidget {
),
]
),
const SizedBox(height: EmailAttachmentsStyles.marginHeader),
if (responsiveUtils.isMobile(context))
Row(
children: [
if (hideItemsCount > 0)
TMailButtonWidget(
text: AppLocalizations.of(context).moreAttachments(hideItemsCount),
backgroundColor: Colors.transparent,
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
padding: EdgeInsets.zero,
margin: EmailAttachmentsStyles.moreButtonMargin,
textStyle: const TextStyle(
fontSize: EmailAttachmentsStyles.buttonMoreAttachmentsTextSize,
color: EmailAttachmentsStyles.buttonMoreAttachmentsTextColor,
fontWeight: EmailAttachmentsStyles.buttonMoreAttachmentsFontWeight,
),
onTapActionCallback: onTapShowAllAttachmentFile,
),
const Spacer(),
if (showDownloadAllAttachmentsButton)
TMailButtonWidget(
text: AppLocalizations.of(context).downloadAll,
icon: imagePaths.icDownloadAll,
iconAlignment: TextDirection.rtl,
backgroundColor: Colors.transparent,
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
padding: EmailAttachmentsStyles.buttonPadding,
textStyle: const TextStyle(
fontSize: EmailAttachmentsStyles.buttonTextSize,
color: EmailAttachmentsStyles.buttonTextColor,
fontWeight: EmailAttachmentsStyles.buttonFontWeight
),
onTapActionCallback: onTapDownloadAllButton,
),
]
),
],
),
);