Merge branch 'feature/null-safety'
This commit is contained in:
commit
eb04cec551
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,5 @@
|
||||||
|
## 3.0.0
|
||||||
|
Adds null safety support ([#510](https://github.com/miguelpruivo/flutter_file_picker/issues/510)).
|
||||||
## 2.1.7
|
## 2.1.7
|
||||||
### iOS
|
### iOS
|
||||||
- Fixes an issue where a crash could happen when picking a lot of media files in low memory devices ([#606](https://github.com/miguelpruivo/flutter_file_picker/issues/606)).
|
- Fixes an issue where a crash could happen when picking a lot of media files in low memory devices ([#606](https://github.com/miguelpruivo/flutter_file_picker/issues/606)).
|
||||||
|
@ -17,13 +19,13 @@ iOS & Android: Updates `size` property from `PlatformFile` to be in bytes instea
|
||||||
iOS: Fixes iOS ViewController which is nil when UIWindow.rootViewController have changed. ([#525](https://github.com/miguelpruivo/flutter_file_picker/issues/525)). Thank you @devcxm.
|
iOS: Fixes iOS ViewController which is nil when UIWindow.rootViewController have changed. ([#525](https://github.com/miguelpruivo/flutter_file_picker/issues/525)). Thank you @devcxm.
|
||||||
|
|
||||||
## 2.1.3
|
## 2.1.3
|
||||||
Android: Updates file name handling method. ([#487](https://github.com/miguelpruivo/flutter_file_picker/issues/487)).
|
Android: Updates file name handling method. ([#487](https://github.com/miguelpruivo/flutter_file_picker/issues/487))
|
||||||
|
|
||||||
## 2.1.2
|
## 2.1.2
|
||||||
Desktop (Go): Fixed desktop plugin implementation. Thank you @DenchikBY.
|
Desktop (Go): Fixed desktop plugin implementation. Thank you @DenchikBY. ([#382](https://github.com/miguelpruivo/flutter_file_picker/issues/382#issuecomment-744055654))
|
||||||
|
|
||||||
## 2.1.1
|
## 2.1.1
|
||||||
iOS: Fixes an issue that could result in a crash when selecting a media item twice. ([#518](https://github.com/miguelpruivo/flutter_file_picker/issues/518)).
|
iOS: Fixes an issue that could result in a crash when selecting a media item twice. ([#518](https://github.com/miguelpruivo/flutter_file_picker/issues/518))
|
||||||
|
|
||||||
## 2.1.0
|
## 2.1.0
|
||||||
Adds `withReadStream` that allows bigger files to be streamed read into a `Stream<List<int>>`. Thanks @redsolver.
|
Adds `withReadStream` that allows bigger files to be streamed read into a `Stream<List<int>>`. Thanks @redsolver.
|
||||||
|
@ -34,8 +36,8 @@ Updates `extension` helper getter to use the `name` property instead of `path`,
|
||||||
## 2.0.12
|
## 2.0.12
|
||||||
Android:
|
Android:
|
||||||
|
|
||||||
- Fixes an issue that could result in some files not being properly retrieved due to special characters on their names. ([#472](https://github.com/miguelpruivo/flutter_file_picker/issues/472)).
|
- Fixes an issue that could result in some files not being properly retrieved due to special characters on their names. ([#472](https://github.com/miguelpruivo/flutter_file_picker/issues/472))
|
||||||
- Fixes a NPE that could happen with some devices. ([#482](https://github.com/miguelpruivo/flutter_file_picker/issues/482)).
|
- Fixes a NPE that could happen with some devices. ([#482](https://github.com/miguelpruivo/flutter_file_picker/issues/482))
|
||||||
|
|
||||||
|
|
||||||
## 2.0.11
|
## 2.0.11
|
||||||
|
|
|
@ -2,15 +2,14 @@
|
||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
// ignore: unused_import
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:file_picker/src/file_picker_web.dart';
|
import 'package:file_picker/src/file_picker_web.dart';
|
||||||
|
|
||||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
// ignore: public_member_api_docs
|
||||||
void registerPlugins(PluginRegistry registry) {
|
void registerPlugins(Registrar registrar) {
|
||||||
FilePickerWeb.registerWith(registry.registrarFor(FilePickerWeb));
|
FilePickerWeb.registerWith(registrar);
|
||||||
registry.registerMessageHandler();
|
registrar.registerMessageHandler();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
||||||
|
|
||||||
void _clearCachedFiles() {
|
void _clearCachedFiles() {
|
||||||
FilePicker.platform.clearTemporaryFiles().then((result) {
|
FilePicker.platform.clearTemporaryFiles().then((result) {
|
||||||
_scaffoldKey.currentState.showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
backgroundColor: result ? Colors.green : Colors.red,
|
backgroundColor: result ? Colors.green : Colors.red,
|
||||||
content: Text((result
|
content: Text((result
|
||||||
|
|
|
@ -2,6 +2,9 @@ name: file_picker_example
|
||||||
description: An example of how to use the file_picker plugin.
|
description: An example of how to use the file_picker plugin.
|
||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.10.0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
@ -60,14 +60,14 @@ abstract class FilePicker extends PlatformInterface {
|
||||||
/// with useful information regarding the picked [List<PlatformFile>].
|
/// with useful information regarding the picked [List<PlatformFile>].
|
||||||
///
|
///
|
||||||
/// Returns [null] if aborted.
|
/// Returns [null] if aborted.
|
||||||
Future<FilePickerResult> pickFiles({
|
Future<FilePickerResult?> pickFiles({
|
||||||
FileType type = FileType.any,
|
FileType type = FileType.any,
|
||||||
List<String> allowedExtensions,
|
List<String>? allowedExtensions,
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus)? onFileLoading,
|
||||||
bool allowCompression,
|
bool? allowCompression,
|
||||||
bool allowMultiple = false,
|
bool allowMultiple = false,
|
||||||
bool withData,
|
bool? withData,
|
||||||
bool withReadStream,
|
bool? withReadStream,
|
||||||
}) async =>
|
}) async =>
|
||||||
throw UnimplementedError('pickFiles() has not been implemented.');
|
throw UnimplementedError('pickFiles() has not been implemented.');
|
||||||
|
|
||||||
|
@ -78,13 +78,13 @@ abstract class FilePicker extends PlatformInterface {
|
||||||
/// of it whenever needed. However, this will force the cleanup if you want to manage those on your own.
|
/// of it whenever needed. However, this will force the cleanup if you want to manage those on your own.
|
||||||
///
|
///
|
||||||
/// Returns [true] if the files were removed with success, [false] otherwise.
|
/// Returns [true] if the files were removed with success, [false] otherwise.
|
||||||
Future<bool> clearTemporaryFiles() async => throw UnimplementedError(
|
Future<bool?> clearTemporaryFiles() async => throw UnimplementedError(
|
||||||
'clearTemporaryFiles() has not been implemented.');
|
'clearTemporaryFiles() has not been implemented.');
|
||||||
|
|
||||||
/// Selects a directory and returns its absolute path.
|
/// Selects a directory and returns its absolute path.
|
||||||
///
|
///
|
||||||
/// On Android, this requires to be running on SDK 21 or above, else won't work.
|
/// On Android, this requires to be running on SDK 21 or above, else won't work.
|
||||||
/// Returns [null] if folder path couldn't be resolved.
|
/// Returns [null] if folder path couldn't be resolved.
|
||||||
Future<String> getDirectoryPath() async =>
|
Future<String?> getDirectoryPath() async =>
|
||||||
throw UnimplementedError('getDirectoryPath() has not been implemented.');
|
throw UnimplementedError('getDirectoryPath() has not been implemented.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,17 @@ const EventChannel _eventChannel =
|
||||||
/// An implementation of [FilePicker] that uses method channels.
|
/// An implementation of [FilePicker] that uses method channels.
|
||||||
class FilePickerIO extends FilePicker {
|
class FilePickerIO extends FilePicker {
|
||||||
static const String _tag = 'MethodChannelFilePicker';
|
static const String _tag = 'MethodChannelFilePicker';
|
||||||
static StreamSubscription _eventSubscription;
|
static StreamSubscription? _eventSubscription;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<FilePickerResult> pickFiles({
|
Future<FilePickerResult?> pickFiles({
|
||||||
FileType type = FileType.any,
|
FileType type = FileType.any,
|
||||||
List<String> allowedExtensions,
|
List<String>? allowedExtensions,
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus)? onFileLoading,
|
||||||
bool allowCompression = true,
|
bool? allowCompression = true,
|
||||||
bool allowMultiple = false,
|
bool allowMultiple = false,
|
||||||
bool withData = false,
|
bool? withData = false,
|
||||||
bool withReadStream = false,
|
bool? withReadStream = false,
|
||||||
}) =>
|
}) =>
|
||||||
_getPath(
|
_getPath(
|
||||||
type,
|
type,
|
||||||
|
@ -44,11 +44,11 @@ class FilePickerIO extends FilePicker {
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> clearTemporaryFiles() async =>
|
Future<bool?> clearTemporaryFiles() async =>
|
||||||
_channel.invokeMethod<bool>('clear');
|
_channel.invokeMethod<bool>('clear');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> getDirectoryPath() async {
|
Future<String?> getDirectoryPath() async {
|
||||||
try {
|
try {
|
||||||
return await _channel.invokeMethod('dir', {});
|
return await _channel.invokeMethod('dir', {});
|
||||||
} on PlatformException catch (ex) {
|
} on PlatformException catch (ex) {
|
||||||
|
@ -60,14 +60,14 @@ class FilePickerIO extends FilePicker {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<FilePickerResult> _getPath(
|
Future<FilePickerResult?> _getPath(
|
||||||
FileType fileType,
|
FileType fileType,
|
||||||
bool allowMultipleSelection,
|
bool allowMultipleSelection,
|
||||||
bool allowCompression,
|
bool? allowCompression,
|
||||||
List<String> allowedExtensions,
|
List<String>? allowedExtensions,
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus)? onFileLoading,
|
||||||
bool withData,
|
bool? withData,
|
||||||
bool withReadStream,
|
bool? withReadStream,
|
||||||
) async {
|
) async {
|
||||||
final String type = describeEnum(fileType);
|
final String type = describeEnum(fileType);
|
||||||
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
||||||
|
@ -85,7 +85,7 @@ class FilePickerIO extends FilePicker {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Map> result = await _channel.invokeListMethod(type, {
|
final List<Map>? result = await _channel.invokeListMethod(type, {
|
||||||
'allowMultipleSelection': allowMultipleSelection,
|
'allowMultipleSelection': allowMultipleSelection,
|
||||||
'allowedExtensions': allowedExtensions,
|
'allowedExtensions': allowedExtensions,
|
||||||
'allowCompression': allowCompression,
|
'allowCompression': allowCompression,
|
||||||
|
@ -102,7 +102,7 @@ class FilePickerIO extends FilePicker {
|
||||||
platformFiles.add(
|
platformFiles.add(
|
||||||
PlatformFile.fromMap(
|
PlatformFile.fromMap(
|
||||||
platformFileMap,
|
platformFileMap,
|
||||||
readStream: withReadStream
|
readStream: withReadStream!
|
||||||
? File(platformFileMap['path']).openRead()
|
? File(platformFileMap['path']).openRead()
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
|
|
@ -19,7 +19,7 @@ class FilePickerResult {
|
||||||
/// original files (which can be accessed through its URI property).
|
/// original files (which can be accessed through its URI property).
|
||||||
///
|
///
|
||||||
/// Only available on IO. Throws `UnsupportedError` on Web.
|
/// Only available on IO. Throws `UnsupportedError` on Web.
|
||||||
List<String> get paths => files
|
List<String?> get paths => files
|
||||||
.map((file) => kIsWeb
|
.map((file) => kIsWeb
|
||||||
? throw UnsupportedError(
|
? throw UnsupportedError(
|
||||||
'Picking paths is unsupported on Web. Please, use bytes property instead.')
|
'Picking paths is unsupported on Web. Please, use bytes property instead.')
|
||||||
|
@ -27,5 +27,5 @@ class FilePickerResult {
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
/// A `List<String>` containing all names from picked files with its extensions.
|
/// A `List<String>` containing all names from picked files with its extensions.
|
||||||
List<String> get names => files.map((file) => file.name).toList();
|
List<String?> get names => files.map((file) => file.name).toList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import 'file_picker_result.dart';
|
||||||
import 'platform_file.dart';
|
import 'platform_file.dart';
|
||||||
|
|
||||||
class FilePickerWeb extends FilePicker {
|
class FilePickerWeb extends FilePicker {
|
||||||
Element _target;
|
late Element _target;
|
||||||
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
|
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
|
||||||
|
|
||||||
final int _readStreamChunkSize = 1000 * 1000; // 1 MB
|
final int _readStreamChunkSize = 1000 * 1000; // 1 MB
|
||||||
|
@ -26,12 +26,12 @@ class FilePickerWeb extends FilePicker {
|
||||||
|
|
||||||
/// Initializes a DOM container where we can host input elements.
|
/// Initializes a DOM container where we can host input elements.
|
||||||
Element _ensureInitialized(String id) {
|
Element _ensureInitialized(String id) {
|
||||||
Element target = querySelector('#$id');
|
Element? target = querySelector('#$id');
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
final Element targetElement = Element.tag('flt-file-picker-inputs')
|
final Element targetElement = Element.tag('flt-file-picker-inputs')
|
||||||
..id = id;
|
..id = id;
|
||||||
|
|
||||||
querySelector('body').children.add(targetElement);
|
querySelector('body')!.children.add(targetElement);
|
||||||
target = targetElement;
|
target = targetElement;
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
|
@ -40,18 +40,18 @@ class FilePickerWeb extends FilePicker {
|
||||||
@override
|
@override
|
||||||
Future<FilePickerResult> pickFiles({
|
Future<FilePickerResult> pickFiles({
|
||||||
FileType type = FileType.any,
|
FileType type = FileType.any,
|
||||||
List<String> allowedExtensions,
|
List<String>? allowedExtensions,
|
||||||
bool allowMultiple = false,
|
bool allowMultiple = false,
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus)? onFileLoading,
|
||||||
bool allowCompression,
|
bool? allowCompression,
|
||||||
bool withData = true,
|
bool? withData = true,
|
||||||
bool withReadStream = false,
|
bool? withReadStream = false,
|
||||||
}) async {
|
}) async {
|
||||||
final Completer<List<PlatformFile>> filesCompleter =
|
final Completer<List<PlatformFile>> filesCompleter =
|
||||||
Completer<List<PlatformFile>>();
|
Completer<List<PlatformFile>>();
|
||||||
|
|
||||||
String accept = _fileType(type, allowedExtensions);
|
String accept = _fileType(type, allowedExtensions);
|
||||||
InputElement uploadInput = FileUploadInputElement();
|
InputElement uploadInput = FileUploadInputElement() as InputElement;
|
||||||
uploadInput.draggable = true;
|
uploadInput.draggable = true;
|
||||||
uploadInput.multiple = allowMultiple;
|
uploadInput.multiple = allowMultiple;
|
||||||
uploadInput.accept = accept;
|
uploadInput.accept = accept;
|
||||||
|
@ -63,14 +63,14 @@ class FilePickerWeb extends FilePicker {
|
||||||
}
|
}
|
||||||
changeEventTriggered = true;
|
changeEventTriggered = true;
|
||||||
|
|
||||||
final List<File> files = uploadInput.files;
|
final List<File> files = uploadInput.files!;
|
||||||
final List<PlatformFile> pickedFiles = [];
|
final List<PlatformFile> pickedFiles = [];
|
||||||
|
|
||||||
void addPickedFile(
|
void addPickedFile(
|
||||||
File file,
|
File file,
|
||||||
Uint8List bytes,
|
Uint8List? bytes,
|
||||||
String path,
|
String? path,
|
||||||
Stream<List<int>> readStream,
|
Stream<List<int>>? readStream,
|
||||||
) {
|
) {
|
||||||
pickedFiles.add(PlatformFile(
|
pickedFiles.add(PlatformFile(
|
||||||
name: file.name,
|
name: file.name,
|
||||||
|
@ -86,15 +86,15 @@ class FilePickerWeb extends FilePicker {
|
||||||
}
|
}
|
||||||
|
|
||||||
files.forEach((File file) {
|
files.forEach((File file) {
|
||||||
if (withReadStream) {
|
if (withReadStream!) {
|
||||||
addPickedFile(file, null, null, _openFileReadStream(file));
|
addPickedFile(file, null, null, _openFileReadStream(file));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!withData) {
|
if (!withData!) {
|
||||||
final FileReader reader = FileReader();
|
final FileReader reader = FileReader();
|
||||||
reader.onLoadEnd.listen((e) {
|
reader.onLoadEnd.listen((e) {
|
||||||
addPickedFile(file, null, reader.result, null);
|
addPickedFile(file, null, reader.result as String?, null);
|
||||||
});
|
});
|
||||||
reader.readAsDataUrl(file);
|
reader.readAsDataUrl(file);
|
||||||
return;
|
return;
|
||||||
|
@ -102,7 +102,7 @@ class FilePickerWeb extends FilePicker {
|
||||||
|
|
||||||
final FileReader reader = FileReader();
|
final FileReader reader = FileReader();
|
||||||
reader.onLoadEnd.listen((e) {
|
reader.onLoadEnd.listen((e) {
|
||||||
addPickedFile(file, reader.result, null, null);
|
addPickedFile(file, reader.result as Uint8List?, null, null);
|
||||||
});
|
});
|
||||||
reader.readAsArrayBuffer(file);
|
reader.readAsArrayBuffer(file);
|
||||||
});
|
});
|
||||||
|
@ -119,7 +119,7 @@ class FilePickerWeb extends FilePicker {
|
||||||
return FilePickerResult(await filesCompleter.future);
|
return FilePickerResult(await filesCompleter.future);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String _fileType(FileType type, List<String> allowedExtensions) {
|
static String _fileType(FileType type, List<String>? allowedExtensions) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FileType.any:
|
case FileType.any:
|
||||||
return '';
|
return '';
|
||||||
|
@ -137,11 +137,9 @@ class FilePickerWeb extends FilePicker {
|
||||||
return 'video/*|image/*';
|
return 'video/*|image/*';
|
||||||
|
|
||||||
case FileType.custom:
|
case FileType.custom:
|
||||||
return allowedExtensions.fold(
|
return allowedExtensions!
|
||||||
'', (prev, next) => '${prev.isEmpty ? '' : '$prev,'} .$next');
|
.fold('', (prev, next) => '${prev.isEmpty ? '' : '$prev,'} .$next');
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<List<int>> _openFileReadStream(File file) async* {
|
Stream<List<int>> _openFileReadStream(File file) async* {
|
||||||
|
@ -155,7 +153,7 @@ class FilePickerWeb extends FilePicker {
|
||||||
final blob = file.slice(start, end);
|
final blob = file.slice(start, end);
|
||||||
reader.readAsArrayBuffer(blob);
|
reader.readAsArrayBuffer(blob);
|
||||||
await reader.onLoad.first;
|
await reader.onLoad.first;
|
||||||
yield reader.result;
|
yield reader.result as List<int>;
|
||||||
start += _readStreamChunkSize;
|
start += _readStreamChunkSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,21 +21,21 @@ class PlatformFile {
|
||||||
/// ```
|
/// ```
|
||||||
/// final File myFile = File(platformFile.path);
|
/// final File myFile = File(platformFile.path);
|
||||||
/// ```
|
/// ```
|
||||||
final String path;
|
final String? path;
|
||||||
|
|
||||||
/// File name including its extension.
|
/// File name including its extension.
|
||||||
final String name;
|
final String? name;
|
||||||
|
|
||||||
/// Byte data for this file. Particurlarly useful if you want to manipulate its data
|
/// Byte data for this file. Particurlarly useful if you want to manipulate its data
|
||||||
/// or easily upload to somewhere else.
|
/// or easily upload to somewhere else.
|
||||||
final Uint8List bytes;
|
final Uint8List? bytes;
|
||||||
|
|
||||||
/// File content as stream
|
/// File content as stream
|
||||||
final Stream<List<int>> readStream;
|
final Stream<List<int>>? readStream;
|
||||||
|
|
||||||
/// The file size in bytes.
|
/// The file size in bytes.
|
||||||
final int size;
|
final int? size;
|
||||||
|
|
||||||
/// File extension for this file.
|
/// File extension for this file.
|
||||||
String get extension => name?.split('.')?.last;
|
String? get extension => name?.split('.').last;
|
||||||
}
|
}
|
||||||
|
|
12
pubspec.yaml
12
pubspec.yaml
|
@ -1,7 +1,7 @@
|
||||||
name: file_picker
|
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.
|
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
|
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
||||||
version: 2.1.7
|
version: 3.0.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
@ -9,13 +9,13 @@ dependencies:
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_plugin_android_lifecycle: ^1.0.6
|
flutter_plugin_android_lifecycle: ^2.0.0
|
||||||
plugin_platform_interface: ^1.0.1
|
plugin_platform_interface: ^2.0.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.0.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.10.0 <2.0.0"
|
flutter: ">=1.10.0"
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
plugin:
|
plugin:
|
||||||
platforms:
|
platforms:
|
||||||
|
|
Loading…
Reference in New Issue