diff --git a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
index 964a84149..00bff2d25 100644
--- a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
+++ b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
@@ -6,6 +6,7 @@ import 'package:core/utils/app_logger.dart';
import 'package:core/utils/html/html_interaction.dart';
import 'package:core/utils/html/html_utils.dart';
import 'package:core/utils/platform_info.dart';
+import 'package:core/utils/preview_eml_file_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
@@ -16,6 +17,7 @@ import 'package:url_launcher/url_launcher_string.dart';
typedef OnScrollHorizontalEndAction = Function(bool leftDirection);
typedef OnLoadWidthHtmlViewerAction = Function(bool isScrollPageViewActivated);
typedef OnMailtoDelegateAction = Future Function(Uri? uri);
+typedef OnPreviewEMLDelegateAction = Future Function(Uri? uri);
class HtmlContentViewer extends StatefulWidget {
@@ -26,6 +28,7 @@ class HtmlContentViewer extends StatefulWidget {
final OnLoadWidthHtmlViewerAction? onLoadWidthHtmlViewer;
final OnMailtoDelegateAction? onMailtoDelegateAction;
final OnScrollHorizontalEndAction? onScrollHorizontalEnd;
+ final OnPreviewEMLDelegateAction? onPreviewEMLDelegateAction;
const HtmlContentViewer({
Key? key,
@@ -34,7 +37,8 @@ class HtmlContentViewer extends StatefulWidget {
this.direction,
this.onLoadWidthHtmlViewer,
this.onMailtoDelegateAction,
- this.onScrollHorizontalEnd
+ this.onScrollHorizontalEnd,
+ this.onPreviewEMLDelegateAction,
}) : super(key: key);
@override
@@ -246,7 +250,7 @@ class _HtmlContentViewState extends State {
NavigationAction navigationAction
) async {
final url = navigationAction.request.url?.toString();
-
+ log('_HtmlContentViewState::_shouldOverrideUrlLoading: URL = $url');
if (url == null) {
return NavigationActionPolicy.CANCEL;
}
@@ -256,9 +260,15 @@ class _HtmlContentViewState extends State {
}
final requestUri = Uri.parse(url);
- final mailtoHandler = widget.onMailtoDelegateAction;
- if (mailtoHandler != null && requestUri.isScheme('mailto')) {
- await mailtoHandler(requestUri);
+ if (widget.onMailtoDelegateAction != null &&
+ requestUri.isScheme('mailto')) {
+ await widget.onMailtoDelegateAction?.call(requestUri);
+ return NavigationActionPolicy.CANCEL;
+ }
+
+ if (widget.onPreviewEMLDelegateAction != null &&
+ requestUri.isScheme(PreviewEmlFileUtils.emlPreviewerScheme)) {
+ await widget.onPreviewEMLDelegateAction?.call(requestUri);
return NavigationActionPolicy.CANCEL;
}
diff --git a/core/lib/utils/preview_eml_file_utils.dart b/core/lib/utils/preview_eml_file_utils.dart
index 992e1daa5..9a4bafab8 100644
--- a/core/lib/utils/preview_eml_file_utils.dart
+++ b/core/lib/utils/preview_eml_file_utils.dart
@@ -7,6 +7,7 @@ import 'package:html/dom.dart';
import 'package:html/parser.dart';
class PreviewEmlFileUtils {
+ static const String emlPreviewerScheme = 'eml-previewer';
Element? _createEmailElement({
required String subjectPrefix,
diff --git a/lib/features/email/data/datasource_impl/email_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_datasource_impl.dart
index a157345e1..fa9d7c060 100644
--- a/lib/features/email/data/datasource_impl/email_datasource_impl.dart
+++ b/lib/features/email/data/datasource_impl/email_datasource_impl.dart
@@ -452,11 +452,8 @@ class EmailDataSourceImpl extends EmailDataSource {
final iconBase64Data = await _fileUtils.convertImageAssetToBase64(
attachment.getIcon(_imagePaths));
- final link = attachment.isEMLFile && PlatformInfo.isWeb
- ? RouteUtils.createUrlWebLocationBar(
- AppRoutes.emailEMLPreviewer,
- previewId: attachment.blobId?.value,
- ).toString()
+ final link = attachment.isEMLFile
+ ? _generateEMLAttachmentLink(attachment.blobId?.value)
: null;
final previewAttachment = PreviewAttachment(
@@ -501,6 +498,21 @@ class EmailDataSourceImpl extends EmailDataSource {
}).catchError(_exceptionThrower.throwException);
}
+ String _generateEMLAttachmentLink(String? blobId) {
+ if (blobId == null) return '';
+
+ if (PlatformInfo.isWeb) {
+ return RouteUtils.createUrlWebLocationBar(
+ AppRoutes.emailEMLPreviewer,
+ previewId: blobId,
+ ).toString();
+ } else if (PlatformInfo.isMobile) {
+ return '${PreviewEmlFileUtils.emlPreviewerScheme}://$blobId';
+ } else {
+ return '';
+ }
+ }
+
Future _transformEmailContent(
List emailContents,
Map mapCidImageDownloadUrl,
diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart
index 0f2033b40..d1bb82d91 100644
--- a/lib/features/email/presentation/controller/single_email_controller.dart
+++ b/lib/features/email/presentation/controller/single_email_controller.dart
@@ -93,6 +93,7 @@ import 'package:tmail_ui_user/features/email/presentation/model/blob_calendar_ev
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_loaded.dart';
import 'package:tmail_ui_user/features/email/presentation/model/email_unsubscribe.dart';
+import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.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';
@@ -1919,7 +1920,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
if (PlatformInfo.isWeb && PlatformInfo.isCanvasKit && attachment.isPDFFile) {
previewPDFFileAction(context, attachment);
} else if (attachment.isEMLFile) {
- previewEMLFileAction(attachment, AppLocalizations.of(context));
+ previewEMLFileAction(attachment.blobId, AppLocalizations.of(context));
} else {
handleDownloadAttachmentAction(context, attachment);
}
@@ -1952,7 +1953,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
);
}
- void previewEMLFileAction(Attachment attachment, AppLocalizations appLocalizations) {
+ void previewEMLFileAction(Id? blobId, AppLocalizations appLocalizations) {
SmartDialog.showLoading(
msg: appLocalizations.loadingPleaseWait,
maskColor: Colors.black38,
@@ -1963,15 +1964,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
return;
}
- if (attachment.blobId == null) {
+ if (blobId == null) {
consumeState(Stream.value(Left(ParseEmailByBlobIdFailure(NotFoundBlobIdException([])))));
return;
}
- consumeState(_parseEmailByBlobIdInteractor.execute(
- accountId!,
- attachment.blobId!,
- ));
+ consumeState(_parseEmailByBlobIdInteractor.execute(accountId!, blobId));
}
void _handleParseEmailByBlobIdSuccess(ParseEmailByBlobIdSuccess success) {
@@ -2033,30 +2031,51 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
return;
}
- showModalBottomSheet(
- context: currentContext!,
- showDragHandle: true,
- useSafeArea: true,
- isScrollControlled: true,
- shape: const RoundedRectangleBorder(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(20.0),
- topRight: Radius.circular(20.0),
- ),
- ),
- builder: (_) {
- return DraggableScrollableSheet(
- initialChildSize: 1.0,
- builder: (__, ___) => EmailPreviewerDialogView(
- emlPreviewer: success.emlPreviewer,
- onMailtoDelegateAction: openMailToLink,
- )
- );
- },
- );
+ showModalSheetToPreviewEMLAttachment(
+ currentContext!,
+ success.emlPreviewer);
}
}
+ void showModalSheetToPreviewEMLAttachment(
+ BuildContext context,
+ EMLPreviewer emlPreviewer,
+ ) {
+ showModalBottomSheet(
+ context: context,
+ showDragHandle: true,
+ useSafeArea: true,
+ isScrollControlled: true,
+ shape: const RoundedRectangleBorder(
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(20.0),
+ topRight: Radius.circular(20.0),
+ ),
+ ),
+ builder: (_) {
+ return DraggableScrollableSheet(
+ initialChildSize: 1.0,
+ builder: (context, ___) => EmailPreviewerDialogView(
+ emlPreviewer: emlPreviewer,
+ onMailtoDelegateAction: openMailToLink,
+ onPreviewEMLDelegateAction: (uri) => _openEMLPreviewer(context, uri),
+ ),
+ );
+ },
+ );
+ }
+
+ Future _openEMLPreviewer(BuildContext context, Uri? uri) async {
+ log('SingleEmailController::_openEMLPreviewer:uri = $uri');
+ if (uri == null) return;
+
+ final blobId = uri.authority;
+ log('SingleEmailController::_openEMLPreviewer:blobId = $blobId');
+ if (blobId.isEmpty) return;
+
+ previewEMLFileAction(Id(blobId), AppLocalizations.of(context));
+ }
+
void handleMailToAttendees(CalendarOrganizer? organizer, List? attendees) {
final listEmailAddressAttendees = attendees
?.map((attendee) => EmailAddress(attendee.name?.name, attendee.mailto?.mailAddress.value))
diff --git a/lib/features/email_previewer/email_previewer_dialog_view.dart b/lib/features/email_previewer/email_previewer_dialog_view.dart
index 919127bc1..85c482fa8 100644
--- a/lib/features/email_previewer/email_previewer_dialog_view.dart
+++ b/lib/features/email_previewer/email_previewer_dialog_view.dart
@@ -9,11 +9,13 @@ class EmailPreviewerDialogView extends StatelessWidget {
final EMLPreviewer emlPreviewer;
final OnMailtoDelegateAction onMailtoDelegateAction;
+ final OnPreviewEMLDelegateAction onPreviewEMLDelegateAction;
const EmailPreviewerDialogView({
super.key,
required this.emlPreviewer,
required this.onMailtoDelegateAction,
+ required this.onPreviewEMLDelegateAction,
});
@override
@@ -26,6 +28,7 @@ class EmailPreviewerDialogView extends StatelessWidget {
initialWidth: context.width,
direction: AppUtils.getCurrentDirection(context),
onMailtoDelegateAction: onMailtoDelegateAction,
+ onPreviewEMLDelegateAction: onPreviewEMLDelegateAction,
),
),
);