mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-928 Restore file upload functionality, improve error appearance, and add translated units and file upload sizes.
This commit is contained in:
@@ -447,8 +447,120 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
||||
if ($scope.clientProperties.keyboardEnabled && !event.defaultPrevented) {
|
||||
client.sendKeyEvent(0, keysym);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Converts the given bytes to a base64-encoded string.
|
||||
*
|
||||
* @param {Uint8Array} bytes A Uint8Array which contains the data to be
|
||||
* encoded as base64.
|
||||
* @return {String} The base64-encoded string.
|
||||
*/
|
||||
function getBase64(bytes) {
|
||||
|
||||
var data = "";
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignores the given event.
|
||||
*
|
||||
* @param {Event} e The event to ignore.
|
||||
*/
|
||||
function ignoreEvent(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the given file to the server.
|
||||
*
|
||||
* @param {File} file The file to upload.
|
||||
*/
|
||||
function uploadFile(file) {
|
||||
|
||||
// Construct reader for file
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
|
||||
// Open file for writing
|
||||
var stream = client.createFileStream(file.type, file.name);
|
||||
|
||||
var valid = true;
|
||||
var bytes = new Uint8Array(reader.result);
|
||||
var offset = 0;
|
||||
|
||||
// Add upload notification
|
||||
$scope.$emit('guacClientFileUploadStart', client, stream.index, file.type, file.name, bytes.length);
|
||||
|
||||
// Invalidate stream on all errors
|
||||
// Continue upload when acknowledged
|
||||
stream.onack = function(status) {
|
||||
|
||||
// Handle errors
|
||||
if (status.isError()) {
|
||||
valid = false;
|
||||
$scope.$emit('guacClientFileUploadError', client, stream.index, file.type, file.name, bytes.length, status.code);
|
||||
}
|
||||
|
||||
// Abort upload if stream is invalid
|
||||
if (!valid) return false;
|
||||
|
||||
// Encode packet as base64
|
||||
var slice = bytes.subarray(offset, offset+4096);
|
||||
var base64 = getBase64(slice);
|
||||
|
||||
// Write packet
|
||||
stream.sendBlob(base64);
|
||||
|
||||
// Advance to next packet
|
||||
offset += 4096;
|
||||
|
||||
// If at end, stop upload
|
||||
if (offset >= bytes.length) {
|
||||
stream.sendEnd();
|
||||
$scope.$emit('guacClientFileUploadProgress', client, stream.index, file.type, file.name, bytes.length, bytes.length);
|
||||
$scope.$emit('guacClientFileUploadEnd', client, stream.index, file.type, file.name, bytes.length);
|
||||
}
|
||||
|
||||
// Otherwise, update progress
|
||||
else
|
||||
$scope.$emit('guacClientFileUploadProgress', client, stream.index, file.type, file.name, bytes.length, offset);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
|
||||
}
|
||||
|
||||
// Handle and ignore dragenter/dragover
|
||||
displayContainer.addEventListener("dragenter", ignoreEvent, false);
|
||||
displayContainer.addEventListener("dragover", ignoreEvent, false);
|
||||
|
||||
// File drop event handler
|
||||
displayContainer.addEventListener("drop", function(e) {
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Ignore file drops if no attached client
|
||||
if (!client) return;
|
||||
|
||||
// Upload each file
|
||||
var files = e.dataTransfer.files;
|
||||
for (var i=0; i<files.length; i++)
|
||||
uploadFile(files[i]);
|
||||
|
||||
}, false);
|
||||
|
||||
/*
|
||||
* END CLIENT DIRECTIVE
|
||||
|
Reference in New Issue
Block a user