From d6347296155a3f7aefaa987a9e52f83134c41f51 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 12 Apr 2023 15:28:37 +0300 Subject: [PATCH] pdf download added. --- android/app/build.gradle | 11 ++- android/local.properties | 2 +- lib/classes/utils.dart | 113 +++++++++++++++++++++++++- lib/new_ui/screens/about_screen.dart | 6 +- lib/ui/screens/pdf_viewer_screen.dart | 26 +++++- lib/widgets/aya_player_widget.dart | 2 +- 6 files changed, 146 insertions(+), 14 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 5b954fa..9340738 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 31 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -43,11 +43,11 @@ android { disable 'InvalidPackage' } + defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.cloudsolutions.tangheem" minSdkVersion 19 - targetSdkVersion 31 + targetSdkVersion 33 versionCode 1 versionName "1.0.0" multiDexEnabled true @@ -65,6 +65,11 @@ android { debug { signingConfig signingConfigs.debug } + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } // release { // minifyEnabled true // shrinkResources true diff --git a/android/local.properties b/android/local.properties index a32620b..c5ea3f8 100644 --- a/android/local.properties +++ b/android/local.properties @@ -1,5 +1,5 @@ sdk.dir=/Users/sikandersaleem/Library/Android/sdk flutter.sdk=/Users/sikandersaleem/sdks/flutter -flutter.buildMode=debug +flutter.buildMode=profile flutter.versionName=1.0.0 flutter.versionCode=1 \ No newline at end of file diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 751ef18..8dd8cc8 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -1,8 +1,12 @@ +import 'dart:io'; +import 'dart:typed_data'; + import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:tangheem/exceptions/api_exception.dart'; import 'package:tangheem/ui/dialogs/loading_dialog.dart'; - +import 'package:http/http.dart' as http; import 'colors.dart'; class Utils { @@ -11,8 +15,7 @@ class Utils { static bool get isLoading => _isLoadingVisible; static void showToast(String message) { - Fluttertoast.showToast( - msg: message, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); + Fluttertoast.showToast(msg: message, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); } static dynamic getNotNullValue(List list, int index) { @@ -75,4 +78,108 @@ class Utils { showToast(errorMessage); } } + + static Future getStoragePath(String fileName) async { + Directory storageDirectory; + if (Platform.isAndroid) { + storageDirectory = await getExternalStorageDirectory(); + } else if (Platform.isIOS) { + storageDirectory = await getApplicationDocumentsDirectory(); + } else { + return ""; + } + + String storagePath = storageDirectory.path; + if (storagePath.contains("/Android/data")) { + storagePath = storagePath.substring(0, storagePath.indexOf("/Android/data")); + } + + if (Platform.isAndroid) { + storagePath += "/Download/Tangheem/"; + } else { + storagePath += "/PDFs/"; + } + + var d = Directory(storagePath); + if (!d.existsSync()) { + d.createSync(recursive: true); + } + storagePath += fileName; + return storagePath; + } + + static void downloadFile(String url, String path, {Function(bool) onResponse}) { + var httpClient = http.Client(); + var request = http.Request('GET', Uri.parse(url)); + var response = httpClient.send(request); + String dir = path; + + List> chunks = []; + int downloaded = 0; + int lastVal; + + response.asStream().listen((http.StreamedResponse r) { + r.stream.listen((List chunk) { + debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}'); + lastVal = (downloaded / r.contentLength * 100).toInt(); + + chunks.add(chunk); + downloaded += chunk.length; + }, onDone: () async { + debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}'); + if (lastVal == 0) { + onResponse(false); + return; + } + // Save the file + File file = new File('$dir'); + final Uint8List bytes = Uint8List(r.contentLength); + int offset = 0; + for (List chunk in chunks) { + bytes.setRange(offset, offset + chunk.length, chunk); + offset += chunk.length; + } + await file.writeAsBytes(bytes); + onResponse(true); + return; + }, onError: (ex) { + debugPrint("onError:$ex"); + }, cancelOnError: true); + }).onError((ex) { + debugPrint("onError:$ex"); + onResponse(false); + }); + } + + void saveToPhoneStorage(String filePath) async { + File file = File(filePath); + Directory storageDirectory; + if (Platform.isAndroid) { + storageDirectory = await getExternalStorageDirectory(); + } else if (Platform.isIOS) { + storageDirectory = await getApplicationDocumentsDirectory(); + } else { + return; + } + + String storagePath = storageDirectory.path; + if (storagePath.contains("/Android/data")) { + storagePath = storagePath.substring(0, storagePath.indexOf("/Android/data")); + } + + if (Platform.isAndroid) { + storagePath += "/Download/Tangheem/"; + } else { + storagePath += "/Recording/"; + } + + var d = Directory(storagePath); + if (!d.existsSync()) { + d.createSync(recursive: true); + } + storagePath += "Tangheem${DateTime.now().millisecondsSinceEpoch}.mp3"; + print("storagePath:$storagePath"); + await file.copy(storagePath); + Utils.showToast("تم التنزيل"); + } } diff --git a/lib/new_ui/screens/about_screen.dart b/lib/new_ui/screens/about_screen.dart index 38875c8..8dc6f4b 100644 --- a/lib/new_ui/screens/about_screen.dart +++ b/lib/new_ui/screens/about_screen.dart @@ -33,11 +33,11 @@ class _AboutScreenState extends State { void getContents() async { Utils.showLoading(context); try { - if (haqooqAlMosasa == null && tareefAlMosasa == null) { - List responseList = await Future.wait([TangheemUserApiClient().getContentInfo(2), if (haqooqAlMosasa == null) TangheemUserApiClient().getContentInfo(1)]); + if ((haqooqAlMosasa ?? []).isEmpty || (tareefAlMosasa ?? []).isEmpty) { + List responseList = await Future.wait([TangheemUserApiClient().getContentInfo(2), if ((haqooqAlMosasa ?? []).isEmpty) TangheemUserApiClient().getContentInfo(1)]); tareefAlMosasa = responseList[0].data ?? []; AppState().tareefAlMosasa = tareefAlMosasa; - if (haqooqAlMosasa == null) { + if ((haqooqAlMosasa ?? []).isEmpty) { haqooqAlMosasa = responseList[1].data ?? []; AppState().haqooqAlMosasa = haqooqAlMosasa; } diff --git a/lib/ui/screens/pdf_viewer_screen.dart b/lib/ui/screens/pdf_viewer_screen.dart index fe31ed9..d69ef55 100644 --- a/lib/ui/screens/pdf_viewer_screen.dart +++ b/lib/ui/screens/pdf_viewer_screen.dart @@ -61,6 +61,24 @@ class _PdfListScreenState extends State { super.dispose(); } + void startFileDownload(String url, String fileName) async { + try { + Utils.showLoading(context); + String path = await Utils.getStoragePath(fileName); + Utils.downloadFile(ApiConsts.baseUrl + url, path, onResponse: (isSuccess) { + Utils.hideLoading(context); + if (isSuccess) { + Utils.showToast("تم حفظ الملف بنجاح"); + } else { + Utils.showToast("فشل حفظ الملف ، حاول مرة أخرى"); + } + }); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + } + } + @override Widget build(BuildContext context) { return SizedBox( @@ -91,7 +109,9 @@ class _PdfListScreenState extends State { "assets/icons/new/download_pdf.svg", width: 44, height: 50, - ), + ).onPress(() { + startFileDownload(contentList[index].exposeFilePath, contentList[index].fileName); + }), 7.width, ClipRRect( borderRadius: BorderRadius.circular(7), @@ -122,10 +142,10 @@ class _PdfListScreenState extends State { Directionality( textDirection: TextDirection.rtl, child: (contentList[index].fileName?.trim() ?? "").toText(18, color: ColorConsts.darkText).paddingOnly(left: 12, right: 12), - ), + ).expanded, ], ), - ).expanded, + ), ).onPress(() { Navigator.pushNamed(context, PdfViewerScreen.routeName, arguments: contentList[index]); }).expanded, diff --git a/lib/widgets/aya_player_widget.dart b/lib/widgets/aya_player_widget.dart index 8ecd94c..16ede2e 100644 --- a/lib/widgets/aya_player_widget.dart +++ b/lib/widgets/aya_player_widget.dart @@ -341,7 +341,7 @@ class _AyaPlayerWidgetState extends State { } storagePath += "Tangheem-$name-${DateTime.now().millisecondsSinceEpoch}${filePath.substring(filePath.lastIndexOf('.'), filePath.length)}"; Utils.showLoading(context); - downloadFile(ApiConsts.baseUrl + filePath, storagePath, onResponse: (isSuccess) { + Utils.downloadFile(ApiConsts.baseUrl + filePath, storagePath, onResponse: (isSuccess) { Utils.hideLoading(context); if (isSuccess) { Utils.showToast("تم حفظ الآية بنجاح");