selectWebFiles function
Selects files using the browser's native file picker without loading file contents.
Implementation
Future<List<web.File>> selectWebFiles({
bool allowMultiple = false,
List<String> acceptedFileTypes = const [],
}) {
final completer = Completer<List<web.File>>();
if (kTesting) print('[selectWebFiles] Creating file input element');
// Create a temporary file input element
final input = web.document.createElement('input') as web.HTMLInputElement;
input.type = 'file';
// Configure input element
if (allowMultiple) {
input.multiple = true;
if (kTesting) print('[selectWebFiles] Multiple selection enabled');
}
// Handle accepted file types
if (acceptedFileTypes.isNotEmpty) {
// Special case: if the only item is '*', don't set any accept filter (accept all)
if (acceptedFileTypes.length == 1 && acceptedFileTypes[0] == '*') {
if (kTesting) print('[selectWebFiles] Accept all file types (*)');
} else {
input.accept = acceptedFileTypes.join(',');
if (kTesting)
print('[selectWebFiles] Accept types: ${acceptedFileTypes.join(',')}');
}
}
// Hide the input element
input.style.display = 'none';
// Add the input to the document body
web.document.body?.appendChild(input);
if (kTesting) print('[selectWebFiles] Input added to document body');
// Handle file selection
input.addEventListener(
'change',
(web.Event event) {
if (kTesting) print('[selectWebFiles] Change event fired');
final selectedFiles = <web.File>[];
if (input.files != null) {
final files = input.files!;
if (kTesting) print('[selectWebFiles] ${files.length} files selected');
// Convert FileList to List<File>
for (var i = 0; i < files.length; i++) {
final file = files.item(i);
if (file != null) {
if (kTesting) {
print(
'[selectWebFiles] File: ${file.name}, size: ${file.size} bytes');
}
selectedFiles.add(file);
}
}
}
// Clean up
web.document.body?.removeChild(input);
if (kTesting) print('[selectWebFiles] Input removed from document');
// Return the selected files
completer.complete(selectedFiles);
}.toJS,
);
// Open the file picker dialog
if (kTesting) print('[selectWebFiles] Opening file picker dialog');
input.click();
// Set a safety timeout (2 minutes)
Timer(Duration(minutes: 2), () {
if (!completer.isCompleted) {
if (kTesting)
print('[selectWebFiles] Timeout reached, assuming no files selected');
try {
web.document.body?.removeChild(input);
} catch (_) {
// Element might have been removed already
}
completer.complete([]);
}
});
return completer.future;
}