Adds null safety support (#510)
This commit is contained in:
parent
627c0a31b2
commit
85dba080cd
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue