From b98df4fd691e6184907f7f027028e06081333e1b Mon Sep 17 00:00:00 2001 From: Tien Do Nam Date: Tue, 29 Aug 2023 11:07:12 +0200 Subject: [PATCH] feat: add file_selector package --- android/app/src/main/AndroidManifest.xml | 4 ++- lib/pages/receive_options_page.dart | 4 +-- lib/pages/tabs/settings_tab.dart | 4 +-- lib/util/native/file_picker.dart | 27 ++++++++++++++------ lib/util/native/pick_directory_path.dart | 18 +++++++++++++ pubspec.lock | 32 ++++++++++++++++++++++++ pubspec.yaml | 1 + 7 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 lib/util/native/pick_directory_path.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ad3bb9f88e..da419b4841 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -24,7 +24,9 @@ android:name="${applicationName}" android:usesCleartextTraffic="true" android:banner="@drawable/banner" - android:icon="@mipmap/ic_launcher"> + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true" + > with Riverpie { return; } - final directory = await FilePicker.platform.getDirectoryPath(); + final directory = await pickDirectoryPath(); if (directory != null) { await ref.notifier(settingsProvider).setDestination(directory); } diff --git a/lib/util/native/file_picker.dart b/lib/util/native/file_picker.dart index 4c46187eb7..91130a422c 100644 --- a/lib/util/native/file_picker.dart +++ b/lib/util/native/file_picker.dart @@ -1,11 +1,13 @@ import 'dart:async'; import 'package:file_picker/file_picker.dart'; +import 'package:file_selector/file_selector.dart' as file_selector; import 'package:flutter/material.dart'; import 'package:localsend_app/gen/strings.g.dart'; import 'package:localsend_app/pages/apk_picker_page.dart'; import 'package:localsend_app/provider/selection/selected_sending_files_provider.dart'; import 'package:localsend_app/theme.dart'; +import 'package:localsend_app/util/native/pick_directory_path.dart'; import 'package:localsend_app/util/native/platform_check.dart'; import 'package:localsend_app/util/sleep.dart'; import 'package:localsend_app/util/ui/asset_picker_translated_text_delegate.dart'; @@ -92,12 +94,23 @@ enum FilePickerOption { ); } try { - final result = await FilePicker.platform.pickFiles(allowMultiple: true); - if (result != null) { - await ref.notifier(selectedSendingFilesProvider).addFiles( - files: result.files, - converter: CrossFileConverters.convertPlatformFile, - ); + if (checkPlatform([TargetPlatform.android])) { + // We also need to use the file_picker package because file_selector does not expose the raw path. + final result = await FilePicker.platform.pickFiles(allowMultiple: true); + if (result != null) { + await ref.notifier(selectedSendingFilesProvider).addFiles( + files: result.files, + converter: CrossFileConverters.convertPlatformFile, + ); + } + } else { + final result = await file_selector.openFiles(); + if (result.isNotEmpty) { + await ref.notifier(selectedSendingFilesProvider).addFiles( + files: result, + converter: CrossFileConverters.convertXFile, + ); + } } } catch (e) { // ignore: use_build_context_synchronously @@ -130,7 +143,7 @@ enum FilePickerOption { ); await sleepAsync(200); // Wait for the dialog to be shown try { - final directoryPath = await FilePicker.platform.getDirectoryPath(); + final directoryPath = await pickDirectoryPath(); if (directoryPath != null) { await ref.notifier(selectedSendingFilesProvider).addDirectory(directoryPath); } diff --git a/lib/util/native/pick_directory_path.dart b/lib/util/native/pick_directory_path.dart new file mode 100644 index 0000000000..c489884dc6 --- /dev/null +++ b/lib/util/native/pick_directory_path.dart @@ -0,0 +1,18 @@ +import 'package:file_picker/file_picker.dart'; +import 'package:file_selector/file_selector.dart' as file_selector; +import 'package:flutter/material.dart'; +import 'package:localsend_app/util/native/platform_check.dart'; + +/// Opens a file picker to select a directory. +/// Returns null if the user cancels the selection. +Future pickDirectoryPath() async { + if (checkPlatform([TargetPlatform.android])) { + /// We need to use the file_picker package because file_selector does not expose the raw path. + /// We need the raw path to properly manipulate the path to save new files, or + /// to list files recursively. + /// https://github.com/miguelpruivo/flutter_file_picker/issues/1282 + return await FilePicker.platform.getDirectoryPath(); + } else { + return await file_selector.getDirectoryPath(); + } +} diff --git a/pubspec.lock b/pubspec.lock index 7997b0332f..34fd915fda 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -369,6 +369,30 @@ packages: url: "https://pub.dev" source: hosted version: "5.3.4" + file_selector: + dependency: "direct main" + description: + name: file_selector + sha256: "59b35aa4af7988be7ec88f9ddaa6c71c5b54bf0f8b35009389d9343b10e9c3af" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + file_selector_android: + dependency: transitive + description: + name: file_selector_android + sha256: "43e5c719f671b9181bef1bf2851135c3ad993a9a6c804a4ccb07579cfee84e34" + url: "https://pub.dev" + source: hosted + version: "0.5.0+2" + file_selector_ios: + dependency: transitive + description: + name: file_selector_ios + sha256: "507af301b21b1dbb6fd0615ba21190b2b4574edb672929f32ce7f610c40a9bd9" + url: "https://pub.dev" + source: hosted + version: "0.5.1+5" file_selector_linux: dependency: transitive description: @@ -393,6 +417,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.6.0" + file_selector_web: + dependency: transitive + description: + name: file_selector_web + sha256: e292740c469df0aeeaba0895bf622bea351a05e87d22864c826bf21c4780e1d7 + url: "https://pub.dev" + source: hosted + version: "0.9.2" file_selector_windows: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b1a79e0d24..6140569604 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,6 +19,7 @@ dependencies: dio: 5.3.2 dynamic_color: 1.6.6 file_picker: 5.3.4 + file_selector: 1.0.0 flutter: sdk: flutter flutter_localizations: