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
@@ -0,0 +1,54 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dio/dio.dart';
import 'package:model/download/download_task_id.dart';
import 'package:model/email/attachment.dart';
class StartDownloadAllAttachmentsForWeb extends UIState {
StartDownloadAllAttachmentsForWeb(this.taskId, this.attachment, {this.cancelToken});
final DownloadTaskId taskId;
final Attachment attachment;
final CancelToken? cancelToken;
@override
List<Object?> get props => [taskId, attachment, cancelToken];
}
class DownloadingAllAttachmentsForWeb extends LoadingState {
DownloadingAllAttachmentsForWeb(
this.taskId,
this.fileName,
this.progress,
this.downloaded,
this.total,
);
final DownloadTaskId taskId;
final String fileName;
final double progress;
final int downloaded;
final int total;
@override
List<Object?> get props => [taskId, fileName, progress, downloaded, total];
}
class DownloadAllAttachmentsForWebSuccess extends UIState {
DownloadAllAttachmentsForWebSuccess({required this.taskId});
final DownloadTaskId taskId;
@override
List<Object> get props => [taskId];
}
class DownloadAllAttachmentsForWebFailure extends FeatureFailure {
DownloadAllAttachmentsForWebFailure({super.exception, required this.taskId, this.cancelToken});
final DownloadTaskId taskId;
final CancelToken? cancelToken;
@override
List<Object?> get props => [exception, taskId, cancelToken];
}
@@ -0,0 +1,62 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart';
class DownloadAndGettingHtmlContentFromAttachment extends LoadingState {
DownloadAndGettingHtmlContentFromAttachment({
required this.blobId,
this.sourceView,
});
final Id? blobId;
final DownloadSourceView? sourceView;
@override
List<Object?> get props => [blobId, sourceView];
}
class DownloadAndGetHtmlContentFromAttachmentSuccess extends UIState {
DownloadAndGetHtmlContentFromAttachmentSuccess({
required this.sanitizedHtmlContent,
required this.htmlAttachmentTitle,
required this.attachment,
required this.accountId,
required this.session,
this.sourceView,
});
final String sanitizedHtmlContent;
final String htmlAttachmentTitle;
final Attachment attachment;
final AccountId accountId;
final Session session;
final DownloadSourceView? sourceView;
@override
List<Object?> get props => [
sanitizedHtmlContent,
htmlAttachmentTitle,
attachment,
accountId,
session,
sourceView,
];
}
class DownloadAndGetHtmlContentFromAttachmentFailure extends FeatureFailure {
DownloadAndGetHtmlContentFromAttachmentFailure({
super.exception,
required this.blobId,
this.sourceView,
});
final Id? blobId;
final DownloadSourceView? sourceView;
@override
List<Object?> get props => [blobId, sourceView];
}
@@ -0,0 +1,115 @@
import 'dart:typed_data';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dio/dio.dart';
import 'package:model/download/download_task_id.dart';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart';
class IdleDownloadAttachmentForWeb extends UIState {}
class StartDownloadAttachmentForWeb extends UIState {
final DownloadTaskId taskId;
final Attachment attachment;
final CancelToken? cancelToken;
final bool previewerSupported;
final DownloadSourceView? sourceView;
StartDownloadAttachmentForWeb(
this.taskId,
this.attachment, [
this.cancelToken,
this.previewerSupported = false,
this.sourceView,
]);
@override
List<Object?> get props => [
taskId,
attachment,
cancelToken,
previewerSupported,
sourceView,
];
}
class DownloadingAttachmentForWeb extends UIState {
final DownloadTaskId taskId;
final Attachment attachment;
final double progress;
final int downloaded;
final int total;
final DownloadSourceView? sourceView;
DownloadingAttachmentForWeb(
this.taskId,
this.attachment,
this.progress,
this.downloaded,
this.total,
this.sourceView,
);
@override
List<Object?> get props => [
taskId,
attachment,
progress,
downloaded,
total,
sourceView,
];
}
class DownloadAttachmentForWebSuccess extends UIState {
final DownloadTaskId taskId;
final Attachment attachment;
final Uint8List bytes;
final bool previewerSupported;
final DownloadSourceView? sourceView;
DownloadAttachmentForWebSuccess(
this.taskId,
this.attachment,
this.bytes,
this.previewerSupported,
this.sourceView,
);
@override
List<Object?> get props => [
taskId,
attachment,
bytes,
previewerSupported,
sourceView,
];
}
class DownloadAttachmentForWebFailure extends FeatureFailure {
final DownloadTaskId? taskId;
final Attachment? attachment;
final CancelToken? cancelToken;
final DownloadSourceView? sourceView;
DownloadAttachmentForWebFailure({
this.attachment,
this.taskId,
this.cancelToken,
this.sourceView,
super.exception,
});
@override
List<Object?> get props => [
attachment,
taskId,
cancelToken,
sourceView,
...super.props,
];
}
@@ -0,0 +1,18 @@
import 'package:core/data/network/download/downloaded_response.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class ExportingAllAttachments extends LoadingState {}
class ExportAllAttachmentsSuccess extends UIState {
ExportAllAttachmentsSuccess(this.downloadedResponse);
final DownloadedResponse downloadedResponse;
@override
List<Object> get props => [downloadedResponse];
}
class ExportAllAttachmentsFailure extends FeatureFailure {
ExportAllAttachmentsFailure({super.exception});
}
@@ -0,0 +1,17 @@
import 'package:core/data/network/download/downloaded_response.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class ExportAttachmentSuccess extends UIState {
final DownloadedResponse downloadedResponse;
ExportAttachmentSuccess(this.downloadedResponse);
@override
List<Object> get props => [downloadedResponse];
}
class ExportAttachmentFailure extends FeatureFailure {
ExportAttachmentFailure(dynamic exception) : super(exception: exception);
}
@@ -0,0 +1,36 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:model/email/attachment.dart';
class GettingHtmlContentFromUploadFile extends LoadingState {}
class GetHtmlContentFromUploadFileSuccess extends UIState {
GetHtmlContentFromUploadFileSuccess({
required this.sanitizedHtmlContent,
required this.htmlAttachmentTitle,
required this.attachment,
required this.accountId,
required this.session,
});
final String sanitizedHtmlContent;
final String htmlAttachmentTitle;
final Attachment attachment;
final AccountId? accountId;
final Session? session;
@override
List<Object?> get props => [
sanitizedHtmlContent,
htmlAttachmentTitle,
attachment,
accountId,
session,
];
}
class GetHtmlContentFromUploadFileFailure extends FeatureFailure {
GetHtmlContentFromUploadFileFailure({super.exception});
}
@@ -0,0 +1,27 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.dart';
class GettingPreviewEmailEMLContentShared extends LoadingState {}
class GetPreviewEmailEMLContentSharedSuccess extends UIState {
final EMLPreviewer emlPreviewer;
GetPreviewEmailEMLContentSharedSuccess(this.emlPreviewer);
@override
List<Object?> get props => [emlPreviewer];
}
class GetPreviewEmailEMLContentSharedFailure extends FeatureFailure {
final String? keyStored;
GetPreviewEmailEMLContentSharedFailure({
this.keyStored,
dynamic exception,
}) : super(exception: exception);
@override
List<Object?> get props => [keyStored, exception];
}
@@ -0,0 +1,26 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.dart';
class GettingPreviewEMLContentInMemory extends LoadingState {}
class GetPreviewEMLContentInMemorySuccess extends UIState {
final EMLPreviewer emlPreviewer;
GetPreviewEMLContentInMemorySuccess(this.emlPreviewer);
@override
List<Object?> get props => [emlPreviewer];
}
class GetPreviewEMLContentInMemoryFailure extends FeatureFailure {
final String? keyStored;
GetPreviewEMLContentInMemoryFailure({
this.keyStored,
dynamic exception,
}) : super(exception: exception);
@override
List<Object?> get props => [keyStored, exception];
}
@@ -0,0 +1,11 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class MovingPreviewEmailEMLContentFromPersistentToMemory extends LoadingState {}
class MovePreviewEmailEMLContentFromPersistentToMemorySuccess extends UIState {}
class MovePreviewEmailEMLContentFromPersistentToMemoryFailure extends FeatureFailure {
MovePreviewEmailEMLContentFromPersistentToMemoryFailure(dynamic exception) : super(exception: exception);
}
@@ -0,0 +1,37 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
class ParsingEmailByBlobId extends LoadingState {}
class ParseEmailByBlobIdSuccess extends UIState {
final AccountId accountId;
final Session session;
final String ownEmailAddress;
final Email email;
final Id blobId;
ParseEmailByBlobIdSuccess({
required this.email,
required this.blobId,
required this.accountId,
required this.session,
required this.ownEmailAddress,
});
@override
List<Object?> get props => [
email,
blobId,
accountId,
session,
ownEmailAddress,
];
}
class ParseEmailByBlobIdFailure extends FeatureFailure {
ParseEmailByBlobIdFailure(dynamic exception) : super(exception: exception);
}
@@ -0,0 +1,38 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class PreviewingEmailFromEmlFile extends LoadingState {}
class PreviewEmailFromEmlFileSuccess extends UIState {
final EMLPreviewer emlPreviewer;
final AccountId accountId;
final Session session;
final String ownEmailAddress;
final AppLocalizations appLocalizations;
PreviewEmailFromEmlFileSuccess(
this.emlPreviewer,
this.accountId,
this.session,
this.ownEmailAddress,
this.appLocalizations,
);
@override
List<Object?> get props => [
emlPreviewer,
accountId,
session,
ownEmailAddress,
appLocalizations,
];
}
class PreviewEmailFromEmlFileFailure extends FeatureFailure {
PreviewEmailFromEmlFileFailure(dynamic exception)
: super(exception: exception);
}
@@ -0,0 +1,11 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class RemovingPreviewEmailEMLContentShared extends LoadingState {}
class RemovePreviewEmailEMLContentSharedSuccess extends UIState {}
class RemovePreviewEmailEMLContentSharedFailure extends FeatureFailure {
RemovePreviewEmailEMLContentSharedFailure(dynamic exception) : super(exception: exception);
}