TF-2708 Allow Chrome to download PDF after view (#2712)
This commit is contained in:
@@ -2,18 +2,23 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:core/data/constants/constant.dart';
|
||||
import 'package:core/data/network/download/download_client.dart';
|
||||
import 'package:core/data/network/download/downloaded_response.dart';
|
||||
import 'package:core/domain/exceptions/download_file_exception.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
class DownloadManager {
|
||||
final DownloadClient _downloadClient;
|
||||
final DeviceInfoPlugin _deviceInfoPlugin;
|
||||
|
||||
DownloadManager(this._downloadClient);
|
||||
DownloadManager(this._downloadClient, this._deviceInfoPlugin);
|
||||
|
||||
Future<DownloadedResponse> downloadFile(
|
||||
String downloadUrl,
|
||||
@@ -104,14 +109,18 @@ class DownloadManager {
|
||||
}
|
||||
}
|
||||
|
||||
void openDownloadedFileWeb(Uint8List bytes, String? mimeType) {
|
||||
Future<void> openDownloadedFileWeb(Uint8List bytes, String? mimeType) async {
|
||||
try {
|
||||
final blob = html.Blob([bytes], mimeType);
|
||||
final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
|
||||
html.window.open(url, '_blank');
|
||||
|
||||
html.Url.revokeObjectUrl(url);
|
||||
final deviceInfo = await _deviceInfoPlugin.deviceInfo;
|
||||
if ('${deviceInfo.data['browserName']}' != 'BrowserName.chrome'
|
||||
|| mimeType != Constant.pdfMimeType) {
|
||||
final blob = html.Blob([bytes], mimeType);
|
||||
final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
html.window.open(url, '_blank');
|
||||
html.Url.revokeObjectUrl(url);
|
||||
} else {
|
||||
HtmlUtils.openNewTabHtmlDocument(HtmlUtils.pdfViewer(bytes));
|
||||
}
|
||||
} catch (exception) {
|
||||
logError('DownloadManager::openDownloadedFileWeb(): ERROR: $exception');
|
||||
rethrow;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'js_interop_stub.dart' if (dart.library.html) 'dart:js_interop';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:core/data/constants/constant.dart';
|
||||
import 'package:core/presentation/extensions/html_extension.dart';
|
||||
@@ -148,4 +150,45 @@ class HtmlUtils {
|
||||
|
||||
html.Url.revokeObjectUrl(url);
|
||||
}
|
||||
|
||||
static get iframeFullScreenCssStyle => '''
|
||||
position: fixed;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;''';
|
||||
|
||||
static String pdfViewer(Uint8List bytes) {
|
||||
return '''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
iframe {
|
||||
${HtmlUtils.iframeFullScreenCssStyle}
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
||||
<script>
|
||||
const bytesJs = new Uint8Array(${bytes.toJS}).buffer;
|
||||
const blob = new Blob([bytesJs], { type: "application/pdf" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
window.onload = function() {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = url;
|
||||
document.body.appendChild(iframe);
|
||||
};
|
||||
window.addEventListener("beforeunload", function listener(event) {
|
||||
URL.revokeObjectURL(url);
|
||||
window.removeEventListener("beforeunload", listener);
|
||||
});
|
||||
</script>
|
||||
</html>''';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
extension Uint8ListExtension on Uint8List {
|
||||
dynamic get toJS => throw UnimplementedError();
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import 'dart:io';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:contact/data/network/contact_api.dart';
|
||||
import 'package:core/core.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||
@@ -101,7 +102,7 @@ class NetworkBindings extends Bindings {
|
||||
void _bindingApi() {
|
||||
Get.put(HttpClient(Get.find<Dio>()));
|
||||
Get.put(DownloadClient(Get.find<DioClient>(), Get.find<CompressFileUtils>()));
|
||||
Get.put(DownloadManager(Get.find<DownloadClient>()));
|
||||
Get.put(DownloadManager(Get.find<DownloadClient>(), Get.find<DeviceInfoPlugin>()));
|
||||
Get.put(MailboxAPI(Get.find<HttpClient>(), Get.find<Uuid>()));
|
||||
Get.put(SessionAPI(Get.find<HttpClient>()));
|
||||
Get.put(ThreadAPI(Get.find<HttpClient>()));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||
@@ -56,7 +57,7 @@ class NetworkIsolateBindings extends Bindings {
|
||||
void _bindingApi() {
|
||||
final httpClient = Get.put(HttpClient(Get.find<Dio>(tag: BindingTag.isolateTag)), tag: BindingTag.isolateTag);
|
||||
Get.put(DownloadClient(Get.find<DioClient>(tag: BindingTag.isolateTag), Get.find<CompressFileUtils>()), tag: BindingTag.isolateTag);
|
||||
Get.put(DownloadManager(Get.find<DownloadClient>(tag: BindingTag.isolateTag)), tag: BindingTag.isolateTag);
|
||||
Get.put(DownloadManager(Get.find<DownloadClient>(tag: BindingTag.isolateTag), Get.find<DeviceInfoPlugin>()), tag: BindingTag.isolateTag);
|
||||
Get.put(ThreadAPI(httpClient), tag: BindingTag.isolateTag);
|
||||
Get.put(EmailAPI(
|
||||
httpClient,
|
||||
|
||||
Reference in New Issue
Block a user