diff --git a/android/build.gradle b/android/build.gradle index 2fb1afbd4..043f3dca2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.6.2' classpath 'com.google.gms:google-services:4.3.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 90f271dfd..493072b3c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/lib/ui/expense/view/expense_view.dart b/lib/ui/expense/view/expense_view.dart index f0199361f..d7282992b 100644 --- a/lib/ui/expense/view/expense_view.dart +++ b/lib/ui/expense/view/expense_view.dart @@ -116,8 +116,7 @@ class _ExpenseViewState extends State .getImage(source: ImageSource.camera); if (image != null && image.path != null) { final bytes = await image.readAsBytes(); - multipartFile = MultipartFile.fromBytes( - 'file', bytes, + multipartFile = MultipartFile.fromBytes('file', bytes, filename: image.path.split('/').last); } } else { diff --git a/lib/ui/settings/company_details.dart b/lib/ui/settings/company_details.dart index 49fdcb754..daa949ee7 100644 --- a/lib/ui/settings/company_details.dart +++ b/lib/ui/settings/company_details.dart @@ -24,6 +24,7 @@ import 'package:invoiceninja_flutter/utils/files.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; +import 'package:file_picker/file_picker.dart'; class CompanyDetails extends StatefulWidget { const CompanyDetails({ @@ -426,7 +427,10 @@ class _CompanyDetailsState extends State label: localization.uploadLogo, iconData: Icons.cloud_upload, onPressed: () async { - final multipartFile = await pickFile(fileIndex: 'company_logo'); + final multipartFile = await pickFile( + fileIndex: 'company_logo', + fileType: FileType.image, + ); if (multipartFile != null) { viewModel.onUploadLogo(context, multipartFile); } diff --git a/lib/utils/files.dart b/lib/utils/files.dart index 9de405acf..ed47ae38f 100644 --- a/lib/utils/files.dart +++ b/lib/utils/files.dart @@ -1,17 +1,33 @@ +import 'dart:io'; + import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:permission_handler/permission_handler.dart'; -Future pickFile({String fileIndex = 'file'}) async { +Future pickFile( + {String fileIndex, + FileType fileType, + List allowedExtensions}) async { if (kIsWeb) { - return _pickFile(fileIndex: fileIndex); + return _pickFile( + fileIndex: fileIndex, + fileType: fileType, + allowedExtensions: allowedExtensions, + ); } else { - final permissionStatus = await [Permission.photos].request(); + final permissionType = fileType == FileType.image && Platform.isIOS + ? Permission.photos + : Permission.storage; + final permissionStatus = await [permissionType].request(); final permission = - permissionStatus[Permission.photos] ?? PermissionStatus.undetermined; + permissionStatus[permissionType] ?? PermissionStatus.undetermined; if (permission == PermissionStatus.granted) { - return _pickFile(fileIndex: fileIndex); + return _pickFile( + fileIndex: fileIndex, + fileType: fileType, + allowedExtensions: allowedExtensions, + ); } else { openAppSettings(); return null; @@ -19,8 +35,16 @@ Future pickFile({String fileIndex = 'file'}) async { } } -Future _pickFile({String fileIndex}) async { - final result = await FilePicker.platform.pickFiles(); +Future _pickFile( + {String fileIndex, + FileType fileType, + List allowedExtensions}) async { + final result = await FilePicker.platform.pickFiles( + withData: true, + type: fileType ?? FileType.any, + allowedExtensions: allowedExtensions ?? [], + allowCompression: true, + ); if (result != null) { final file = result.files.single; return MultipartFile.fromBytes(fileIndex ?? 'file', file.bytes,