TF-4075 Show/Hide all attachments inside email view

(cherry picked from commit 2827c6485edd54cac25f8653878b0e9407cd7592)
This commit is contained in:
dab246
2025-10-06 19:35:56 +07:00
committed by Dat H. Pham
parent 6bbebd8e67
commit 5f3098484b
9 changed files with 57 additions and 644 deletions
@@ -97,6 +97,7 @@ import 'package:tmail_ui_user/features/email/presentation/bindings/mdn_interacto
import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_attendee_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_organizer_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/handle_open_attachment_list_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/update_attendance_status_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/model/blob_calendar_event.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
@@ -105,8 +106,6 @@ import 'package:tmail_ui_user/features/email/presentation/model/email_unsubscrib
import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_action_reactor/email_action_reactor.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_bottom_sheet_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_dialog_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/html_attachment_previewer.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/pdf_viewer/pdf_viewer.dart';
import 'package:tmail_ui_user/features/email_previewer/email_previewer_dialog_view.dart';
@@ -150,7 +149,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
final _downloadManager = Get.find<DownloadManager>();
final _printUtils = Get.find<PrintUtils>();
final _attachmentListScrollController = ScrollController();
final GetEmailContentInteractor _getEmailContentInteractor;
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
@@ -180,6 +178,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
final emailContents = RxnString();
final attachments = <Attachment>[].obs;
final isDisplayAllAttachments = RxBool(false);
final emlPreviewer = <Attachment>[].obs;
final blobCalendarEvent = Rxn<BlobCalendarEvent>();
final emailLoadedViewState = Rx<Either<Failure, Success>>(Right(UIState.idle));
final emailUnsubscribe = Rxn<EmailUnsubscribe>();
@@ -189,8 +189,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
final isEmailContentClipped = RxBool(false);
final attendanceStatus = Rxn<AttendanceStatus>();
final htmlContentViewKey = GlobalKey<HtmlContentViewState>();
final ScrollController emailScrollController = ScrollController();
final attachmentListKey = GlobalKey();
Identity? _identitySelected;
ButtonState? _printEmailButtonState;
@@ -201,6 +200,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
StreamController<Either<Failure, Success>>.broadcast();
Stream<Either<Failure, Success>> get downloadProgressState => _downloadProgressStateController.stream;
ThreadDetailController? get threadDetailController => _threadDetailController;
PresentationEmail? get currentEmail {
if (PlatformInfo.isMobile &&
_threadDetailController?.isThreadDetailEnabled != true) {
@@ -267,8 +268,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void onClose() {
_threadDetailController = null;
_downloadProgressStateController.close();
_attachmentListScrollController.dispose();
emailScrollController.dispose();
CalendarEventInteractorBindings().dispose();
MdnInteractorBindings().dispose();
super.onClose();
@@ -425,6 +424,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
worker.dispose();
}
Get.delete<SingleEmailController>(tag: _currentEmailId!.id.value);
} else if (action is OpenAttachmentListAction) {
if (_currentEmailId == null || action.emailId != _currentEmailId) {
return;
}
jumpToAttachmentList();
mailboxDashBoardController.clearEmailUIAction();
}
}));
@@ -1754,39 +1759,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.openComposer(ComposerArguments.fromEmailAddress(emailAddress));
}
void openAttachmentList(BuildContext context, List<Attachment> attachments) {
final tag = _currentEmailId?.id.value;
if (responsiveUtils.isMobile(context)) {
(AttachmentListBottomSheetBuilder(context, attachments, imagePaths, _attachmentListScrollController, tag)
..onCloseButtonAction(() => popBack())
..onDownloadAttachmentFileAction((attachment) => handleDownloadAttachmentAction(attachment))
..onViewAttachmentFileAction((attachment) => handleViewAttachmentAction(context, attachment))
..onDownloadAllButtonAction(isDownloadAllSupported()
? () => downloadAllAttachmentsForWeb('TwakeMail-${DateTime.now()}')
: null
)
).show();
} else {
Get.dialog(
PointerInterceptor(
child: AttachmentListDialogBuilder(
imagePaths: imagePaths,
attachments: attachments,
responsiveUtils: responsiveUtils,
scrollController: _attachmentListScrollController,
backgroundColor: Colors.black.withAlpha(24),
onCloseButtonAction: () => popBack(),
onDownloadAttachmentFileAction: (attachment) => handleDownloadAttachmentAction(attachment),
onViewAttachmentFileAction: (attachment) => handleViewAttachmentAction(context, attachment),
onDownloadAllButtonAction: isDownloadAllSupported()
? () => downloadAllAttachmentsForWeb('TwakeMail-${DateTime.now()}')
: null,
singleEmailControllerTag: tag,
)
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
void showAllAttachmentsAction() {
isDisplayAllAttachments.value = true;
}
void hideAllAttachmentsAction() {
isDisplayAllAttachments.value = false;
}
void _unsubscribeEmail(BuildContext context, PresentationEmail presentationEmail) {
@@ -453,6 +453,7 @@ class EmailView extends GetWidget<SingleEmailController> {
responsiveUtils: controller.responsiveUtils,
attachments: controller.attachments,
imagePaths: controller.imagePaths,
isDisplayAllAttachments: controller.isDisplayAllAttachments.value,
onDragStarted: controller
.mailboxDashBoardController.enableAttachmentDraggableApp,
onDragEnd: (_) {
@@ -467,10 +468,8 @@ class EmailView extends GetWidget<SingleEmailController> {
context,
attachment,
),
onTapShowAllAttachmentFile: () => controller.openAttachmentList(
context,
controller.attachments,
),
onTapShowAllAttachmentFile: controller.showAllAttachmentsAction,
onTapHideAllAttachments: controller.hideAllAttachmentsAction,
showDownloadAllAttachmentsButton:
controller.downloadAllButtonIsEnabled(),
onTapDownloadAllButton: () =>
@@ -1,30 +0,0 @@
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:flutter/material.dart';
class AttachmentListActionButtonBuilder extends StatelessWidget {
final String? name;
final TextStyle? textStyle;
final Color? bgColor;
final Function? action;
const AttachmentListActionButtonBuilder({
super.key,
this.name,
this.textStyle,
this.bgColor,
this.action
});
@override
Widget build(BuildContext context) {
return buildButtonWrapText(
name ?? '',
radius: 10,
height: 44,
textStyle: textStyle,
bgColor: bgColor,
onTap: () => action?.call(),
padding: const EdgeInsets.symmetric(horizontal: 16),
);
}
}
@@ -1,158 +0,0 @@
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';
import 'package:model/email/attachment.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_action_button_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_bottom_sheet_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_item_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class AttachmentListBottomSheetBodyBuilder extends StatelessWidget {
final ImagePaths imagePaths;
final List<Attachment> attachments;
final double statusBarHeight;
final ScrollController scrollController;
final OnDownloadAllButtonAction? onDownloadAllButtonAction;
final OnDownloadAttachmentFileAction? onDownloadAttachmentFileAction;
final OnViewAttachmentFileAction? onViewAttachmentFileAction;
final OnCancelButtonAction? onCancelButtonAction;
final OnCloseButtonAction? onCloseButtonAction;
final String? singleEmailControllerTag;
const AttachmentListBottomSheetBodyBuilder({
super.key,
required this.imagePaths,
required this.attachments,
required this.statusBarHeight,
required this.scrollController,
this.onDownloadAllButtonAction,
this.onDownloadAttachmentFileAction,
this.onViewAttachmentFileAction,
this.onCancelButtonAction,
this.onCloseButtonAction,
this.singleEmailControllerTag,
});
@override
Widget build(BuildContext context) {
return PointerInterceptor(
child: SafeArea(
top: true,
bottom: false,
left: false,
right: false,
child: GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Padding(
padding: EdgeInsets.only(top: statusBarHeight),
child: ClipRRect(
borderRadius: AttachmentListStyles.modalRadius,
child: Scaffold(
appBar: AppBar(
leading: const SizedBox.shrink(),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context).attachmentList,
style: AttachmentListStyles.titleTextStyle
),
const SizedBox(width: AttachmentListStyles.titleSpace),
Text(
'${attachments.length} ${AppLocalizations.of(context).files}',
style: AttachmentListStyles.subTitleTextStyle
),
],
),
centerTitle: true,
actions: [
TMailButtonWidget.fromIcon(
icon: imagePaths.icCircleClose,
backgroundColor: Colors.transparent,
iconSize: 28,
margin: const EdgeInsetsDirectional.only(end: 12),
padding: const EdgeInsets.all(5),
onTapActionCallback: onCloseButtonAction,
)
],
),
body: Container(
decoration: AttachmentListStyles.dialogBodyDecorationMobile,
child: Column(
children: [
Expanded(
child: RawScrollbar(
trackColor: AttachmentListStyles.scrollbarTrackColor,
thumbColor: AttachmentListStyles.scrollbarThumbColor,
radius: AttachmentListStyles.scrollbarThumbRadius,
trackRadius: AttachmentListStyles.scrollbarTrackRadius,
thickness: AttachmentListStyles.scrollbarThickness,
thumbVisibility: true,
trackVisibility: true,
controller: scrollController,
trackBorderColor: AttachmentListStyles.scrollbarTrackBorderColor,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: ListView.separated(
controller: scrollController,
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: attachments.length,
itemBuilder: (context, index) {
return AttachmentListItemWidget(
attachment: attachments[index],
downloadAttachmentAction: onDownloadAttachmentFileAction,
viewAttachmentAction: onViewAttachmentFileAction,
singleEmailControllerTag: singleEmailControllerTag,
);
},
separatorBuilder: (context, index) {
return const Divider(
color: AttachmentListStyles.separatorColor,
);
},
),
),
),
),
Padding(
padding: AttachmentListStyles.actionButtonsRowPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (onDownloadAllButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).downloadAll,
bgColor: AppColor.primaryColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
color: Colors.white,
),
action: onDownloadAllButtonAction,
),
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
if (onCancelButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).close,
bgColor: AttachmentListStyles.cancelButtonColor,
textStyle: AttachmentListStyles.cancelButtonTextStyle
)
],
),
),
const SizedBox(height: AttachmentListStyles.dialogBottomSpace)
],
),
),
),
),
),
)
),
);
}
}
@@ -1,79 +0,0 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_bottom_sheet_body_builder.dart';
typedef OnDownloadAllButtonAction = void Function();
typedef OnCancelButtonAction = void Function();
typedef OnCloseButtonAction = void Function();
class AttachmentListBottomSheetBuilder {
final BuildContext _context;
final List<Attachment> _attachments;
final ImagePaths _imagePaths;
final ScrollController _scrollController;
final String? _singleEmailControllerTag;
late double _statusBarHeight;
OnDownloadAllButtonAction? _onDownloadAllButtonAction;
OnDownloadAttachmentFileAction? _onDownloadAttachmentFileAction;
OnViewAttachmentFileAction? _onViewAttachmentFileAction;
OnCancelButtonAction? _onCancelButtonAction;
OnCloseButtonAction? _onCloseButtonAction;
AttachmentListBottomSheetBuilder(
this._context,
this._attachments,
this._imagePaths,
this._scrollController,
this._singleEmailControllerTag,
) {
_statusBarHeight = Get.statusBarHeight / MediaQuery.of(_context).devicePixelRatio;
}
void onDownloadAllButtonAction(OnDownloadAllButtonAction? onDownloadAllButtonAction) {
_onDownloadAllButtonAction = onDownloadAllButtonAction;
}
void onDownloadAttachmentFileAction(OnDownloadAttachmentFileAction onDownloadAttachmentFileAction) {
_onDownloadAttachmentFileAction = onDownloadAttachmentFileAction;
}
void onViewAttachmentFileAction(OnViewAttachmentFileAction onViewAttachmentFileAction) {
_onViewAttachmentFileAction = onViewAttachmentFileAction;
}
void onCancelButtonAction(OnCancelButtonAction onCancelButtonAction) {
_onCancelButtonAction = onCancelButtonAction;
}
void onCloseButtonAction(OnCloseButtonAction onCloseButtonAction) {
_onCloseButtonAction = onCloseButtonAction;
}
Future show() {
return showModalBottomSheet(
context: _context,
isScrollControlled: true,
barrierColor: AttachmentListStyles.barrierColor,
backgroundColor: AttachmentListStyles.modalBackgroundColor,
enableDrag: false,
builder: (context) => AttachmentListBottomSheetBodyBuilder(
imagePaths: _imagePaths,
attachments: _attachments,
statusBarHeight: _statusBarHeight,
scrollController: _scrollController,
onDownloadAllButtonAction: _onDownloadAllButtonAction,
onDownloadAttachmentFileAction: _onDownloadAttachmentFileAction,
onViewAttachmentFileAction: _onViewAttachmentFileAction,
onCancelButtonAction: _onCancelButtonAction,
onCloseButtonAction: _onCloseButtonAction,
singleEmailControllerTag: _singleEmailControllerTag,
),
);
}
}
@@ -1,157 +0,0 @@
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';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_action_button_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_bottom_sheet_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_item_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class AttachmentListDialogBodyBuilder extends StatelessWidget {
final BuildContext context;
final ImagePaths imagePaths;
final List<Attachment> attachments;
final ScrollController scrollController;
final double? widthDialog;
final double? heightDialog;
final OnDownloadAllButtonAction? onDownloadAllButtonAction;
final OnDownloadAttachmentFileAction? onDownloadAttachmentFileAction;
final OnViewAttachmentFileAction? onViewAttachmentFileAction;
final OnCancelButtonAction? onCancelButtonAction;
final OnCloseButtonAction? onCloseButtonAction;
final String? singleEmailControllerTag;
const AttachmentListDialogBodyBuilder({
super.key,
required this.context,
required this.imagePaths,
required this.attachments,
required this.scrollController,
this.widthDialog,
this.heightDialog,
this.onDownloadAllButtonAction,
this.onDownloadAttachmentFileAction,
this.onViewAttachmentFileAction,
this.onCancelButtonAction,
this.onCloseButtonAction,
this.singleEmailControllerTag,
});
@override
Widget build(BuildContext context) {
return Container(
width: widthDialog,
height: heightDialog,
decoration: AttachmentListStyles.dialogBodyDecoration,
child: Column(
children: [
Container(
padding: AttachmentListStyles.headerPadding,
decoration: AttachmentListStyles.headerDecoration,
child: Row(
children: [
const SizedBox(width: 50),
Expanded(
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
AppLocalizations.of(context).attachmentList,
style: AttachmentListStyles.titleTextStyle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(width: AttachmentListStyles.titleSpace),
Flexible(
child: Text(
'${attachments.length} ${AppLocalizations.of(context).files}',
style: AttachmentListStyles.subTitleTextStyle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
)
],
),
)
),
const SizedBox(width: 8),
TMailButtonWidget.fromIcon(
icon: imagePaths.icCircleClose,
onTapActionCallback: onCloseButtonAction,
iconSize: 28,
backgroundColor: Colors.transparent,
padding: const EdgeInsets.all(5),
),
const SizedBox(width: 8)
],
)
),
Expanded(
child: RawScrollbar(
trackColor: AttachmentListStyles.scrollbarTrackColor,
thumbColor: AttachmentListStyles.scrollbarThumbColor,
radius: AttachmentListStyles.scrollbarThumbRadius,
trackRadius: AttachmentListStyles.scrollbarTrackRadius,
thickness: AttachmentListStyles.scrollbarThickness,
thumbVisibility: true,
trackVisibility: true,
controller: scrollController,
trackBorderColor: AttachmentListStyles.scrollbarTrackBorderColor,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: ListView.separated(
controller: scrollController,
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: attachments.length,
itemBuilder: (context, index) {
return AttachmentListItemWidget(
attachment: attachments[index],
downloadAttachmentAction: onDownloadAttachmentFileAction,
viewAttachmentAction: onViewAttachmentFileAction,
singleEmailControllerTag: singleEmailControllerTag,
);
},
separatorBuilder: (context, index) {
return const Divider(
color: AttachmentListStyles.separatorColor,
);
},
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (onDownloadAllButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).downloadAll,
bgColor: AppColor.primaryColor,
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
color: Colors.white,
),
action: onDownloadAllButtonAction,
),
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
if (onCancelButtonAction != null)
AttachmentListActionButtonBuilder(
name: AppLocalizations.of(context).close,
bgColor: AttachmentListStyles.cancelButtonColor,
textStyle: AttachmentListStyles.cancelButtonTextStyle
)
],
),
const SizedBox(height: AttachmentListStyles.dialogBottomSpace)
],
),
);
}
}
@@ -1,70 +0,0 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_bottom_sheet_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_list/attachment_list_dialog_body_builder.dart';
class AttachmentListDialogBuilder extends StatelessWidget {
final ImagePaths imagePaths;
final List<Attachment> attachments;
final ResponsiveUtils responsiveUtils;
final ScrollController scrollController;
final Color? backgroundColor;
final double? widthDialog;
final double? heightDialog;
final OnDownloadAllButtonAction? onDownloadAllButtonAction;
final OnDownloadAttachmentFileAction? onDownloadAttachmentFileAction;
final OnViewAttachmentFileAction? onViewAttachmentFileAction;
final OnCancelButtonAction? onCancelButtonAction;
final OnCloseButtonAction? onCloseButtonAction;
final String? singleEmailControllerTag;
const AttachmentListDialogBuilder({
Key? key,
required this.imagePaths,
required this.attachments,
required this.responsiveUtils,
required this.scrollController,
this.backgroundColor,
this.widthDialog,
this.heightDialog,
this.onDownloadAllButtonAction,
this.onDownloadAttachmentFileAction,
this.onViewAttachmentFileAction,
this.onCancelButtonAction,
this.onCloseButtonAction,
this.singleEmailControllerTag,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Dialog(
key: const ValueKey('attachment_list_dialog'),
shape: AttachmentListStyles.shapeBorder,
insetPadding: responsiveUtils.isDesktop(context)
? AttachmentListStyles.dialogPaddingWeb
: AttachmentListStyles.dialogPaddingTablet,
alignment: Alignment.center,
backgroundColor: backgroundColor,
child: AttachmentListDialogBodyBuilder(
context: context,
imagePaths: imagePaths,
attachments: attachments,
widthDialog: widthDialog,
heightDialog: heightDialog,
scrollController: scrollController,
onDownloadAllButtonAction: onDownloadAllButtonAction,
onDownloadAttachmentFileAction: onDownloadAttachmentFileAction,
onViewAttachmentFileAction: onViewAttachmentFileAction,
onCancelButtonAction: onCancelButtonAction,
onCloseButtonAction: onCloseButtonAction,
singleEmailControllerTag: singleEmailControllerTag,
),
);
}
}
@@ -1,99 +0,0 @@
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/presentation/views/text/middle_ellipsis_text.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:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_item_widget_styles.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
class AttachmentListItemWidget extends StatelessWidget {
final Attachment attachment;
final OnDownloadAttachmentFileAction? downloadAttachmentAction;
final OnViewAttachmentFileAction? viewAttachmentAction;
final String? singleEmailControllerTag;
final _imagePaths = Get.find<ImagePaths>();
AttachmentListItemWidget({
Key? key,
required this.attachment,
this.downloadAttachmentAction,
this.viewAttachmentAction,
this.singleEmailControllerTag,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(
() {
final controller = Get.find<SingleEmailController>(tag: singleEmailControllerTag);
final attachmentsViewState = controller.attachmentsViewState;
bool isLoading = false;
if (attachment.blobId != null) {
isLoading = !EmailUtils.checkingIfAttachmentActionIsEnabled(
attachmentsViewState[attachment.blobId!]);
}
return Material(
type: MaterialType.transparency,
child: InkWell(
onTap: isLoading ? null : () => (viewAttachmentAction?? downloadAttachmentAction)?.call(attachment),
child: Padding(
padding: AttachmentListItemWidgetStyle.contentPadding,
child: Row(
children: [
isLoading
? const SizedBox(
width: AttachmentListItemWidgetStyle.iconSize,
height: AttachmentListItemWidgetStyle.iconSize,
child: CircularProgressIndicator(strokeWidth: 2))
: SvgPicture.asset(attachment.getIcon(_imagePaths),
width: AttachmentListItemWidgetStyle.iconSize,
height: AttachmentListItemWidgetStyle.iconSize,
fit: BoxFit.fill
),
const SizedBox(width: AttachmentListItemWidgetStyle.space),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MiddleEllipsisText(
(attachment.name ?? ''),
style: AttachmentListItemWidgetStyle.labelTextStyle,
),
const SizedBox(height: AttachmentListItemWidgetStyle.fileTitleBottomSpace),
Text(
filesize(attachment.size?.value),
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
style: AttachmentListItemWidgetStyle.sizeLabelTextStyle,
)
]
)
),
const SizedBox(width: AttachmentListItemWidgetStyle.space),
TMailButtonWidget.fromIcon(
icon: _imagePaths.icDownloadAttachment,
backgroundColor: Colors.transparent,
onTapActionCallback: isLoading
? null
: () => downloadAttachmentAction?.call(attachment)
)
]
),
),
),
);
}
);
}
}
@@ -1,4 +1,5 @@
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/utils/theme_utils.dart';
@@ -25,6 +26,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
final ResponsiveUtils responsiveUtils;
final ImagePaths imagePaths;
final OnTapActionCallback? onTapShowAllAttachmentFile;
final OnTapActionCallback? onTapHideAllAttachments;
final bool showDownloadAllAttachmentsButton;
final bool isDisplayAllAttachments;
final OnTapActionCallback? onTapDownloadAllButton;
@@ -40,6 +42,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
this.downloadAttachmentAction,
this.viewAttachmentAction,
this.onTapShowAllAttachmentFile,
this.onTapHideAllAttachments,
this.showDownloadAllAttachmentsButton = false,
this.isDisplayAllAttachments = false,
this.onTapDownloadAllButton,
@@ -59,9 +62,27 @@ class EmailAttachmentsWidget extends StatelessWidget {
: null,
);
if (responsiveUtils.isMobile(context)) {
bool isMobile = responsiveUtils.isMobile(context);
final hideButton = SizedBox(
height: 36,
width: isMobile ? double.infinity : null,
child: ConfirmDialogButton(
label: AppLocalizations.of(context).hideAll,
backgroundColor: Theme.of(context).colorScheme.outline.withValues(
alpha: 0.08,
),
textStyle: ThemeUtils.textStyleM3TitleSmall.copyWith(
color: AppColor.steelGrayA540,
),
radius: 5,
onTapAction: onTapHideAllAttachments,
),
);
if (isMobile) {
final attachmentRecord = _getDisplayedAndHiddenAttachment(
context,
isMobile,
responsiveUtils.getDeviceWidth(context),
);
final displayedAttachments = attachmentRecord.displayedAttachments;
@@ -104,11 +125,15 @@ class EmailAttachmentsWidget extends StatelessWidget {
backgroundColor: Theme.of(context).colorScheme.outline.withValues(
alpha: 0.08,
),
textStyle: ThemeUtils.textStyleM3TitleSmall,
textStyle: ThemeUtils.textStyleM3TitleSmall.copyWith(
color: AppColor.steelGrayA540,
),
radius: 5,
onTapAction: onTapShowAllAttachmentFile,
),
),
if (isDisplayAllAttachments)
hideButton,
],
),
);
@@ -136,7 +161,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
child: LayoutBuilder(
builder: (context, constraints) {
final attachmentRecord = _getDisplayedAndHiddenAttachment(
context,
isMobile,
constraints.maxWidth,
);
final displayedAttachments = attachmentRecord.displayedAttachments;
@@ -181,11 +206,15 @@ class EmailAttachmentsWidget extends StatelessWidget {
backgroundColor: Theme.of(context).colorScheme.outline.withValues(
alpha: 0.08,
),
textStyle: ThemeUtils.textStyleM3TitleSmall,
textStyle: ThemeUtils.textStyleM3TitleSmall.copyWith(
color: AppColor.steelGrayA540,
),
radius: 5,
onTapAction: onTapShowAllAttachmentFile,
),
),
if (isDisplayAllAttachments)
hideButton,
],
);
}
@@ -198,7 +227,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
}
({List<Attachment> displayedAttachments, int hiddenItemsCount})
_getDisplayedAndHiddenAttachment(BuildContext context, double maxWidth) {
_getDisplayedAndHiddenAttachment(bool isMobile, double maxWidth) {
if (isDisplayAllAttachments) {
return (displayedAttachments: attachments, hiddenItemsCount: 0);
}
@@ -206,7 +235,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
final displayedAttachments = EmailUtils.getAttachmentDisplayed(
maxWidth: maxWidth,
attachments: attachments,
isMobile: responsiveUtils.isMobile(context),
isMobile: isMobile,
);
int hiddenItemsCount = attachments.length - displayedAttachments.length;