mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-190: Update client thumbnail roughly every 5 seconds.
This commit is contained in:
@@ -24,14 +24,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
function defineManagedClient($rootScope, $injector) {
|
function defineManagedClient($rootScope, $injector) {
|
||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
var ClientProperties = $injector.get('ClientProperties');
|
var ClientProperties = $injector.get('ClientProperties');
|
||||||
var ClientIdentifier = $injector.get('ClientIdentifier');
|
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||||
var ClipboardData = $injector.get('ClipboardData');
|
var ClipboardData = $injector.get('ClipboardData');
|
||||||
var ManagedClientState = $injector.get('ManagedClientState');
|
var ManagedClientState = $injector.get('ManagedClientState');
|
||||||
var ManagedDisplay = $injector.get('ManagedDisplay');
|
var ManagedClientThumbnail = $injector.get('ManagedClientThumbnail');
|
||||||
var ManagedFilesystem = $injector.get('ManagedFilesystem');
|
var ManagedDisplay = $injector.get('ManagedDisplay');
|
||||||
var ManagedFileUpload = $injector.get('ManagedFileUpload');
|
var ManagedFilesystem = $injector.get('ManagedFilesystem');
|
||||||
var ManagedShareLink = $injector.get('ManagedShareLink');
|
var ManagedFileUpload = $injector.get('ManagedFileUpload');
|
||||||
|
var ManagedShareLink = $injector.get('ManagedShareLink');
|
||||||
|
|
||||||
// Required services
|
// Required services
|
||||||
var $document = $injector.get('$document');
|
var $document = $injector.get('$document');
|
||||||
@@ -46,7 +47,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
var guacHistory = $injector.get('guacHistory');
|
var guacHistory = $injector.get('guacHistory');
|
||||||
var guacImage = $injector.get('guacImage');
|
var guacImage = $injector.get('guacImage');
|
||||||
var guacVideo = $injector.get('guacVideo');
|
var guacVideo = $injector.get('guacVideo');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount of time to wait between updates to the client
|
||||||
|
* thumbnail, in milliseconds.
|
||||||
|
*
|
||||||
|
* @type Number
|
||||||
|
*/
|
||||||
|
var THUMBNAIL_UPDATE_FREQUENCY = 5000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object which serves as a surrogate interface, encapsulating a Guacamole
|
* Object which serves as a surrogate interface, encapsulating a Guacamole
|
||||||
* client while it is active, allowing it to be detached and reattached
|
* client while it is active, allowing it to be detached and reattached
|
||||||
@@ -98,6 +107,15 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
*/
|
*/
|
||||||
this.name = template.name;
|
this.name = template.name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The most recently-generated thumbnail for this connection, as
|
||||||
|
* stored within the local connection history. If no thumbnail is
|
||||||
|
* stored, this will be null.
|
||||||
|
*
|
||||||
|
* @type ManagedClientThumbnail
|
||||||
|
*/
|
||||||
|
this.thumbnail = template.thumbnail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current clipboard contents.
|
* The current clipboard contents.
|
||||||
*
|
*
|
||||||
@@ -227,45 +245,6 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the thumbnail of the given managed client within the connection
|
|
||||||
* history under its associated ID. If the client is not connected, this
|
|
||||||
* function has no effect.
|
|
||||||
*
|
|
||||||
* @param {String} managedClient
|
|
||||||
* The client whose history entry should be updated.
|
|
||||||
*/
|
|
||||||
var updateHistoryEntry = function updateHistoryEntry(managedClient) {
|
|
||||||
|
|
||||||
var display = managedClient.client.getDisplay();
|
|
||||||
|
|
||||||
// Update stored thumbnail of previous connection
|
|
||||||
if (display && display.getWidth() > 0 && display.getHeight() > 0) {
|
|
||||||
|
|
||||||
// Get screenshot
|
|
||||||
var canvas = display.flatten();
|
|
||||||
|
|
||||||
// Calculate scale of thumbnail (max 320x240, max zoom 100%)
|
|
||||||
var scale = Math.min(320 / canvas.width, 240 / canvas.height, 1);
|
|
||||||
|
|
||||||
// Create thumbnail canvas
|
|
||||||
var thumbnail = $document[0].createElement("canvas");
|
|
||||||
thumbnail.width = canvas.width*scale;
|
|
||||||
thumbnail.height = canvas.height*scale;
|
|
||||||
|
|
||||||
// Scale screenshot to thumbnail
|
|
||||||
var context = thumbnail.getContext("2d");
|
|
||||||
context.drawImage(canvas,
|
|
||||||
0, 0, canvas.width, canvas.height,
|
|
||||||
0, 0, thumbnail.width, thumbnail.height
|
|
||||||
);
|
|
||||||
|
|
||||||
guacHistory.updateThumbnail(managedClient.id, thumbnail.toDataURL("image/png"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the creation of a new audio stream, recorded from the user's
|
* Requests the creation of a new audio stream, recorded from the user's
|
||||||
* local audio input device. If audio input is supported by the connection,
|
* local audio input device. If audio input is supported by the connection,
|
||||||
@@ -403,12 +382,14 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
// Begin streaming audio input if possible
|
// Begin streaming audio input if possible
|
||||||
requestAudioStream(client);
|
requestAudioStream(client);
|
||||||
|
|
||||||
|
// Update thumbnail with initial display contents
|
||||||
|
ManagedClient.updateThumbnail(managedClient);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Update history when disconnecting
|
// Update history when disconnecting
|
||||||
case 4: // Disconnecting
|
case 4: // Disconnecting
|
||||||
case 5: // Disconnected
|
case 5: // Disconnected
|
||||||
updateHistoryEntry(managedClient);
|
ManagedClient.updateThumbnail(managedClient);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -431,6 +412,21 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Automatically update the client thumbnail
|
||||||
|
client.onsync = function syncReceived() {
|
||||||
|
|
||||||
|
var thumbnail = managedClient.thumbnail;
|
||||||
|
var timestamp = new Date().getTime();
|
||||||
|
|
||||||
|
// Update thumbnail if it doesn't exist or is old
|
||||||
|
if (!thumbnail || timestamp - thumbnail.timestamp >= THUMBNAIL_UPDATE_FREQUENCY) {
|
||||||
|
$rootScope.$apply(function updateClientThumbnail() {
|
||||||
|
ManagedClient.updateThumbnail(managedClient);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Handle any received clipboard data
|
// Handle any received clipboard data
|
||||||
client.onclipboard = function clientClipboardReceived(stream, mimetype) {
|
client.onclipboard = function clientClipboardReceived(stream, mimetype) {
|
||||||
|
|
||||||
@@ -651,6 +647,52 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the thumbnail of the given managed client within the connection
|
||||||
|
* history under its associated ID. If the client is not connected, this
|
||||||
|
* function has no effect.
|
||||||
|
*
|
||||||
|
* @param {ManagedClient} managedClient
|
||||||
|
* The client whose history entry should be updated.
|
||||||
|
*/
|
||||||
|
ManagedClient.updateThumbnail = function updateThumbnail(managedClient) {
|
||||||
|
|
||||||
|
var display = managedClient.client.getDisplay();
|
||||||
|
|
||||||
|
// Update stored thumbnail of previous connection
|
||||||
|
if (display && display.getWidth() > 0 && display.getHeight() > 0) {
|
||||||
|
|
||||||
|
// Get screenshot
|
||||||
|
var canvas = display.flatten();
|
||||||
|
|
||||||
|
// Calculate scale of thumbnail (max 320x240, max zoom 100%)
|
||||||
|
var scale = Math.min(320 / canvas.width, 240 / canvas.height, 1);
|
||||||
|
|
||||||
|
// Create thumbnail canvas
|
||||||
|
var thumbnail = $document[0].createElement("canvas");
|
||||||
|
thumbnail.width = canvas.width*scale;
|
||||||
|
thumbnail.height = canvas.height*scale;
|
||||||
|
|
||||||
|
// Scale screenshot to thumbnail
|
||||||
|
var context = thumbnail.getContext("2d");
|
||||||
|
context.drawImage(canvas,
|
||||||
|
0, 0, canvas.width, canvas.height,
|
||||||
|
0, 0, thumbnail.width, thumbnail.height
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store updated thumbnail within client
|
||||||
|
managedClient.thumbnail = new ManagedClientThumbnail({
|
||||||
|
timestamp : new Date().getTime(),
|
||||||
|
canvas : thumbnail
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update historical thumbnail
|
||||||
|
guacHistory.updateThumbnail(managedClient.id, thumbnail.toDataURL("image/png"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
return ManagedClient;
|
return ManagedClient;
|
||||||
|
|
||||||
}]);
|
}]);
|
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ManagedClientThumbnail class used by ManagedClient.
|
||||||
|
*/
|
||||||
|
angular.module('client').factory('ManagedClientThumbnail', [function defineManagedClientThumbnail() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object which represents a thumbnail of the Guacamole client display,
|
||||||
|
* along with the time that the thumbnail was generated.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {ManagedClientThumbnail|Object} [template={}]
|
||||||
|
* The object whose properties should be copied within the new
|
||||||
|
* ManagedClientThumbnail.
|
||||||
|
*/
|
||||||
|
var ManagedClientThumbnail = function ManagedClientThumbnail(template) {
|
||||||
|
|
||||||
|
// Use empty object by default
|
||||||
|
template = template || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time that this thumbnail was generated, as the number of
|
||||||
|
* milliseconds elapsed since midnight of January 1, 1970 UTC.
|
||||||
|
*
|
||||||
|
* @type Number
|
||||||
|
*/
|
||||||
|
this.timestamp = template.timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The thumbnail of the Guacamole client display.
|
||||||
|
*
|
||||||
|
* @type HTMLCanvasElement
|
||||||
|
*/
|
||||||
|
this.canvas = template.canvas;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return ManagedClientThumbnail;
|
||||||
|
|
||||||
|
}]);
|
Reference in New Issue
Block a user