TF-32 Add domain layer of export attachment for ios platform

This commit is contained in:
dab246
2021-09-16 09:46:14 +07:00
committed by Dat H. Pham
parent 20f98ce541
commit 0158142e45
15 changed files with 268 additions and 5 deletions
+3
View File
@@ -33,6 +33,7 @@ export 'presentation/views/text/text_form_field_builder.dart';
export 'presentation/views/image/icon_builder.dart';
export 'presentation/views/context_menu/context_menu_action_builder.dart';
export 'presentation/views/context_menu/context_menu_builder.dart';
export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
@@ -48,6 +49,8 @@ export 'data/network/config/dynamic_url_interceptors.dart';
export 'data/network/config/endpoint.dart';
export 'data/network/config/service_path.dart';
export 'data/network/dio_client.dart';
export 'data/network/download/download_client.dart';
export 'data/network/download/download_manager.dart';
// State
export 'presentation/state/success.dart';
@@ -0,0 +1,29 @@
import 'dart:io';
import 'package:core/core.dart';
import 'package:dio/dio.dart';
class DownloadClient {
final DioClient _dioClient;
DownloadClient(this._dioClient);
Future<ResponseBody> downloadFile(
String url,
String baseAuth,
CancelToken? cancelToken,
) async {
final headerParam = _dioClient.getHeaders();
headerParam[HttpHeaders.authorizationHeader] = baseAuth;
headerParam[HttpHeaders.acceptHeader] = DioClient.jmapHeader;
final responseBody = await _dioClient.get(
url,
options: Options(headers: headerParam, responseType: ResponseType.stream),
cancelToken: cancelToken);
return (responseBody as ResponseBody);
}
}
@@ -0,0 +1,76 @@
import 'dart:async';
import 'dart:io';
import 'package:core/core.dart';
import 'package:core/data/network/download/download_client.dart';
import 'package:dio/dio.dart';
class DownloadManager {
final DownloadClient _downloadClient;
DownloadManager(this._downloadClient);
Future<String> downloadFile(
String downloadUrl,
Future<Directory> directoryToSave,
String filename,
String baseAuth,
{CancelToken? cancelToken}
) async {
final streamController = StreamController<String>();
try {
await Future.wait([
_downloadClient.downloadFile(downloadUrl, baseAuth, cancelToken),
directoryToSave
]).then((values) {
final fileStream = (values[0] as ResponseBody).stream;
final tempFilePath = '${(values[1] as Directory).absolute.path}/$filename';
final file = File(tempFilePath);
file.createSync(recursive: true);
var randomAccessFile = file.openSync(mode: FileMode.write);
late StreamSubscription subscription;
subscription = fileStream
.takeWhile((_) => cancelToken == null || !cancelToken.isCancelled)
.listen((data) {
subscription.pause();
randomAccessFile.writeFrom(data).then((_randomAccessFile) {
randomAccessFile = _randomAccessFile;
subscription.resume();
if (cancelToken != null && cancelToken.isCancelled) {
streamController.sink.addError(CancelDownloadFileException(cancelToken.cancelError?.message));
}
}).catchError((error) async {
await subscription.cancel();
streamController.sink.addError(CommonDownloadFileException(error.toString()));
await streamController.close();
});
}, onDone: () async {
await randomAccessFile.close();
if (cancelToken != null && cancelToken.isCancelled) {
streamController.sink.addError(CancelDownloadFileException(cancelToken.cancelError?.message));
} else {
streamController.sink.add(tempFilePath);
}
await streamController.close();
}, onError: (error) async {
await randomAccessFile.close();
await file.delete();
streamController.sink.addError(CommonDownloadFileException(error.toString()));
await streamController.close();
});
});
} catch(exception) {
if (cancelToken != null && cancelToken.isCancelled) {
streamController.sink.addError(CancelDownloadFileException(cancelToken.cancelError?.message));
await streamController.close();
return streamController.stream.first;
} else {
throw exception;
}
}
return streamController.stream.first;
}
}
@@ -55,4 +55,5 @@ extension AppColor on Color {
static const toastBackgroundColor = Color(0xFFACAFFF);
static const toastSuccessBackgroundColor = Color(0xFF04AA11);
static const toastErrorBackgroundColor = Color(0xFFFF5858);
static const backgroundCountAttachment = Color(0x681C1C1C);
}
@@ -37,6 +37,8 @@ class ImagePaths {
String get icComposerFileShare => _getImagePath('ic_composer_file_share.svg');
String get icExpandAddress => _getImagePath('ic_expand_address.svg');
String get icSelected => _getImagePath('ic_selected.svg');
String get icExpandAttachment => _getImagePath('ic_expand_attachment.svg');
String get icDownload => _getImagePath('ic_download.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -0,0 +1,71 @@
import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
typedef OnCancelDownloadActionClick = void Function();
class DownloadingFileDialogBuilder {
Key? _key;
String _title = '';
String _content = '';
String _actionText = '';
OnCancelDownloadActionClick? _onCancelDownloadActionClick;
DownloadingFileDialogBuilder();
void key(Key key) {
_key = key;
}
void title(String title) {
_title = title;
}
void content(String content) {
_content = content;
}
void actionText(String actionText) {
_actionText = actionText;
}
void addCancelDownloadActionClick(OnCancelDownloadActionClick onCancelDownloadActionClick) {
_onCancelDownloadActionClick = onCancelDownloadActionClick;
}
Widget build() {
return CupertinoAlertDialog(
key: _key ?? Key('DownloadingFileBuilder'),
title: Text(_title, style: TextStyle(fontSize: 17.0, color: Colors.black)),
content: Padding(
padding: EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
child: Center(
child: Column(
children: [
SizedBox(
width: 20.0,
height: 20.0,
child: CupertinoActivityIndicator()),
SizedBox(height: 16),
Text(
_content,
style: TextStyle(fontSize: 13.0, color: Colors.black),
softWrap: false,
maxLines: 1)
],
),
)),
actions: [
TextButton(
onPressed: () {
if (_onCancelDownloadActionClick != null) {
_onCancelDownloadActionClick!();
}},
child: Text(_actionText, style: TextStyle(fontSize: 17.0, color: AppColor.appColor)),
)
],
);
}
}