js: Get files from input and send them to mattr.
Change-Id: Idd121f8ac8cf1cbe0dad972d878d44c9aabd9762
diff --git a/js/Makefile b/js/Makefile
index 03ecad2..89375cd 100644
--- a/js/Makefile
+++ b/js/Makefile
@@ -40,12 +40,11 @@
src/gen-vdl: $(shell find ../go/src/ -name "*.vdl")
v23 run vdl generate --lang=javascript --js-out-dir=src/gen-vdl v.io/x/media_sharing
-build/bundle.js: src/index.js $(shell find src/ -name "*.js") src/gen-vdl node_modules
- mkdir -p build
-ifndef NOMINIFY
- $(call BROWSERIFY,$<,$@)
-else
+build/bundle.js: src/index.js $(shell find src/ -name "*.js") src/gen-vdl lint node_modules
+ifdef MINIFY
$(call BROWSERIFY-MIN,$<,$@)
+else
+ $(call BROWSERIFY,$<,$@)
endif
build/index.html: public/index.html
diff --git a/js/package.json b/js/package.json
index 1f95d9a..2f579a7 100644
--- a/js/package.json
+++ b/js/package.json
@@ -6,7 +6,9 @@
"main": "src/index.js",
"license": "ISC",
"dependencies": {
- "domready": "~1.0.8"
+ "domready": "~1.0.8",
+ "format": "~0.2.1",
+ "inherits": "~2.0.1"
},
"devDependencies": {
"browserify": "~10.2.0",
diff --git a/js/public/index.html b/js/public/index.html
index 2a0efc7..3dc8ff3 100644
--- a/js/public/index.html
+++ b/js/public/index.html
@@ -5,6 +5,10 @@
<script src="bundle.js"></script>
</head>
<body>
- <div id="content"></div>
+ <div id="content">
+ <input type="file" id="file-input">
+ <br>
+ <div id="status"></div>
+ </div>
</body>
</html>
diff --git a/js/src/file-emitter.js b/js/src/file-emitter.js
new file mode 100644
index 0000000..b31d522
--- /dev/null
+++ b/js/src/file-emitter.js
@@ -0,0 +1,72 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var EE = require('events').EventEmitter;
+var format = require('format');
+var inherits = require('inherits');
+
+module.exports = FileEmitter;
+
+function FileEmitter(input) {
+ EE.call(this);
+
+ // TODO(nlacasse): Consider making these an argument to FileEmitter;
+ this._allowedTypes = ['audio', 'image', 'video'];
+ this._maxSize = 10 * 1000 * 1000; // 10MB
+
+ input.addEventListener('change', this._onFileChange.bind(this), false);
+}
+
+inherits(FileEmitter, EE);
+
+FileEmitter.prototype._isAllowedType = function(type) {
+ for (var i = 0; i < this._allowedTypes.length; i++) {
+ if (type.indexOf(this._allowedTypes[i]) === 0) {
+ return true;
+ }
+ }
+ return false;
+};
+
+FileEmitter.prototype._onFileChange = function(ev) {
+ var files = ev.target.files;
+ if (files.length === 0) {
+ this.emit('error', 'No files selected.');
+ return;
+ }
+
+ // TODO(nlacasse): Consider handling multiple files? For now we just take
+ // the first. Perhaps if multiple files are selected, we send each to a
+ // different media server?
+ var file = files[0];
+
+ if (!this._isAllowedType(file.type)) {
+ this.emit('error', format('Filetype %s is not supported.', file.type));
+ return;
+ }
+
+ // TODO(nlacasse): Consider removing the file size limit.
+ if (file.size > this._maxSize) {
+ this.emit('error', format('File too large.'));
+ return;
+ }
+
+ var reader = new FileReader();
+
+ var self = this;
+ reader.addEventListener('error', function(ev) {
+ self.emit('error', ev);
+ });
+
+ reader.addEventListener('load', function() {
+ self.emit('file', {
+ name: file.name,
+ type: file.type,
+ size: file.size,
+ bytes: new Uint8Array(reader.result)
+ });
+ });
+
+ reader.readAsArrayBuffer(file);
+};
diff --git a/js/src/index.js b/js/src/index.js
index 7571ce0..61c3f44 100644
--- a/js/src/index.js
+++ b/js/src/index.js
@@ -3,7 +3,64 @@
// license that can be found in the LICENSE file.
var domready = require('domready');
+var format = require('format');
+var vanadium = require('vanadium');
-domready(function() {
- document.querySelector('#content').innerText = 'Hello Vanadium World';
-});
+var FileEmitter = require('./file-emitter');
+
+domready(onDomReady);
+
+// Entry point of the app.
+function onDomReady() {
+ vanadium.init(function(err, rt) {
+ if (err) {
+ appendStatus('ERROR: ' + err);
+ return;
+ }
+
+ // Connect the file input to a FileEmitter.
+ var fileInput = document.getElementById('file-input');
+ var fileEmitter = new FileEmitter(fileInput);
+
+ fileEmitter.on('error', function(text) {
+ appendStatus('ERROR: ' + text);
+ });
+
+ fileEmitter.on('file', function(file) {
+ appendStatus(format('Sending file %s of type %s and %d bytes.',
+ file.name, file.type, file.size));
+ sendToDisplay(rt, file, function(err) {
+ if (err) {
+ appendStatus('ERROR: ' + err);
+ return;
+ }
+ appendStatus('Success.');
+ });
+ });
+ });
+}
+
+// Append text to the status div.
+function appendStatus(text) {
+ var status = document.getElementById('status');
+ status.innerHTML += text + '<br>';
+}
+
+function sendToDisplay(rt, file, cb) {
+ var ctx = rt.getContext();
+ var client = rt.newClient();
+ client.bindTo(ctx, 'users/mattr@google.com/media', function(err, s) {
+ if (err) {
+ return cb(err);
+ }
+
+ var promise = s.displayBytes(ctx, file.type);
+ promise.catch(cb);
+ promise.stream.on('error', cb);
+ promise.stream.on('finish', function() { cb(null); });
+
+ // TODO(nlacasse): Chunk these bytes! Currently we send the file in one big
+ // chunk.
+ promise.stream.end(file.bytes);
+ });
+}