public
Created

Chrome file chooser example in Dart

  • Download Gist
gistfile1.dart
Dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
import 'dart:async';
import 'dart:html';
import 'package:js/js.dart' as js;
 
Future<FileEntry> chooseEntry({
String type, // TODO(rms): use Greg's enum.
String suggestedName,
List<AcceptOption> accepts,
bool acceptsAllTypes}) {
final completer = new Completer<FileEntry>();
final options = { };
if (type != null) options['type'] = type;
if (suggestedName != null) options['suggestedName'] = suggestedName;
if (accepts != null) options['accepts'] = accepts;
if (acceptsAllTypes != null) options['acceptsAllTypes'] = acceptsAllTypes;
js.scoped(() {
js.context.chrome.fileSystem.chooseEntry(
js.map(options),
new js.Callback.once(([fileEntry]) {
// TODO(rms): who will call _FileEntry._dispose() ?
completer.complete(fileEntry == null
? null // TODO(rms): console error on cancel, is that ok?
: new _FileEntry(fileEntry));
}));
});
return completer.future;
}
 
Future<String> getDisplayPath(FileEntry entry) {
if (entry is! _FileEntry)
throw new UnsupportedError('file entry must be from Chrome file system');
final completer = new Completer<String>();
js.scoped(() {
js.context.chrome.fileSystem.getDisplayPath(
entry._proxy,
new js.Callback.once((displayPath) => completer.complete(displayPath)));
});
return completer.future;
}
 
class AcceptOption {
// TODO:
}
 
class _FileEntry implements FileEntry {
js.Proxy _proxy;
_FileEntry(js.Proxy proxy) {_proxy = js.retain(proxy); }
void _dispose() => js.release(_proxy);
FileSystem get filesystem { throw new UnimplementedError(); }
String get fullPath => js.scoped(() => _proxy.fullPath);
bool get isDirectory => js.scoped(() => _proxy.isDirectory);
bool get isFile => js.scoped(() => _proxy.isFile);
String get name => js.scoped(() => _proxy.name);
Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
throw new UnimplementedError();
}
Future<FileWriter> createWriter() { throw new UnimplementedError(); }
Future<File> file() {
final completer = new Completer<File>();
js.scoped(() {
// TODO(rms): pass an ErrorCallback also.
_proxy.file(new js.Callback.once((file) {
// TODO(rms): who will call _File._dispose() ?
completer.complete(new _File(file));
}));
});
return completer.future;
}
Future<Metadata> getMetadata() { throw new UnimplementedError(); }
Future<Entry> getParent() { throw new UnimplementedError(); }
Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
throw new UnimplementedError();
}
Future remove() { throw new UnimplementedError(); }
String toUrl() => js.scoped(() => _proxy.toURL());
}
 
class _File implements File {
js.Proxy _proxy;
_File(js.Proxy proxy) { _proxy = js.retain(proxy); }
void _dispose() => js.release(_proxy);
DateTime get lastModifiedDate { throw new UnimplementedError(); }
String get name => js.scoped(() => _proxy.name);
String get relativePath => js.scoped(() => _proxy.relativePath);
int get size => js.scoped(() => _proxy.size);
String get type => js.scoped(() => _proxy.type);
Blob slice([int start, int end, String contentType]) {
throw new UnimplementedError();
}
}
 
// TODO(rms): Dartium crashes if I try to use dart:html's FileReader w/ _File
class ChromeFileReader implements FileReader {
js.Callback _jsLoadEnd;
js.Proxy _proxy;
ChromeFileReader() {
js.scoped(() {
_jsLoadEnd = new js.Callback.many((e) {
// TODO(rms): handle the event arg
_onLoadEnd.add(null);
});
_proxy = js.retain(new js.Proxy(js.context.FileReader));
_proxy.addEventListener('loadend', _jsLoadEnd);
// TODO: more event listeners
});
}
void _dispose() {
_proxy.removeEventListener('loadend', _jsLoadEnd);
_jsLoadEnd.dispose();
js.release(_proxy);
}
FileError get error { throw new UnimplementedError(); }
Events get on { throw new UnimplementedError(); }
Stream<ProgressEvent> get onAbort { throw new UnimplementedError(); }
Stream<Event> get onError { throw new UnimplementedError(); }
Stream<ProgressEvent> get onLoad { throw new UnimplementedError(); }
StreamController _onLoadEnd = new StreamController();
// TODO(rms): a class that implements ProgressEvent
Stream/*<ProgressEvent>*/ get onLoadEnd => _onLoadEnd.stream;
Stream<ProgressEvent> get onLoadStart { throw new UnimplementedError(); }
Stream<ProgressEvent> get onProgress { throw new UnimplementedError(); }
int get readyState => js.scoped(() => _proxy.readyState);
Object get result => js.scoped(() => _proxy.result);
void abort() { throw new UnimplementedError(); }
bool dispatchEvent(Event evt) { throw new UnimplementedError(); }
void readAsArrayBuffer(Blob blob) { throw new UnimplementedError(); }
void readAsBinaryString(Blob blob) { throw new UnimplementedError(); }
void readAsDataUrl(Blob blob) { throw new UnimplementedError(); }
void readAsText(Blob blob, [String encoding]) {
// TODO(rms): implement this method proper-like
js.scoped(() {
if (blob is _File) {
_proxy.readAsText(blob._proxy);
}
});
}
}
 
main() {
var openFile = new ButtonElement()..text='Open';
openFile.onClick.listen((_) {
chooseEntry()
.then((entry) {
if (entry != null) {
print('chose path: ${entry.fullPath}');
print('at URL: ${entry.toUrl()}');
getDisplayPath(entry).then((displayPath) {
print('display path: $displayPath');
entry.file().then((file) {
print('file name: ${file.name}, type: ${file.type}');
final reader = new ChromeFileReader();
reader.onLoadEnd.listen((_) {
print('result:');
print('${reader.result}');
});
reader.readAsText(file);
});
});
}
});
});
 
document.body.append(openFile);
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.