TF-4050 Preview and download uploaded file in composer on web

This commit is contained in:
dab246
2025-11-07 01:12:20 +07:00
committed by Dat H. Pham
parent ecd3ac0295
commit 972b20ec16
72 changed files with 2438 additions and 1751 deletions
@@ -3,7 +3,6 @@ import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/text/middle_ellipsis_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/styles/attachment_item_composer_widget_style.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_progress_loading_composer_widget.dart';
@@ -11,11 +10,11 @@ import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
typedef OnDeleteAttachmentAction = void Function(UploadTaskId uploadTaskId);
typedef OnPreviewAttachmentAction = void Function(UploadTaskId uploadTaskId);
class AttachmentItemComposerWidget extends StatelessWidget with AppLoaderMixin {
final _imagePaths = Get.find<ImagePaths>();
final ImagePaths imagePaths;
final String fileIcon;
final String fileName;
final String fileSize;
@@ -26,10 +25,12 @@ class AttachmentItemComposerWidget extends StatelessWidget with AppLoaderMixin {
final EdgeInsetsGeometry? itemMargin;
final EdgeInsetsGeometry? itemPadding;
final OnDeleteAttachmentAction? onDeleteAttachmentAction;
final OnPreviewAttachmentAction? onPreviewAttachmentAction;
final Widget? buttonAction;
AttachmentItemComposerWidget({
const AttachmentItemComposerWidget({
super.key,
required this.imagePaths,
required this.fileIcon,
required this.fileName,
required this.fileSize,
@@ -41,10 +42,65 @@ class AttachmentItemComposerWidget extends StatelessWidget with AppLoaderMixin {
this.itemPadding,
this.buttonAction,
this.onDeleteAttachmentAction,
this.onPreviewAttachmentAction,
});
@override
Widget build(BuildContext context) {
Widget bodyItem = Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
SvgPicture.asset(
fileIcon,
width: AttachmentItemComposerWidgetStyle.iconSize,
height: AttachmentItemComposerWidgetStyle.iconSize,
fit: BoxFit.fill
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
Flexible(
child: MiddleEllipsisText(
fileName,
style: AttachmentItemComposerWidgetStyle.labelTextStyle,
)
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
Text(
fileSize,
style: AttachmentItemComposerWidgetStyle.sizeLabelTextStyle
),
],
),
AttachmentProgressLoadingComposerWidget(
uploadStatus: uploadStatus,
percentUploading: percentUploading,
)
],
),
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
TMailButtonWidget.fromIcon(
icon: imagePaths.icCancel,
iconSize: AttachmentItemComposerWidgetStyle.deleteIconSize,
borderRadius: AttachmentItemComposerWidgetStyle.deleteIconRadius,
padding: AttachmentItemComposerWidgetStyle.deleteIconPadding,
iconColor: AttachmentItemComposerWidgetStyle.deleteIconColor,
onTapActionCallback: () => onDeleteAttachmentAction?.call(uploadTaskId),
)
],
);
if (onPreviewAttachmentAction != null) {
bodyItem = InkWell(
onTap: () => onPreviewAttachmentAction!(uploadTaskId),
child: bodyItem,
);
}
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(AttachmentItemComposerWidgetStyle.radius)),
@@ -54,52 +110,7 @@ class AttachmentItemComposerWidget extends StatelessWidget with AppLoaderMixin {
width: AttachmentItemComposerWidgetStyle.width,
padding: itemPadding ?? AttachmentItemComposerWidgetStyle.padding,
margin: itemMargin,
child: Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
SvgPicture.asset(
fileIcon,
width: AttachmentItemComposerWidgetStyle.iconSize,
height: AttachmentItemComposerWidgetStyle.iconSize,
fit: BoxFit.fill
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
Flexible(
child: MiddleEllipsisText(
fileName,
style: AttachmentItemComposerWidgetStyle.labelTextStyle,
)
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
Text(
fileSize,
style: AttachmentItemComposerWidgetStyle.sizeLabelTextStyle
),
],
),
AttachmentProgressLoadingComposerWidget(
uploadStatus: uploadStatus,
percentUploading: percentUploading,
)
],
),
),
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
TMailButtonWidget.fromIcon(
icon: _imagePaths.icCancel,
iconSize: AttachmentItemComposerWidgetStyle.deleteIconSize,
borderRadius: AttachmentItemComposerWidgetStyle.deleteIconRadius,
padding: AttachmentItemComposerWidgetStyle.deleteIconPadding,
iconColor: AttachmentItemComposerWidgetStyle.deleteIconColor,
onTapActionCallback: () => onDeleteAttachmentAction?.call(uploadTaskId),
)
],
),
child: bodyItem,
);
}
}
@@ -76,6 +76,7 @@ class _MobileAttachmentComposerWidgetState extends State<MobileAttachmentCompose
itemBuilder: (context, index) {
final file = _listFileDisplayed[index];
return AttachmentItemComposerWidget(
imagePaths: _imagePaths,
fileIcon: file.getIcon(_imagePaths),
fileName: file.fileName,
fileSize: filesize(file.fileSize),
@@ -139,6 +140,7 @@ class _MobileAttachmentComposerWidgetState extends State<MobileAttachmentCompose
itemBuilder: (context, index) {
final file = _listFileDisplayed[index];
return AttachmentItemComposerWidget(
imagePaths: _imagePaths,
fileIcon: file.getIcon(_imagePaths),
fileName: file.fileName,
fileSize: filesize(file.fileSize),
@@ -16,6 +16,7 @@ class AttachmentComposerWidget extends StatefulWidget {
final bool isCollapsed;
final OnDeleteAttachmentAction onDeleteAttachmentAction;
final OnToggleExpandAttachmentAction onToggleExpandAttachmentAction;
final OnPreviewAttachmentAction onPreviewAttachmentAction;
const AttachmentComposerWidget({
super.key,
@@ -23,6 +24,7 @@ class AttachmentComposerWidget extends StatefulWidget {
required this.isCollapsed,
required this.onDeleteAttachmentAction,
required this.onToggleExpandAttachmentAction,
required this.onPreviewAttachmentAction,
});
@override
@@ -76,6 +78,7 @@ class _AttachmentComposerWidgetState extends State<AttachmentComposerWidget> {
runSpacing: AttachmentComposerWidgetStyle.listItemSpace,
children: widget.listFileUploaded
.map((file) => AttachmentItemComposerWidget(
imagePaths: _imagePaths,
fileIcon: file.getIcon(_imagePaths),
fileName: file.fileName,
fileSize: filesize(file.fileSize),
@@ -83,6 +86,7 @@ class _AttachmentComposerWidgetState extends State<AttachmentComposerWidget> {
percentUploading: file.percentUploading,
uploadTaskId: file.uploadTaskId,
onDeleteAttachmentAction: widget.onDeleteAttachmentAction,
onPreviewAttachmentAction: widget.onPreviewAttachmentAction,
))
.toList(),
),