seleccionaArchivo static method

Future<Map<String, Uint8List>> seleccionaArchivo(
  1. List<String> extensionesPermitidas,
  2. int maxFileSizeBytes, {
  3. int? compressionQuality,
  4. bool permiteSeleccionMultiple = false,
})

Selecciona uno o varios archivos y devuelve un mapa (nombre ⇒ bytes). Lanza SelectorArchivoException ante cualquier incidencia.

Implementation

static Future<Map<String, Uint8List>> seleccionaArchivo(
  List<String> extensionesPermitidas,
  int maxFileSizeBytes, {
  int? compressionQuality, // 0-100 (null → no comprimir)
  bool permiteSeleccionMultiple = false,
}) async {
  /* 2 ── INVOCAR FILE PICKER ───────────────────────────────────────────── */
  final allowed = extensionesPermitidas.map((e) => e.toLowerCase()).toSet();
  final result = await FilePicker.platform.pickFiles(
    type: FileType.custom,
    allowedExtensions: allowed.toList(),
    withData: true,
    withReadStream: !kIsWeb,
    allowMultiple: permiteSeleccionMultiple,
  );

  if (result == null) {
    throw SelectorArchivoException(
      SelectorArchivoError.usuarioCancelo,
      'Selección cancelada por el usuario.',
    );
  }

  /* 3 ── PROCESAR CADA ARCHIVO ─────────────────────────────────────────── */
  final archivos = <String, ArchivoFlutterUtilsModel>{};

  for (final file in result.files) {
    final name = file.name;
    final ext = name.split('.').last.toLowerCase();
    final soportaCompresion = _kImgExts.contains(ext);

    _validarExtension(ext, allowed);

    _checkSize(
        file.bytes!.lengthInBytes, maxFileSizeBytes, soportaCompresion);

    // Obtener bytes (desde memoria o stream).
    final bytes = await _leerBytesArchivo(
      file,
      maxFileSizeBytes: maxFileSizeBytes,
    );

    final archivoModel = ArchivoFlutterUtilsModel(
      bytes,
      soportaCompresion,
    );

    archivos[name] = archivoModel;
  }
  final Map<String, Uint8List> salida = (kIsWeb)
      ? _archivosCompromidos(archivos, compressionQuality)
      : await Isolate.run(() {
          return _archivosCompromidos(
            archivos,
            compressionQuality,
          );
        }).timeout(
          const Duration(seconds: 30),
          onTimeout: () {
            throw SelectorArchivoException(
              SelectorArchivoError.lecturaFallida,
              'Tiempo de espera agotado al procesar los archivos.',
            );
          },
        );
  /* 4 ── LIMPIEZA Y SALIDA ─────────────────────────────────────────────── */
  if (!kIsWeb) await FilePicker.platform.clearTemporaryFiles();

  if (salida.isEmpty) {
    throw SelectorArchivoException(
      SelectorArchivoError.lecturaFallida,
      'No se pudo obtener el contenido del archivo.',
    );
  }
  return salida;
}