Add basic support for file upload via dragging.

This commit is contained in:
Michael Jumper
2013-09-23 20:52:11 -07:00
parent 4a0003b53d
commit 94c0ec1f17
2 changed files with 121 additions and 0 deletions

View File

@@ -533,6 +533,53 @@ Guacamole.Client = function(tunnel) {
tunnel.sendMessage("clipboard", data);
};
/**
* Opens a new file for writing, having the given index, mimetype and
* filename.
*
* @param {Number} index The index of the file to write to. This index must
* be unused.
* @param {String} mimetype The mimetype of the file being sent.
* @param {String} filename The filename of the file being sent.
*/
this.openFile = function(index, mimetype, filename) {
// Do not send requests if not connected
if (!isConnected())
return;
tunnel.sendMessage("file", index, mimetype, filename);
};
/**
* Given the index of a file, writes a blob of data to that file.
*
* @param {Number} index The index of the file to write to.
* @param {String} data Base64-encoded data to write to the file.
*/
this.sendBlob = function(index, data) {
// Do not send requests if not connected
if (!isConnected())
return;
tunnel.sendMessage("blob", index, data);
};
/**
* Marks a currently-open file as closed.
*
* @param {Number} index The index of the file to close.
*/
this.closeFile = function(index) {
// Do not send requests if not connected
if (!isConnected())
return;
tunnel.sendMessage("end", index);
};
/**
* Fired whenever the state of this Guacamole.Client changes.
*

View File

@@ -1042,5 +1042,79 @@ GuacUI.Client.attach = function(guac) {
// Stop detection if press stops
GuacUI.Client.display.addEventListener('touchend', GuacUI.Client.stopLongPressDetect, true);
function _ignore(e) {
e.preventDefault();
e.stopPropagation();
}
function _get_base64(buffer) {
var data = "";
var bytes = new Uint8Array(buffer);
// Produce binary string from bytes in buffer
for (var i=0; i<bytes.byteLength; i++)
data += String.fromCharCode(bytes[i]);
// Convert to base64
return window.btoa(data);
}
function _upload_file(index, file) {
// Construct reader for file
var reader = new FileReader();
reader.onloadend = function() {
// Open file for writing
GuacUI.Client.attachedClient.openFile(index, file.type, file.name);
var buffer = reader.result;
var offset = 0;
function continueUpload() {
// Encode packet as base64
var slice = buffer.slice(offset, offset+4096);
var base64 = _get_base64(slice);
// "Write" packet
GuacUI.Client.attachedClient.sendBlob(index, base64);
// Advance to next packet, or close if EOF
offset += 4096;
if (offset < buffer.byteLength)
window.setTimeout(continueUpload, 500);
else
GuacUI.Client.attachedClient.closeFile(index);
};
// Start upload
window.setTimeout(continueUpload, 500);
};
reader.readAsArrayBuffer(file);
}
// Handle and ignore dragenter/dragover
document.body.addEventListener("dragenter", _ignore, false);
document.body.addEventListener("dragover", _ignore, false);
// File drop event handler
document.body.addEventListener("drop", function(e) {
e.preventDefault();
e.stopPropagation();
// Upload each file
var files = e.dataTransfer.files;
for (var i=0; i<files.length; i++)
_upload_file(i, files[i]);
}, false);
};