pickFiles method

  1. @override
Future<List<PickedFile>?> pickFiles(
  1. FilePickerOptions options
)
override

Picks files from the device storage based on the provided options.

Platform implementations should override this method to handle file picking on their respective platforms.

Implementation

@override
Future<List<PickedFile>?> pickFiles(FilePickerOptions options) async {
  final completer = Completer<List<PickedFile>?>();

  try {
    final input = html.FileUploadInputElement();
    input.style.display = 'none';

    // Set accept attribute based on file type
    input.accept = _getAcceptString(options.type, options.allowedExtensions);

    // Set multiple selection
    input.multiple = options.allowMultiple;

    // Add to DOM
    html.document.body?.append(input);

    // Set up event listeners
    input.onChange.listen((event) async {
      final files = input.files;
      if (files != null && files.isNotEmpty) {
        final pickedFiles = <PickedFile>[];

        for (final file in files) {
          try {
            final pickedFile = await _processWebFile(file, options);
            if (pickedFile != null) {
              pickedFiles.add(pickedFile);
            }
          } catch (e) {
            debugPrint('Error processing file ${file.name}: $e');
          }
        }

        // Remove input from DOM
        input.remove();
        completer.complete(pickedFiles.isEmpty ? null : pickedFiles);
      } else {
        input.remove();
        completer.complete(null);
      }
    });

    input.onError.listen((event) {
      input.remove();
      completer.complete(null);
    });

    // Handle cancel (when user closes dialog without selecting)
    final cancelTimer = Timer(const Duration(minutes: 5), () {
      if (!completer.isCompleted) {
        input.remove();
        completer.complete(null);
      }
    });

    // Detect window focus to handle cancel
    html.window.onFocus.listen((event) {
      Timer(const Duration(milliseconds: 500), () {
        if (!completer.isCompleted && (input.files?.isEmpty ?? true)) {
          cancelTimer.cancel();
          input.remove();
          completer.complete(null);
        }
      });
    });

    // Trigger file picker
    input.click();
  } catch (e) {
    completer.complete(null);
  }

  return completer.future;
}