TF-4050 Preview and download uploaded file in composer on web
This commit is contained in:
@@ -15,6 +15,7 @@ import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_e
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_recipients_collapsed_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/handle_keyboard_shortcut_actions_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/mark_as_important_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/preview_upload_file_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/remove_draggable_email_address_between_recipient_fields_extension.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/prefix_recipient_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/styles/composer_style.dart';
|
||||
@@ -70,6 +71,22 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
}
|
||||
});
|
||||
|
||||
final attachmentWidget = Obx(() {
|
||||
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
||||
return AttachmentComposerWidget(
|
||||
listFileUploaded: controller.uploadController.listUploadAttachments,
|
||||
isCollapsed: controller.isAttachmentCollapsed,
|
||||
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
||||
onPreviewAttachmentAction: (id) =>
|
||||
controller.previewUploadFile(context, id),
|
||||
onToggleExpandAttachmentAction: (isCollapsed) =>
|
||||
controller.isAttachmentCollapsed = isCollapsed,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
|
||||
final bodyWidget = ResponsiveWidget(
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
mobile: MobileResponsiveContainerView(
|
||||
@@ -251,18 +268,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
}
|
||||
),
|
||||
),
|
||||
Obx(() {
|
||||
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
||||
return AttachmentComposerWidget(
|
||||
listFileUploaded: controller.uploadController.listUploadAttachments,
|
||||
isCollapsed: controller.isAttachmentCollapsed,
|
||||
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
||||
onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
attachmentWidget,
|
||||
Obx(() {
|
||||
if (controller.richTextWebController!.isFormattingOptionsEnabled) {
|
||||
return ToolbarRichTextWidget(
|
||||
@@ -504,18 +510,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
}
|
||||
),
|
||||
),
|
||||
Obx(() {
|
||||
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
||||
return AttachmentComposerWidget(
|
||||
listFileUploaded: controller.uploadController.listUploadAttachments,
|
||||
isCollapsed: controller.isAttachmentCollapsed,
|
||||
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
||||
onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
attachmentWidget,
|
||||
Obx(() {
|
||||
if (controller.richTextWebController!.isFormattingOptionsEnabled) {
|
||||
return ToolbarRichTextWidget(
|
||||
@@ -785,18 +780,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
}
|
||||
),
|
||||
),
|
||||
Obx(() {
|
||||
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
||||
return AttachmentComposerWidget(
|
||||
listFileUploaded: controller.uploadController.listUploadAttachments,
|
||||
isCollapsed: controller.isAttachmentCollapsed,
|
||||
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
||||
onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
attachmentWidget,
|
||||
Obx(() {
|
||||
if (controller.richTextWebController!.isFormattingOptionsEnabled) {
|
||||
return ToolbarRichTextWidget(
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_download_attachment_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_preview_attachment_extension.dart';
|
||||
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
extension PreviewUploadFileExtension on ComposerController {
|
||||
void previewUploadFile(BuildContext context, UploadTaskId uploadId) {
|
||||
final uploadFile = uploadController.getUploadFileId(uploadId);
|
||||
|
||||
if (uploadFile == null || uploadFile.attachment == null) {
|
||||
appToast.showToastWarningMessage(
|
||||
context,
|
||||
AppLocalizations.of(context).noPreviewAvailable,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
mailboxDashBoardController.previewUploadFile(
|
||||
context: context,
|
||||
uploadFile: uploadFile,
|
||||
isDialogLoadingVisible: true,
|
||||
onPreviewOrDownloadAction: (attachment, isPreview) {
|
||||
mailboxDashBoardController.downloadAttachment(
|
||||
attachment: attachment,
|
||||
previewerSupported: isPreview,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -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(),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user