Adds null safety support (#510)

This commit is contained in:
Miguel Ruivo 2020-11-21 21:26:32 +00:00
parent 627c0a31b2
commit 85dba080cd
7 changed files with 57 additions and 56 deletions

View File

@ -50,7 +50,7 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
void _clearCachedFiles() {
FilePicker.platform.clearTemporaryFiles().then((result) {
_scaffoldKey.currentState.showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: result ? Colors.green : Colors.red,
content: Text((result

View File

@ -2,6 +2,9 @@ name: file_picker_example
description: An example of how to use the file_picker plugin.
version: 1.0.0+1
environment:
sdk: ">=2.8.1 <3.0.0"
dependencies:
flutter:
sdk: flutter

View File

@ -60,14 +60,14 @@ abstract class FilePicker extends PlatformInterface {
/// with useful information regarding the picked [List<PlatformFile>].
///
/// Returns [null] if aborted.
Future<FilePickerResult> pickFiles({
Future<FilePickerResult?> pickFiles({
FileType type = FileType.any,
List<String> allowedExtensions,
Function(FilePickerStatus) onFileLoading,
bool allowCompression,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileLoading,
bool? allowCompression,
bool allowMultiple = false,
bool withData,
bool withReadStream,
bool? withData,
bool? withReadStream,
}) async =>
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.
///
/// 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.');
/// Selects a directory and returns its absolute path.
///
/// 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.
Future<String> getDirectoryPath() async =>
Future<String?> getDirectoryPath() async =>
throw UnimplementedError('getDirectoryPath() has not been implemented.');
}

View File

@ -21,17 +21,17 @@ const EventChannel _eventChannel =
/// An implementation of [FilePicker] that uses method channels.
class FilePickerIO extends FilePicker {
static const String _tag = 'MethodChannelFilePicker';
static StreamSubscription _eventSubscription;
static StreamSubscription? _eventSubscription;
@override
Future<FilePickerResult> pickFiles({
Future<FilePickerResult?> pickFiles({
FileType type = FileType.any,
List<String> allowedExtensions,
Function(FilePickerStatus) onFileLoading,
bool allowCompression = true,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileLoading,
bool? allowCompression = true,
bool allowMultiple = false,
bool withData = false,
bool withReadStream = false,
bool? withData = false,
bool? withReadStream = false,
}) =>
_getPath(
type,
@ -44,11 +44,11 @@ class FilePickerIO extends FilePicker {
);
@override
Future<bool> clearTemporaryFiles() async =>
Future<bool?> clearTemporaryFiles() async =>
_channel.invokeMethod<bool>('clear');
@override
Future<String> getDirectoryPath() async {
Future<String?> getDirectoryPath() async {
try {
return await _channel.invokeMethod('dir', {});
} on PlatformException catch (ex) {
@ -60,14 +60,14 @@ class FilePickerIO extends FilePicker {
return null;
}
Future<FilePickerResult> _getPath(
Future<FilePickerResult?> _getPath(
FileType fileType,
bool allowMultipleSelection,
bool allowCompression,
List<String> allowedExtensions,
Function(FilePickerStatus) onFileLoading,
bool withData,
bool withReadStream,
bool? allowCompression,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileLoading,
bool? withData,
bool? withReadStream,
) async {
final String type = describeEnum(fileType);
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,
'allowedExtensions': allowedExtensions,
'allowCompression': allowCompression,
@ -102,7 +102,7 @@ class FilePickerIO extends FilePicker {
platformFiles.add(
PlatformFile.fromMap(
platformFileMap,
readStream: withReadStream
readStream: withReadStream!
? File(platformFileMap['path']).openRead()
: null,
),

View File

@ -27,5 +27,5 @@ class FilePickerResult {
.toList();
/// 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();
}

View File

@ -9,7 +9,7 @@ import 'file_picker_result.dart';
import 'platform_file.dart';
class FilePickerWeb extends FilePicker {
Element _target;
late Element _target;
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
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.
Element _ensureInitialized(String id) {
Element target = querySelector('#$id');
Element? target = querySelector('#$id');
if (target == null) {
final Element targetElement = Element.tag('flt-file-picker-inputs')
..id = id;
querySelector('body').children.add(targetElement);
querySelector('body')!.children.add(targetElement);
target = targetElement;
}
return target;
@ -40,18 +40,18 @@ class FilePickerWeb extends FilePicker {
@override
Future<FilePickerResult> pickFiles({
FileType type = FileType.any,
List<String> allowedExtensions,
List<String>? allowedExtensions,
bool allowMultiple = false,
Function(FilePickerStatus) onFileLoading,
bool allowCompression,
bool withData = true,
bool withReadStream = false,
Function(FilePickerStatus)? onFileLoading,
bool? allowCompression,
bool? withData = true,
bool? withReadStream = false,
}) async {
final Completer<List<PlatformFile>> filesCompleter =
Completer<List<PlatformFile>>();
String accept = _fileType(type, allowedExtensions);
InputElement uploadInput = FileUploadInputElement();
InputElement uploadInput = FileUploadInputElement() as InputElement;
uploadInput.draggable = true;
uploadInput.multiple = allowMultiple;
uploadInput.accept = accept;
@ -63,14 +63,14 @@ class FilePickerWeb extends FilePicker {
}
changeEventTriggered = true;
final List<File> files = uploadInput.files;
final List<File> files = uploadInput.files!;
final List<PlatformFile> pickedFiles = [];
void addPickedFile(
File file,
Uint8List bytes,
String path,
Stream<List<int>> readStream,
Uint8List? bytes,
String? path,
Stream<List<int>>? readStream,
) {
pickedFiles.add(PlatformFile(
name: file.name,
@ -86,15 +86,15 @@ class FilePickerWeb extends FilePicker {
}
files.forEach((File file) {
if (withReadStream) {
if (withReadStream!) {
addPickedFile(file, null, null, _openFileReadStream(file));
return;
}
if (!withData) {
if (!withData!) {
final FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
addPickedFile(file, null, reader.result, null);
addPickedFile(file, null, reader.result as String?, null);
});
reader.readAsDataUrl(file);
return;
@ -102,7 +102,7 @@ class FilePickerWeb extends FilePicker {
final FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
addPickedFile(file, reader.result, null, null);
addPickedFile(file, reader.result as Uint8List?, null, null);
});
reader.readAsArrayBuffer(file);
});
@ -119,7 +119,7 @@ class FilePickerWeb extends FilePicker {
return FilePickerResult(await filesCompleter.future);
}
static String _fileType(FileType type, List<String> allowedExtensions) {
static String _fileType(FileType type, List<String>? allowedExtensions) {
switch (type) {
case FileType.any:
return '';
@ -137,11 +137,9 @@ class FilePickerWeb extends FilePicker {
return 'video/*|image/*';
case FileType.custom:
return allowedExtensions.fold(
'', (prev, next) => '${prev.isEmpty ? '' : '$prev,'} .$next');
break;
return allowedExtensions!
.fold('', (prev, next) => '${prev.isEmpty ? '' : '$prev,'} .$next');
}
return '';
}
Stream<List<int>> _openFileReadStream(File file) async* {
@ -155,7 +153,7 @@ class FilePickerWeb extends FilePicker {
final blob = file.slice(start, end);
reader.readAsArrayBuffer(blob);
await reader.onLoad.first;
yield reader.result;
yield reader.result as List<int>;
start += _readStreamChunkSize;
}
}

View File

@ -21,21 +21,21 @@ class PlatformFile {
/// ```
/// final File myFile = File(platformFile.path);
/// ```
final String path;
final String? path;
/// 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
/// or easily upload to somewhere else.
final Uint8List bytes;
final Uint8List? bytes;
/// File content as stream
final Stream<List<int>> readStream;
final Stream<List<int>>? readStream;
/// The file size in bytes.
final int size;
final int? size;
/// File extension for this file.
String get extension => name?.split('.')?.last;
String? get extension => name?.split('.').last;
}