Adds onLoadingFile parameter to handle file processing status
This commit is contained in:
parent
b1881d521b
commit
ffed7696c7
|
@ -1,5 +1,8 @@
|
|||
## 1.11.0
|
||||
Adds `onFileLoading` handler for every picking method that will provide picking status: `FilePickerStatus.loading` and `FilePickerStatus.done` so you can, for example, display a custom loader.
|
||||
|
||||
## 1.10.0
|
||||
**Android & iOS:** Adds `getDirectoryPath()` method that allows you to select and pick directory paths. Android, requires SDK 21 or above for this to work, and iOS requires iOS 11 or above.
|
||||
Adds `getDirectoryPath()` method that allows you to select and pick directory paths. Android, requires SDK 21 or above for this to work, and iOS requires iOS 11 or above.
|
||||
|
||||
## 1.9.0+1
|
||||
Adds a temporary workaround on Android where it can trigger `onRequestPermissionsResult` twice, related to Flutter issue [49365](https://github.com/flutter/flutter/issues/49365) for anyone affected in Flutter versions below 1.14.6.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<img alt="Awesome Flutter" src="https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square">
|
||||
</a>
|
||||
<a href="https://codemagic.io/apps/5ce89f4a9b46f5000ca89638/5ce89f4a9b46f5000ca89637/latest_build">
|
||||
<img alt="Build Status" src="https://api.codemagic.io/apps/5ce89f4a9b46f5000ca89638/5ce89f4a9b46f5000ca89637/status_badge.svg">
|
||||
<img alt="Build Status" src="https://api.codemagic.io/apps/5ee2d379c2d4737a756cbd00/5ee2d3b829657a000c4c4317/status_badge.svg">
|
||||
</a>
|
||||
<a href="https://www.buymeacoffee.com/gQyz2MR">
|
||||
<img alt="Buy me a coffee" src="https://img.shields.io/badge/Donate-Buy%20Me%20A%20Coffee-yellow.svg">
|
||||
|
@ -35,15 +35,18 @@ If you have any feature that you want to see in this package, please feel free t
|
|||
## Documentation
|
||||
See the **[File Picker Wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki)** for every detail on about how to install, setup and use it.
|
||||
|
||||
### File Picker Wiki
|
||||
|
||||
1. [Installation](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/Installation)
|
||||
2. [Setup](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/Setup)
|
||||
* [Android](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/Setup#android)
|
||||
* [iOS](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/Setup#ios)
|
||||
* [Web](https://github.com/miguelpruivo/flutter_file_picker/wiki/Setup#--web)
|
||||
* [Desktop (go-flutter)](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/Setup/_edit#desktop-go-flutter)
|
||||
3. [API](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/api)
|
||||
* [Filters](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/API#filters)
|
||||
* [Parameters](https://github.com/miguelpruivo/flutter_file_picker/wiki/API#parameters)
|
||||
* [Methods](https://github.com/miguelpruivo/plugins_flutter_file_picker/wiki/API#methods)
|
||||
4. [Example App](https://github.com/miguelpruivo/flutter_file_picker/blob/master/example/lib/src/file_picker_demo.dart)
|
||||
5. [Troubleshooting](https://github.com/miguelpruivo/flutter_file_picker/wiki/Troubleshooting)
|
||||
|
||||
## Usage
|
||||
|
|
|
@ -7,6 +7,9 @@ import android.content.pm.PackageManager;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -16,6 +19,7 @@ import androidx.core.app.ActivityCompat;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
|
@ -30,6 +34,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
private boolean isMultipleSelection = false;
|
||||
private String type;
|
||||
private String[] allowedExtensions;
|
||||
private EventChannel.EventSink eventSink;
|
||||
|
||||
public FilePickerDelegate(final Activity activity) {
|
||||
this(
|
||||
|
@ -51,6 +56,10 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
);
|
||||
}
|
||||
|
||||
public void setEventHandler(final EventChannel.EventSink eventSink) {
|
||||
this.eventSink = eventSink;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
FilePickerDelegate(final Activity activity, final MethodChannel.Result result, final PermissionManager permissionManager) {
|
||||
this.activity = activity;
|
||||
|
@ -63,6 +72,11 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
public boolean onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
|
||||
if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
||||
|
||||
if (eventSink != null) {
|
||||
eventSink.success(true);
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -217,6 +231,10 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
}
|
||||
|
||||
private void finishWithSuccess(final Object data) {
|
||||
if (eventSink != null) {
|
||||
this.dispatchEventStatus(false);
|
||||
}
|
||||
|
||||
// Temporary fix, remove this null-check after Flutter Engine 1.14 has landed on stable
|
||||
if (this.pendingResult != null) {
|
||||
this.pendingResult.success(data);
|
||||
|
@ -228,10 +246,23 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
if (this.pendingResult == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventSink != null) {
|
||||
this.dispatchEventStatus(false);
|
||||
}
|
||||
this.pendingResult.error(errorCode, errorMessage, null);
|
||||
this.clearPendingResult();
|
||||
}
|
||||
|
||||
private void dispatchEventStatus(final boolean status) {
|
||||
new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(final Message message) {
|
||||
eventSink.success(status);
|
||||
}
|
||||
}.obtainMessage().sendToTarget();
|
||||
}
|
||||
|
||||
|
||||
private void clearPendingResult() {
|
||||
this.pendingResult = null;
|
||||
|
|
|
@ -19,6 +19,7 @@ import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
|||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
@ -31,6 +32,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
|
|||
|
||||
private static final String TAG = "FilePicker";
|
||||
private static final String CHANNEL = "miguelruivo.flutter.plugins.filepicker";
|
||||
private static final String EVENT_CHANNEL = "miguelruivo.flutter.plugins.filepickerevent";
|
||||
|
||||
private class LifeCycleObserver
|
||||
implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
|
||||
|
@ -249,6 +251,17 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
|
|||
this.delegate = new FilePickerDelegate(activity);
|
||||
this.channel = new MethodChannel(messenger, CHANNEL);
|
||||
this.channel.setMethodCallHandler(this);
|
||||
new EventChannel(messenger, EVENT_CHANNEL).setStreamHandler(new EventChannel.StreamHandler() {
|
||||
@Override
|
||||
public void onListen(final Object arguments, final EventChannel.EventSink events) {
|
||||
delegate.setEventHandler(events);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(final Object arguments) {
|
||||
delegate.setEventHandler(null);
|
||||
}
|
||||
});
|
||||
this.observer = new LifeCycleObserver(activity);
|
||||
if (registrar != null) {
|
||||
// V1 embedding setup for activity listeners.
|
||||
|
@ -273,6 +286,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
|
|||
this.delegate = null;
|
||||
this.channel.setMethodCallHandler(null);
|
||||
this.channel = null;
|
||||
this.delegate.setEventHandler(null);
|
||||
this.application.unregisterActivityLifecycleCallbacks(this.observer);
|
||||
this.application = null;
|
||||
}
|
||||
|
|
|
@ -31,11 +31,17 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
if (_multiPick) {
|
||||
_path = null;
|
||||
_paths = await FilePicker.getMultiFilePath(
|
||||
type: _pickingType, allowedExtensions: (_extension?.isNotEmpty ?? false) ? _extension?.replaceAll(' ', '')?.split(',') : null);
|
||||
type: _pickingType,
|
||||
allowedExtensions: (_extension?.isNotEmpty ?? false)
|
||||
? _extension?.replaceAll(' ', '')?.split(',')
|
||||
: null);
|
||||
} else {
|
||||
_paths = null;
|
||||
_path = await FilePicker.getFilePath(
|
||||
type: _pickingType, allowedExtensions: (_extension?.isNotEmpty ?? false) ? _extension?.replaceAll(' ', '')?.split(',') : null);
|
||||
type: _pickingType,
|
||||
allowedExtensions: (_extension?.isNotEmpty ?? false)
|
||||
? _extension?.replaceAll(' ', '')?.split(',')
|
||||
: null);
|
||||
}
|
||||
} on PlatformException catch (e) {
|
||||
print("Unsupported operation" + e.toString());
|
||||
|
@ -43,7 +49,9 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
if (!mounted) return;
|
||||
setState(() {
|
||||
_loadingPath = false;
|
||||
_fileName = _path != null ? _path.split('/').last : _paths != null ? _paths.keys.toString() : '...';
|
||||
_fileName = _path != null
|
||||
? _path.split('/').last
|
||||
: _paths != null ? _paths.keys.toString() : '...';
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -52,7 +60,9 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
_scaffoldKey.currentState.showSnackBar(
|
||||
SnackBar(
|
||||
backgroundColor: result ? Colors.green : Colors.red,
|
||||
content: Text((result ? 'Temporary files removed with success.' : 'Failed to clean temporary files')),
|
||||
content: Text((result
|
||||
? 'Temporary files removed with success.'
|
||||
: 'Failed to clean temporary files')),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
@ -124,7 +134,8 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
maxLength: 15,
|
||||
autovalidate: true,
|
||||
controller: _controller,
|
||||
decoration: InputDecoration(labelText: 'File extension'),
|
||||
decoration:
|
||||
InputDecoration(labelText: 'File extension'),
|
||||
keyboardType: TextInputType.text,
|
||||
textCapitalization: TextCapitalization.none,
|
||||
)
|
||||
|
@ -133,8 +144,10 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
new ConstrainedBox(
|
||||
constraints: BoxConstraints.tightFor(width: 200.0),
|
||||
child: new SwitchListTile.adaptive(
|
||||
title: new Text('Pick multiple files', textAlign: TextAlign.right),
|
||||
onChanged: (bool value) => setState(() => _multiPick = value),
|
||||
title: new Text('Pick multiple files',
|
||||
textAlign: TextAlign.right),
|
||||
onChanged: (bool value) =>
|
||||
setState(() => _multiPick = value),
|
||||
value: _multiPick,
|
||||
),
|
||||
),
|
||||
|
@ -159,18 +172,28 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
),
|
||||
new Builder(
|
||||
builder: (BuildContext context) => _loadingPath
|
||||
? Padding(padding: const EdgeInsets.only(bottom: 10.0), child: const CircularProgressIndicator())
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10.0),
|
||||
child: const CircularProgressIndicator())
|
||||
: _path != null || _paths != null
|
||||
? new Container(
|
||||
padding: const EdgeInsets.only(bottom: 30.0),
|
||||
height: MediaQuery.of(context).size.height * 0.50,
|
||||
child: new Scrollbar(
|
||||
child: new ListView.separated(
|
||||
itemCount: _paths != null && _paths.isNotEmpty ? _paths.length : 1,
|
||||
itemCount: _paths != null && _paths.isNotEmpty
|
||||
? _paths.length
|
||||
: 1,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final bool isMultiPath = _paths != null && _paths.isNotEmpty;
|
||||
final String name = 'File $index: ' + (isMultiPath ? _paths.keys.toList()[index] : _fileName ?? '...');
|
||||
final path = isMultiPath ? _paths.values.toList()[index].toString() : _path;
|
||||
final bool isMultiPath =
|
||||
_paths != null && _paths.isNotEmpty;
|
||||
final String name = 'File $index: ' +
|
||||
(isMultiPath
|
||||
? _paths.keys.toList()[index]
|
||||
: _fileName ?? '...');
|
||||
final path = isMultiPath
|
||||
? _paths.values.toList()[index].toString()
|
||||
: _path;
|
||||
|
||||
return new ListTile(
|
||||
title: new Text(
|
||||
|
@ -179,7 +202,9 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
subtitle: new Text(path),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) => new Divider(),
|
||||
separatorBuilder:
|
||||
(BuildContext context, int index) =>
|
||||
new Divider(),
|
||||
)),
|
||||
)
|
||||
: new Container(),
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
#import <Photos/Photos.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
@interface FilePickerPlugin : NSObject<FlutterPlugin, UIDocumentPickerDelegate, UITabBarDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
|
||||
@interface FilePickerPlugin : NSObject<FlutterPlugin, FlutterStreamHandler, UIDocumentPickerDelegate, UITabBarDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
|
||||
@end
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
@interface FilePickerPlugin() <UIImagePickerControllerDelegate, MPMediaPickerControllerDelegate, DKImageAssetExporterObserver>
|
||||
@property (nonatomic) FlutterResult result;
|
||||
@property (nonatomic) FlutterEventSink eventSink;
|
||||
@property (nonatomic) UIViewController *viewController;
|
||||
@property (nonatomic) UIImagePickerController *galleryPickerController;
|
||||
@property (nonatomic) UIDocumentPickerViewController *documentPickerController;
|
||||
|
@ -21,13 +22,17 @@
|
|||
methodChannelWithName:@"miguelruivo.flutter.plugins.filepicker"
|
||||
binaryMessenger:[registrar messenger]];
|
||||
|
||||
FlutterEventChannel* eventChannel = [FlutterEventChannel
|
||||
eventChannelWithName:@"miguelruivo.flutter.plugins.filepickerevent"
|
||||
binaryMessenger:[registrar messenger]];
|
||||
|
||||
UIViewController *viewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
FilePickerPlugin* instance = [[FilePickerPlugin alloc] initWithViewController:viewController];
|
||||
|
||||
[registrar addMethodCallDelegate:instance channel:channel];
|
||||
[eventChannel setStreamHandler:instance];
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithViewController:(UIViewController *)viewController {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
|
@ -37,6 +42,16 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
|
||||
_eventSink = events;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (FlutterError *)onCancelWithArguments:(id)arguments {
|
||||
_eventSink = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
if (_result) {
|
||||
result([FlutterError errorWithCode:@"multiple_request"
|
||||
|
@ -143,16 +158,20 @@
|
|||
- (void) resolveMultiPickFromGallery:(MediaType)type {
|
||||
DKImagePickerController * dkImagePickerController = [[DKImagePickerController alloc] init];
|
||||
|
||||
// Create alert dialog for asset caching
|
||||
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIActivityIndicatorView* indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
|
||||
|
||||
if(_eventSink == nil) {
|
||||
// Create alert dialog for asset caching
|
||||
[alert.view setCenter: _viewController.view.center];
|
||||
[alert.view addConstraint: [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:100]];
|
||||
|
||||
UIActivityIndicatorView* indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
|
||||
// Create a default loader if user don't provide a status handler
|
||||
indicator.hidesWhenStopped = YES;
|
||||
[indicator setCenter: alert.view.center];
|
||||
indicator.autoresizingMask = (UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin);
|
||||
[alert.view addSubview: indicator];
|
||||
}
|
||||
|
||||
dkImagePickerController.exportsWhenCompleted = YES;
|
||||
dkImagePickerController.showsCancelButton = YES;
|
||||
|
@ -164,12 +183,23 @@
|
|||
|
||||
if(status == DKImagePickerControllerExportStatusExporting && dkImagePickerController.selectedAssets.count > 0){
|
||||
Log("Exporting assets, this operation may take a while if remote (iCloud) assets are being cached.");
|
||||
|
||||
if(self->_eventSink != nil){
|
||||
self->_eventSink([NSNumber numberWithBool:YES]);
|
||||
} else {
|
||||
[indicator startAnimating];
|
||||
[self->_viewController showViewController:alert sender:nil];
|
||||
}
|
||||
|
||||
} else {
|
||||
if(self->_eventSink != nil) {
|
||||
self->_eventSink([NSNumber numberWithBool:NO]);
|
||||
} else {
|
||||
[indicator stopAnimating];
|
||||
[alert dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
}
|
||||
}];
|
||||
|
||||
// Did cancel
|
||||
|
|
|
@ -3,7 +3,8 @@ import 'dart:io';
|
|||
|
||||
import 'package:file_picker_platform_interface/file_picker_platform_interface.dart';
|
||||
|
||||
export 'package:file_picker_platform_interface/file_picker_platform_interface.dart' show FileType;
|
||||
export 'package:file_picker_platform_interface/file_picker_platform_interface.dart'
|
||||
show FileType;
|
||||
|
||||
final FilePickerPlatform _filePickerPlatform = FilePickerPlatform.instance;
|
||||
|
||||
|
@ -14,11 +15,21 @@ class FilePicker {
|
|||
///
|
||||
/// Extension filters are allowed with `FileType.custom`, when used, make sure to provide a `List`
|
||||
/// of [allowedExtensions] (e.g. [`pdf`, `svg`, `jpg`].).
|
||||
///
|
||||
/// If you want to track picking status, for example, because some files may take some time to be
|
||||
/// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler
|
||||
/// that will give you the current status of picking.
|
||||
///
|
||||
/// Defaults to `FileType.any` which will display all file types.
|
||||
static Future<String> getFilePath({FileType type = FileType.any, List<String> allowedExtensions}) async =>
|
||||
static Future<String> getFilePath({
|
||||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
}) async =>
|
||||
await _filePickerPlatform.getFiles(
|
||||
type: type,
|
||||
allowedExtensions: allowedExtensions,
|
||||
onFileLoading: onFileLoading,
|
||||
);
|
||||
|
||||
/// Returns an iterable `Map<String,String>` where the `key` is the name of the file
|
||||
|
@ -26,22 +37,37 @@ class FilePicker {
|
|||
///
|
||||
/// A `List` with [allowedExtensions] can be provided to filter the allowed files to picked.
|
||||
/// If provided, make sure you select `FileType.custom` as type.
|
||||
///
|
||||
/// If you want to track picking status, for example, because some files may take some time to be
|
||||
/// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler
|
||||
/// that will give you the current status of picking.
|
||||
///
|
||||
/// Defaults to `FileType.any`, which allows any combination of files to be multi selected at once.
|
||||
static Future<Map<String, String>> getMultiFilePath({FileType type = FileType.any, List<String> allowedExtensions}) async =>
|
||||
static Future<Map<String, String>> getMultiFilePath({
|
||||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
}) async =>
|
||||
await _filePickerPlatform.getFiles(
|
||||
type: type,
|
||||
allowMultiple: true,
|
||||
allowedExtensions: allowedExtensions,
|
||||
onFileLoading: onFileLoading,
|
||||
);
|
||||
|
||||
/// Returns a `File` object from the selected file path.
|
||||
///
|
||||
/// This is an utility method that does the same of `getFilePath()` but saving some boilerplate if
|
||||
/// you are planing to create a `File` for the returned path.
|
||||
static Future<File> getFile({FileType type = FileType.any, List<String> allowedExtensions}) async {
|
||||
static Future<File> getFile({
|
||||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
}) async {
|
||||
final String filePath = await _filePickerPlatform.getFiles(
|
||||
type: type,
|
||||
allowedExtensions: allowedExtensions,
|
||||
onFileLoading: onFileLoading,
|
||||
);
|
||||
return filePath != null ? File(filePath) : null;
|
||||
}
|
||||
|
@ -50,14 +76,21 @@ class FilePicker {
|
|||
///
|
||||
/// This is an utility method that does the same of `getMultiFilePath()` but saving some boilerplate if
|
||||
/// you are planing to create a list of `File`s for the returned paths.
|
||||
static Future<List<File>> getMultiFile({FileType type = FileType.any, List<String> allowedExtensions}) async {
|
||||
static Future<List<File>> getMultiFile({
|
||||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
}) async {
|
||||
final Map<String, String> paths = await _filePickerPlatform.getFiles(
|
||||
type: type,
|
||||
allowMultiple: true,
|
||||
allowedExtensions: allowedExtensions,
|
||||
onFileLoading: onFileLoading,
|
||||
);
|
||||
|
||||
return paths != null && paths.isNotEmpty ? paths.values.map((path) => File(path)).toList() : null;
|
||||
return paths != null && paths.isNotEmpty
|
||||
? paths.values.map((path) => File(path)).toList()
|
||||
: null;
|
||||
}
|
||||
|
||||
/// Selects a directory and returns its absolute path.
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
name: file_picker
|
||||
description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.
|
||||
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
||||
version: 1.10.0
|
||||
version: 1.11.0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_plugin_android_lifecycle: ^1.0.6
|
||||
file_picker_platform_interface: ^1.1.0
|
||||
file_picker_web: ^1.0.0
|
||||
file_picker_platform_interface: ^1.2.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.0.0 <3.0.0"
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
## 1.0.1+1
|
||||
|
||||
Updates homepage & description.
|
||||
|
||||
## 1.0.1
|
||||
|
||||
Updates API to support `onFileLoading` from FilePickerInterface.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
Adds public API documentation and updates file_picker_platform_interface dependency.
|
||||
|
|
|
@ -18,7 +18,7 @@ This is what the above means to your `pubspec.yaml`:
|
|||
...
|
||||
dependencies:
|
||||
...
|
||||
file_picker_web: ^0.0.1
|
||||
file_picker_web: ^1.0.0
|
||||
...
|
||||
```
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class _MyAppState extends State<MyApp> {
|
|||
List<File> _files = [];
|
||||
|
||||
void _pickFiles() async {
|
||||
_files = await FilePicker.getFile() ?? [];
|
||||
_files = await FilePicker.getMultiFile() ?? [];
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ class FilePicker extends FilePickerPlatform {
|
|||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
bool allowMultiple = false,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
}) async {
|
||||
final Completer<List<html.File>> pickedFiles = Completer<List<html.File>>();
|
||||
html.InputElement uploadInput = html.FileUploadInputElement();
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
name: file_picker_web
|
||||
description: Web platform implementation of file_picker
|
||||
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker/file_picker_web
|
||||
version: 1.0.0
|
||||
description: Web platform implementation of file_picker. Provides a way to pick files with filter support for Web.
|
||||
homepage: https://github.com/miguelpruivo/flutter_file_picker/tree/master/file_picker_web
|
||||
version: 1.0.1+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.10.0"
|
||||
|
||||
dependencies:
|
||||
file_picker_platform_interface: ^1.0.0
|
||||
file_picker_platform_interface: ^1.2.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
|
|
Loading…
Reference in New Issue