useFile function
Uses file_picker
to pick a file and returns that file as PlatformFile.
Loading, error and data states are handled through the AsyncSnapshot type.
Implementation
FileHandler<PlatformFile> useFile({
required FileType fileType,
List<String>? allowedExtensions,
}) {
final filePickerResult = useState<FilePickerResult?>(null);
final isLoading = useState<bool>(false);
final error = useState<Object?>(null);
final stackTrace = useState<StackTrace?>(null);
final isMounted = useIsMounted();
void clearError() {
error.value = null;
stackTrace.value = null;
}
final _error = error.value;
final _stackTrace = stackTrace.value;
Future<PlatformFile?> select() async {
clearError();
isLoading.value = true;
try {
final result = await FilePicker.platform.pickFiles(
type: fileType,
allowedExtensions: allowedExtensions,
allowMultiple: false,
);
if (result != null && result.files.isNotEmpty && isMounted()) {
filePickerResult.value = result;
return result.files.single;
} else {
return null;
}
} catch (_error, _stackTrace) {
error.value = _error;
stackTrace.value = _stackTrace;
rethrow;
} finally {
if (isMounted()) {
isLoading.value = false;
}
}
}
final filePickerValue = filePickerResult.value;
final AsyncSnapshot<PlatformFile> snapshot;
if (isLoading.value) {
snapshot = const AsyncSnapshot<PlatformFile>.waiting();
} else if (filePickerValue != null) {
snapshot = AsyncSnapshot<PlatformFile>.withData(
ConnectionState.done,
filePickerValue.files.single,
);
} else if (_error != null && _stackTrace != null) {
snapshot = AsyncSnapshot<PlatformFile>.withError(
ConnectionState.done,
_error,
_stackTrace,
);
} else {
assert(_error == null && _stackTrace == null);
snapshot = const AsyncSnapshot<PlatformFile>.nothing();
}
return FileHandler(
select: select,
snapshot: snapshot,
);
}