useFiles function

FilesHandler<PlatformFile> useFiles({
  1. required FileType fileType,
  2. List<String>? allowedExtensions,
})

Uses file_picker to pick multiple files and returns them. Loading, error and data states are handled through the AsyncSnapshot type.

Implementation

FilesHandler<PlatformFile> useFiles({
  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<List<PlatformFile>?> select() async {
    clearError();
    isLoading.value = true;

    try {
      final result = await FilePicker.platform.pickFiles(
        type: fileType,
        allowedExtensions: allowedExtensions,
        allowMultiple: true,
      );

      if (result != null && isMounted()) {
        filePickerResult.value = result;
        return result.files;
      }
    } catch (_error, _stackTrace) {
      error.value = _error;
      stackTrace.value = _stackTrace;
      // TODO: Should i rethrow?
      rethrow;
    } finally {
      if (isMounted()) {
        isLoading.value = false;
      }
    }
  }

  final filePickerValue = filePickerResult.value;
  final AsyncSnapshot<List<PlatformFile>> snapshot;

  if (isLoading.value) {
    snapshot = const AsyncSnapshot<List<PlatformFile>>.waiting();
  } else if (filePickerValue != null) {
    snapshot = AsyncSnapshot<List<PlatformFile>>.withData(
      ConnectionState.done,
      filePickerValue.files,
    );
  } else if (_error != null && _stackTrace != null) {
    snapshot = AsyncSnapshot<List<PlatformFile>>.withError(
      ConnectionState.done,
      _error,
      _stackTrace,
    );
  } else {
    assert(_error == null && _stackTrace == null);
    snapshot = const AsyncSnapshot<List<PlatformFile>>.nothing();
  }

  return FilesHandler(
    select: select,
    snapshot: snapshot,
  );
}