54 lines
1.3 KiB
Dart
54 lines
1.3 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:universal_html/html.dart' as html;
|
|
|
|
|
|
class PickedCsvFile {
|
|
final String name;
|
|
final String content;
|
|
|
|
const PickedCsvFile({required this.name, required this.content});
|
|
}
|
|
|
|
abstract class CsvInputService {
|
|
Future<PickedCsvFile?> pickCsv();
|
|
}
|
|
|
|
class WebCsvInputService implements CsvInputService {
|
|
@override
|
|
Future<PickedCsvFile?> pickCsv() async {
|
|
final input = html.FileUploadInputElement()
|
|
..accept = '.csv,text/csv'
|
|
..multiple = false;
|
|
|
|
final completer = Completer<html.File?>();
|
|
input.onChange.listen((_) {
|
|
completer.complete(
|
|
input.files?.isNotEmpty == true ? input.files!.first : null,
|
|
);
|
|
});
|
|
input.click();
|
|
|
|
final file = await completer.future;
|
|
if (file == null) return null;
|
|
|
|
final reader = html.FileReader();
|
|
final readCompleter = Completer<String>();
|
|
reader.onError.listen((_) {
|
|
readCompleter.completeError(StateError('Failed to read file'));
|
|
});
|
|
reader.onLoadEnd.listen((_) {
|
|
final result = reader.result;
|
|
if (result is String) {
|
|
readCompleter.complete(result);
|
|
} else {
|
|
readCompleter.completeError(StateError('Unsupported file payload'));
|
|
}
|
|
});
|
|
reader.readAsText(file);
|
|
|
|
final content = await readCompleter.future;
|
|
return PickedCsvFile(name: file.name, content: content);
|
|
}
|
|
}
|